1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.util;
15
16 import java.io.UnsupportedEncodingException;
17 import java.nio.charset.Charset;
18
19 import org.eclipse.jetty.util.log.Log;
20
21
22
23
24
25
26
27
28
29
30
31 public class StringUtil
32 {
33 public static final String ALL_INTERFACES="0.0.0.0";
34 public static final String CRLF="\015\012";
35 public static final String __LINE_SEPARATOR=
36 System.getProperty("line.separator","\n");
37
38 public static final String __ISO_8859_1="ISO-8859-1";
39 public final static String __UTF8="UTF-8";
40 public final static String __UTF8Alt="UTF8";
41 public final static String __UTF16="UTF-16";
42
43 public final static Charset __UTF8_CHARSET;
44 public final static Charset __ISO_8859_1_CHARSET;
45
46 static
47 {
48 __UTF8_CHARSET=Charset.forName(__UTF8);
49 __ISO_8859_1_CHARSET=Charset.forName(__ISO_8859_1);
50 }
51
52 private static char[] lowercases = {
53 '\000','\001','\002','\003','\004','\005','\006','\007',
54 '\010','\011','\012','\013','\014','\015','\016','\017',
55 '\020','\021','\022','\023','\024','\025','\026','\027',
56 '\030','\031','\032','\033','\034','\035','\036','\037',
57 '\040','\041','\042','\043','\044','\045','\046','\047',
58 '\050','\051','\052','\053','\054','\055','\056','\057',
59 '\060','\061','\062','\063','\064','\065','\066','\067',
60 '\070','\071','\072','\073','\074','\075','\076','\077',
61 '\100','\141','\142','\143','\144','\145','\146','\147',
62 '\150','\151','\152','\153','\154','\155','\156','\157',
63 '\160','\161','\162','\163','\164','\165','\166','\167',
64 '\170','\171','\172','\133','\134','\135','\136','\137',
65 '\140','\141','\142','\143','\144','\145','\146','\147',
66 '\150','\151','\152','\153','\154','\155','\156','\157',
67 '\160','\161','\162','\163','\164','\165','\166','\167',
68 '\170','\171','\172','\173','\174','\175','\176','\177' };
69
70
71
72
73
74
75
76 public static String asciiToLowerCase(String s)
77 {
78 char[] c = null;
79 int i=s.length();
80
81
82 while (i-->0)
83 {
84 char c1=s.charAt(i);
85 if (c1<=127)
86 {
87 char c2=lowercases[c1];
88 if (c1!=c2)
89 {
90 c=s.toCharArray();
91 c[i]=c2;
92 break;
93 }
94 }
95 }
96
97 while (i-->0)
98 {
99 if(c[i]<=127)
100 c[i] = lowercases[c[i]];
101 }
102
103 return c==null?s:new String(c);
104 }
105
106
107
108 public static boolean startsWithIgnoreCase(String s,String w)
109 {
110 if (w==null)
111 return true;
112
113 if (s==null || s.length()<w.length())
114 return false;
115
116 for (int i=0;i<w.length();i++)
117 {
118 char c1=s.charAt(i);
119 char c2=w.charAt(i);
120 if (c1!=c2)
121 {
122 if (c1<=127)
123 c1=lowercases[c1];
124 if (c2<=127)
125 c2=lowercases[c2];
126 if (c1!=c2)
127 return false;
128 }
129 }
130 return true;
131 }
132
133
134 public static boolean endsWithIgnoreCase(String s,String w)
135 {
136 if (w==null)
137 return true;
138
139 if (s==null)
140 return false;
141
142 int sl=s.length();
143 int wl=w.length();
144
145 if (sl<wl)
146 return false;
147
148 for (int i=wl;i-->0;)
149 {
150 char c1=s.charAt(--sl);
151 char c2=w.charAt(i);
152 if (c1!=c2)
153 {
154 if (c1<=127)
155 c1=lowercases[c1];
156 if (c2<=127)
157 c2=lowercases[c2];
158 if (c1!=c2)
159 return false;
160 }
161 }
162 return true;
163 }
164
165
166
167
168
169 public static int indexFrom(String s,String chars)
170 {
171 for (int i=0;i<s.length();i++)
172 if (chars.indexOf(s.charAt(i))>=0)
173 return i;
174 return -1;
175 }
176
177
178
179
180
181 public static String replace(String s, String sub, String with)
182 {
183 int c=0;
184 int i=s.indexOf(sub,c);
185 if (i == -1)
186 return s;
187
188 StringBuilder buf = new StringBuilder(s.length()+with.length());
189
190 do
191 {
192 buf.append(s.substring(c,i));
193 buf.append(with);
194 c=i+sub.length();
195 } while ((i=s.indexOf(sub,c))!=-1);
196
197 if (c<s.length())
198 buf.append(s.substring(c,s.length()));
199
200 return buf.toString();
201
202 }
203
204
205
206
207
208 public static String unquote(String s)
209 {
210 return QuotedStringTokenizer.unquote(s);
211 }
212
213
214
215
216
217
218
219
220
221 public static void append(StringBuilder buf,
222 String s,
223 int offset,
224 int length)
225 {
226 synchronized(buf)
227 {
228 int end=offset+length;
229 for (int i=offset; i<end;i++)
230 {
231 if (i>=s.length())
232 break;
233 buf.append(s.charAt(i));
234 }
235 }
236 }
237
238
239
240
241
242
243
244 public static void append(StringBuilder buf,byte b,int base)
245 {
246 int bi=0xff&b;
247 int c='0'+(bi/base)%base;
248 if (c>'9')
249 c= 'a'+(c-'0'-10);
250 buf.append((char)c);
251 c='0'+bi%base;
252 if (c>'9')
253 c= 'a'+(c-'0'-10);
254 buf.append((char)c);
255 }
256
257
258 public static void append2digits(StringBuffer buf,int i)
259 {
260 if (i<100)
261 {
262 buf.append((char)(i/10+'0'));
263 buf.append((char)(i%10+'0'));
264 }
265 }
266
267
268 public static void append2digits(StringBuilder buf,int i)
269 {
270 if (i<100)
271 {
272 buf.append((char)(i/10+'0'));
273 buf.append((char)(i%10+'0'));
274 }
275 }
276
277
278
279
280
281
282 public static String nonNull(String s)
283 {
284 if (s==null)
285 return "";
286 return s;
287 }
288
289
290 public static boolean equals(String s,char[] buf, int offset, int length)
291 {
292 if (s.length()!=length)
293 return false;
294 for (int i=0;i<length;i++)
295 if (buf[offset+i]!=s.charAt(i))
296 return false;
297 return true;
298 }
299
300
301 public static String toUTF8String(byte[] b,int offset,int length)
302 {
303 try
304 {
305 return new String(b,offset,length,__UTF8);
306 }
307 catch (UnsupportedEncodingException e)
308 {
309 throw new IllegalArgumentException(e);
310 }
311 }
312
313
314 public static String toString(byte[] b,int offset,int length,String charset)
315 {
316 try
317 {
318 return new String(b,offset,length,charset);
319 }
320 catch (UnsupportedEncodingException e)
321 {
322 throw new IllegalArgumentException(e);
323 }
324 }
325
326
327
328 public static boolean isUTF8(String charset)
329 {
330 return charset==__UTF8||__UTF8.equalsIgnoreCase(charset)||__UTF8Alt.equalsIgnoreCase(charset);
331 }
332
333
334
335 public static String printable(String name)
336 {
337 if (name==null)
338 return null;
339 StringBuilder buf = new StringBuilder(name.length());
340 for (int i=0;i<name.length();i++)
341 {
342 char c=name.charAt(i);
343 if (!Character.isISOControl(c))
344 buf.append(c);
345 }
346 return buf.toString();
347 }
348
349
350 public static String printable(byte[] b)
351 {
352 StringBuilder buf = new StringBuilder();
353 for (int i=0;i<b.length;i++)
354 {
355 char c=(char)b[i];
356 if (Character.isWhitespace(c)|| c>' ' && c<0x7f)
357 buf.append(c);
358 else
359 {
360 buf.append("0x");
361 TypeUtil.toHex(b[i],buf);
362 }
363 }
364 return buf.toString();
365 }
366
367 public static byte[] getBytes(String s)
368 {
369 try
370 {
371 return s.getBytes(__ISO_8859_1);
372 }
373 catch(Exception e)
374 {
375 Log.warn(e);
376 return s.getBytes();
377 }
378 }
379
380 public static byte[] getBytes(String s,String charset)
381 {
382 try
383 {
384 return s.getBytes(charset);
385 }
386 catch(Exception e)
387 {
388 Log.warn(e);
389 return s.getBytes();
390 }
391 }
392
393
394
395
396
397
398
399
400
401
402 public static String sidBytesToString(byte[] sidBytes)
403 {
404 StringBuilder sidString = new StringBuilder();
405
406
407 sidString.append("S-");
408
409
410 sidString.append(Byte.toString(sidBytes[0])).append('-');
411
412 StringBuilder tmpBuilder = new StringBuilder();
413
414
415 for (int i = 2; i <= 7; ++i)
416 {
417 tmpBuilder.append(Integer.toHexString(sidBytes[i] & 0xFF));
418 }
419
420 sidString.append(Long.parseLong(tmpBuilder.toString(), 16));
421
422
423 int subAuthorityCount = sidBytes[1];
424
425
426 for (int i = 0; i < subAuthorityCount; ++i)
427 {
428 int offset = i * 4;
429 tmpBuilder.setLength(0);
430
431 tmpBuilder.append(String.format("%02X%02X%02X%02X",
432 (sidBytes[11 + offset] & 0xFF),
433 (sidBytes[10 + offset] & 0xFF),
434 (sidBytes[9 + offset] & 0xFF),
435 (sidBytes[8 + offset] & 0xFF)));
436 sidString.append('-').append(Long.parseLong(tmpBuilder.toString(), 16));
437 }
438
439 return sidString.toString();
440 }
441
442
443
444
445
446
447
448
449 public static byte[] sidStringToBytes( String sidString )
450 {
451 String[] sidTokens = sidString.split("-");
452
453 int subAuthorityCount = sidTokens.length - 3;
454
455 int byteCount = 0;
456 byte[] sidBytes = new byte[1 + 1 + 6 + (4 * subAuthorityCount)];
457
458
459 sidBytes[byteCount++] = (byte)Integer.parseInt(sidTokens[1]);
460
461
462 sidBytes[byteCount++] = (byte)subAuthorityCount;
463
464
465 String hexStr = Long.toHexString(Long.parseLong(sidTokens[2]));
466
467 while( hexStr.length() < 12)
468 {
469 hexStr = "0" + hexStr;
470 }
471
472
473 for ( int i = 0 ; i < hexStr.length(); i = i + 2)
474 {
475 sidBytes[byteCount++] = (byte)Integer.parseInt(hexStr.substring(i, i + 2),16);
476 }
477
478
479 for ( int i = 3; i < sidTokens.length ; ++i)
480 {
481 hexStr = Long.toHexString(Long.parseLong(sidTokens[i]));
482
483 while( hexStr.length() < 8)
484 {
485 hexStr = "0" + hexStr;
486 }
487
488
489 for ( int j = hexStr.length(); j > 0; j = j - 2)
490 {
491 sidBytes[byteCount++] = (byte)Integer.parseInt(hexStr.substring(j-2, j),16);
492 }
493 }
494
495 return sidBytes;
496 }
497 }