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