diff options
| author | Daisuke Miyakawa <dmiyakawa@google.com> | 2010-04-19 14:15:29 +0900 |
|---|---|---|
| committer | Daisuke Miyakawa <dmiyakawa@google.com> | 2010-04-19 18:52:08 +0900 |
| commit | 931a0a94321d948014f44170d4cee9eb1fc05310 (patch) | |
| tree | 6d6d1c45f05cbeca12fe45d3d816ee91cc7cf4c4 /core/java/android/pim | |
| parent | e6b205bbf21a741f1541751eb1375a58d6a9fc6c (diff) | |
| download | frameworks_base-931a0a94321d948014f44170d4cee9eb1fc05310.zip frameworks_base-931a0a94321d948014f44170d4cee9eb1fc05310.tar.gz frameworks_base-931a0a94321d948014f44170d4cee9eb1fc05310.tar.bz2 | |
Refactor vCard so that it correctly choose charset while importing
some files.
Change-Id: I27600e260cd7ca42a25481d5ff61f262c9328d61
Diffstat (limited to 'core/java/android/pim')
| -rw-r--r-- | core/java/android/pim/vcard/VCardComposer.java | 2 | ||||
| -rw-r--r-- | core/java/android/pim/vcard/VCardConfig.java | 177 | ||||
| -rw-r--r-- | core/java/android/pim/vcard/VCardEntryCommitter.java | 4 | ||||
| -rw-r--r-- | core/java/android/pim/vcard/VCardEntryConstructor.java | 107 | ||||
| -rw-r--r-- | core/java/android/pim/vcard/VCardParser.java | 17 | ||||
| -rw-r--r-- | core/java/android/pim/vcard/VCardParserImpl_V21.java | 29 | ||||
| -rw-r--r-- | core/java/android/pim/vcard/VCardParserImpl_V30.java | 9 | ||||
| -rw-r--r-- | core/java/android/pim/vcard/VCardParser_V21.java | 15 | ||||
| -rw-r--r-- | core/java/android/pim/vcard/VCardParser_V30.java | 15 |
9 files changed, 183 insertions, 192 deletions
diff --git a/core/java/android/pim/vcard/VCardComposer.java b/core/java/android/pim/vcard/VCardComposer.java index 1bc7785..d718297 100644 --- a/core/java/android/pim/vcard/VCardComposer.java +++ b/core/java/android/pim/vcard/VCardComposer.java @@ -376,7 +376,7 @@ public class VCardComposer { mCharset = charset; } } - Log.d(LOG_TAG, "use the charset \"" + mCharset + "\""); + Log.d(LOG_TAG, "Use the charset \"" + mCharset + "\""); } /** diff --git a/core/java/android/pim/vcard/VCardConfig.java b/core/java/android/pim/vcard/VCardConfig.java index 50e63c1..e05476e 100644 --- a/core/java/android/pim/vcard/VCardConfig.java +++ b/core/java/android/pim/vcard/VCardConfig.java @@ -39,12 +39,12 @@ public class VCardConfig { /* package */ static final int LOG_LEVEL = LOG_LEVEL_NONE; /** - * <P> + * <p> * The charset used during import. - * </P> - * <P> - * We cannot determine which charset should be used to interpret a given vCard file, - * while we have to decode sime encoded data (e.g. BASE64) to binary. + * </p> + * <p> + * We cannot determine which charset should be used to interpret a given vCard file + * at first, while we have to decode sime encoded data (e.g. BASE64) to binary. * In order to avoid "misinterpretation" of charset as much as possible, * "ISO-8859-1" (a.k.a Latin-1) is first used for reading a stream. * When charset is specified in a property (with "CHARSET=..." parameter), @@ -52,12 +52,15 @@ public class VCardConfig { * assuming "ISO-8859-1" is able to map "all" 8bit characters to some unicode, * and it has 1 to 1 mapping in all 8bit characters. * If the assumption is not correct, this setting will cause some bug. - * </P> + * </p> */ - /* package */ static final String DEFAULT_TEMPORARY_CHARSET = "ISO-8859-1"; + /* package */ static final String DEFAULT_INTERMEDIATE_CHARSET = "ISO-8859-1"; - // TODO: still intermediate procedures uses this charset. Fix it. - public static final String DEFAULT_IMPORT_CHARSET = "ISO-8859-1"; + /** + * The charset used when there's no information affbout what charset should be used to + * encode the binary given from vCard. + */ + public static final String DEFAULT_IMPORT_CHARSET = "UTF-8"; public static final String DEFAULT_EXPORT_CHARSET = "UTF-8"; public static final int FLAG_V21 = 0; @@ -82,130 +85,138 @@ public class VCardConfig { private static final int FLAG_CHARSET_MASK_FOR_EKPORT = 0xF00; /** + * <p> * The flag indicating the vCard composer will add some "X-" properties used only in Android * when the formal vCard specification does not have appropriate fields for that data. - * + * </p> + * <p> * For example, Android accepts nickname information while vCard 2.1 does not. * When this flag is on, vCard composer emits alternative "X-" property (like "X-NICKNAME") * instead of just dropping it. - * + * </p> + * <p> * vCard parser code automatically parses the field emitted even when this flag is off. - * - * Note that this flag does not assure all the information must be hold in the emitted vCard. + * </p> */ private static final int FLAG_USE_ANDROID_PROPERTY = 0x80000000; /** + * <p> * The flag indicating the vCard composer will add some "X-" properties seen in the * vCard data emitted by the other softwares/devices when the formal vCard specification - * does not have appropriate field(s) for that data. - * + * does not have appropriate field(s) for that data. + * </p> + * <p> * One example is X-PHONETIC-FIRST-NAME/X-PHONETIC-MIDDLE-NAME/X-PHONETIC-LAST-NAME, which are * for phonetic name (how the name is pronounced), seen in the vCard emitted by some other * non-Android devices/softwares. We chose to enable the vCard composer to use those * defact properties since they are also useful for Android devices. - * + * </p> + * <p> * Note for developers: only "X-" properties should be added with this flag. vCard 2.1/3.0 * allows any kind of "X-" properties but does not allow non-"X-" properties (except IANA tokens * in vCard 3.0). Some external parsers may get confused with non-valid, non-"X-" properties. + * </p> */ private static final int FLAG_USE_DEFACT_PROPERTY = 0x40000000; /** + * <p> * The flag indicating some specific dialect seen in vCard of DoCoMo (one of Japanese * mobile careers) should be used. This flag does not include any other information like * that "the vCard is for Japanese". So it is "possible" that "the vCard should have DoCoMo's * dialect but the name order should be European", but it is not recommended. + * </p> */ private static final int FLAG_DOCOMO = 0x20000000; /** - * <P> + * <p> * The flag indicating the vCard composer does "NOT" use Quoted-Printable toward "primary" * properties even though it is required by vCard 2.1 (QP is prohibited in vCard 3.0). - * </P> - * <P> + * </p> + * <p> * We actually cannot define what is the "primary" property. Note that this is NOT defined * in vCard specification either. Also be aware that it is NOT related to "primary" notion * used in {@link android.provider.ContactsContract}. * This notion is just for vCard composition in Android. - * </P> - * <P> + * </p> + * <p> * We added this Android-specific notion since some (incomplete) vCard exporters for vCard 2.1 * do NOT use Quoted-Printable encoding toward some properties related names like "N", "FN", etc. * even when their values contain non-ascii or/and CR/LF, while they use the encoding in the * other properties like "ADR", "ORG", etc. - * <P> + * <p> * We are afraid of the case where some vCard importer also forget handling QP presuming QP is * not used in such fields. - * </P> - * <P> + * </p> + * <p> * This flag is useful when some target importer you are going to focus on does not accept * such properties with Quoted-Printable encoding. - * </P> - * <P> + * </p> + * <p> * Again, we should not use this flag at all for complying vCard 2.1 spec. - * </P> - * <P> + * </p> + * <p> * In vCard 3.0, Quoted-Printable is explicitly "prohibitted", so we don't need to care this * kind of problem (hopefully). - * </P> + * </p> */ public static final int FLAG_REFRAIN_QP_TO_NAME_PROPERTIES = 0x10000000; /** - * <P> + * <p> * The flag indicating that phonetic name related fields must be converted to * appropriate form. Note that "appropriate" is not defined in any vCard specification. * This is Android-specific. - * </P> - * <P> + * </p> + * <p> * One typical (and currently sole) example where we need this flag is the time when * we need to emit Japanese phonetic names into vCard entries. The property values * should be encoded into half-width katakana when the target importer is Japanese mobile * phones', which are probably not able to parse full-width hiragana/katakana for * historical reasons, while the vCard importers embedded to softwares for PC should be * able to parse them as we expect. - * </P> + * </p> */ public static final int FLAG_CONVERT_PHONETIC_NAME_STRINGS = 0x0800000; /** - * <P> + * <p> * The flag indicating the vCard composer "for 2.1" emits "TYPE=" string toward TYPE params * every time possible. The default behavior does not emit it and is valid in the spec. * In vCrad 3.0, this flag is unnecessary, since "TYPE=" is MUST in vCard 3.0 specification. - * </P> - * <P> + * </p> + * <p> * Detail: * How more than one TYPE fields are expressed is different between vCard 2.1 and vCard 3.0. * </p> - * <P> + * <p> * e.g.<BR /> * 1) Probably valid in both vCard 2.1 and vCard 3.0: "ADR;TYPE=DOM;TYPE=HOME:..."<BR /> * 2) Valid in vCard 2.1 but not in vCard 3.0: "ADR;DOM;HOME:..."<BR /> * 3) Valid in vCard 3.0 but not in vCard 2.1: "ADR;TYPE=DOM,HOME:..."<BR /> - * </P> - * <P> + * </p> + * <p> * 2) had been the default of VCard exporter/importer in Android, but it is found that * some external exporter is not able to parse the type format like 2) but only 3). - * </P> - * <P> + * </p> + * <p> * If you are targeting to the importer which cannot accept TYPE params without "TYPE=" * strings (which should be rare though), please use this flag. - * </P> - * <P> + * </p> + * <p> * Example usage: int vcardType = (VCARD_TYPE_V21_GENERIC | FLAG_APPEND_TYPE_PARAM); - * </P> + * </p> */ public static final int FLAG_APPEND_TYPE_PARAM = 0x04000000; /** - * <P> + * <p> * The flag indicating the vCard composer does touch nothing toward phone number Strings * but leave it as is. - * </P> - * <P> + * </p> + * <p> * The vCard specifications mention nothing toward phone numbers, while some devices * do (wrongly, but with innevitable reasons). * For example, there's a possibility Japanese mobile phones are expected to have @@ -216,11 +227,11 @@ public class VCardConfig { * becomes "111-222-3333"). * Unfortunate side effect of that use was some control characters used in the other * areas may be badly affected by the formatting. - * </P> - * <P> + * </p> + * <p> * This flag disables that formatting, affecting both importer and exporter. * If the user is aware of some side effects due to the implicit formatting, use this flag. - * </P> + * </p> */ public static final int FLAG_REFRAIN_PHONE_NUMBER_FORMATTING = 0x02000000; @@ -284,12 +295,12 @@ public class VCardConfig { /* package */ static String VCARD_TYPE_V21_GENERIC_STR = "v21_generic"; /** - * <P> + * <p> * General vCard format with the version 3.0. Uses UTF-8 for the charset. - * </P> - * <P> + * </p> + * <p> * Not fully ready yet. Use with caution when you use this. - * </P> + * </p> */ public static final int VCARD_TYPE_V30_GENERIC = (FLAG_V30 | NAME_ORDER_DEFAULT | FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY); @@ -297,10 +308,10 @@ public class VCardConfig { /* package */ static final String VCARD_TYPE_V30_GENERIC_STR = "v30_generic"; /** - * <P> + * <p> * General vCard format for the vCard 2.1 with some Europe convension. Uses Utf-8. * Currently, only name order is considered ("Prefix Middle Given Family Suffix") - * </P> + * </p> */ public static final int VCARD_TYPE_V21_EUROPE = (FLAG_V21 | NAME_ORDER_EUROPE | FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY); @@ -308,12 +319,12 @@ public class VCardConfig { /* package */ static final String VCARD_TYPE_V21_EUROPE_STR = "v21_europe"; /** - * <P> + * <p> * General vCard format with the version 3.0 with some Europe convension. Uses UTF-8. - * </P> - * <P> + * </p> + * <p> * Not ready yet. Use with caution when you use this. - * </P> + * </p> */ public static final int VCARD_TYPE_V30_EUROPE = (FLAG_V30 | NAME_ORDER_EUROPE | FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY); @@ -321,12 +332,12 @@ public class VCardConfig { /* package */ static final String VCARD_TYPE_V30_EUROPE_STR = "v30_europe"; /** - * <P> + * <p> * The vCard 2.1 format for miscellaneous Japanese devices, using UTF-8 as default charset. - * </P> - * <P> + * </p> + * <p> * Not ready yet. Use with caution when you use this. - * </P> + * </p> */ public static final int VCARD_TYPE_V21_JAPANESE = (FLAG_V21 | NAME_ORDER_JAPANESE | FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY); @@ -334,13 +345,13 @@ public class VCardConfig { /* package */ static final String VCARD_TYPE_V21_JAPANESE_STR = "v21_japanese_utf8"; /** - * <P> + * <p> * vCard 2.1 format for miscellaneous Japanese devices. Shift_Jis is used for * parsing/composing the vCard data. - * </P> - * <P> + * </p> + * <p> * Not ready yet. Use with caution when you use this. - * </P> + * </p> */ public static final int VCARD_TYPE_V21_JAPANESE_SJIS = (FLAG_V21 | NAME_ORDER_JAPANESE | FLAG_USE_SHIFT_JIS_FOR_EXPORT | @@ -349,13 +360,13 @@ public class VCardConfig { /* package */ static final String VCARD_TYPE_V21_JAPANESE_SJIS_STR = "v21_japanese_sjis"; /** - * <P> + * <p> * vCard format for miscellaneous Japanese devices, using Shift_Jis for * parsing/composing the vCard data. - * </P> - * <P> + * </p> + * <p> * Not ready yet. Use with caution when you use this. - * </P> + * </p> */ public static final int VCARD_TYPE_V30_JAPANESE_SJIS = (FLAG_V30 | NAME_ORDER_JAPANESE | FLAG_USE_SHIFT_JIS_FOR_EXPORT | @@ -364,12 +375,12 @@ public class VCardConfig { /* package */ static final String VCARD_TYPE_V30_JAPANESE_SJIS_STR = "v30_japanese_sjis"; /** - * <P> + * <p> * The vCard 3.0 format for miscellaneous Japanese devices, using UTF-8 as default charset. - * </P> - * <P> + * </p> + * <p> * Not ready yet. Use with caution when you use this. - * </P> + * </p> */ public static final int VCARD_TYPE_V30_JAPANESE = (FLAG_V30 | NAME_ORDER_JAPANESE | FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY); @@ -377,14 +388,14 @@ public class VCardConfig { /* package */ static final String VCARD_TYPE_V30_JAPANESE_STR = "v30_japanese_utf8"; /** - * <P> + * <p> * The vCard 2.1 based format which (partially) considers the convention in Japanese * mobile phones, where phonetic names are translated to half-width katakana if * possible, etc. - * </P> - * <P> + * </p> + * <p> * Not ready yet. Use with caution when you use this. - * </P> + * </p> */ public static final int VCARD_TYPE_V21_JAPANESE_MOBILE = (FLAG_V21 | NAME_ORDER_JAPANESE | FLAG_USE_SHIFT_JIS_FOR_EXPORT | @@ -393,14 +404,14 @@ public class VCardConfig { /* package */ static final String VCARD_TYPE_V21_JAPANESE_MOBILE_STR = "v21_japanese_mobile"; /** - * <P> + * <p> * The vCard format used in DoCoMo, which is one of Japanese mobile phone careers. * </p> - * <P> + * <p> * Base version is vCard 2.1, but the data has several DoCoMo-specific convensions. * No Android-specific property nor defact property is included. The "Primary" properties * are NOT encoded to Quoted-Printable. - * </P> + * </p> */ public static final int VCARD_TYPE_DOCOMO = (VCARD_TYPE_V21_JAPANESE_MOBILE | FLAG_DOCOMO); diff --git a/core/java/android/pim/vcard/VCardEntryCommitter.java b/core/java/android/pim/vcard/VCardEntryCommitter.java index 59a2baf..a8c8057 100644 --- a/core/java/android/pim/vcard/VCardEntryCommitter.java +++ b/core/java/android/pim/vcard/VCardEntryCommitter.java @@ -52,9 +52,9 @@ public class VCardEntryCommitter implements VCardEntryHandler { } } - public void onEntryCreated(final VCardEntry contactStruct) { + public void onEntryCreated(final VCardEntry vcardEntry) { long start = System.currentTimeMillis(); - mCreatedUris.add(contactStruct.pushIntoContentResolver(mContentResolver)); + mCreatedUris.add(vcardEntry.pushIntoContentResolver(mContentResolver)); mTimeToCommit += System.currentTimeMillis() - start; } diff --git a/core/java/android/pim/vcard/VCardEntryConstructor.java b/core/java/android/pim/vcard/VCardEntryConstructor.java index 23bec75..3c66f39 100644 --- a/core/java/android/pim/vcard/VCardEntryConstructor.java +++ b/core/java/android/pim/vcard/VCardEntryConstructor.java @@ -16,6 +16,7 @@ package android.pim.vcard; import android.accounts.Account; +import android.text.TextUtils; import android.util.CharsetUtils; import android.util.Log; @@ -33,28 +34,19 @@ import java.util.List; public class VCardEntryConstructor implements VCardInterpreter { private static String LOG_TAG = "VCardEntryConstructor"; - /** - * If there's no other information available, this class uses this charset for encoding - * byte arrays to String. - */ - /* package */ static final String DEFAULT_CHARSET_FOR_DECODED_BYTES = "UTF-8"; - private VCardEntry.Property mCurrentProperty = new VCardEntry.Property(); - private VCardEntry mCurrentContactStruct; + private VCardEntry mCurrentVCardEntry; private String mParamType; - /** - * The charset using which {@link VCardInterpreter} parses the text. - */ - private String mInputCharset; + // The charset using which {@link VCardInterpreter} parses the text. + // Each String is first decoded into binary stream with this charset, and encoded back + // to "target charset", which may be explicitly specified by the vCard with "CHARSET" + // property or implicitly mentioned by its version (e.g. vCard 3.0 recommends UTF-8). + private final String mSourceCharset; - /** - * The charset with which byte array is encoded to String. - */ - final private String mCharsetForDecodedBytes; - final private boolean mStrictLineBreakParsing; - final private int mVCardType; - final private Account mAccount; + private final boolean mStrictLineBreakParsing; + private final int mVCardType; + private final Account mAccount; /** For measuring performance. */ private long mTimePushIntoContentResolver; @@ -62,30 +54,25 @@ public class VCardEntryConstructor implements VCardInterpreter { final private List<VCardEntryHandler> mEntryHandlers = new ArrayList<VCardEntryHandler>(); public VCardEntryConstructor() { - this(null, null, false, VCardConfig.VCARD_TYPE_V21_GENERIC, null); + this(null, false, VCardConfig.VCARD_TYPE_V21_GENERIC, null); } public VCardEntryConstructor(final int vcardType) { - this(null, null, false, vcardType, null); + this(null, false, vcardType, null); } - public VCardEntryConstructor(final String charset, final boolean strictLineBreakParsing, + public VCardEntryConstructor(final String inputCharset, final int vcardType, final Account account) { - this(null, charset, strictLineBreakParsing, vcardType, account); + this(inputCharset, false, vcardType, account); } - public VCardEntryConstructor(final String inputCharset, final String charsetForDetodedBytes, + public VCardEntryConstructor(final String inputCharset, final boolean strictLineBreakParsing, final int vcardType, final Account account) { if (inputCharset != null) { - mInputCharset = inputCharset; - } else { - mInputCharset = VCardConfig.DEFAULT_TEMPORARY_CHARSET; - } - if (charsetForDetodedBytes != null) { - mCharsetForDecodedBytes = charsetForDetodedBytes; + mSourceCharset = inputCharset; } else { - mCharsetForDecodedBytes = DEFAULT_CHARSET_FOR_DECODED_BYTES; + mSourceCharset = VCardConfig.DEFAULT_INTERMEDIATE_CHARSET; } mStrictLineBreakParsing = strictLineBreakParsing; mVCardType = vcardType; @@ -112,7 +99,7 @@ public class VCardEntryConstructor implements VCardInterpreter { * Called when the parse failed between {@link #startEntry()} and {@link #endEntry()}. */ public void clear() { - mCurrentContactStruct = null; + mCurrentVCardEntry = null; mCurrentProperty = new VCardEntry.Property(); } @@ -120,18 +107,18 @@ public class VCardEntryConstructor implements VCardInterpreter { * Assume that VCard is not nested. In other words, this code does not accept */ public void startEntry() { - if (mCurrentContactStruct != null) { + if (mCurrentVCardEntry != null) { Log.e(LOG_TAG, "Nested VCard code is not supported now."); } - mCurrentContactStruct = new VCardEntry(mVCardType, mAccount); + mCurrentVCardEntry = new VCardEntry(mVCardType, mAccount); } public void endEntry() { - mCurrentContactStruct.consolidateFields(); + mCurrentVCardEntry.consolidateFields(); for (VCardEntryHandler entryHandler : mEntryHandlers) { - entryHandler.onEntryCreated(mCurrentContactStruct); + entryHandler.onEntryCreated(mCurrentVCardEntry); } - mCurrentContactStruct = null; + mCurrentVCardEntry = null; } public void startProperty() { @@ -139,7 +126,7 @@ public class VCardEntryConstructor implements VCardInterpreter { } public void endProperty() { - mCurrentContactStruct.addProperty(mCurrentProperty); + mCurrentVCardEntry.addProperty(mCurrentProperty); } public void propertyName(String name) { @@ -166,25 +153,28 @@ public class VCardEntryConstructor implements VCardInterpreter { mParamType = null; } - private String encodeString(String originalString, String charsetForDecodedBytes) { - if (mInputCharset.equalsIgnoreCase(charsetForDecodedBytes)) { + private static String encodeToSystemCharset(String originalString, + String sourceCharset, String targetCharset) { + if (sourceCharset.equalsIgnoreCase(targetCharset)) { return originalString; } - Charset charset = Charset.forName(mInputCharset); - ByteBuffer byteBuffer = charset.encode(originalString); + final Charset charset = Charset.forName(sourceCharset); + final ByteBuffer byteBuffer = charset.encode(originalString); // byteBuffer.array() "may" return byte array which is larger than // byteBuffer.remaining(). Here, we keep on the safe side. - byte[] bytes = new byte[byteBuffer.remaining()]; + final byte[] bytes = new byte[byteBuffer.remaining()]; byteBuffer.get(bytes); try { - return new String(bytes, charsetForDecodedBytes); + String ret = new String(bytes, targetCharset); + return ret; } catch (UnsupportedEncodingException e) { - Log.e(LOG_TAG, "Failed to encode: charset=" + charsetForDecodedBytes); + Log.e(LOG_TAG, "Failed to encode: charset=" + targetCharset); return null; } } - private String handleOneValue(String value, String charsetForDecodedBytes, String encoding) { + private String handleOneValue(String value, + String sourceCharset, String targetCharset, String encoding) { if (encoding != null) { if (encoding.equals("BASE64") || encoding.equals("B")) { mCurrentProperty.setPropertyBytes(Base64.decodeBase64(value.getBytes())); @@ -250,9 +240,9 @@ public class VCardEntryConstructor implements VCardInterpreter { } byte[] bytes; try { - bytes = builder.toString().getBytes(mInputCharset); + bytes = builder.toString().getBytes(sourceCharset); } catch (UnsupportedEncodingException e1) { - Log.e(LOG_TAG, "Failed to encode: charset=" + mInputCharset); + Log.e(LOG_TAG, "Failed to encode: charset=" + targetCharset); bytes = builder.toString().getBytes(); } @@ -264,15 +254,18 @@ public class VCardEntryConstructor implements VCardInterpreter { } try { - return new String(bytes, charsetForDecodedBytes); + String ret = new String(bytes, targetCharset); + return ret; } catch (UnsupportedEncodingException e) { - Log.e(LOG_TAG, "Failed to encode: charset=" + charsetForDecodedBytes); + Log.e(LOG_TAG, "Failed to encode: charset=" + targetCharset); return new String(bytes); } } - // Unknown encoding. Fall back to default. + Log.w(LOG_TAG, "Unknown encoding. Fall back to default."); } - return encodeString(value, charsetForDecodedBytes); + + // Just translate the charset of a given String from inputCharset to a system one. + return encodeToSystemCharset(value, sourceCharset, targetCharset); } public void propertyValues(List<String> values) { @@ -281,20 +274,18 @@ public class VCardEntryConstructor implements VCardInterpreter { } final Collection<String> charsetCollection = mCurrentProperty.getParameters("CHARSET"); - final String charset = - ((charsetCollection != null) ? charsetCollection.iterator().next() : null); final Collection<String> encodingCollection = mCurrentProperty.getParameters("ENCODING"); final String encoding = ((encodingCollection != null) ? encodingCollection.iterator().next() : null); - - String charsetForDecodedBytes = CharsetUtils.nameForDefaultVendor(charset); - if (charsetForDecodedBytes == null || charsetForDecodedBytes.length() == 0) { - charsetForDecodedBytes = mCharsetForDecodedBytes; + String targetCharset = CharsetUtils.nameForDefaultVendor( + ((charsetCollection != null) ? charsetCollection.iterator().next() : null)); + if (TextUtils.isEmpty(targetCharset)) { + targetCharset = VCardConfig.DEFAULT_IMPORT_CHARSET; } for (final String value : values) { mCurrentProperty.addToPropertyValueList( - handleOneValue(value, charsetForDecodedBytes, encoding)); + handleOneValue(value, mSourceCharset, targetCharset, encoding)); } } diff --git a/core/java/android/pim/vcard/VCardParser.java b/core/java/android/pim/vcard/VCardParser.java index e9ea251..31b9369 100644 --- a/core/java/android/pim/vcard/VCardParser.java +++ b/core/java/android/pim/vcard/VCardParser.java @@ -38,24 +38,9 @@ public interface VCardParser { * * @param is The source to parse. * @param interepreter A {@link VCardInterpreter} object which used to construct data. - * @return Returns true for success. Otherwise returns false. * @throws IOException, VCardException */ - public boolean parse(InputStream is, VCardInterpreter interepreter) - throws IOException, VCardException; - - /** - * <p> - * The method variants which accept charset. - * </p> - * - * @param is The source to parse. - * @param charset Charset to be used. - * @param interpreter The VCardBuilderBase object. - * @return Returns true when successful. Otherwise returns false. - * @throws IOException, VCardException - */ - public boolean parse(InputStream is, String charset, VCardInterpreter interpreter) + public void parse(InputStream is, VCardInterpreter interepreter) throws IOException, VCardException; /** diff --git a/core/java/android/pim/vcard/VCardParserImpl_V21.java b/core/java/android/pim/vcard/VCardParserImpl_V21.java index 0bd6c41..7d294cc 100644 --- a/core/java/android/pim/vcard/VCardParserImpl_V21.java +++ b/core/java/android/pim/vcard/VCardParserImpl_V21.java @@ -21,6 +21,7 @@ import android.pim.vcard.exception.VCardInvalidCommentLineException; import android.pim.vcard.exception.VCardInvalidLineException; import android.pim.vcard.exception.VCardNestedException; import android.pim.vcard.exception.VCardVersionException; +import android.text.TextUtils; import android.util.Log; import java.io.BufferedReader; @@ -36,6 +37,7 @@ import java.util.Set; * <p> * Basic implementation achieving vCard parsing. Based on vCard 2.1, * </p> + * @hide */ /* package */ class VCardParserImpl_V21 { private static final String LOG_TAG = "VCardParserImpl_V21"; @@ -66,6 +68,8 @@ import java.util.Set; protected boolean mCanceled; protected VCardInterpreter mInterpreter; + protected final String mImportCharset; + /** * <p> * The encoding type for deconding byte streams. This member variable is @@ -131,13 +135,20 @@ import java.util.Set; private long mTimeHandleBase64; public VCardParserImpl_V21() { - this(VCardConfig.VCARD_TYPE_DEFAULT); + this(VCardConfig.VCARD_TYPE_DEFAULT, null); } public VCardParserImpl_V21(int vcardType) { + this(vcardType, null); + } + + public VCardParserImpl_V21(int vcardType, String importCharset) { if ((vcardType & VCardConfig.FLAG_TORELATE_NEST) != 0) { mNestCount = 1; } + + mImportCharset = (!TextUtils.isEmpty(importCharset) ? importCharset : + VCardConfig.DEFAULT_INTERMEDIATE_CHARSET); } /** @@ -684,9 +695,9 @@ import java.util.Set; try { final String result = getBase64(propertyValue); if (mInterpreter != null) { - ArrayList<String> v = new ArrayList<String>(); - v.add(result); - mInterpreter.propertyValues(v); + ArrayList<String> arrayList = new ArrayList<String>(); + arrayList.add(result); + mInterpreter.propertyValues(arrayList); } } catch (OutOfMemoryError error) { Log.e(LOG_TAG, "OutOfMemoryError happened during parsing BASE64 data!"); @@ -920,17 +931,13 @@ import java.util.Set; } - public boolean parse(InputStream is, String charset, VCardInterpreter interpreter) + public void parse(InputStream is, VCardInterpreter interpreter) throws IOException, VCardException { if (is == null) { throw new NullPointerException("InputStream must not be null."); } - if (charset == null) { - charset = VCardConfig.DEFAULT_TEMPORARY_CHARSET; - } - - final InputStreamReader tmpReader = new InputStreamReader(is, charset); + final InputStreamReader tmpReader = new InputStreamReader(is, mImportCharset); if (VCardConfig.showPerformanceLog()) { mReader = new CustomBufferedReader(tmpReader); } else { @@ -952,8 +959,6 @@ import java.util.Set; if (VCardConfig.showPerformanceLog()) { showPerformanceInfo(); } - - return true; } public final void cancel() { diff --git a/core/java/android/pim/vcard/VCardParserImpl_V30.java b/core/java/android/pim/vcard/VCardParserImpl_V30.java index 250866b..a48a3b4 100644 --- a/core/java/android/pim/vcard/VCardParserImpl_V30.java +++ b/core/java/android/pim/vcard/VCardParserImpl_V30.java @@ -32,6 +32,7 @@ import android.util.Log; * {@link VCardParser_V30} does not inherit {@link VCardParser_V21}, while * {@link VCardParserImpl_V30} inherits {@link VCardParserImpl_V21}. * </p> + * @hide */ /* package */ class VCardParserImpl_V30 extends VCardParserImpl_V21 { private static final String LOG_TAG = "VCardParserImpl_V30"; @@ -43,8 +44,12 @@ import android.util.Log; super(); } - public VCardParserImpl_V30(int parseMode) { - super(parseMode); + public VCardParserImpl_V30(int vcardType) { + super(vcardType, null); + } + + public VCardParserImpl_V30(int vcardType, String importCharset) { + super(vcardType, importCharset); } @Override diff --git a/core/java/android/pim/vcard/VCardParser_V21.java b/core/java/android/pim/vcard/VCardParser_V21.java index a545394..b625695 100644 --- a/core/java/android/pim/vcard/VCardParser_V21.java +++ b/core/java/android/pim/vcard/VCardParser_V21.java @@ -94,20 +94,17 @@ public final class VCardParser_V21 implements VCardParser { mVCardParserImpl = new VCardParserImpl_V21(); } - public VCardParser_V21(int parseType) { - mVCardParserImpl = new VCardParserImpl_V21(parseType); + public VCardParser_V21(int vcardType) { + mVCardParserImpl = new VCardParserImpl_V21(vcardType); } - //// Implemented methods - - public boolean parse(InputStream is, VCardInterpreter interepreter) - throws IOException, VCardException { - return mVCardParserImpl.parse(is, VCardConfig.DEFAULT_TEMPORARY_CHARSET, interepreter); + public VCardParser_V21(int parseType, String inputCharset) { + mVCardParserImpl = new VCardParserImpl_V21(parseType, null); } - public boolean parse(InputStream is, String charset, VCardInterpreter interpreter) + public void parse(InputStream is, VCardInterpreter interepreter) throws IOException, VCardException { - return mVCardParserImpl.parse(is, charset, interpreter); + mVCardParserImpl.parse(is, interepreter); } public void cancel() { diff --git a/core/java/android/pim/vcard/VCardParser_V30.java b/core/java/android/pim/vcard/VCardParser_V30.java index d6d9bb4d..40792ab 100644 --- a/core/java/android/pim/vcard/VCardParser_V30.java +++ b/core/java/android/pim/vcard/VCardParser_V30.java @@ -72,20 +72,17 @@ public class VCardParser_V30 implements VCardParser { mVCardParserImpl = new VCardParserImpl_V30(); } - public VCardParser_V30(int parseType) { - mVCardParserImpl = new VCardParserImpl_V30(parseType); + public VCardParser_V30(int vcardType) { + mVCardParserImpl = new VCardParserImpl_V30(vcardType); } - //// Implemented methods - - public boolean parse(InputStream is, VCardInterpreter interepreter) - throws IOException, VCardException { - return mVCardParserImpl.parse(is, VCardConfig.DEFAULT_TEMPORARY_CHARSET, interepreter); + public VCardParser_V30(int vcardType, String importCharset) { + mVCardParserImpl = new VCardParserImpl_V30(vcardType, importCharset); } - public boolean parse(InputStream is, String charset, VCardInterpreter interpreter) + public void parse(InputStream is, VCardInterpreter interepreter) throws IOException, VCardException { - return mVCardParserImpl.parse(is, charset, interpreter); + mVCardParserImpl.parse(is, interepreter); } public void cancel() { |
