History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/io/Converters.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/io/Converters.java+341−0
@@ -0,0 +1,341 @@
1+/*
2+ * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package sun.io;
27+
28+import java.io.UnsupportedEncodingException;
29+import java.lang.ref.SoftReference;
30+import java.util.Properties;
31+
32+/**
33+ * Package-private utility class that caches the default converter classes and
34+ * provides other logic common to both the ByteToCharConverter and
35+ * CharToByteConverter classes.
36+ *
37+ * @author Mark Reinhold
38+ * @since 1.2
39+ *
40+ * @deprecated Replaced by {@link java.nio.charset}. THIS API WILL BE
41+ * REMOVED IN J2SE 1.6.
42+ */
43+@Deprecated
44+public class Converters {
45+
46+ private Converters() { } /* To prevent instantiation */
47+
48+ /* Lock for all static fields in this class */
49+ private static Object lock = Converters.class;
50+
51+ /* Cached values of system properties */
52+ private static String converterPackageName = null; /* file.encoding.pkg */
53+ private static String defaultEncoding = null; /* file.encoding */
54+
55+ /* Converter type constants and names */
56+ public static final int BYTE_TO_CHAR = 0;
57+ public static final int CHAR_TO_BYTE = 1;
58+ private static final String[] converterPrefix = { "ByteToChar",
59+ "CharToByte" };
60+
61+
62+ // -- Converter class cache --
63+
64+ private static final int CACHE_SIZE = 3;
65+
66+ /* For the default charset, whatever it turns out to be */
67+ private static final Object DEFAULT_NAME = new Object();
68+
69+ /* Cached converter classes, CACHE_SIZE per converter type. Each cache
70+ * entry is a soft reference to a two-object array; the first element of
71+ * the array is the converter class, the second is an object (typically a
72+ * string) representing the encoding name that was used to request the
73+ * converter, e.g.,
74+ *
75+ * ((Object[])classCache[CHAR_TO_BYTE][i].get())[0]
76+ *
77+ * will be a CharToByteConverter and
78+ *
79+ * ((Object[])classCache[CHAR_TO_BYTE][i].get())[1]
80+ *
81+ * will be the string encoding name used to request it, assuming that cache
82+ * entry i is valid.
83+ *
84+ * Ordinarily we'd do this with a private static utility class, but since
85+ * this code can be involved in the startup sequence it's important to keep
86+ * the footprint down.
87+ */
88+ @SuppressWarnings("unchecked")
89+ private static SoftReference<Object[]>[][] classCache
90+ = (SoftReference<Object[]>[][]) new SoftReference<?>[][] {
91+ new SoftReference<?>[CACHE_SIZE],
92+ new SoftReference<?>[CACHE_SIZE]
93+ };
94+
95+ private static void moveToFront(Object[] oa, int i) {
96+ Object ob = oa[i];
97+ for (int j = i; j > 0; j--)
98+ oa[j] = oa[j - 1];
99+ oa[0] = ob;
100+ }
101+
102+ private static Class<?> cache(int type, Object encoding) {
103+ SoftReference<Object[]>[] srs = classCache[type];
104+ for (int i = 0; i < CACHE_SIZE; i++) {
105+ SoftReference<Object[]> sr = srs[i];
106+ if (sr == null)
107+ continue;
108+ Object[] oa = sr.get();
109+ if (oa == null) {
110+ srs[i] = null;
111+ continue;
112+ }
113+ if (oa[1].equals(encoding)) {
114+ moveToFront(srs, i);
115+ return (Class<?>)oa[0];
116+ }
117+ }
118+ return null;
119+ }
120+
121+ private static Class<?> cache(int type, Object encoding, Class<?> c) {
122+ SoftReference<Object[]>[] srs = classCache[type];
123+ srs[CACHE_SIZE - 1] = new SoftReference<>(new Object[] { c, encoding });
124+ moveToFront(srs, CACHE_SIZE - 1);
125+ return c;
126+ }
127+
128+ /* Used to avoid doing expensive charset lookups for charsets that are not
129+ * yet directly supported by NIO.
130+ */
131+ public static boolean isCached(int type, String encoding) {
132+ synchronized (lock) {
133+ SoftReference<Object[]>[] srs = classCache[type];
134+ for (int i = 0; i < CACHE_SIZE; i++) {
135+ SoftReference<Object[]> sr = srs[i];
136+ if (sr == null)
137+ continue;
138+ Object[] oa = sr.get();
139+ if (oa == null) {
140+ srs[i] = null;
141+ continue;
142+ }
143+ if (oa[1].equals(encoding))
144+ return true;
145+ }
146+ return false;
147+ }
148+ }
149+
150+
151+
152+ /** Get the name of the converter package */
153+ private static String getConverterPackageName() {
154+ String cp = converterPackageName;
155+ if (cp != null) return cp;
156+ java.security.PrivilegedAction<String> pa =
157+ new sun.security.action.GetPropertyAction("file.encoding.pkg");
158+ cp = java.security.AccessController.doPrivileged(pa);
159+ if (cp != null) {
160+ /* Property is set, so take it as the true converter package */
161+ converterPackageName = cp;
162+ } else {
163+ /* Fall back to sun.io */
164+ cp = "sun.io";
165+ }
166+ return cp;
167+ }
168+
169+ public static String getDefaultEncodingName() {
170+ synchronized (lock) {
171+ if (defaultEncoding == null) {
172+ java.security.PrivilegedAction<String> pa =
173+ new sun.security.action.GetPropertyAction("file.encoding");
174+ defaultEncoding = java.security.AccessController.doPrivileged(pa);
175+ }
176+ }
177+ return defaultEncoding;
178+ }
179+
180+ public static void resetDefaultEncodingName() {
181+ // This method should only be called during VM initialization.
182+ if (sun.misc.VM.isBooted())
183+ return;
184+
185+ synchronized (lock) {
186+ defaultEncoding = "ISO-8859-1";
187+ Properties p = System.getProperties();
188+ p.setProperty("file.encoding", defaultEncoding);
189+ System.setProperties(p);
190+ }
191+ }
192+
193+ /**
194+ * Get the class that implements the given type of converter for the named
195+ * encoding, or throw an UnsupportedEncodingException if no such class can
196+ * be found
197+ */
198+ private static Class<?> getConverterClass(int type, String encoding)
199+ throws UnsupportedEncodingException
200+ {
201+ String enc = null;
202+
203+ /* "ISO8859_1" is the canonical name for the ISO-Latin-1 encoding.
204+ Native code in the JDK commonly uses the alias "8859_1" instead of
205+ "ISO8859_1". We hardwire this alias here in order to avoid loading
206+ the full alias table just for this case. */
207+ if (!encoding.equals("ISO8859_1")) {
208+ if (encoding.equals("8859_1")) {
209+ enc = "ISO8859_1";
210+ /*
211+ * On Solaris with nl_langinfo() called in GetJavaProperties():
212+ *
213+ * locale undefined -> NULL -> hardcoded default
214+ * "C" locale -> "" -> hardcoded default (on 2.6)
215+ * "C" locale -> "646" (on 2.7)
216+ * "en_US" locale -> "ISO8859-1"
217+ * "en_GB" locale -> "ISO8859-1" (on 2.7)
218+ * "en_UK" locale -> "ISO8859-1" (on 2.6)
219+ */
220+ } else if (encoding.equals("ISO8859-1")) {
221+ enc = "ISO8859_1";
222+ } else if (encoding.equals("646")) {
223+ enc = "ASCII";
224+ } else {
225+ enc = CharacterEncoding.aliasName(encoding);
226+ }
227+ }
228+ if (enc == null) {
229+ enc = encoding;
230+ }
231+
232+ try {
233+ return Class.forName(getConverterPackageName()
234+ + "." + converterPrefix[type] + enc);
235+ } catch(ClassNotFoundException e) {
236+ throw new UnsupportedEncodingException(enc);
237+ }
238+
239+ }
240+
241+ /**
242+ * Instantiate the given converter class, or throw an
243+ * UnsupportedEncodingException if it cannot be instantiated
244+ */
245+ private static Object newConverter(String enc, Class<?> c)
246+ throws UnsupportedEncodingException
247+ {
248+ try {
249+ return c.newInstance();
250+ } catch(InstantiationException e) {
251+ throw new UnsupportedEncodingException(enc);
252+ } catch(IllegalAccessException e) {
253+ throw new UnsupportedEncodingException(enc);
254+ }
255+ }
256+
257+ /**
258+ * Create a converter object that implements the given type of converter
259+ * for the given encoding, or throw an UnsupportedEncodingException if no
260+ * appropriate converter class can be found and instantiated
261+ */
262+ static Object newConverter(int type, String enc)
263+ throws UnsupportedEncodingException
264+ {
265+ Class<?> c;
266+ synchronized (lock) {
267+ c = cache(type, enc);
268+ if (c == null) {
269+ c = getConverterClass(type, enc);
270+ if (!c.getName().equals("sun.io.CharToByteUTF8"))
271+ cache(type, enc, c);
272+ }
273+ }
274+ return newConverter(enc, c);
275+ }
276+
277+ /**
278+ * Find the class that implements the given type of converter for the
279+ * default encoding. If the default encoding cannot be determined or is
280+ * not yet defined, return a class that implements the fallback default
281+ * encoding, which is just ISO 8859-1.
282+ */
283+ private static Class<?> getDefaultConverterClass(int type) {
284+ boolean fillCache = false;
285+ Class<?> c;
286+
287+ /* First check the class cache */
288+ c = cache(type, DEFAULT_NAME);
289+ if (c != null)
290+ return c;
291+
292+ /* Determine the encoding name */
293+ String enc = getDefaultEncodingName();
294+ if (enc != null) {
295+ /* file.encoding has been set, so cache the converter class */
296+ fillCache = true;
297+ } else {
298+ /* file.encoding has not been set, so use a default encoding which
299+ will not be cached */
300+ enc = "ISO8859_1";
301+ }
302+
303+ /* We have an encoding name; try to find its class */
304+ try {
305+ c = getConverterClass(type, enc);
306+ if (fillCache) {
307+ cache(type, DEFAULT_NAME, c);
308+ }
309+ } catch (UnsupportedEncodingException x) {
310+ /* Can't find the default class, so fall back to ISO 8859-1 */
311+ try {
312+ c = getConverterClass(type, "ISO8859_1");
313+ } catch (UnsupportedEncodingException y) {
314+ throw new InternalError("Cannot find default "
315+ + converterPrefix[type]
316+ + " converter class");
317+ }
318+ }
319+ return c;
320+
321+ }
322+
323+ /**
324+ * Create a converter object that implements the given type of converter
325+ * for the default encoding, falling back to ISO 8859-1 if the default
326+ * encoding cannot be determined.
327+ */
328+ static Object newDefaultConverter(int type) {
329+ Class<?> c;
330+ synchronized (lock) {
331+ c = getDefaultConverterClass(type);
332+ }
333+ try {
334+ return newConverter("", c);
335+ } catch (UnsupportedEncodingException x) {
336+ throw new InternalError("Cannot instantiate default converter"
337+ + " class " + c.getName());
338+ }
339+ }
340+
341+}