summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorDaisuke Miyakawa <dmiyakawa@google.com>2009-11-20 16:09:34 +0900
committerDaisuke Miyakawa <dmiyakawa@google.com>2009-11-20 16:13:07 +0900
commita750fdd765ec253ffa8bf3d4848d5c3a35e1979b (patch)
treee423b7aec597ea8117ea767f9ea1516663d89939 /core
parentb439f561a6aa3900f1850e71a4aa60618af13f90 (diff)
downloadframeworks_base-a750fdd765ec253ffa8bf3d4848d5c3a35e1979b.zip
frameworks_base-a750fdd765ec253ffa8bf3d4848d5c3a35e1979b.tar.gz
frameworks_base-a750fdd765ec253ffa8bf3d4848d5c3a35e1979b.tar.bz2
Fix a problem in which Android custom fields are not emitted correctly in non-Ascii languages.
Internal issue number: 2195990
Diffstat (limited to 'core')
-rw-r--r--core/java/android/pim/vcard/VCardBuilder.java79
-rw-r--r--core/java/android/pim/vcard/VCardParser_V21.java3
-rw-r--r--core/java/android/pim/vcard/VCardUtils.java75
3 files changed, 98 insertions, 59 deletions
diff --git a/core/java/android/pim/vcard/VCardBuilder.java b/core/java/android/pim/vcard/VCardBuilder.java
index 3980940..09ac1fd 100644
--- a/core/java/android/pim/vcard/VCardBuilder.java
+++ b/core/java/android/pim/vcard/VCardBuilder.java
@@ -1536,13 +1536,10 @@ public class VCardBuilder {
}
public void appendAndroidSpecificProperty(final String mimeType, ContentValues contentValues) {
- List<String> rawValueList = new ArrayList<String>();
- rawValueList.add(mimeType);
- final List<String> columnNameList;
if (!sAllowedAndroidPropertySet.contains(mimeType)) {
return;
}
-
+ final List<String> rawValueList = new ArrayList<String>();
for (int i = 1; i <= VCardConstants.MAX_DATA_COLUMN; i++) {
String value = contentValues.getAsString("data" + i);
if (value == null) {
@@ -1551,8 +1548,38 @@ public class VCardBuilder {
rawValueList.add(value);
}
- appendLineWithCharsetAndQPDetection(
- VCardConstants.PROPERTY_X_ANDROID_CUSTOM, rawValueList);
+ boolean needCharset =
+ (mShouldAppendCharsetParam &&
+ !VCardUtils.containsOnlyNonCrLfPrintableAscii(rawValueList));
+ boolean reallyUseQuotedPrintable =
+ (mShouldUseQuotedPrintable &&
+ !VCardUtils.containsOnlyNonCrLfPrintableAscii(rawValueList));
+ mBuilder.append(VCardConstants.PROPERTY_X_ANDROID_CUSTOM);
+ if (needCharset) {
+ mBuilder.append(VCARD_PARAM_SEPARATOR);
+ mBuilder.append(mVCardCharsetParameter);
+ }
+ if (reallyUseQuotedPrintable) {
+ mBuilder.append(VCARD_PARAM_SEPARATOR);
+ mBuilder.append(VCARD_PARAM_ENCODING_QP);
+ }
+ mBuilder.append(VCARD_DATA_SEPARATOR);
+ mBuilder.append(mimeType); // Should not be encoded.
+ for (String rawValue : rawValueList) {
+ final String encodedValue;
+ if (reallyUseQuotedPrintable) {
+ encodedValue = encodeQuotedPrintable(rawValue);
+ } else {
+ // TODO: one line may be too huge, which may be invalid in vCard 3.0
+ // (which says "When generating a content line, lines longer than
+ // 75 characters SHOULD be folded"), though several
+ // (even well-known) applications do not care this.
+ encodedValue = escapeCharacters(rawValue);
+ }
+ mBuilder.append(VCARD_ITEM_SEPARATOR);
+ mBuilder.append(encodedValue);
+ }
+ mBuilder.append(VCARD_END_OF_LINE);
}
public void appendLineWithCharsetAndQPDetection(final String propertyName,
@@ -1560,7 +1587,7 @@ public class VCardBuilder {
appendLineWithCharsetAndQPDetection(propertyName, null, rawValue);
}
- private void appendLineWithCharsetAndQPDetection(
+ public void appendLineWithCharsetAndQPDetection(
final String propertyName, final List<String> rawValueList) {
appendLineWithCharsetAndQPDetection(propertyName, null, rawValueList);
}
@@ -1578,22 +1605,12 @@ public class VCardBuilder {
public void appendLineWithCharsetAndQPDetection(final String propertyName,
final List<String> parameterList, final List<String> rawValueList) {
- boolean needCharset = false;
- boolean reallyUseQuotedPrintable = false;
- for (String rawValue : rawValueList) {
- if (!needCharset && mShouldUseQuotedPrintable &&
- !VCardUtils.containsOnlyPrintableAscii(rawValue)) {
- needCharset = true;
- }
- if (!reallyUseQuotedPrintable &&
- !VCardUtils.containsOnlyNonCrLfPrintableAscii(rawValue)) {
- reallyUseQuotedPrintable = true;
- }
- if (needCharset && reallyUseQuotedPrintable) {
- break;
- }
- }
-
+ boolean needCharset =
+ (mShouldAppendCharsetParam &&
+ !VCardUtils.containsOnlyNonCrLfPrintableAscii(rawValueList));
+ boolean reallyUseQuotedPrintable =
+ (mShouldUseQuotedPrintable &&
+ !VCardUtils.containsOnlyNonCrLfPrintableAscii(rawValueList));
appendLine(propertyName, parameterList, rawValueList,
needCharset, reallyUseQuotedPrintable);
}
@@ -1610,8 +1627,9 @@ public class VCardBuilder {
}
public void appendLine(final String propertyName,
- final String rawValue, final boolean needCharset, boolean needQuotedPrintable) {
- appendLine(propertyName, null, rawValue, needCharset, needQuotedPrintable);
+ final String rawValue, final boolean needCharset,
+ boolean reallyUseQuotedPrintable) {
+ appendLine(propertyName, null, rawValue, needCharset, reallyUseQuotedPrintable);
}
public void appendLine(final String propertyName, final List<String> parameterList,
@@ -1620,7 +1638,8 @@ public class VCardBuilder {
}
public void appendLine(final String propertyName, final List<String> parameterList,
- final String rawValue, final boolean needCharset, boolean needQuotedPrintable) {
+ final String rawValue, final boolean needCharset,
+ boolean reallyUseQuotedPrintable) {
mBuilder.append(propertyName);
if (parameterList != null && parameterList.size() > 0) {
mBuilder.append(VCARD_PARAM_SEPARATOR);
@@ -1632,7 +1651,7 @@ public class VCardBuilder {
}
final String encodedValue;
- if (needQuotedPrintable) {
+ if (reallyUseQuotedPrintable) {
mBuilder.append(VCARD_PARAM_SEPARATOR);
mBuilder.append(VCARD_PARAM_ENCODING_QP);
encodedValue = encodeQuotedPrintable(rawValue);
@@ -1664,14 +1683,16 @@ public class VCardBuilder {
mBuilder.append(VCARD_PARAM_SEPARATOR);
mBuilder.append(mVCardCharsetParameter);
}
+ if (needQuotedPrintable) {
+ mBuilder.append(VCARD_PARAM_SEPARATOR);
+ mBuilder.append(VCARD_PARAM_ENCODING_QP);
+ }
mBuilder.append(VCARD_DATA_SEPARATOR);
boolean first = true;
for (String rawValue : rawValueList) {
final String encodedValue;
if (needQuotedPrintable) {
- mBuilder.append(VCARD_PARAM_SEPARATOR);
- mBuilder.append(VCARD_PARAM_ENCODING_QP);
encodedValue = encodeQuotedPrintable(rawValue);
} else {
// TODO: one line may be too huge, which may be invalid in vCard 3.0
diff --git a/core/java/android/pim/vcard/VCardParser_V21.java b/core/java/android/pim/vcard/VCardParser_V21.java
index ec569d4..e7c19cf 100644
--- a/core/java/android/pim/vcard/VCardParser_V21.java
+++ b/core/java/android/pim/vcard/VCardParser_V21.java
@@ -117,9 +117,6 @@ public class VCardParser_V21 extends VCardParser {
this(detector.getEstimatedType());
}
- /**
- * TODO: Merge detector and parser mode.
- */
public VCardParser_V21(int parseType) {
super(parseType);
if (parseType == VCardConfig.PARSE_TYPE_FOMA) {
diff --git a/core/java/android/pim/vcard/VCardUtils.java b/core/java/android/pim/vcard/VCardUtils.java
index 80457bb..ec75a98 100644
--- a/core/java/android/pim/vcard/VCardUtils.java
+++ b/core/java/android/pim/vcard/VCardUtils.java
@@ -352,6 +352,13 @@ public class VCardUtils {
if (values == null) {
return true;
}
+ return containsOnlyPrintableAscii(Arrays.asList(values));
+ }
+
+ public static boolean containsOnlyPrintableAscii(final Collection<String> values) {
+ if (values == null) {
+ return true;
+ }
final int asciiFirst = 0x20;
final int asciiLast = 0x7E; // included
for (final String value : values) {
@@ -378,6 +385,13 @@ public class VCardUtils {
if (values == null) {
return true;
}
+ return containsOnlyNonCrLfPrintableAscii(Arrays.asList(values));
+ }
+
+ public static boolean containsOnlyNonCrLfPrintableAscii(final Collection<String> values) {
+ if (values == null) {
+ return true;
+ }
final int asciiFirst = 0x20;
final int asciiLast = 0x7E; // included
for (final String value : values) {
@@ -399,32 +413,6 @@ public class VCardUtils {
new HashSet<Character>(Arrays.asList('[', ']', '=', ':', '.', ',', ' '));
/**
- * <P>
- * Returns true when the given String is categorized as "word" specified in vCard spec 2.1.
- * </P>
- * <P>
- * vCard 2.1 specifies:<BR />
- * word = &lt;any printable 7bit us-ascii except []=:., &gt;
- * </P>
- */
- public static boolean isV21Word(final String value) {
- if (TextUtils.isEmpty(value)) {
- return true;
- }
- final int asciiFirst = 0x20;
- final int asciiLast = 0x7E; // included
- final int length = value.length();
- for (int i = 0; i < length; i = value.offsetByCodePoints(i, 1)) {
- final int c = value.codePointAt(i);
- if (!(asciiFirst <= c && c <= asciiLast) ||
- sUnAcceptableAsciiInV21WordSet.contains((char)c)) {
- return false;
- }
- }
- return true;
- }
-
- /**
* This is useful since vCard 3.0 often requires the ("X-") properties and groups
* should contain only alphabets, digits, and hyphen.
*
@@ -437,6 +425,13 @@ public class VCardUtils {
if (values == null) {
return true;
}
+ return containsOnlyAlphaDigitHyphen(Arrays.asList(values));
+ }
+
+ public static boolean containsOnlyAlphaDigitHyphen(final Collection<String> values) {
+ if (values == null) {
+ return true;
+ }
final int upperAlphabetFirst = 0x41; // A
final int upperAlphabetAfterLast = 0x5b; // [
final int lowerAlphabetFirst = 0x61; // a
@@ -461,7 +456,33 @@ public class VCardUtils {
}
return true;
}
-
+
+ /**
+ * <P>
+ * Returns true when the given String is categorized as "word" specified in vCard spec 2.1.
+ * </P>
+ * <P>
+ * vCard 2.1 specifies:<BR />
+ * word = &lt;any printable 7bit us-ascii except []=:., &gt;
+ * </P>
+ */
+ public static boolean isV21Word(final String value) {
+ if (TextUtils.isEmpty(value)) {
+ return true;
+ }
+ final int asciiFirst = 0x20;
+ final int asciiLast = 0x7E; // included
+ final int length = value.length();
+ for (int i = 0; i < length; i = value.offsetByCodePoints(i, 1)) {
+ final int c = value.codePointAt(i);
+ if (!(asciiFirst <= c && c <= asciiLast) ||
+ sUnAcceptableAsciiInV21WordSet.contains((char)c)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
public static String toHalfWidthString(final String orgString) {
if (TextUtils.isEmpty(orgString)) {
return null;