1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.jdtaus.core.nio.util;
22
23 import java.io.BufferedReader;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.InputStreamReader;
27 import java.net.URL;
28 import java.nio.ByteBuffer;
29 import java.nio.CharBuffer;
30 import java.nio.charset.Charset;
31 import java.nio.charset.spi.CharsetProvider;
32 import java.util.Enumeration;
33 import java.util.HashMap;
34 import java.util.Iterator;
35 import java.util.LinkedList;
36 import java.util.List;
37 import java.util.Map;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 public class Charsets
53 {
54
55
56
57 private static final List providers = new LinkedList();
58
59
60 private static final Map charsets = new HashMap( 100 );
61
62
63 private Charsets()
64 {
65 super();
66 }
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 private static Charset getCharset( final String name )
89 throws IOException, ClassNotFoundException, InstantiationException,
90 IllegalAccessException
91 {
92
93 if ( providers.size() == 0 )
94 {
95 synchronized ( Charsets.class )
96 {
97
98
99 ClassLoader classLoader = Thread.currentThread().
100 getContextClassLoader();
101
102 if ( classLoader == null )
103 {
104 classLoader = ClassLoader.getSystemClassLoader();
105 }
106
107 assert classLoader != null :
108 "Expected system classloader to always be available.";
109
110
111
112 final Enumeration providerFiles = classLoader.getResources(
113 "META-INF/services/java.nio.charset.spi.CharsetProvider" );
114
115 if ( providerFiles != null )
116 {
117 while ( providerFiles.hasMoreElements() )
118 {
119 final URL url = ( URL ) providerFiles.nextElement();
120 BufferedReader reader = null;
121
122 try
123 {
124 String line;
125 reader = new BufferedReader(
126 new InputStreamReader( url.openStream(),
127 "UTF-8" ) );
128
129 while ( ( line = reader.readLine() ) != null )
130 {
131
132
133
134 if ( line.indexOf( '#' ) < 0 )
135 {
136 providers.add(
137 classLoader.loadClass( line ).
138 newInstance() );
139
140 }
141 }
142
143 reader.close();
144 reader = null;
145 }
146 finally
147 {
148 if ( reader != null )
149 {
150 reader.close();
151 }
152 }
153 }
154 }
155 }
156 }
157
158
159 Charset charset = ( Charset ) charsets.get( name );
160 if ( charset == null )
161 {
162 synchronized ( Charsets.class )
163 {
164
165 for ( final Iterator it = providers.iterator(); it.hasNext();)
166 {
167 charset =
168 ( ( CharsetProvider ) it.next() ).charsetForName( name );
169
170 if ( charset != null )
171 {
172 charsets.put( name, charset );
173 break;
174 }
175 }
176 }
177 }
178
179
180 if ( charset == null )
181 {
182 synchronized ( Charsets.class )
183 {
184 charset = Charset.forName( name );
185 charsets.put( name, charset );
186 }
187 }
188
189 return charset;
190 }
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206 public static byte[] encode( final String str, final String charset )
207 {
208 if ( str == null )
209 {
210 throw new NullPointerException( "str" );
211 }
212 if ( charset == null )
213 {
214 throw new NullPointerException( "charset" );
215 }
216
217 final byte[] ret;
218 try
219 {
220 final Charset cset = Charsets.getCharset( charset );
221 final ByteBuffer buf = cset.encode( str );
222
223 if ( buf.hasArray() )
224 {
225 if ( buf.array().length == buf.limit() )
226 {
227 ret = buf.array();
228 }
229 else
230 {
231 ret = new byte[ buf.limit() ];
232 System.arraycopy( buf.array(), buf.arrayOffset(),
233 ret, 0, ret.length );
234
235 }
236 }
237 else
238 {
239 ret = new byte[ buf.limit() ];
240 buf.rewind();
241 buf.get( ret );
242 }
243 }
244 catch ( final ClassNotFoundException e )
245 {
246 throw new AssertionError( e );
247 }
248 catch ( final InstantiationException e )
249 {
250 throw new AssertionError( e );
251 }
252 catch ( final IllegalAccessException e )
253 {
254 throw new AssertionError( e );
255 }
256 catch ( final IOException e )
257 {
258 throw new AssertionError( e );
259 }
260
261 return ret;
262 }
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277 public static String decode( final byte[] bytes, final String charset )
278 {
279 if ( bytes == null )
280 {
281 throw new NullPointerException( "bytes" );
282 }
283 if ( charset == null )
284 {
285 throw new NullPointerException( "charset" );
286 }
287
288 final String ret;
289 try
290 {
291 final Charset cset = Charsets.getCharset( charset );
292 final CharBuffer buf = cset.decode( ByteBuffer.wrap( bytes ) );
293
294 if ( buf.hasArray() )
295 {
296 ret = String.valueOf( buf.array(), buf.arrayOffset(),
297 buf.length() );
298
299 }
300 else
301 {
302 final char[] c = new char[ buf.length() ];
303 buf.rewind();
304 buf.get( c );
305 ret = String.valueOf( c );
306 }
307 }
308 catch ( final ClassNotFoundException e )
309 {
310 throw new AssertionError( e );
311 }
312 catch ( final InstantiationException e )
313 {
314 throw new AssertionError( e );
315 }
316 catch ( final IllegalAccessException e )
317 {
318 throw new AssertionError( e );
319 }
320 catch ( final IOException e )
321 {
322 throw new AssertionError( e );
323 }
324
325 return ret;
326 }
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346 public static String decode( final byte[] bytes, final int off,
347 final int count, final String charset )
348 {
349 if ( bytes == null )
350 {
351 throw new NullPointerException( "bytes" );
352 }
353 if ( charset == null )
354 {
355 throw new NullPointerException( "charset" );
356 }
357 if ( off < 0 || off >= bytes.length )
358 {
359 throw new ArrayIndexOutOfBoundsException( off );
360 }
361 if ( count < 0 || off + count >= bytes.length )
362 {
363 throw new ArrayIndexOutOfBoundsException( count + off );
364 }
365
366 final String ret;
367 try
368 {
369 final Charset cset = Charsets.getCharset( charset );
370 final CharBuffer buf = cset.decode(
371 ByteBuffer.wrap( bytes, off, count ) );
372
373 if ( buf.hasArray() )
374 {
375 ret = String.valueOf( buf.array(), buf.arrayOffset(),
376 buf.length() );
377
378 }
379 else
380 {
381 final char[] c = new char[ buf.length() ];
382 buf.rewind();
383 buf.get( c );
384 ret = String.valueOf( c );
385 }
386 }
387 catch ( final ClassNotFoundException e )
388 {
389 throw new AssertionError( e );
390 }
391 catch ( final InstantiationException e )
392 {
393 throw new AssertionError( e );
394 }
395 catch ( final IllegalAccessException e )
396 {
397 throw new AssertionError( e );
398 }
399 catch ( final IOException e )
400 {
401 throw new AssertionError( e );
402 }
403
404 return ret;
405 }
406
407
408 }