1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.asn1new.util;
18
19 import java.io.UnsupportedEncodingException;
20
21 /***
22 * Little helper class. Nothing that should stay here, but I need those
23 * to debug.
24 *
25 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
26 */
27 public class StringUtils
28 {
29
30
31 /*** Hex chars */
32 private static final byte[] HEX_CHAR =
33 new byte[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
34
35 private static int UTF8_MULTI_BYTES_MASK = 0x0080;
36
37 private static int UTF8_TWO_BYTES_MASK = 0x00E0;
38 private static int UTF8_TWO_BYTES = 0x00C0;
39
40 private static int UTF8_THREE_BYTES_MASK = 0x00F0;
41 private static int UTF8_THREE_BYTES = 0x00E0;
42
43 private static int UTF8_FOUR_BYTES_MASK = 0x00F8;
44 private static int UTF8_FOUR_BYTES = 0x00F0;
45
46 private static int UTF8_FIVE_BYTES_MASK = 0x00FC;
47 private static int UTF8_FIVE_BYTES = 0x00F8;
48
49 private static int UTF8_SIX_BYTES_MASK = 0x00FE;
50 private static int UTF8_SIX_BYTES = 0x00FC;
51
52 /*** <alpha> ::= [0x41-0x5A] | [0x61-0x7A] */
53 public static final boolean[] ALPHA =
54 {
55 false, false, false, false, false, false, false, false, false, false, false, false, false,
56 false, false, false, false, false, false, false, false, false, false, false, false, false,
57 false, false, false, false, false, false, false, false, false, false, false, false, false,
58 false, false, false, false, false, false, false, false, false, false, false, false, false,
59 false, false, false, false, false, false, false, false, false, false, false, false, false,
60 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
61 true, true, true, true, true, true, true, true, true, true, true, false, false, false,
62 false, false, false, true, true, true, true, true, true, true, true, true, true, true,
63 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
64 false, false, false, false, false
65 };
66
67 /*** <alpha> | <digit> | '-' */
68 public static final boolean[] CHAR =
69 {
70 false, false, false, false, false, false, false, false, false, false, false, false, false,
71 false, false, false, false, false, false, false, false, false, false, false, false, false,
72 false, false, false, false, false, false, false, false, false, false, false, false, false,
73 false, false, false, false, false, false, true, false, false, true, true, true, true, true,
74 true, true, true, true, true, false, false, false, false, false, false, false, true, true,
75 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
76 true, true, true, true, true, true, true, true, true, false, false, false, false, false,
77 false, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
78 true, true, true, true, true, true, true, true, true, true, true, true, false, false,
79 false, false, false
80 };
81
82 /*** '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' */
83 public static final boolean[] DIGIT =
84 {
85 false, false, false, false, false, false, false, false, false, false, false, false, false,
86 false, false, false, false, false, false, false, false, false, false, false, false, false,
87 false, false, false, false, false, false, false, false, false, false, false, false, false,
88 false, false, false, false, false, false, false, false, false, true, true, true, true,
89 true, true, true, true, true, true, false, false, false, false, false, false, false, false,
90 false, false, false, false, false, false, false, false, false, false, false, false, false,
91 false, false, false, false, false, false, false, false, false, false, false, false, false,
92 false, false, false, false, false, false, false, false, false, false, false, false, false,
93 false, false, false, false, false, false, false, false, false, false, false, false, false,
94 false, false, false, false, false, false, false, false, false, false,
95 };
96
97 /*** <hex> ::= [0x30-0x39] | [0x41-0x46] | [0x61-0x66] */
98 private static final boolean[] HEX =
99 {
100 false, false, false, false, false, false, false, false, false, false, false, false, false,
101 false, false, false, false, false, false, false, false, false, false, false, false, false,
102 false, false, false, false, false, false, false, false, false, false, false, false, false,
103 false, false, false, false, false, false, false, false, false, true, true, true, true,
104 true, true, true, true, true, true, false, false, false, false, false, false, false, true,
105 true, true, true, true, true, false, false, false, false, false, false, false, false,
106 false, false, false, false, false, false, false, false, false, false, false, false, false,
107 false, false, false, false, false, true, true, true, true, true, true, false, false, false,
108 false, false, false, false, false, false, false, false, false, false, false, false, false,
109 false, false, false, false, false, false, false, false, false
110 };
111
112 private static int CHAR_ONE_BYTE_MASK = 0xFFFFFF80;
113
114 private static int CHAR_TWO_BYTES_MASK = 0xFFFFF800;
115
116 private static int CHAR_THREE_BYTES_MASK = 0xFFFF0000;
117
118 private static int CHAR_FOUR_BYTES_MASK = 0xFFE00000;
119
120 private static int CHAR_FIVE_BYTES_MASK = 0xFC000000;
121
122 private static int CHAR_SIX_BYTES_MASK = 0x80000000;
123
124 public static final int NOT_EQUAL = -1;
125
126
127
128 /***
129 * Helper function that dump a byte in hex form
130 *
131 * @param octet The byte to dump
132 * @return A string representation of the byte
133 */
134 public static String dumpByte( byte octet )
135 {
136 return new String(
137 new byte[] { '0', 'x', HEX_CHAR[( octet & 0x00F0 ) >> 4], HEX_CHAR[octet & 0x000F] } );
138 }
139
140 /***
141 * Helper function that dump an array of bytes in hex form
142 *
143 * @param octet The bytes array to dump
144 * @return A string representation of the array of bytes
145 */
146 public static String dumpBytes( byte[] buffer )
147 {
148 StringBuffer sb = new StringBuffer();
149
150 for (int i = 0; i < buffer.length ; i++)
151 {
152 sb.append("0x").append((char)(HEX_CHAR[( buffer[i] & 0x00F0 ) >> 4])).append((char)(HEX_CHAR[buffer[i] & 0x000F])).append(" ");
153 }
154
155 return sb.toString();
156 }
157
158 /***
159 * Return the Unicode char which is coded in the bytes at position 0.
160 *
161 * @param bytes The byte[] represntation of an Unicode string.
162 * @return The first char found.
163 */
164 public static char bytesToChar(byte[] bytes)
165 {
166 return bytesToChar(bytes, 0);
167 }
168
169 /***
170 * Count the number of bytes needed to return an Unicode char. This
171 * can be from 1 to 6.
172 * @param bytes The bytes to read
173 * @param pos Position to start counting. It must be a valid start of a
174 * encoded char !
175 * @return The number of bytes to create a char, or -1 if the encoding is wrong.
176 *
177 * TODO : Should stop after the third byte, as a char is only 2 bytes long.
178 */
179 public static int countBytesPerChar(byte[] bytes, int pos)
180 {
181 if ((bytes[pos] & UTF8_MULTI_BYTES_MASK) == 0)
182 {
183 return 1;
184 } else if ((bytes[pos] & UTF8_TWO_BYTES_MASK) == UTF8_TWO_BYTES)
185 {
186 return 2;
187 }
188 else if ((bytes[pos] & UTF8_THREE_BYTES_MASK) == UTF8_THREE_BYTES)
189 {
190 return 3;
191 }
192 else if ((bytes[pos] & UTF8_FOUR_BYTES_MASK) == UTF8_FOUR_BYTES)
193 {
194 return 4;
195 }
196 else if ((bytes[pos] & UTF8_FIVE_BYTES_MASK) == UTF8_FIVE_BYTES)
197 {
198 return 5;
199 }
200 else if ((bytes[pos] & UTF8_SIX_BYTES_MASK) == UTF8_SIX_BYTES)
201 {
202 return 6;
203 }
204 else
205 {
206 return -1;
207 }
208 }
209
210 /***
211 * Return the number of bytes that hold an Unicode char.
212 *
213 * @param car The character to be decoded
214 * @return The number of bytes to hold the char.
215 *
216 * TODO : Should stop after the third byte, as a char is only 2 bytes long.
217 */
218 public static int countNbBytesPerChar( char car )
219 {
220 if ( ( car & CHAR_ONE_BYTE_MASK ) == 0 )
221 {
222 return 1;
223 }
224 else if ( ( car & CHAR_TWO_BYTES_MASK ) == 0 )
225 {
226 return 2;
227 }
228 else if ( ( car & CHAR_THREE_BYTES_MASK ) == 0 )
229 {
230 return 3;
231 }
232 else if ( ( car & CHAR_FOUR_BYTES_MASK ) == 0 )
233 {
234 return 4;
235 }
236 else if ( ( car & CHAR_FIVE_BYTES_MASK ) == 0 )
237 {
238 return 5;
239 }
240 else if ( ( car & CHAR_SIX_BYTES_MASK ) == 0 )
241 {
242 return 6;
243 }
244 else
245 {
246 return -1;
247 }
248 }
249
250 /***
251 * Count the number of bytes included in the given char[].
252 * @param chars The char array to decode
253 * @return The number of bytes in the char array
254 */
255 public static int countBytes(char[] chars) throws UnsupportedEncodingException
256 {
257 int nbBytes = 0;
258 int currentPos = 0;
259
260 while ( currentPos < chars.length )
261 {
262 int nbb = countNbBytesPerChar( chars[currentPos] );
263
264
265
266 currentPos += (nbb < 4 ? 1 : 2 );
267 nbBytes += nbb;
268 }
269
270 return nbBytes;
271 }
272
273 /***
274 * Return the Unicode char which is coded in the bytes at the given position.
275 * @param bytes The byte[] represntation of an Unicode string.
276 * @param pos The current position to start decoding the char
277 * @return The char found.
278 * @return The decoded char, or -1 if no char can be decoded
279 *
280 * TODO : Should stop after the third byte, as a char is only 2 bytes long.
281 */
282 public static char bytesToChar(byte[] bytes, int pos)
283 {
284 if ((bytes[pos] & UTF8_MULTI_BYTES_MASK) == 0)
285 {
286 return (char)bytes[pos];
287 }
288 else
289 {
290 if ((bytes[pos] & UTF8_TWO_BYTES_MASK) == UTF8_TWO_BYTES)
291 {
292
293 return (char)(
294 ( ( bytes[pos] & 0x1C ) << 6 ) +
295 ( ( bytes[pos] & 0x03 ) << 6 ) +
296 ( bytes[pos + 1] & 0x3F )
297 );
298 }
299 else if ((bytes[pos] & UTF8_THREE_BYTES_MASK) == UTF8_THREE_BYTES)
300 {
301
302 return (char)(
303
304 ( ( bytes[pos] & 0x0F) << 12 ) +
305
306 ( ( bytes[pos + 1] & 0x3C) << 6 ) +
307
308 ( ( bytes[pos + 1] & 0x03) << 6 ) +
309
310 ( bytes[pos + 2] & 0x3F )
311
312 );
313 }
314 else if ((bytes[pos] & UTF8_FOUR_BYTES_MASK) == UTF8_FOUR_BYTES)
315 {
316
317 return (char)(
318
319 ( ( bytes[pos] & 0x07) << 18 ) +
320
321 ( ( bytes[pos + 1] & 0x30) << 16 ) +
322
323 ( ( bytes[pos + 1] & 0x0F) << 12 ) +
324
325 ( ( bytes[pos + 2] & 0x3C) << 6 ) +
326
327 ( ( bytes[pos + 2] & 0x03) << 6 ) +
328
329 ( bytes[pos + 3] & 0x3F )
330
331 );
332 }
333 else if ((bytes[pos] & UTF8_FIVE_BYTES_MASK) == UTF8_FIVE_BYTES)
334 {
335
336 return (char)(
337
338 ( ( bytes[pos] & 0x03) << 24 ) +
339
340 ( ( bytes[pos + 1] & 0x3F) << 18 ) +
341
342 ( ( bytes[pos + 2] & 0x30) << 12 ) +
343
344 ( ( bytes[pos + 2] & 0x0F) << 12 ) +
345
346 ( ( bytes[pos + 3] & 0x3C) << 6 ) +
347
348 ( ( bytes[pos + 3] & 0x03) << 6 ) +
349
350 ( bytes[pos + 4] & 0x3F )
351
352 );
353 }
354 else if ((bytes[pos] & UTF8_FIVE_BYTES_MASK) == UTF8_FIVE_BYTES)
355 {
356
357 return (char)(
358
359
360 ( ( bytes[pos] & 0x01) << 30 ) +
361
362
363 ( ( bytes[pos + 1] & 0x3F) << 24 ) +
364
365
366 ( ( bytes[pos + 2] & 0x3F) << 18 ) +
367
368
369 ( ( bytes[pos + 3] & 0x30) << 12 ) +
370
371
372 ( ( bytes[pos + 3] & 0x0F) << 12 ) +
373
374
375 ( ( bytes[pos + 4] & 0x3C) << 6 ) +
376
377
378 ( ( bytes[pos + 4] & 0x03) << 6 ) +
379
380
381 ( bytes[pos + 5] & 0x3F )
382
383 );
384 }
385 else
386 {
387 return (char)-1;
388 }
389 }
390 }
391
392 /***
393 * Count the number of chars included in the given byte[].
394 * @param bytes The byte array to decode
395 * @return The number of char in the byte array
396 */
397 public static int countChars(byte[] bytes)
398 {
399 int nbChars = 0;
400 int currentPos = 0;
401
402 while (currentPos < bytes.length)
403 {
404 currentPos += countBytesPerChar(bytes, currentPos);
405 nbChars ++;
406 }
407
408 return nbChars;
409 }
410
411 /***
412 * Check if a text is present at the current position in a buffer.
413 *
414 * @param byteArray The buffer which contains the data
415 * @param index Current position in the buffer
416 * @param text The text we want to check
417 *
418 * @return <code>true</code> if the buffer contains the text.
419 */
420 public static int areEquals( byte[] byteArray, int index, String text )
421 {
422 if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( byteArray.length <= index ) ||
423 ( index < 0 ) || ( text == null ) )
424 {
425 return NOT_EQUAL;
426 }
427 else
428 {
429 try
430 {
431 byte[] data = text.getBytes( "UTF-8" );
432
433 return areEquals( byteArray, index, data );
434 }
435 catch ( UnsupportedEncodingException uee )
436 {
437 return NOT_EQUAL;
438 }
439 }
440 }
441
442 /***
443 * Check if a text is present at the current position in a buffer.
444 *
445 * @param byteArray The buffer which contains the data
446 * @param index Current position in the buffer
447 * @param text The text we want to check
448 *
449 * @return <code>true</code> if the buffer contains the text.
450 */
451 public static int areEquals( char[] charArray, int index, String text )
452 {
453 if ( ( charArray == null ) || ( charArray.length == 0 ) || ( charArray.length <= index ) ||
454 ( index < 0 ) || ( text == null ) )
455 {
456 return NOT_EQUAL;
457 }
458 else
459 {
460 char[] data = text.toCharArray();
461
462 return areEquals( charArray, index, data );
463 }
464 }
465
466 /***
467 * Check if a text is present at the current position in a buffer.
468 *
469 * @param charArray The buffer which contains the data
470 * @param index Current position in the buffer
471 * @param charArray2 The text we want to check
472 *
473 * @return <code>true</code> if the buffer contains the text.
474 */
475 public static int areEquals( char[] charArray, int index, char[] charArray2 )
476 {
477
478 if ( ( charArray == null ) ||
479 ( charArray.length == 0 ) ||
480 ( charArray.length <= index ) ||
481 ( index < 0 ) ||
482 ( charArray2 == null ) ||
483 ( charArray2.length == 0 ) ||
484 ( charArray2.length > ( charArray.length + index ) ) )
485 {
486 return NOT_EQUAL;
487 }
488 else
489 {
490 for ( int i = 0; i < charArray2.length; i++ )
491 {
492 if ( charArray[index++] != charArray2[i] )
493 {
494 return NOT_EQUAL;
495 }
496 }
497
498 return index;
499 }
500 }
501
502 /***
503 * Check if a text is present at the current position in a buffer.
504 *
505 * @param byteArray The buffer which contains the data
506 * @param index Current position in the buffer
507 * @param byteArray2 The text we want to check
508 *
509 * @return <code>true</code> if the buffer contains the text.
510 */
511 public static int areEquals( byte[] byteArray, int index, byte[] byteArray2 )
512 {
513
514 if ( ( byteArray == null ) ||
515 ( byteArray.length == 0 ) ||
516 ( byteArray.length <= index ) ||
517 ( index < 0 ) ||
518 ( byteArray2 == null ) ||
519 ( byteArray2.length == 0 ) ||
520 ( byteArray2.length > ( byteArray.length + index ) ) )
521 {
522 return NOT_EQUAL;
523 }
524 else
525 {
526 for ( int i = 0; i < byteArray2.length; i++ )
527 {
528 if ( byteArray[index++] != byteArray2[i] )
529 {
530 return NOT_EQUAL;
531 }
532 }
533
534 return index;
535 }
536 }
537
538 /***
539 * Test if the current character is equal to a specific character.
540 * This function works only for character between 0 and 127, as it
541 * does compare a byte and a char (which is 16 bits wide)
542 *
543 *
544 * @param byteArray The buffer which contains the data
545 * @param index Current position in the buffer
546 * @param car The character we want to compare with the current buffer position
547 *
548 * @return <code>true</code> if the current character equals the given character.
549 */
550 public static boolean isCharASCII( byte[] byteArray, int index, char car )
551 {
552 if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( index < 0 ) ||
553 ( index >= byteArray.length ) )
554 {
555 return false;
556 }
557 else
558 {
559 return ( ( byteArray[index] == car ) ? true : false );
560 }
561 }
562
563 /***
564 * Test if the current character is equal to a specific character.
565 *
566 *
567 * @param byteArray The buffer which contains the data
568 * @param index Current position in the buffer
569 * @param car The character we want to compare with the current buffer position
570 *
571 * @return <code>true</code> if the current character equals the given character.
572 */
573 public static boolean isCharASCII( char[] chars, int index, char car )
574 {
575 if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) ||
576 ( index >= chars.length ) )
577 {
578 return false;
579 }
580 else
581 {
582 return ( ( chars[index] == car ) ? true : false );
583 }
584 }
585
586 /***
587 * Check if the current character is an Hex Char
588 * <hex> ::= [0x30-0x39] | [0x41-0x46] | [0x61-0x66]
589 *
590 * @param byteArray The buffer which contains the data
591 * @param index Current position in the buffer
592 *
593 * @return <code>true</code> if the current character is a Hex Char
594 */
595 public static boolean isHex( byte[] byteArray, int index )
596 {
597 if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( index < 0 ) ||
598 ( index >= byteArray.length ) )
599 {
600 return false;
601 }
602 else
603 {
604 byte c = byteArray[index];
605
606 if ( ( c > 127 ) || ( StringUtils.HEX[c] == false ) )
607 {
608 return false;
609 }
610 else
611 {
612 return true;
613 }
614 }
615 }
616
617 /***
618 * Check if the current character is an Hex Char
619 * <hex> ::= [0x30-0x39] | [0x41-0x46] | [0x61-0x66]
620 *
621 * @param chars The buffer which contains the data
622 * @param index Current position in the buffer
623 *
624 * @return <code>true</code> if the current character is a Hex Char
625 */
626 public static boolean isHex( char[] chars, int index )
627 {
628 if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) ||
629 ( index >= chars.length ) )
630 {
631 return false;
632 }
633 else
634 {
635 char c = chars[index];
636
637 if ( ( c > 127 ) || ( StringUtils.HEX[c] == false ) )
638 {
639 return false;
640 }
641 else
642 {
643 return true;
644 }
645 }
646 }
647
648 /***
649 * Test if the current character is a digit
650 * <digit> ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
651 *
652 * @param byteArray The buffer which contains the data
653 *
654 * @return <code>true</code> if the current character is a Digit
655 */
656 public static boolean isDigit( byte[] byteArray )
657 {
658 if ( ( byteArray == null ) || ( byteArray.length == 0 ) )
659 {
660 return false;
661 }
662 else
663 {
664 return ( ( ( byteArray[0] > 127 ) || ! StringUtils.DIGIT[byteArray[0]] ) ? false : true );
665 }
666 }
667
668 /***
669 * Test if the current character is an Alpha character :
670 * <alpha> ::= [0x41-0x5A] | [0x61-0x7A]
671 *
672 * @param byteArray The buffer which contains the data
673 * @param index Current position in the buffer
674 *
675 * @return <code>true</code> if the current character is an Alpha character
676 */
677 public static boolean isAlphaASCII( byte[] byteArray, int index )
678 {
679 if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( index < 0 ) ||
680 ( index >= byteArray.length ) )
681 {
682 return false;
683 }
684 else
685 {
686 byte c = byteArray[index++];
687
688 if ( ( c > 127 ) || ( StringUtils.ALPHA[c] == false ) )
689 {
690 return false;
691 }
692 else
693 {
694 return true;
695 }
696 }
697 }
698
699 /***
700 * Test if the current character is an Alpha character :
701 * <alpha> ::= [0x41-0x5A] | [0x61-0x7A]
702 *
703 * @param chars The buffer which contains the data
704 * @param index Current position in the buffer
705 *
706 * @return <code>true</code> if the current character is an Alpha character
707 */
708 public static boolean isAlphaASCII( char[] chars, int index )
709 {
710 if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) ||
711 ( index >= chars.length ) )
712 {
713 return false;
714 }
715 else
716 {
717 char c = chars[index++];
718
719 if ( ( c > 127 ) || ( StringUtils.ALPHA[c] == false ) )
720 {
721 return false;
722 }
723 else
724 {
725 return true;
726 }
727 }
728 }
729
730 /***
731 * Test if the current character is a digit
732 * <digit> ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
733 *
734 * @param byteArray The buffer which contains the data
735 * @param index Current position in the buffer
736 *
737 * @return <code>true</code> if the current character is a Digit
738 */
739 public static boolean isDigit( byte[] byteArray, int index )
740 {
741 if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( index < 0 ) ||
742 ( index >= byteArray.length ) )
743 {
744 return false;
745 }
746 else
747 {
748 return ( ( ( byteArray[index] > 127 ) || ! StringUtils.DIGIT[byteArray[index]] ) ? false : true );
749 }
750 }
751
752 /***
753 * Test if the current character is a digit
754 * <digit> ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
755 *
756 * @param byteArray The buffer which contains the data
757 * @param index Current position in the buffer
758 *
759 * @return <code>true</code> if the current character is a Digit
760 */
761 public static boolean isDigit( char[] chars, int index )
762 {
763 if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) ||
764 ( index >= chars.length ) )
765 {
766 return false;
767 }
768 else
769 {
770 return ( ( ( chars[index] > 127 ) || ! StringUtils.DIGIT[chars[index]] ) ? false : true );
771 }
772 }
773
774 /***
775 * Test if the current character is a digit
776 * <digit> ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
777 *
778 * @param byteArray The buffer which contains the data
779 *
780 * @return <code>true</code> if the current character is a Digit
781 */
782 public static boolean isDigit( char[] chars )
783 {
784 if ( ( chars == null ) || ( chars.length == 0 ) )
785 {
786 return false;
787 }
788 else
789 {
790 return ( ( ( chars[0] > 127 ) || ! StringUtils.DIGIT[chars[0]] ) ? false : true );
791 }
792 }
793
794 /***
795 * Check if the current character is an 7 bits ASCII CHAR (between 0 and 127).
796 * <char> ::= <alpha> | <digit> | '-'
797 *
798 * @param byteArray The buffer which contains the data
799 * @param index Current position in the buffer
800 *
801 * @return The position of the next character, if the current one is a CHAR.
802 */
803 public static boolean isAlphaDigitMinus( byte[] byteArray, int index )
804 {
805 if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( index < 0 ) ||
806 ( index >= byteArray.length ) )
807 {
808 return false;
809 }
810 else
811 {
812 byte c = byteArray[index++];
813
814 if ( ( c > 127 ) || ( StringUtils.CHAR[c] == false ) )
815 {
816 return false;
817 }
818 else
819 {
820 return true;
821 }
822 }
823 }
824
825 /***
826 * Check if the current character is an 7 bits ASCII CHAR (between 0 and 127).
827 * <char> ::= <alpha> | <digit> | '-'
828 *
829 * @param chars The buffer which contains the data
830 * @param index Current position in the buffer
831 *
832 * @return The position of the next character, if the current one is a CHAR.
833 */
834 public static boolean isAlphaDigitMinus( char[] chars, int index )
835 {
836 if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) ||
837 ( index >= chars.length ) )
838 {
839 return false;
840 }
841 else
842 {
843 char c = chars[index++];
844
845 if ( ( c > 127 ) || ( StringUtils.CHAR[c] == false ) )
846 {
847 return false;
848 }
849 else
850 {
851 return true;
852 }
853 }
854 }
855
856
857
858 /***
859 * The empty String <code>""</code>.
860 * @since 2.0
861 */
862 public static final String EMPTY = "";
863
864
865
866 /***
867 * <p>Checks if a String is empty ("") or null.</p>
868 *
869 * <pre>
870 * StringUtils.isEmpty(null) = true
871 * StringUtils.isEmpty("") = true
872 * StringUtils.isEmpty(" ") = false
873 * StringUtils.isEmpty("bob") = false
874 * StringUtils.isEmpty(" bob ") = false
875 * </pre>
876 *
877 * <p>NOTE: This method changed in Lang version 2.0.
878 * It no longer trims the String.
879 * That functionality is available in isBlank().</p>
880 *
881 * @param str the String to check, may be null
882 * @return <code>true</code> if the String is empty or null
883 */
884 public static boolean isEmpty(String str) {
885 return str == null || str.length() == 0;
886 }
887
888 /***
889 * <p>Checks if a String is not empty ("") and not null.</p>
890 *
891 * <pre>
892 * StringUtils.isNotEmpty(null) = false
893 * StringUtils.isNotEmpty("") = false
894 * StringUtils.isNotEmpty(" ") = true
895 * StringUtils.isNotEmpty("bob") = true
896 * StringUtils.isNotEmpty(" bob ") = true
897 * </pre>
898 *
899 * @param str the String to check, may be null
900 * @return <code>true</code> if the String is not empty and not null
901 */
902 public static boolean isNotEmpty(String str) {
903 return str != null && str.length() > 0;
904 }
905
906 /***
907 * <p>Removes spaces (char <= 32) from both start and
908 * ends of this String, handling <code>null</code> by returning
909 * <code>null</code>.</p>
910 *
911 * Trim removes start and end characters <= 32.
912 *
913 * <pre>
914 * StringUtils.trim(null) = null
915 * StringUtils.trim("") = ""
916 * StringUtils.trim(" ") = ""
917 * StringUtils.trim("abc") = "abc"
918 * StringUtils.trim(" abc ") = "abc"
919 * </pre>
920 *
921 * @param str the String to be trimmed, may be null
922 * @return the trimmed string, <code>null</code> if null String input
923 */
924 public static String trim(String str) {
925 if ( isEmpty( str ) )
926 {
927 return str;
928 }
929
930 char[] array = str.toCharArray();
931 int start = 0;
932 int end = array.length;
933
934 while ( ( start < end ) && ( array[start] == ' ' ) )
935 {
936 start++;
937 }
938
939 while ( ( end > start ) && ( array[end - 1] == ' ' ) )
940 {
941 end--;
942 }
943
944 return new String( array, start, ( end - start ) );
945 }
946
947 /***
948 * <p>Removes spaces (char <= 32) from start
949 * of this String, handling <code>null</code> by returning
950 * <code>null</code>.</p>
951 *
952 * Trim removes start characters <= 32.
953 *
954 * <pre>
955 * StringUtils.trimLeft(null) = null
956 * StringUtils.trimLeft("") = ""
957 * StringUtils.trimLeft(" ") = ""
958 * StringUtils.trimLeft("abc") = "abc"
959 * StringUtils.trimLeft(" abc ") = "abc "
960 * </pre>
961 *
962 * @param str the String to be trimmed, may be null
963 * @return the trimmed string, <code>null</code> if null String input
964 */
965 public static String trimLeft( String str ) {
966 if ( isEmpty( str ) )
967 {
968 return str;
969 }
970
971 char[] array = str.toCharArray();
972 int start = 0;
973
974 while ( ( start < array.length ) && ( array[start] == ' ' ) )
975 {
976 start++;
977 }
978
979 return new String( array, start, array.length - start );
980 }
981 /***
982 * <p>Removes spaces (char <= 32) from start
983 * of this array, handling <code>null</code> by returning
984 * <code>null</code>.</p>
985 *
986 * Trim removes start characters <= 32.
987 *
988 * <pre>
989 * StringUtils.trimLeft(null) = null
990 * StringUtils.trimLeft("") = ""
991 * StringUtils.trimLeft(" ") = ""
992 * StringUtils.trimLeft("abc") = "abc"
993 * StringUtils.trimLeft(" abc ") = "abc "
994 * </pre>
995 *
996 * @param chars the chars array to be trimmed, may be null
997 * @return the position of the first char which is not a space,
998 * or the last position of the array.
999 */
1000 public static int trimLeft( char[] chars, int pos ) {
1001 if ( chars == null )
1002 {
1003 return pos;
1004 }
1005
1006 while ( ( pos < chars.length ) && ( chars[pos] == ' ' ) )
1007 {
1008 pos++;
1009 }
1010
1011 return pos;
1012 }
1013
1014 /***
1015 * <p>Removes spaces (char <= 32) from start
1016 * of this array, handling <code>null</code> by returning
1017 * <code>null</code>.</p>
1018 *
1019 * Trim removes start characters <= 32.
1020 *
1021 * <pre>
1022 * StringUtils.trimLeft(null) = null
1023 * StringUtils.trimLeft("") = ""
1024 * StringUtils.trimLeft(" ") = ""
1025 * StringUtils.trimLeft("abc") = "abc"
1026 * StringUtils.trimLeft(" abc ") = "abc "
1027 * </pre>
1028 *
1029 * @param bytes the byte array to be trimmed, may be null
1030 * @return the position of the first byte which is not a space,
1031 * or the last position of the array.
1032 */
1033 public static int trimLeft( byte[] bytes, int pos ) {
1034 if ( bytes == null )
1035 {
1036 return pos;
1037 }
1038
1039 while ( ( pos < bytes.length ) && ( bytes[pos] == ' ' ) )
1040 {
1041 pos++;
1042 }
1043
1044 return pos;
1045 }
1046
1047
1048 /***
1049 * <p>Removes spaces (char <= 32) from end
1050 * of this String, handling <code>null</code> by returning
1051 * <code>null</code>.</p>
1052 *
1053 * Trim removes start characters <= 32.
1054 *
1055 * <pre>
1056 * StringUtils.trimRight(null) = null
1057 * StringUtils.trimRight("") = ""
1058 * StringUtils.trimRight(" ") = ""
1059 * StringUtils.trimRight("abc") = "abc"
1060 * StringUtils.trimRight(" abc ") = " abc"
1061 * </pre>
1062 *
1063 * @param str the String to be trimmed, may be null
1064 * @return the trimmed string, <code>null</code> if null String input
1065 */
1066 public static String trimRight( String str ) {
1067 if ( isEmpty( str ) )
1068 {
1069 return str;
1070 }
1071
1072 char[] array = str.toCharArray();
1073 int start = 0;
1074 int end = array.length;
1075
1076 while ( ( start < end ) && ( array[start] == ' ' ) )
1077 {
1078 start++;
1079 }
1080
1081 return new String( array, start, ( end - start ) );
1082 }
1083
1084 /***
1085 * <p>Removes spaces (char <= 32) from end
1086 * of this array, handling <code>null</code> by returning
1087 * <code>null</code>.</p>
1088 *
1089 * Trim removes start characters <= 32.
1090 *
1091 * <pre>
1092 * StringUtils.trimRight(null) = null
1093 * StringUtils.trimRight("") = ""
1094 * StringUtils.trimRight(" ") = ""
1095 * StringUtils.trimRight("abc") = "abc"
1096 * StringUtils.trimRight(" abc ") = " abc"
1097 * </pre>
1098 *
1099 * @param chars the chars array to be trimmed, may be null
1100 * @return the position of the first char which is not a space,
1101 * or the last position of the array.
1102 */
1103 public static int trimRight( char[] chars, int pos ) {
1104 if ( chars == null )
1105 {
1106 return pos;
1107 }
1108
1109 while ( ( pos > 0 ) && ( chars[pos - 1] == ' ' ) )
1110 {
1111 pos--;
1112 }
1113
1114 return pos;
1115 }
1116
1117 /***
1118 * <p>Removes spaces (char <= 32) from end
1119 * of this array, handling <code>null</code> by returning
1120 * <code>null</code>.</p>
1121 *
1122 * Trim removes start characters <= 32.
1123 *
1124 * <pre>
1125 * StringUtils.trimRight(null) = null
1126 * StringUtils.trimRight("") = ""
1127 * StringUtils.trimRight(" ") = ""
1128 * StringUtils.trimRight("abc") = "abc"
1129 * StringUtils.trimRight(" abc ") = " abc"
1130 * </pre>
1131 *
1132 * @param chars the chars array to be trimmed, may be null
1133 * @return the position of the first char which is not a space,
1134 * or the last position of the array.
1135 */
1136 public static int trimRight( byte[] bytes, int pos ) {
1137 if ( bytes == null )
1138 {
1139 return pos;
1140 }
1141
1142 while ( ( pos >= 0 ) && ( bytes[pos] == ' ' ) )
1143 {
1144 pos--;
1145 }
1146
1147 return pos;
1148 }
1149
1150
1151
1152 /***
1153 * <p>Converts a String to upper case as per {@link String#toUpperCase()}.</p>
1154 *
1155 * <p>A <code>null</code> input String returns <code>null</code>.</p>
1156 *
1157 * <pre>
1158 * StringUtils.upperCase(null) = null
1159 * StringUtils.upperCase("") = ""
1160 * StringUtils.upperCase("aBc") = "ABC"
1161 * </pre>
1162 *
1163 * @param str the String to upper case, may be null
1164 * @return the upper cased String, <code>null</code> if null String input
1165 */
1166 public static String upperCase(String str) {
1167 if (str == null) {
1168 return null;
1169 }
1170 return str.toUpperCase();
1171 }
1172
1173 /***
1174 * <p>Converts a String to lower case as per {@link String#toLowerCase()}.</p>
1175 *
1176 * <p>A <code>null</code> input String returns <code>null</code>.</p>
1177 *
1178 * <pre>
1179 * StringUtils.lowerCase(null) = null
1180 * StringUtils.lowerCase("") = ""
1181 * StringUtils.lowerCase("aBc") = "abc"
1182 * </pre>
1183 *
1184 * @param str the String to lower case, may be null
1185 * @return the lower cased String, <code>null</code> if null String input
1186 */
1187 public static String lowerCase(String str) {
1188 if (str == null) {
1189 return null;
1190 }
1191 return str.toLowerCase();
1192 }
1193
1194
1195
1196 /***
1197 * <p>Compares two Strings, returning <code>true</code> if they are equal.</p>
1198 *
1199 * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
1200 * references are considered to be equal. The comparison is case sensitive.</p>
1201 *
1202 * <pre>
1203 * StringUtils.equals(null, null) = true
1204 * StringUtils.equals(null, "abc") = false
1205 * StringUtils.equals("abc", null) = false
1206 * StringUtils.equals("abc", "abc") = true
1207 * StringUtils.equals("abc", "ABC") = false
1208 * </pre>
1209 *
1210 * @see java.lang.String#equals(Object)
1211 * @param str1 the first String, may be null
1212 * @param str2 the second String, may be null
1213 * @return <code>true</code> if the Strings are equal, case sensitive, or
1214 * both <code>null</code>
1215 */
1216 public static boolean equals(String str1, String str2) {
1217 return str1 == null ? str2 == null : str1.equals(str2);
1218 }
1219
1220 /***
1221 * Return an UTF-8 encoded String
1222 * @param bytes The byte array to be transformed to a String
1223 * @return A String.
1224 */
1225 public static String toUtf8( byte[] bytes )
1226 {
1227 try
1228 {
1229 return new String( bytes, "UTF-8" );
1230 }
1231 catch ( UnsupportedEncodingException uee )
1232 {
1233 return "";
1234 }
1235 }
1236
1237 /***
1238 * Return an UTF-8 encoded String
1239 * @param bytes The byte array to be transformed to a String
1240 * @return A String.
1241 */
1242 public static byte[] getBytesUtf8( String string )
1243 {
1244 try
1245 {
1246 return string.getBytes( "UTF-8" );
1247 }
1248 catch ( UnsupportedEncodingException uee )
1249 {
1250 return new byte[]{};
1251 }
1252 }
1253 }