source: trunk/gcc/libjava/java/nio/charset/Charset.java

Last change on this file was 1389, checked in by bird, 21 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 7.7 KB
Line 
1/* Charset.java --
2 Copyright (C) 2002 Free Software Foundation, Inc.
3
4This file is part of GNU Classpath.
5
6GNU Classpath is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Classpath is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Classpath; see the file COPYING. If not, write to the
18Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1902111-1307 USA.
20
21Linking this library statically or dynamically with other modules is
22making a combined work based on this library. Thus, the terms and
23conditions of the GNU General Public License cover the whole
24combination.
25
26As a special exception, the copyright holders of this library give you
27permission to link this library with independent modules to produce an
28executable, regardless of the license terms of these independent
29modules, and to copy and distribute the resulting executable under
30terms of your choice, provided that you also meet, for each linked
31independent module, the terms and conditions of the license of that
32module. An independent module is a module which is not derived from
33or based on this library. If you modify this library, you may extend
34this exception to your version of the library, but you are not
35obligated to do so. If you do not wish to do so, delete this
36exception statement from your version. */
37
38package java.nio.charset;
39
40import java.nio.ByteBuffer;
41import java.nio.CharBuffer;
42import java.nio.charset.spi.CharsetProvider;
43import java.util.Collections;
44import java.util.HashSet;
45import java.util.Iterator;
46import java.util.Locale;
47import java.util.Set;
48import java.util.SortedMap;
49import java.util.TreeMap;
50import gnu.java.nio.charset.Provider;
51
52/**
53 * @author Jesse Rosenstock
54 * @since 1.4
55 */
56public abstract class Charset implements Comparable
57{
58 private static CharsetEncoder cachedEncoder;
59 private static CharsetDecoder cachedDecoder;
60
61 static
62 {
63 synchronized (Charset.class)
64 {
65 cachedEncoder = null;
66 cachedDecoder = null;
67 }
68 }
69
70 private final String canonicalName;
71 private final String[] aliases;
72
73 protected Charset (String canonicalName, String[] aliases)
74 {
75 checkName (canonicalName);
76 if (aliases != null)
77 {
78 int n = aliases.length;
79 for (int i = 0; i < n; ++i)
80 checkName (aliases[i]);
81 }
82
83 this.canonicalName = canonicalName;
84 this.aliases = aliases;
85 }
86
87 /**
88 * @throws IllegalCharsetNameException if the name is illegal
89 */
90 private static void checkName (String name)
91 {
92 int n = name.length ();
93
94 if (n == 0)
95 throw new IllegalCharsetNameException (name);
96
97 char ch = name.charAt (0);
98 if (!(('A' <= ch && ch <= 'Z')
99 || ('a' <= ch && ch <= 'z')
100 || ('0' <= ch && ch <= '9')))
101 throw new IllegalCharsetNameException (name);
102
103 for (int i = 1; i < n; ++i)
104 {
105 ch = name.charAt (i);
106 if (!(('A' <= ch && ch <= 'Z')
107 || ('a' <= ch && ch <= 'z')
108 || ('0' <= ch && ch <= '9')
109 || ch == '-' || ch == '.' || ch == ':' || ch == '_'))
110 throw new IllegalCharsetNameException (name);
111 }
112 }
113
114 public static boolean isSupported (String charsetName)
115 {
116 return charsetForName (charsetName) != null;
117 }
118
119 public static Charset forName (String charsetName)
120 {
121 Charset cs = charsetForName (charsetName);
122 if (cs == null)
123 throw new UnsupportedCharsetException (charsetName);
124 return cs;
125 }
126
127 /**
128 * Retrieves a charset for the given charset name.
129 *
130 * @return A charset object for the charset with the specified name, or
131 * <code>null</code> if no such charset exists.
132 *
133 * @throws IllegalCharsetNameException if the name is illegal
134 */
135 private static Charset charsetForName (String charsetName)
136 {
137 checkName (charsetName);
138 return provider ().charsetForName (charsetName);
139 }
140
141 public static SortedMap availableCharsets ()
142 {
143 TreeMap charsets = new TreeMap (String.CASE_INSENSITIVE_ORDER);
144
145 for (Iterator i = provider ().charsets (); i.hasNext (); )
146 {
147 Charset cs = (Charset) i.next ();
148 charsets.put (cs.name (), cs);
149 }
150
151 return Collections.unmodifiableSortedMap (charsets);
152 }
153
154 // XXX: we need to support multiple providers, reading them from
155 // java.nio.charset.spi.CharsetProvider in the resource directory
156 // META-INF/services
157 private static final CharsetProvider provider ()
158 {
159 return Provider.provider ();
160 }
161
162 public final String name ()
163 {
164 return canonicalName;
165 }
166
167 public final Set aliases ()
168 {
169 if (aliases == null)
170 return Collections.EMPTY_SET;
171
172 // should we cache the aliasSet instead?
173 int n = aliases.length;
174 HashSet aliasSet = new HashSet (n);
175 for (int i = 0; i < n; ++i)
176 aliasSet.add (aliases[i]);
177 return Collections.unmodifiableSet (aliasSet);
178 }
179
180 public String displayName ()
181 {
182 return canonicalName;
183 }
184
185 public String displayName (Locale locale)
186 {
187 return canonicalName;
188 }
189
190 public final boolean isRegistered ()
191 {
192 return (!canonicalName.startsWith ("x-")
193 && !canonicalName.startsWith ("X-"));
194 }
195
196 public abstract boolean contains (Charset cs);
197
198 public abstract CharsetDecoder newDecoder ();
199
200 public abstract CharsetEncoder newEncoder ();
201
202 public boolean canEncode ()
203 {
204 return true;
205 }
206
207 public final ByteBuffer encode (CharBuffer cb)
208 {
209 try
210 {
211 // NB: This implementation serializes different threads calling
212 // Charset.encode(), a potential performance problem. It might
213 // be better to remove the cache, or use ThreadLocal to cache on
214 // a per-thread basis.
215 synchronized (Charset.class)
216 {
217 if (cachedEncoder == null)
218 {
219 cachedEncoder = newEncoder ()
220 .onMalformedInput (CodingErrorAction.REPLACE)
221 .onUnmappableCharacter (CodingErrorAction.REPLACE);
222 }
223
224 return cachedEncoder.encode (cb);
225 }
226 }
227 catch (CharacterCodingException e)
228 {
229 throw new AssertionError (e);
230 }
231 }
232
233 public final ByteBuffer encode (String str)
234 {
235 return encode (CharBuffer.wrap (str));
236 }
237
238 public CharBuffer decode (ByteBuffer bb)
239 {
240 try
241 {
242 // NB: This implementation serializes different threads calling
243 // Charset.decode(), a potential performance problem. It might
244 // be better to remove the cache, or use ThreadLocal to cache on
245 // a per-thread basis.
246 synchronized (Charset.class)
247 {
248 if (cachedDecoder == null)
249 {
250 cachedDecoder = newDecoder ()
251 .onMalformedInput (CodingErrorAction.REPLACE)
252 .onUnmappableCharacter (CodingErrorAction.REPLACE);
253 }
254
255 return cachedDecoder.decode (bb);
256 }
257 }
258 catch (CharacterCodingException e)
259 {
260 throw new AssertionError (e);
261 }
262 }
263
264 public final int compareTo (Object ob)
265 {
266 return canonicalName.compareToIgnoreCase (((Charset) ob).canonicalName);
267 }
268
269 public final int hashCode ()
270 {
271 return canonicalName.hashCode ();
272 }
273
274 public final boolean equals (Object ob)
275 {
276 if (ob instanceof Charset)
277 return canonicalName.equalsIgnoreCase (((Charset) ob).canonicalName);
278 else
279 return false;
280 }
281
282 public final String toString ()
283 {
284 return canonicalName;
285 }
286}
Note: See TracBrowser for help on using the repository browser.