Charset.java revision bcf7c66e617ad0c33bb320184bb2401def517342
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.nio.charset; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.BufferedReader; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStream; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStreamReader; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.URL; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.ByteBuffer; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.CharBuffer; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.charset.spi.CharsetProvider; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.AccessController; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.PrivilegedAction; 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Collections; 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Comparator; 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Enumeration; 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.HashMap; 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.HashSet; 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Iterator; 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Locale; 37bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughesimport java.util.Map; 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Set; 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.SortedMap; 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.TreeMap; 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 42eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson// BEGIN android-changed 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport com.ibm.icu4jni.charset.CharsetProviderICU; 44eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson// END android-changed 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A charset defines a mapping between a Unicode character sequence and a byte 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * sequence. It facilitates the encoding from a Unicode character sequence into 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a byte sequence, and the decoding from a byte sequence into a Unicode 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * character sequence. 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A charset has a canonical name, which is usually in uppercase. Typically it 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * also has one or more aliases. The name string can only consist of the 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * following characters: '0' - '9', 'A' - 'Z', 'a' - 'z', '.', ':'. '-' and '_'. 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The first character of the name must be a digit or a letter. 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The following charsets should be supported by any java platform: US-ASCII, 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ISO-8859-1, UTF-8, UTF-16BE, UTF-16LE, UTF-16. 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Additional charsets can be made available by configuring one or more charset 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * providers through provider configuration files. Such files are always named 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * as "java.nio.charset.spi.CharsetProvider" and located in the 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * "META-INF/services" sub folder of one or more classpaths. The files should be 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encoded in "UTF-8". Each line of their content specifies the class name of a 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * charset provider which extends 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <code>java.nio.charset.spi.CharsetProvider</code>. A line should end with 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * '\r', '\n' or '\r\n'. Leading and trailing whitespaces are trimmed. Blank 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * lines, and lines (after trimming) starting with "#" which are regarded as 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * comments, are both ignored. Duplicates of names already found are also 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ignored. Both the configuration files and the provider classes will be loaded 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * using the thread context class loader. 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class is thread-safe. 74eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.nio.charset.spi.CharsetProvider 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic abstract class Charset implements Comparable<Charset> { 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 80eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * The name of configuration files where charset provider class names can be 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified. 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final String PROVIDER_CONFIGURATION_FILE_NAME = "META-INF/services/java.nio.charset.spi.CharsetProvider"; //$NON-NLS-1$ 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 86eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * The encoding of configuration files 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final String PROVIDER_CONFIGURATION_FILE_ENCODING = "UTF-8"; //$NON-NLS-1$ 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 91eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * The comment string used in configuration files 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final String PROVIDER_CONFIGURATION_FILE_COMMENT = "#"; //$NON-NLS-1$ 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static ClassLoader systemClassLoader; 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // built in provider instance, assuming thread-safe 98eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson // BEGIN android-changed 99bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes private static final CharsetProviderICU _builtInProvider = new CharsetProviderICU(); 100eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson // END android-changed 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // cached built in charsets 103bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes private static SortedMap<String, Charset> _builtInCharsets = null; 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final String canonicalName; 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // the aliases set 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final HashSet<String> aliasesSet; 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // cached Charset table 111eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson private final static HashMap<String, Charset> cachedCharsetTable = new HashMap<String, Charset>(); 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 113eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson private static boolean inForNameInternal = false; 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a <code>Charset</code> object. Duplicated aliases are 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ignored. 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param canonicalName 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the canonical name of the charset. 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param aliases 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * an array containing all aliases of the charset. May be null. 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalCharsetNameException 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * on an illegal value being supplied for either 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <code>canonicalName</code> or for any element of 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <code>aliases</code>. 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 128eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson protected Charset(String canonicalName, String[] aliases) { 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (null == canonicalName) { 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // check whether the given canonical name is legal 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkCharsetName(canonicalName); 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.canonicalName = canonicalName; 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // check each alias and put into a set 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.aliasesSet = new HashSet<String>(); 137bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes if (aliases != null) { 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < aliases.length; i++) { 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkCharsetName(aliases[i]); 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.aliasesSet.add(aliases[i]); 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Checks whether a character is a special character that can be used in 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * charset names, other than letters and digits. 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static boolean isSpecial(char c) { 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ('-' == c || '.' == c || ':' == c || '_' == c); 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Checks whether a character is a letter (ascii) which are defined in the 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * spec. 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static boolean isLetter(char c) { 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Checks whether a character is a digit (ascii) which are defined in the 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * spec. 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static boolean isDigit(char c) { 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ('0' <= c && c <= '9'); 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Checks whether a given string is a legal charset name. The argument name 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * should not be null. 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static void checkCharsetName(String name) { 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // An empty string is illegal charset name 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (name.length() == 0) { 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalCharsetNameException(name); 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The first character must be a letter or a digit 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // This is related to HARMONY-68 (won't fix) 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // char first = name.charAt(0); 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if (!isLetter(first) && !isDigit(first)) { 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // throw new IllegalCharsetNameException(name); 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // } 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Check the remaining characters 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int length = name.length(); 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < length; i++) { 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char c = name.charAt(i); 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isLetter(c) && !isDigit(c) && !isSpecial(c)) { 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalCharsetNameException(name); 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Use privileged code to get the context class loader. 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static ClassLoader getContextClassLoader() { 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final Thread t = Thread.currentThread(); 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return AccessController 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .doPrivileged(new PrivilegedAction<ClassLoader>() { 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public ClassLoader run() { 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return t.getContextClassLoader(); 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project }); 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Use privileged code to get the system class loader. 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static void getSystemClassLoader() { 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (null == systemClassLoader) { 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project systemClassLoader = AccessController 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .doPrivileged(new PrivilegedAction<ClassLoader>() { 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public ClassLoader run() { 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ClassLoader.getSystemClassLoader(); 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project }); 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Add the charsets supported by the given provider to the map. 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 224bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes private static void addCharsets(CharsetProvider cp, Map<String, Charset> charsets) { 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Iterator<Charset> it = cp.charsets(); 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (it.hasNext()) { 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Charset cs = it.next(); 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Only new charsets will be added 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!charsets.containsKey(cs.name())) { 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project charsets.put(cs.name(), cs); 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Trim comment string, and then trim white spaces. 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static String trimClassName(String name) { 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String trimedName = name; 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int index = name.indexOf(PROVIDER_CONFIGURATION_FILE_COMMENT); 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Trim comments 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (index != -1) { 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project trimedName = name.substring(0, index); 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return trimedName.trim(); 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Read a configuration file and add the charsets supported by the providers 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified by this configuration file to the map. 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static void loadConfiguredCharsets(URL configFile, 253bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes ClassLoader contextClassLoader, Map<String, Charset> charsets) { 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project BufferedReader reader = null; 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InputStream is = configFile.openStream(); 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Read each line for charset provider class names 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project reader = new BufferedReader(new InputStreamReader(is, 259b748a9b827665a8b19d60af4b419503b45e74329Elliott Hughes PROVIDER_CONFIGURATION_FILE_ENCODING)); 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String providerClassName = reader.readLine(); 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (null != providerClassName) { 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project providerClassName = trimClassName(providerClassName); 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Skip comments and blank lines 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (providerClassName.length() > 0) { // Non empty string 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Load the charset provider 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object cp = null; 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class<?> c = Class.forName(providerClassName, true, 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project contextClassLoader); 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cp = c.newInstance(); 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (Exception ex) { 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // try to use system classloader when context 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // classloader failed to load config file. 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project getSystemClassLoader(); 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class<?> c = Class.forName(providerClassName, true, 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project systemClassLoader); 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cp = c.newInstance(); 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (Exception e) { 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new Error(e.getMessage(), e); 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Put the charsets supported by this provider into the map 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project addCharsets((CharsetProvider) cp, charsets); 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Read the next line of the config file 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project providerClassName = reader.readLine(); 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException ex) { 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Can't read this configuration file, ignore 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (null != reader) { 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project reader.close(); 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException ex) { 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Ignore closing exception 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets a map of all available charsets supported by the runtime. 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The returned map contains mappings from canonical names to corresponding 306eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * instances of <code>Charset</code>. The canonical names can be considered 307eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * as case-insensitive. 308eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an unmodifiable map of all available charsets supported by the 310eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * runtime 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @SuppressWarnings("unchecked") 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static SortedMap<String, Charset> availableCharsets() { 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Initialize the built-in charsets map cache if necessary 315bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes if (_builtInCharsets == null) { 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (Charset.class) { 317bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes if (_builtInCharsets == null) { 318bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes _builtInCharsets = _builtInProvider.initAvailableCharsets(); 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 323bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes // Start with the built-in charsets... 324bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes SortedMap<String, Charset> charsets = new TreeMap<String, Charset>(_builtInCharsets); 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 326bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes // Add all charsets provided by charset providers... 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ClassLoader contextClassLoader = getContextClassLoader(); 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Enumeration<URL> e = null; 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 330bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes if (contextClassLoader != null) { 331bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes e = contextClassLoader.getResources(PROVIDER_CONFIGURATION_FILE_NAME); 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project getSystemClassLoader(); 334bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes e = systemClassLoader.getResources(PROVIDER_CONFIGURATION_FILE_NAME); 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Examine each configuration file 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (e.hasMoreElements()) { 338bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes loadConfiguredCharsets(e.nextElement(), contextClassLoader, charsets); 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException ex) { 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Unexpected ClassLoader exception, ignore 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return Collections.unmodifiableSortedMap(charsets); 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Read a configuration file and try to find the desired charset among those 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * which are supported by the providers specified in this configuration 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * file. 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static Charset searchConfiguredCharsets(String charsetName, 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ClassLoader contextClassLoader, URL configFile) { 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project BufferedReader reader = null; 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InputStream is = configFile.openStream(); 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Read each line for charset provider class names 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project reader = new BufferedReader(new InputStreamReader(is, 358b748a9b827665a8b19d60af4b419503b45e74329Elliott Hughes PROVIDER_CONFIGURATION_FILE_ENCODING)); 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String providerClassName = reader.readLine(); 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (null != providerClassName) { 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project providerClassName = trimClassName(providerClassName); 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (providerClassName.length() > 0) { // Non empty string 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Load the charset provider 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object cp = null; 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class<?> c = Class.forName(providerClassName, true, 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project contextClassLoader); 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cp = c.newInstance(); 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (Exception ex) { 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // try to use system classloader when context 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // classloader failed to load config file. 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project getSystemClassLoader(); 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class<?> c = Class.forName(providerClassName, true, 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project systemClassLoader); 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cp = c.newInstance(); 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (SecurityException e) { 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // BEGIN android-changed 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // ignore 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // END android-changed 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (Exception e) { 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new Error(e.getMessage(), e); 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // BEGIN android-changed 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (cp != null) { 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Try to get the desired charset from this provider 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Charset cs = ((CharsetProvider) cp) 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .charsetForName(charsetName); 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (null != cs) { 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return cs; 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // END android-changed 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Read the next line of the config file 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project providerClassName = reader.readLine(); 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException ex) { 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Can't read this configuration file 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (null != reader) { 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project reader.close(); 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException ex) { 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Ignore closing exception 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 415eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * Gets a <code>Charset</code> instance for the specified charset name. If 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the charset is not supported, returns null instead of throwing an 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * exception. 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 419eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson private synchronized static Charset forNameInternal(String charsetName) 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IllegalCharsetNameException { 421eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson 422bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes Charset cs = lookupCachedOrBuiltInCharset(charsetName); 423bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes if (cs != null || inForNameInternal) { 424eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson return cs; 425eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson } 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 427eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson // collect all charsets provided by charset providers 428eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson try { 429bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes Enumeration<URL> e = null; 430bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes ClassLoader contextClassLoader = getContextClassLoader(); 431bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes if (contextClassLoader != null) { 432bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes e = contextClassLoader.getResources(PROVIDER_CONFIGURATION_FILE_NAME); 433eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson } else { 434eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson getSystemClassLoader(); 435eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson if (systemClassLoader == null) { 436eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson // Non available during class library start-up phase 437bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes return null; 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 439bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes e = systemClassLoader.getResources(PROVIDER_CONFIGURATION_FILE_NAME); 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 441eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson } 442eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson 443eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson // examine each configuration file 444eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson while (e.hasMoreElements()) { 445bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes inForNameInternal = true; 446bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes cs = searchConfiguredCharsets(charsetName, contextClassLoader, e.nextElement()); 447bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes inForNameInternal = false; 448bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes if (cs != null) { 449eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson cacheCharset(cs); 450eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson return cs; 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 453eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson } catch (IOException ex) { 454eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson // Unexpected ClassLoader exception, ignore 455eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson } finally { 456bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes inForNameInternal = false; 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 461bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes private synchronized static Charset lookupCachedOrBuiltInCharset(String charsetName) { 462bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes Charset cs = cachedCharsetTable.get(charsetName); 463bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes if (cs != null) { 464bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes return cs; 465bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes } 466bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes if (charsetName == null) { 467bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes throw new IllegalArgumentException(); 468bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes } 469bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes checkCharsetName(charsetName); 470bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes cs = _builtInProvider.charsetForName(charsetName); 471bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes if (cs != null) { 472bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes cacheCharset(cs); 473bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes } 474bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes return cs; 475bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes } 476bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * save charset into cachedCharsetTable 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 480bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes private synchronized static void cacheCharset(Charset cs) { 481bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes // Cache the Charset by its canonical name... 482bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes String canonicalName = cs.name(); 483bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes if (!cachedCharsetTable.containsKey(canonicalName)) { 484bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes cachedCharsetTable.put(canonicalName, cs); 485eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson } 486bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes // And all its aliases... 487bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes for (String alias : cs.aliasesSet) { 488bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes if (!cachedCharsetTable.containsKey(alias)) { 489bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes cachedCharsetTable.put(alias, cs); 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets a <code>Charset</code> instance for the specified charset name. 496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param charsetName 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the canonical name of the charset or an alias. 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a <code>Charset</code> instance for the specified charset name. 500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalCharsetNameException 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified charset name is illegal. 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws UnsupportedCharsetException 503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the desired charset is not supported by this runtime. 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 505eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson public static Charset forName(String charsetName) { 506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Charset c = forNameInternal(charsetName); 507bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes if (c == null) { 508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new UnsupportedCharsetException(charsetName); 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return c; 511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Determines whether the specified charset is supported by this runtime. 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param charsetName 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the charset. 518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if the specified charset is supported, otherwise false. 519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalCharsetNameException 520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified charset name is illegal. 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 522eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson public static synchronized boolean isSupported(String charsetName) { 523bcf7c66e617ad0c33bb320184bb2401def517342Elliott Hughes return forNameInternal(charsetName) != null; 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Determines whether this charset is a super set of the given charset. 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param charset 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a given charset. 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if this charset is a super set of the given charset, 532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * false if it's unknown or this charset is not a superset of 533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the given charset. 534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract boolean contains(Charset charset); 536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets a new instance of an encoder for this charset. 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a new instance of an encoder for this charset. 541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract CharsetEncoder newEncoder(); 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets a new instance of a decoder for this charset. 546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a new instance of a decoder for this charset. 548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract CharsetDecoder newDecoder(); 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the canonical name of this charset. 553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this charset's name in canonical form. 555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final String name() { 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this.canonicalName; 558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the set of this charset's aliases. 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an unmodifiable set of this charset's aliases. 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final Set<String> aliases() { 566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return Collections.unmodifiableSet(this.aliasesSet); 567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the name of this charset for the default locale. 571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 572eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * <p>The default implementation returns the canonical name of this charset. 573eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * Subclasses may return a localized display name. 574eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * 575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the name of this charset for the default locale. 576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String displayName() { 578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this.canonicalName; 579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the name of this charset for the specified locale. 583eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * 584eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * <p>The default implementation returns the canonical name of this charset. 585eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * Subclasses may return a localized display name. 586eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * 587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param l 588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a certain locale 589eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * @return the name of this charset for the specified locale 590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String displayName(Locale l) { 592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this.canonicalName; 593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates whether this charset is known to be registered in the IANA 597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Charset Registry. 598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if the charset is known to be registered, otherwise returns 600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * false. 601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final boolean isRegistered() { 603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return !canonicalName.startsWith("x-") //$NON-NLS-1$ 604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && !canonicalName.startsWith("X-"); //$NON-NLS-1$ 605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns true if this charset supports encoding, false otherwise. 609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if this charset supports encoding, false otherwise. 611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean canEncode() { 613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Encodes the content of the give character buffer and outputs to a byte 618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * buffer that is to be returned. 619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The default action in case of encoding errors is 621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <code>CodingErrorAction.REPLACE</code>. 622eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * 623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param buffer 624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the character buffer containing the content to be encoded. 625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the result of the encoding. 626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 627eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson public final ByteBuffer encode(CharBuffer buffer) { 628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 629eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson return this.newEncoder() 630eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson .onMalformedInput(CodingErrorAction.REPLACE) 631eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson .onUnmappableCharacter(CodingErrorAction.REPLACE).encode( 632eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson buffer); 633eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson 634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (CharacterCodingException ex) { 635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new Error(ex.getMessage(), ex); 636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Encodes a string and outputs to a byte buffer that is to be returned. 641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The default action in case of encoding errors is 643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <code>CodingErrorAction.REPLACE</code>. 644eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * 645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param s 646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the string to be encoded. 647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the result of the encoding. 648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final ByteBuffer encode(String s) { 650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return encode(CharBuffer.wrap(s)); 651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Decodes the content of the specified byte buffer and writes it to a 655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * character buffer that is to be returned. 656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The default action in case of decoding errors is 658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <code>CodingErrorAction.REPLACE</code>. 659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param buffer 661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the byte buffer containing the content to be decoded. 662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a character buffer containing the output of the decoding. 663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final CharBuffer decode(ByteBuffer buffer) { 665eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson 666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 667eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson return this.newDecoder() 668eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson .onMalformedInput(CodingErrorAction.REPLACE) 669eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson .onUnmappableCharacter(CodingErrorAction.REPLACE).decode( 670eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson buffer); 671eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson 672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (CharacterCodingException ex) { 673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new Error(ex.getMessage(), ex); 674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ------------------------------------------------------------------- 679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Methods implementing parent interface Comparable 680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ------------------------------------------------------------------- 681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Compares this charset with the given charset. This comparation is 685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * based on the case insensitive canonical names of the charsets. 686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param charset 688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the given object to be compared with. 689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a negative integer if less than the given object, a positive 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * integer if larger than it, or 0 if equal to it. 691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int compareTo(Charset charset) { 693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this.canonicalName.compareToIgnoreCase(charset.canonicalName); 694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ------------------------------------------------------------------- 698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Methods overriding parent class Object 699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ------------------------------------------------------------------- 700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Determines whether this charset equals to the given object. They are 704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * considered to be equal if they have the same canonical name. 705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj 707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the given object to be compared with. 708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if they have the same canonical name, otherwise false. 709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final boolean equals(Object obj) { 712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (obj instanceof Charset) { 713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Charset that = (Charset) obj; 714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this.canonicalName.equals(that.canonicalName); 715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the hash code of this charset. 721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the hash code of this charset. 723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int hashCode() { 726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this.canonicalName.hashCode(); 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets a string representation of this charset. Usually this contains the 731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * canonical name of the charset. 732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a string representation of this charset. 734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final String toString() { 737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return "Charset[" + this.canonicalName + "]"; //$NON-NLS-1$//$NON-NLS-2$ 738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the system default charset from the virtual machine. 742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the default charset. 744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static Charset defaultCharset() { 746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Charset defaultCharset = null; 747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String encoding = AccessController 748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .doPrivileged(new PrivilegedAction<String>() { 749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String run() { 750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return System.getProperty("file.encoding"); //$NON-NLS-1$ 751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project }); 753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project defaultCharset = Charset.forName(encoding); 755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (UnsupportedCharsetException e) { 756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project defaultCharset = Charset.forName("UTF-8"); //$NON-NLS-1$ 757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return defaultCharset; 759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 761