Loading core/java/android/pim/vcard/VCardConfig.java +2 −1 Original line number Diff line number Diff line Loading @@ -53,8 +53,9 @@ public class VCardConfig { * and it has 1 to 1 mapping in all 8bit characters. * If the assumption is not correct, this setting will cause some bug. * </p> * @hide made public just for unit test */ /* package */ static final String DEFAULT_INTERMEDIATE_CHARSET = "ISO-8859-1"; public static final String DEFAULT_INTERMEDIATE_CHARSET = "ISO-8859-1"; /** * The charset used when there's no information affbout what charset should be used to Loading core/java/android/pim/vcard/VCardEntryConstructor.java +4 −82 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ public class VCardEntryConstructor implements VCardInterpreter { // property or implicitly mentioned by its version (e.g. vCard 3.0 recommends UTF-8). private final String mSourceCharset; private final boolean mStrictLineBreakParsing; private final boolean mStrictLineBreaking; private final int mVCardType; private final Account mAccount; Loading Loading @@ -74,7 +74,7 @@ public class VCardEntryConstructor implements VCardInterpreter { } else { mSourceCharset = VCardConfig.DEFAULT_INTERMEDIATE_CHARSET; } mStrictLineBreakParsing = strictLineBreakParsing; mStrictLineBreaking = strictLineBreakParsing; mVCardType = vcardType; mAccount = account; } Loading Loading @@ -180,86 +180,8 @@ public class VCardEntryConstructor implements VCardInterpreter { mCurrentProperty.setPropertyBytes(Base64.decodeBase64(value.getBytes())); return value; } else if (encoding.equals("QUOTED-PRINTABLE")) { // "= " -> " ", "=\t" -> "\t". // Previous code had done this replacement. Keep on the safe side. StringBuilder builder = new StringBuilder(); int length = value.length(); for (int i = 0; i < length; i++) { char ch = value.charAt(i); if (ch == '=' && i < length - 1) { char nextCh = value.charAt(i + 1); if (nextCh == ' ' || nextCh == '\t') { builder.append(nextCh); i++; continue; } } builder.append(ch); } String quotedPrintable = builder.toString(); String[] lines; if (mStrictLineBreakParsing) { lines = quotedPrintable.split("\r\n"); } else { builder = new StringBuilder(); length = quotedPrintable.length(); ArrayList<String> list = new ArrayList<String>(); for (int i = 0; i < length; i++) { char ch = quotedPrintable.charAt(i); if (ch == '\n') { list.add(builder.toString()); builder = new StringBuilder(); } else if (ch == '\r') { list.add(builder.toString()); builder = new StringBuilder(); if (i < length - 1) { char nextCh = quotedPrintable.charAt(i + 1); if (nextCh == '\n') { i++; } } } else { builder.append(ch); } } String finalLine = builder.toString(); if (finalLine.length() > 0) { list.add(finalLine); } lines = list.toArray(new String[0]); } builder = new StringBuilder(); for (String line : lines) { if (line.endsWith("=")) { line = line.substring(0, line.length() - 1); } builder.append(line); } byte[] bytes; try { bytes = builder.toString().getBytes(sourceCharset); } catch (UnsupportedEncodingException e1) { Log.e(LOG_TAG, "Failed to encode: charset=" + targetCharset); bytes = builder.toString().getBytes(); } try { bytes = QuotedPrintableCodec.decodeQuotedPrintable(bytes); } catch (DecoderException e) { Log.e(LOG_TAG, "Failed to decode quoted-printable: " + e); return ""; } try { String ret = new String(bytes, targetCharset); return ret; } catch (UnsupportedEncodingException e) { Log.e(LOG_TAG, "Failed to encode: charset=" + targetCharset); return new String(bytes); } return VCardUtils.parseQuotedPrintable( value, mStrictLineBreaking, sourceCharset, targetCharset); } Log.w(LOG_TAG, "Unknown encoding. Fall back to default."); } Loading core/java/android/pim/vcard/VCardUtils.java +97 −0 Original line number Diff line number Diff line Loading @@ -22,7 +22,12 @@ import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.CommonDataKinds.StructuredPostal; import android.telephony.PhoneNumberUtils; import android.text.TextUtils; import android.util.Log; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.net.QuotedPrintableCodec; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; Loading @@ -36,6 +41,8 @@ import java.util.Set; * Utilities for VCard handling codes. */ public class VCardUtils { private static final String LOG_TAG = "VCardUtils"; // Note that not all types are included in this map/set, since, for example, TYPE_HOME_FAX is // converted to two parameter Strings. These only contain some minor fields valid in both // vCard and current (as of 2009-08-07) Contacts structure. Loading Loading @@ -540,6 +547,96 @@ public class VCardUtils { return true; } //// The methods bellow may be used by unit test. /** * @hide */ public static String parseQuotedPrintable(String value, boolean strictLineBreaking, String sourceCharset, String targetCharset) { // "= " -> " ", "=\t" -> "\t". // Previous code had done this replacement. Keep on the safe side. final String quotedPrintable; { final StringBuilder builder = new StringBuilder(); final int length = value.length(); for (int i = 0; i < length; i++) { char ch = value.charAt(i); if (ch == '=' && i < length - 1) { char nextCh = value.charAt(i + 1); if (nextCh == ' ' || nextCh == '\t') { builder.append(nextCh); i++; continue; } } builder.append(ch); } quotedPrintable = builder.toString(); } String[] lines; if (strictLineBreaking) { lines = quotedPrintable.split("\r\n"); } else { StringBuilder builder = new StringBuilder(); final int length = quotedPrintable.length(); ArrayList<String> list = new ArrayList<String>(); for (int i = 0; i < length; i++) { char ch = quotedPrintable.charAt(i); if (ch == '\n') { list.add(builder.toString()); builder = new StringBuilder(); } else if (ch == '\r') { list.add(builder.toString()); builder = new StringBuilder(); if (i < length - 1) { char nextCh = quotedPrintable.charAt(i + 1); if (nextCh == '\n') { i++; } } } else { builder.append(ch); } } final String lastLine = builder.toString(); if (lastLine.length() > 0) { list.add(lastLine); } lines = list.toArray(new String[0]); } final StringBuilder builder = new StringBuilder(); for (String line : lines) { if (line.endsWith("=")) { line = line.substring(0, line.length() - 1); } builder.append(line); } byte[] bytes; try { bytes = builder.toString().getBytes(sourceCharset); } catch (UnsupportedEncodingException e1) { Log.e(LOG_TAG, "Failed to encode: charset=" + targetCharset); bytes = builder.toString().getBytes(); } try { bytes = QuotedPrintableCodec.decodeQuotedPrintable(bytes); } catch (DecoderException e) { Log.e(LOG_TAG, "Failed to decode quoted-printable: " + e); return ""; } try { return new String(bytes, targetCharset); } catch (UnsupportedEncodingException e) { Log.e(LOG_TAG, "Failed to encode: charset=" + targetCharset); return new String(bytes); } } private VCardUtils() { } } core/tests/coretests/src/android/pim/vcard/VCardExporterTests.java +3 −3 Original line number Diff line number Diff line Loading @@ -17,7 +17,9 @@ package android.pim.vcard; import android.content.ContentValues; import android.pim.vcard.VCardConfig; import android.pim.vcard.test_utils.ContactEntry; import android.pim.vcard.test_utils.PropertyNodesVerifierElem; import android.pim.vcard.test_utils.PropertyNodesVerifierElem.TypeSet; import android.provider.ContactsContract.CommonDataKinds.Email; import android.provider.ContactsContract.CommonDataKinds.Event; import android.provider.ContactsContract.CommonDataKinds.Im; Loading @@ -31,8 +33,6 @@ import android.provider.ContactsContract.CommonDataKinds.StructuredName; import android.provider.ContactsContract.CommonDataKinds.StructuredPostal; import android.provider.ContactsContract.CommonDataKinds.Website; import android.pim.vcard.PropertyNodesVerifierElem.TypeSet; import java.util.Arrays; /** Loading core/tests/coretests/src/android/pim/vcard/VCardImporterTests.java +3 −2 Original line number Diff line number Diff line Loading @@ -16,7 +16,9 @@ package android.pim.vcard; import android.content.ContentValues; import android.pim.vcard.VCardConfig; import android.pim.vcard.test_utils.ContentValuesVerifier; import android.pim.vcard.test_utils.ContentValuesVerifierElem; import android.pim.vcard.test_utils.PropertyNodesVerifierElem.TypeSet; import android.provider.ContactsContract.Data; import android.provider.ContactsContract.CommonDataKinds.Email; import android.provider.ContactsContract.CommonDataKinds.Event; Loading @@ -29,7 +31,6 @@ import android.provider.ContactsContract.CommonDataKinds.StructuredPostal; import android.provider.ContactsContract.CommonDataKinds.Website; import com.android.frameworks.coretests.R; import android.pim.vcard.PropertyNodesVerifierElem.TypeSet; import java.util.Arrays; Loading Loading
core/java/android/pim/vcard/VCardConfig.java +2 −1 Original line number Diff line number Diff line Loading @@ -53,8 +53,9 @@ public class VCardConfig { * and it has 1 to 1 mapping in all 8bit characters. * If the assumption is not correct, this setting will cause some bug. * </p> * @hide made public just for unit test */ /* package */ static final String DEFAULT_INTERMEDIATE_CHARSET = "ISO-8859-1"; public static final String DEFAULT_INTERMEDIATE_CHARSET = "ISO-8859-1"; /** * The charset used when there's no information affbout what charset should be used to Loading
core/java/android/pim/vcard/VCardEntryConstructor.java +4 −82 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ public class VCardEntryConstructor implements VCardInterpreter { // property or implicitly mentioned by its version (e.g. vCard 3.0 recommends UTF-8). private final String mSourceCharset; private final boolean mStrictLineBreakParsing; private final boolean mStrictLineBreaking; private final int mVCardType; private final Account mAccount; Loading Loading @@ -74,7 +74,7 @@ public class VCardEntryConstructor implements VCardInterpreter { } else { mSourceCharset = VCardConfig.DEFAULT_INTERMEDIATE_CHARSET; } mStrictLineBreakParsing = strictLineBreakParsing; mStrictLineBreaking = strictLineBreakParsing; mVCardType = vcardType; mAccount = account; } Loading Loading @@ -180,86 +180,8 @@ public class VCardEntryConstructor implements VCardInterpreter { mCurrentProperty.setPropertyBytes(Base64.decodeBase64(value.getBytes())); return value; } else if (encoding.equals("QUOTED-PRINTABLE")) { // "= " -> " ", "=\t" -> "\t". // Previous code had done this replacement. Keep on the safe side. StringBuilder builder = new StringBuilder(); int length = value.length(); for (int i = 0; i < length; i++) { char ch = value.charAt(i); if (ch == '=' && i < length - 1) { char nextCh = value.charAt(i + 1); if (nextCh == ' ' || nextCh == '\t') { builder.append(nextCh); i++; continue; } } builder.append(ch); } String quotedPrintable = builder.toString(); String[] lines; if (mStrictLineBreakParsing) { lines = quotedPrintable.split("\r\n"); } else { builder = new StringBuilder(); length = quotedPrintable.length(); ArrayList<String> list = new ArrayList<String>(); for (int i = 0; i < length; i++) { char ch = quotedPrintable.charAt(i); if (ch == '\n') { list.add(builder.toString()); builder = new StringBuilder(); } else if (ch == '\r') { list.add(builder.toString()); builder = new StringBuilder(); if (i < length - 1) { char nextCh = quotedPrintable.charAt(i + 1); if (nextCh == '\n') { i++; } } } else { builder.append(ch); } } String finalLine = builder.toString(); if (finalLine.length() > 0) { list.add(finalLine); } lines = list.toArray(new String[0]); } builder = new StringBuilder(); for (String line : lines) { if (line.endsWith("=")) { line = line.substring(0, line.length() - 1); } builder.append(line); } byte[] bytes; try { bytes = builder.toString().getBytes(sourceCharset); } catch (UnsupportedEncodingException e1) { Log.e(LOG_TAG, "Failed to encode: charset=" + targetCharset); bytes = builder.toString().getBytes(); } try { bytes = QuotedPrintableCodec.decodeQuotedPrintable(bytes); } catch (DecoderException e) { Log.e(LOG_TAG, "Failed to decode quoted-printable: " + e); return ""; } try { String ret = new String(bytes, targetCharset); return ret; } catch (UnsupportedEncodingException e) { Log.e(LOG_TAG, "Failed to encode: charset=" + targetCharset); return new String(bytes); } return VCardUtils.parseQuotedPrintable( value, mStrictLineBreaking, sourceCharset, targetCharset); } Log.w(LOG_TAG, "Unknown encoding. Fall back to default."); } Loading
core/java/android/pim/vcard/VCardUtils.java +97 −0 Original line number Diff line number Diff line Loading @@ -22,7 +22,12 @@ import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.CommonDataKinds.StructuredPostal; import android.telephony.PhoneNumberUtils; import android.text.TextUtils; import android.util.Log; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.net.QuotedPrintableCodec; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; Loading @@ -36,6 +41,8 @@ import java.util.Set; * Utilities for VCard handling codes. */ public class VCardUtils { private static final String LOG_TAG = "VCardUtils"; // Note that not all types are included in this map/set, since, for example, TYPE_HOME_FAX is // converted to two parameter Strings. These only contain some minor fields valid in both // vCard and current (as of 2009-08-07) Contacts structure. Loading Loading @@ -540,6 +547,96 @@ public class VCardUtils { return true; } //// The methods bellow may be used by unit test. /** * @hide */ public static String parseQuotedPrintable(String value, boolean strictLineBreaking, String sourceCharset, String targetCharset) { // "= " -> " ", "=\t" -> "\t". // Previous code had done this replacement. Keep on the safe side. final String quotedPrintable; { final StringBuilder builder = new StringBuilder(); final int length = value.length(); for (int i = 0; i < length; i++) { char ch = value.charAt(i); if (ch == '=' && i < length - 1) { char nextCh = value.charAt(i + 1); if (nextCh == ' ' || nextCh == '\t') { builder.append(nextCh); i++; continue; } } builder.append(ch); } quotedPrintable = builder.toString(); } String[] lines; if (strictLineBreaking) { lines = quotedPrintable.split("\r\n"); } else { StringBuilder builder = new StringBuilder(); final int length = quotedPrintable.length(); ArrayList<String> list = new ArrayList<String>(); for (int i = 0; i < length; i++) { char ch = quotedPrintable.charAt(i); if (ch == '\n') { list.add(builder.toString()); builder = new StringBuilder(); } else if (ch == '\r') { list.add(builder.toString()); builder = new StringBuilder(); if (i < length - 1) { char nextCh = quotedPrintable.charAt(i + 1); if (nextCh == '\n') { i++; } } } else { builder.append(ch); } } final String lastLine = builder.toString(); if (lastLine.length() > 0) { list.add(lastLine); } lines = list.toArray(new String[0]); } final StringBuilder builder = new StringBuilder(); for (String line : lines) { if (line.endsWith("=")) { line = line.substring(0, line.length() - 1); } builder.append(line); } byte[] bytes; try { bytes = builder.toString().getBytes(sourceCharset); } catch (UnsupportedEncodingException e1) { Log.e(LOG_TAG, "Failed to encode: charset=" + targetCharset); bytes = builder.toString().getBytes(); } try { bytes = QuotedPrintableCodec.decodeQuotedPrintable(bytes); } catch (DecoderException e) { Log.e(LOG_TAG, "Failed to decode quoted-printable: " + e); return ""; } try { return new String(bytes, targetCharset); } catch (UnsupportedEncodingException e) { Log.e(LOG_TAG, "Failed to encode: charset=" + targetCharset); return new String(bytes); } } private VCardUtils() { } }
core/tests/coretests/src/android/pim/vcard/VCardExporterTests.java +3 −3 Original line number Diff line number Diff line Loading @@ -17,7 +17,9 @@ package android.pim.vcard; import android.content.ContentValues; import android.pim.vcard.VCardConfig; import android.pim.vcard.test_utils.ContactEntry; import android.pim.vcard.test_utils.PropertyNodesVerifierElem; import android.pim.vcard.test_utils.PropertyNodesVerifierElem.TypeSet; import android.provider.ContactsContract.CommonDataKinds.Email; import android.provider.ContactsContract.CommonDataKinds.Event; import android.provider.ContactsContract.CommonDataKinds.Im; Loading @@ -31,8 +33,6 @@ import android.provider.ContactsContract.CommonDataKinds.StructuredName; import android.provider.ContactsContract.CommonDataKinds.StructuredPostal; import android.provider.ContactsContract.CommonDataKinds.Website; import android.pim.vcard.PropertyNodesVerifierElem.TypeSet; import java.util.Arrays; /** Loading
core/tests/coretests/src/android/pim/vcard/VCardImporterTests.java +3 −2 Original line number Diff line number Diff line Loading @@ -16,7 +16,9 @@ package android.pim.vcard; import android.content.ContentValues; import android.pim.vcard.VCardConfig; import android.pim.vcard.test_utils.ContentValuesVerifier; import android.pim.vcard.test_utils.ContentValuesVerifierElem; import android.pim.vcard.test_utils.PropertyNodesVerifierElem.TypeSet; import android.provider.ContactsContract.Data; import android.provider.ContactsContract.CommonDataKinds.Email; import android.provider.ContactsContract.CommonDataKinds.Event; Loading @@ -29,7 +31,6 @@ import android.provider.ContactsContract.CommonDataKinds.StructuredPostal; import android.provider.ContactsContract.CommonDataKinds.Website; import com.android.frameworks.coretests.R; import android.pim.vcard.PropertyNodesVerifierElem.TypeSet; import java.util.Arrays; Loading