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 for (; providerFiles.hasMoreElements();)
118 {
119 final URL url = ( URL ) providerFiles.nextElement();
120 final InputStream in = url.openStream();
121
122 try
123 {
124 String line;
125 final BufferedReader reader = new BufferedReader(
126 new InputStreamReader( in, "UTF-8" ) );
127
128 while ( ( line = reader.readLine() ) != null )
129 {
130
131
132
133 if ( line.indexOf( '#' ) < 0 )
134 {
135 providers.add( classLoader.loadClass( line ).
136 newInstance() );
137
138 }
139 }
140 }
141 finally
142 {
143 in.close();
144 }
145 }
146 }
147 }
148 }
149
150
151 Charset charset = ( Charset ) charsets.get( name );
152 if ( charset == null )
153 {
154 synchronized ( Charsets.class )
155 {
156
157 for ( Iterator it = providers.iterator(); it.hasNext();)
158 {
159 charset =
160 ( ( CharsetProvider ) it.next() ).charsetForName( name );
161
162 if ( charset != null )
163 {
164 charsets.put( name, charset );
165 break;
166 }
167 }
168 }
169 }
170
171
172 if ( charset == null )
173 {
174 synchronized ( Charsets.class )
175 {
176 charset = Charset.forName( name );
177 charsets.put( name, charset );
178 }
179 }
180
181 return charset;
182 }
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198 public static byte[] encode( final String str, final String charset )
199 {
200 if ( str == null )
201 {
202 throw new NullPointerException( "str" );
203 }
204 if ( charset == null )
205 {
206 throw new NullPointerException( "charset" );
207 }
208
209 final byte[] ret;
210 try
211 {
212 final Charset cset = Charsets.getCharset( charset );
213 final ByteBuffer buf = cset.encode( str );
214
215 if ( buf.hasArray() )
216 {
217 if ( buf.array().length == buf.limit() )
218 {
219 ret = buf.array();
220 }
221 else
222 {
223 ret = new byte[ buf.limit() ];
224 System.arraycopy( buf.array(), buf.arrayOffset(),
225 ret, 0, ret.length );
226
227 }
228 }
229 else
230 {
231 ret = new byte[ buf.limit() ];
232 buf.rewind();
233 buf.get( ret );
234 }
235 }
236 catch ( ClassNotFoundException e )
237 {
238 throw new AssertionError( e );
239 }
240 catch ( InstantiationException e )
241 {
242 throw new AssertionError( e );
243 }
244 catch ( IllegalAccessException e )
245 {
246 throw new AssertionError( e );
247 }
248 catch ( IOException e )
249 {
250 throw new AssertionError( e );
251 }
252
253 return ret;
254 }
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269 public static String decode( final byte[] bytes, final String charset )
270 {
271 if ( bytes == null )
272 {
273 throw new NullPointerException( "bytes" );
274 }
275 if ( charset == null )
276 {
277 throw new NullPointerException( "charset" );
278 }
279
280 final String ret;
281 try
282 {
283 final Charset cset = Charsets.getCharset( charset );
284 final CharBuffer buf = cset.decode( ByteBuffer.wrap( bytes ) );
285
286 if ( buf.hasArray() )
287 {
288 ret = String.valueOf( buf.array(), buf.arrayOffset(),
289 buf.length() );
290
291 }
292 else
293 {
294 final char[] c = new char[ buf.length() ];
295 buf.rewind();
296 buf.get( c );
297 ret = String.valueOf( c );
298 }
299 }
300 catch ( ClassNotFoundException e )
301 {
302 throw new AssertionError( e );
303 }
304 catch ( InstantiationException e )
305 {
306 throw new AssertionError( e );
307 }
308 catch ( IllegalAccessException e )
309 {
310 throw new AssertionError( e );
311 }
312 catch ( IOException e )
313 {
314 throw new AssertionError( e );
315 }
316
317 return ret;
318 }
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338 public static String decode( final byte[] bytes, final int off,
339 final int count, final String charset )
340 {
341 if ( bytes == null )
342 {
343 throw new NullPointerException( "bytes" );
344 }
345 if ( charset == null )
346 {
347 throw new NullPointerException( "charset" );
348 }
349 if ( off < 0 || off >= bytes.length )
350 {
351 throw new ArrayIndexOutOfBoundsException( off );
352 }
353 if ( count < 0 || off + count >= bytes.length )
354 {
355 throw new ArrayIndexOutOfBoundsException( count + off );
356 }
357
358 final String ret;
359 try
360 {
361 final Charset cset = Charsets.getCharset( charset );
362 final CharBuffer buf = cset.decode(
363 ByteBuffer.wrap( bytes, off, count ) );
364
365 if ( buf.hasArray() )
366 {
367 ret = String.valueOf( buf.array(), buf.arrayOffset(),
368 buf.length() );
369
370 }
371 else
372 {
373 final char[] c = new char[ buf.length() ];
374 buf.rewind();
375 buf.get( c );
376 ret = String.valueOf( c );
377 }
378 }
379 catch ( ClassNotFoundException e )
380 {
381 throw new AssertionError( e );
382 }
383 catch ( InstantiationException e )
384 {
385 throw new AssertionError( e );
386 }
387 catch ( IllegalAccessException e )
388 {
389 throw new AssertionError( e );
390 }
391 catch ( IOException e )
392 {
393 throw new AssertionError( e );
394 }
395
396 return ret;
397 }
398
399
400 }