Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a7bb3ba5 authored by Daisuke Miyakawa's avatar Daisuke Miyakawa Committed by Android Git Automerger
Browse files

am f996ed9f: Merge "Make vCard importer/exporter aware of multi-byte parameters." into gingerbread

Merge commit 'f996ed9f' into gingerbread-plus-aosp

* commit 'f996ed9f':
  Make vCard importer/exporter aware of multi-byte parameters.
parents 3719f856 f996ed9f
Loading
Loading
Loading
Loading
+26 −14
Original line number Diff line number Diff line
@@ -1463,6 +1463,9 @@ public class VCardBuilder {
                    parameterList.add(VCardConstants.PARAM_TYPE_VOICE);
                } else if (VCardUtils.isMobilePhoneLabel(label)) {
                    parameterList.add(VCardConstants.PARAM_TYPE_CELL);
                } else if (mIsV30) {
                    // This label is appropriately encoded in appendTypeParameters.
                    parameterList.add(label);
                } else {
                    final String upperLabel = label.toUpperCase();
                    if (VCardUtils.isValidInV21ButUnknownToContactsPhoteType(upperLabel)) {
@@ -1741,12 +1744,20 @@ public class VCardBuilder {
        // which would be recommended way in vcard 3.0 though not valid in vCard 2.1.
        boolean first = true;
        for (final String typeValue : types) {
            if (VCardConfig.isV30(mVCardType)) {
                // Note: vCard 3.0 specifies the different type of acceptable type Strings, but
                //       we don't emit that kind of vCard 3.0 specific type since there should be
                //       high probabilyty in which external importers cannot understand them.
                //
                // e.g. TYPE="\u578B\u306B\u3087" (vCard 3.0 allows non-Ascii characters if they
                //      are quoted.)
                if (first) {
                    first = false;
                } else {
                    mBuilder.append(VCARD_PARAM_SEPARATOR);
                }
                appendTypeParameter(VCardUtils.toStringAvailableAsV30ParameValue(typeValue));
            } else {  // vCard 2.1
                if (!VCardUtils.isV21Word(typeValue)) {
                    continue;
                }
@@ -1758,6 +1769,7 @@ public class VCardBuilder {
                appendTypeParameter(typeValue);
            }
        }
    }

    /**
     * VCARD_PARAM_SEPARATOR must be appended before this method being called.
+4 −0
Original line number Diff line number Diff line
@@ -157,11 +157,15 @@ public class VCardEntryConstructor implements VCardInterpreter {
        mParamType = type;
    }

    @Override
    public void propertyParamValue(String value) {
        if (mParamType == null) {
            // From vCard 2.1 specification. vCard 3.0 formally does not allow this case.
            mParamType = "TYPE";
        }
        if (!VCardUtils.containsOnlyAlphaDigitHyphen(value)) {
            value = encodeString(value, mCharsetForDecodedBytes);
        }
        mCurrentProperty.addParameter(mParamType, value);
        mParamType = null;
    }
+38 −1
Original line number Diff line number Diff line
@@ -16,10 +16,10 @@
package android.pim.vcard;

import android.content.ContentProviderOperation;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.CommonDataKinds.Im;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.provider.ContactsContract.Data;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;

@@ -477,6 +477,43 @@ public class VCardUtils {
        return true;
    }

    /**
     * <P>
     * Returns String available as parameter value in vCard 3.0.
     * </P>
     * <P>
     * RFC 2426 requires vCard composer to quote parameter values when it contains
     * semi-colon, for example (See RFC 2426 for more information).
     * This method checks whether the given String can be used without quotes.
     * </P>
     * <P>
     * Note: We remove DQUOTE silently for now.
     * </P>
     */
    public static String toStringAvailableAsV30ParameValue(String value) {
        if (TextUtils.isEmpty(value)) {
            value = "";
        }
        final int asciiFirst = 0x20;
        final int asciiLast = 0x7E;  // included
        final StringBuilder builder = new StringBuilder();
        final int length = value.length();
        boolean needQuote = false;
        for (int i = 0; i < length; i = value.offsetByCodePoints(i, 1)) {
            final int codePoint = value.codePointAt(i);
            if (codePoint < asciiFirst || codePoint == '"') {
                // CTL characters and DQUOTE are never accepted. Remove them.
                continue;
            }
            builder.appendCodePoint(codePoint);
            if (codePoint == ':' || codePoint == ',' || codePoint == ' ') {
                needQuote = true;
            }
        }
        final String result = builder.toString();
        return ((needQuote || result.isEmpty()) ? ('"' + result + '"') : result);
    }

    public static String toHalfWidthString(final String orgString) {
        if (TextUtils.isEmpty(orgString)) {
            return null;
+5 −0
Original line number Diff line number Diff line
BEGIN:VCARD
VERSION:3.0
N:F;G;M;;
TEL;TYPE="费":1
END:VCARD
+22 −0
Original line number Diff line number Diff line
@@ -1008,4 +1008,26 @@ public class VCardImporterTests extends VCardTestsBase {
                .put(Phone.TYPE, Phone.TYPE_PAGER)
                .put(Phone.NUMBER, "6101231234@pagersample.com");
    }

    public void testMultiBytePropV30_Parse() {
        mVerifier.initForImportTest(V30, R.raw.v30_multibyte_param);
        mVerifier.addPropertyNodesVerifierElem()
                .addExpectedNodeWithOrder("VERSION", "3.0")
                .addExpectedNodeWithOrder("N", Arrays.asList("F", "G", "M", "", ""))
                .addExpectedNodeWithOrder("TEL", "1", new TypeSet("\u8D39"));
    }

    public void testMultiBytePropV30() {
        mVerifier.initForImportTest(V30, R.raw.v30_multibyte_param);
        final ContentValuesVerifierElem elem = mVerifier.addContentValuesVerifierElem();
        elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
                .put(StructuredName.FAMILY_NAME, "F")
                .put(StructuredName.MIDDLE_NAME, "M")
                .put(StructuredName.GIVEN_NAME, "G")
                .put(StructuredName.DISPLAY_NAME, "G M F");
        elem.addExpected(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.TYPE, Phone.TYPE_CUSTOM)
                .put(Phone.LABEL, "\u8D39")
                .put(Phone.NUMBER, "1");
    }
}
Loading