2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libjava / java / nio / charset / Charset.java
blobe0f27e6e697025f39c47708afdfd06a260da8483
1 /* Charset.java --
2 Copyright (C) 2002 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package java.nio.charset;
40 import java.nio.ByteBuffer;
41 import java.nio.CharBuffer;
42 import java.nio.charset.spi.CharsetProvider;
43 import java.util.Collections;
44 import java.util.HashSet;
45 import java.util.Iterator;
46 import java.util.Locale;
47 import java.util.Set;
48 import java.util.SortedMap;
49 import java.util.TreeMap;
50 import gnu.java.nio.charset.Provider;
52 /**
53 * @author Jesse Rosenstock
54 * @since 1.4
56 public abstract class Charset implements Comparable
58 private static CharsetEncoder cachedEncoder;
59 private static CharsetDecoder cachedDecoder;
61 static
63 synchronized (Charset.class)
65 cachedEncoder = null;
66 cachedDecoder = null;
70 private final String canonicalName;
71 private final String[] aliases;
73 protected Charset (String canonicalName, String[] aliases)
75 checkName (canonicalName);
76 if (aliases != null)
78 int n = aliases.length;
79 for (int i = 0; i < n; ++i)
80 checkName (aliases[i]);
83 this.canonicalName = canonicalName;
84 this.aliases = aliases;
87 /**
88 * @throws IllegalCharsetNameException if the name is illegal
90 private static void checkName (String name)
92 int n = name.length ();
94 if (n == 0)
95 throw new IllegalCharsetNameException (name);
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);
103 for (int i = 1; i < n; ++i)
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);
114 public static boolean isSupported (String charsetName)
116 return charsetForName (charsetName) != null;
119 public static Charset forName (String charsetName)
121 Charset cs = charsetForName (charsetName);
122 if (cs == null)
123 throw new UnsupportedCharsetException (charsetName);
124 return cs;
128 * Retrieves a charset for the given charset name.
130 * @return A charset object for the charset with the specified name, or
131 * <code>null</code> if no such charset exists.
133 * @throws IllegalCharsetNameException if the name is illegal
135 private static Charset charsetForName (String charsetName)
137 checkName (charsetName);
138 return provider ().charsetForName (charsetName);
141 public static SortedMap availableCharsets ()
143 TreeMap charsets = new TreeMap (String.CASE_INSENSITIVE_ORDER);
145 for (Iterator i = provider ().charsets (); i.hasNext (); )
147 Charset cs = (Charset) i.next ();
148 charsets.put (cs.name (), cs);
151 return Collections.unmodifiableSortedMap (charsets);
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 ()
159 return Provider.provider ();
162 public final String name ()
164 return canonicalName;
167 public final Set aliases ()
169 if (aliases == null)
170 return Collections.EMPTY_SET;
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);
180 public String displayName ()
182 return canonicalName;
185 public String displayName (Locale locale)
187 return canonicalName;
190 public final boolean isRegistered ()
192 return (!canonicalName.startsWith ("x-")
193 && !canonicalName.startsWith ("X-"));
196 public abstract boolean contains (Charset cs);
198 public abstract CharsetDecoder newDecoder ();
200 public abstract CharsetEncoder newEncoder ();
202 public boolean canEncode ()
204 return true;
207 public final ByteBuffer encode (CharBuffer cb)
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)
217 if (cachedEncoder == null)
219 cachedEncoder = newEncoder ()
220 .onMalformedInput (CodingErrorAction.REPLACE)
221 .onUnmappableCharacter (CodingErrorAction.REPLACE);
224 return cachedEncoder.encode (cb);
227 catch (CharacterCodingException e)
229 throw new AssertionError (e);
233 public final ByteBuffer encode (String str)
235 return encode (CharBuffer.wrap (str));
238 public final CharBuffer decode (ByteBuffer bb)
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)
248 if (cachedDecoder == null)
250 cachedDecoder = newDecoder ()
251 .onMalformedInput (CodingErrorAction.REPLACE)
252 .onUnmappableCharacter (CodingErrorAction.REPLACE);
255 return cachedDecoder.decode (bb);
258 catch (CharacterCodingException e)
260 throw new AssertionError (e);
264 public final int compareTo (Object ob)
266 return canonicalName.compareToIgnoreCase (((Charset) ob).canonicalName);
269 public final int hashCode ()
271 return canonicalName.hashCode ();
274 public final boolean equals (Object ob)
276 if (ob instanceof Charset)
277 return canonicalName.equalsIgnoreCase (((Charset) ob).canonicalName);
278 else
279 return false;
282 public final String toString ()
284 return canonicalName;