1b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein/* 2b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * Copyright (C) 2009 The Android Open Source Project 3b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * 4b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * Licensed under the Apache License, Version 2.0 (the "License"); 5b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * you may not use this file except in compliance with the License. 6b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * You may obtain a copy of the License at 7b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * 8b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * http://www.apache.org/licenses/LICENSE-2.0 9b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * 10b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * Unless required by applicable law or agreed to in writing, software 11b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * distributed under the License is distributed on an "AS IS" BASIS, 12b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * See the License for the specific language governing permissions and 14b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * limitations under the License. 15b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein */ 16b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein 17b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornsteinpackage android.util; 18b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein 19b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornsteinimport android.os.Build; 20df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawaimport android.text.TextUtils; 21b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein 22b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornsteinimport java.nio.charset.Charset; 23b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornsteinimport java.nio.charset.IllegalCharsetNameException; 24b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornsteinimport java.nio.charset.UnsupportedCharsetException; 25df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawaimport java.util.HashMap; 26df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawaimport java.util.Map; 27b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein 28b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein/** 29df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa * <p> 30b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * A class containing utility methods related to character sets. This 31b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * class is primarily useful for code that wishes to be vendor-aware 32df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa * in its interpretation of Japanese charset names (used in DoCoMo, 33df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa * KDDI, and SoftBank). 34df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa * </p> 35df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa * 36df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa * <p> 37df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa * <b>Note:</b> Developers will need to add an appropriate mapping for 38df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa * each vendor-specific charset. You may need to modify the C libraries 39df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa * like icu4c in order to let Android support an additional charset. 40df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa * </p> 41df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa * 42b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * @hide 43b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein */ 44b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornsteinpublic final class CharsetUtils { 45b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein /** 46df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa * name of the vendor "DoCoMo". <b>Note:</b> This isn't a public 47b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * constant, in order to keep this class from becoming a de facto 48b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * reference list of vendor names. 49b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein */ 50b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein private static final String VENDOR_DOCOMO = "docomo"; 51df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa /** 52df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa * Name of the vendor "KDDI". 53df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa */ 54df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa private static final String VENDOR_KDDI = "kddi"; 55df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa /** 56df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa * Name of the vendor "SoftBank". 57df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa */ 58df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa private static final String VENDOR_SOFTBANK = "softbank"; 59df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa 60df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa /** 61df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa * Represents one-to-one mapping from a vendor name to a charset specific to the vendor. 62df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa */ 63df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa private static final Map<String, String> sVendorShiftJisMap = new HashMap<String, String>(); 64df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa 65df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa static { 66df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa // These variants of Shift_JIS come from icu's mapping data (convrtrs.txt) 67df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa sVendorShiftJisMap.put(VENDOR_DOCOMO, "docomo-shift_jis-2007"); 68df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa sVendorShiftJisMap.put(VENDOR_KDDI, "kddi-shift_jis-2007"); 69df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa sVendorShiftJisMap.put(VENDOR_SOFTBANK, "softbank-shift_jis-2007"); 70df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa } 71df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa 72b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein /** 73b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * This class is uninstantiable. 74b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein */ 75b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein private CharsetUtils() { 76b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein // This space intentionally left blank. 77b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein } 78b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein 79b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein /** 80b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * Returns the name of the vendor-specific character set 81b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * corresponding to the given original character set name and 82b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * vendor. If there is no vendor-specific character set for the 83df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa * given name/vendor pair, this returns the original character set name. 84df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa * 85b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * @param charsetName the base character set name 86df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa * @param vendor the vendor to specialize for. All characters should be lower-cased. 87b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * @return the specialized character set name, or {@code charsetName} if 88b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * there is no specialized name 89b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein */ 90b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein public static String nameForVendor(String charsetName, String vendor) { 91df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa if (!TextUtils.isEmpty(charsetName) && !TextUtils.isEmpty(vendor)) { 92df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa // You can add your own mapping here. 93df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa if (isShiftJis(charsetName)) { 94df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa final String vendorShiftJis = sVendorShiftJisMap.get(vendor); 95df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa if (vendorShiftJis != null) { 96df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa return vendorShiftJis; 97df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa } 98df3f1cc3fe1b9b4f598a084d6ff385482836f7ecDaisuke Miyakawa } 99b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein } 100b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein 101b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein return charsetName; 102b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein } 103b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein 104b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein /** 105b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * Returns the name of the vendor-specific character set 106b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * corresponding to the given original character set name and the 107b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * default vendor (that is, the targeted vendor of the device this 108b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * code is running on). This method merely calls through to 109b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * {@link #nameForVendor(String,String)}, passing the default vendor 110b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * as the second argument. 111b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * 112b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * @param charsetName the base character set name 113b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * @return the specialized character set name, or {@code charsetName} if 114b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * there is no specialized name 115b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein */ 116b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein public static String nameForDefaultVendor(String charsetName) { 117b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein return nameForVendor(charsetName, getDefaultVendor()); 118b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein } 119b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein 120b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein /** 121b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * Returns the vendor-specific character set corresponding to the 122b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * given original character set name and vendor. If there is no 123b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * vendor-specific character set for the given name/vendor pair, 124b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * this returns the character set corresponding to the original 125b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * name. The vendor name is matched case-insensitively. This 126b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * method merely calls {@code Charset.forName()} on a name 127b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * transformed by a call to {@link #nameForVendor(String,String)}. 128b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * 129b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * @param charsetName the base character set name 130b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * @param vendor the vendor to specialize for 131b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * @return the specialized character set, or the one corresponding 132b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * directly to {@code charsetName} if there is no specialized 133b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * variant 134b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * @throws UnsupportedCharsetException thrown if the named character 135b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * set is not supported by the system 136b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * @throws IllegalCharsetNameException thrown if {@code charsetName} 137b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * has invalid syntax 138b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein */ 139b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein public static Charset charsetForVendor(String charsetName, String vendor) 140b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein throws UnsupportedCharsetException, IllegalCharsetNameException { 141b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein charsetName = nameForVendor(charsetName, vendor); 142b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein return Charset.forName(charsetName); 143b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein } 144b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein 145b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein /** 146b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * Returns the vendor-specific character set corresponding to the 147b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * given original character set name and default vendor (that is, 148b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * the targeted vendor of the device this code is running on). 149b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * This method merely calls through to {@link 150b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * #charsetForVendor(String,String)}, passing the default vendor 151b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * as the second argument. 152b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * 153b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * @param charsetName the base character set name 154b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * @return the specialized character set, or the one corresponding 155b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * directly to {@code charsetName} if there is no specialized 156b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * variant 157b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * @throws UnsupportedCharsetException thrown if the named character 158b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * set is not supported by the system 159b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * @throws IllegalCharsetNameException thrown if {@code charsetName} 160b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * has invalid syntax 161b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein */ 162b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein public static Charset charsetForVendor(String charsetName) 163b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein throws UnsupportedCharsetException, IllegalCharsetNameException { 164b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein return charsetForVendor(charsetName, getDefaultVendor()); 165b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein } 166b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein 167b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein /** 168b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * Returns whether the given character set name indicates the Shift-JIS 169f0c6ab843e7261755483d1c48e4c03f630cc79b5Daisuke Miyakawa * encoding. Returns false if the name is null. 170b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * 171b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * @param charsetName the character set name 172b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * @return {@code true} if the name corresponds to Shift-JIS or 173b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * {@code false} if not 174b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein */ 175b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein private static boolean isShiftJis(String charsetName) { 176f0c6ab843e7261755483d1c48e4c03f630cc79b5Daisuke Miyakawa // Bail quickly if the length doesn't match. 177f0c6ab843e7261755483d1c48e4c03f630cc79b5Daisuke Miyakawa if (charsetName == null) { 178f0c6ab843e7261755483d1c48e4c03f630cc79b5Daisuke Miyakawa return false; 179f0c6ab843e7261755483d1c48e4c03f630cc79b5Daisuke Miyakawa } 180f0c6ab843e7261755483d1c48e4c03f630cc79b5Daisuke Miyakawa int length = charsetName.length(); 181f0c6ab843e7261755483d1c48e4c03f630cc79b5Daisuke Miyakawa if (length != 4 && length != 9) { 182b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein return false; 183b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein } 184b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein 185b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein return charsetName.equalsIgnoreCase("shift_jis") 186f0c6ab843e7261755483d1c48e4c03f630cc79b5Daisuke Miyakawa || charsetName.equalsIgnoreCase("shift-jis") 187f0c6ab843e7261755483d1c48e4c03f630cc79b5Daisuke Miyakawa || charsetName.equalsIgnoreCase("sjis"); 188b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein } 189b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein 190b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein /** 191b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * Gets the default vendor for this build. 192b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * 193b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein * @return the default vendor name 194b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein */ 195b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein private static String getDefaultVendor() { 196b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein return Build.BRAND; 197b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein } 198b4c218eafd382da778bcc0006de9b8fce267a9cdDan Bornstein} 199