001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 *
019 */
020package org.apache.directory.api.util;
021
022
023/**
024 * Various Character methods are kept here.
025 *
026 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
027 */
028public final class Chars
029{
030    /** &lt;alpha> ::= [0x41-0x5A] | [0x61-0x7A] */
031    public static final boolean[] ALPHA =
032        {
033            false, false, false, false, false, false, false, false,
034            false, false, false, false, false, false, false, false,
035            false, false, false, false, false, false, false, false,
036            false, false, false, false, false, false, false, false,
037            false, false, false, false, false, false, false, false,
038            false, false, false, false, false, false, false, false,
039            false, false, false, false, false, false, false, false,
040            false, false, false, false, false, false, false, false,
041            false, true, true, true, true, true, true, true,
042            true, true, true, true, true, true, true, true,
043            true, true, true, true, true, true, true, true,
044            true, true, true, false, false, false, false, false,
045            false, true, true, true, true, true, true, true,
046            true, true, true, true, true, true, true, true,
047            true, true, true, true, true, true, true, true,
048            true, true, true, false, false, false, false, false
049    };
050    /** &lt;alpha-lower-case> ::= [0x61-0x7A] */
051    public static final boolean[] ALPHA_LOWER_CASE =
052        {
053            false, false, false, false, false, false, false, false,
054            false, false, false, false, false, false, false, false,
055            false, false, false, false, false, false, false, false,
056            false, false, false, false, false, false, false, false,
057            false, false, false, false, false, false, false, false,
058            false, false, false, false, false, false, false, false,
059            false, false, false, false, false, false, false, false,
060            false, false, false, false, false, false, false, false,
061            false, false, false, false, false, false, false, false,
062            false, false, false, false, false, false, false, false,
063            false, false, false, false, false, false, false, false,
064            false, false, false, false, false, false, false, false,
065            false, true, true, true, true, true, true, true,
066            true, true, true, true, true, true, true, true,
067            true, true, true, true, true, true, true, true,
068            true, true, true, false, false, false, false, false
069    };
070    /** &lt;alpha-upper-case> ::= [0x41-0x5A] */
071    public static final boolean[] ALPHA_UPPER_CASE =
072        {
073            false, false, false, false, false, false, false, false,
074            false, false, false, false, false, false, false, false,
075            false, false, false, false, false, false, false, false,
076            false, false, false, false, false, false, false, false,
077            false, false, false, false, false, false, false, false,
078            false, false, false, false, false, false, false, false,
079            false, false, false, false, false, false, false, false,
080            false, false, false, false, false, false, false, false,
081            false, true, true, true, true, true, true, true,
082            true, true, true, true, true, true, true, true,
083            true, true, true, true, true, true, true, true,
084            true, true, true, false, false, false, false, false,
085            false, false, false, false, false, false, false, false,
086            false, false, false, false, false, false, false, false,
087            false, false, false, false, false, false, false, false,
088            false, false, false, false, false, false, false, false,
089    };
090    /** &lt;alpha-digit> | &lt;digit> */
091    public static final boolean[] ALPHA_DIGIT =
092        {
093            false, false, false, false, false, false, false, false,
094            false, false, false, false, false, false, false, false,
095            false, false, false, false, false, false, false, false,
096            false, false, false, false, false, false, false, false,
097            false, false, false, false, false, false, false, false,
098            false, false, false, false, false, false, false, false,
099            true, true, true, true, true, true, true, true,
100            true, true, false, false, false, false, false, false,
101            false, true, true, true, true, true, true, true,
102            true, true, true, true, true, true, true, true,
103            true, true, true, true, true, true, true, true,
104            true, true, true, false, false, false, false, false,
105            false, true, true, true, true, true, true, true,
106            true, true, true, true, true, true, true, true,
107            true, true, true, true, true, true, true, true,
108            true, true, true, false, false, false, false, false
109    };
110    /** &lt;alpha> | &lt;digit> | '-' */
111    public static final boolean[] CHAR =
112        {
113            false, false, false, false, false, false, false, false,
114            false, false, false, false, false, false, false, false,
115            false, false, false, false, false, false, false, false,
116            false, false, false, false, false, false, false, false,
117            false, false, false, false, false, false, false, false,
118            false, false, false, false, false, true, false, false,
119            true, true, true, true, true, true, true, true,
120            true, true, false, false, false, false, false, false,
121            false, true, true, true, true, true, true, true,
122            true, true, true, true, true, true, true, true,
123            true, true, true, true, true, true, true, true,
124            true, true, true, false, false, false, false, false,
125            false, true, true, true, true, true, true, true,
126            true, true, true, true, true, true, true, true,
127            true, true, true, true, true, true, true, true,
128            true, true, true, false, false, false, false, false
129    };
130    /** '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' */
131    public static final boolean[] DIGIT =
132        {
133            false, false, false, false, false, false, false, false,
134            false, false, false, false, false, false, false, false,
135            false, false, false, false, false, false, false, false,
136            false, false, false, false, false, false, false, false,
137            false, false, false, false, false, false, false, false,
138            false, false, false, false, false, false, false, false,
139            true, true, true, true, true, true, true, true,
140            true, true, false, false, false, false, false, false,
141            false, false, false, false, false, false, false, false,
142            false, false, false, false, false, false, false, false,
143            false, false, false, false, false, false, false, false,
144            false, false, false, false, false, false, false, false,
145            false, false, false, false, false, false, false, false,
146            false, false, false, false, false, false, false, false,
147            false, false, false, false, false, false, false, false,
148            false, false, false, false, false, false, false, false
149    };
150    /** &lt;hex> ::= [0x30-0x39] | [0x41-0x46] | [0x61-0x66] */
151    public static final boolean[] HEX =
152        {
153            false, false, false, false, false, false, false, false,
154            false, false, false, false, false, false, false, false,
155            false, false, false, false, false, false, false, false,
156            false, false, false, false, false, false, false, false,
157            false, false, false, false, false, false, false, false,
158            false, false, false, false, false, false, false, false,
159            true, true, true, true, true, true, true, true,
160            true, true, false, false, false, false, false, false,
161            false, true, true, true, true, true, true, false,
162            false, false, false, false, false, false, false, false,
163            false, false, false, false, false, false, false, false,
164            false, false, false, false, false, false, false, false,
165            false, true, true, true, true, true, true, false,
166            false, false, false, false, false, false, false, false,
167            false, false, false, false, false, false, false, false,
168            false, false, false, false, false, false, false, false };
169
170
171    /**
172    * Test if the current character is equal to a specific character.
173    *
174    * @param chars The buffer which contains the data
175    * @param index
176    *            Current position in the buffer
177    * @param car The character we want to compare with the current buffer position
178    * @return <code>true</code> if the current character equals the given character.
179    */
180    public static boolean isCharASCII( char[] chars, int index, char car )
181    {
182        if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) || ( index >= chars.length ) )
183        {
184            return false;
185        }
186        else
187        {
188            return ( ( chars[index] == car ) ? true : false );
189        }
190    }
191
192
193    /**
194     * Test if the current character is equal to a specific character.
195     *
196     * @param string The String which contains the data
197     * @param index Current position in the string
198     * @param car The character we want to compare with the current string
199     *            position
200     * @return <code>true</code> if the current character equals the given
201     *         character.
202     */
203    public static boolean isCharASCII( String string, int index, char car )
204    {
205        if ( string == null )
206        {
207            return false;
208        }
209
210        int length = string.length();
211
212        if ( ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
213        {
214            return false;
215        }
216        else
217        {
218            return string.charAt( index ) == car;
219        }
220    }
221
222
223    /**
224     * Test if the current character is equal to a specific character.
225     *
226     * @param string The String which contains the data
227     * @param index Current position in the string
228     * @param car The character we want to compare with the current string
229     *            position
230     * @return <code>true</code> if the current character equals the given
231     *         character.
232     */
233    public static boolean isICharASCII( String string, int index, char car )
234    {
235        if ( string == null )
236        {
237            return false;
238        }
239
240        int length = string.length();
241
242        if ( ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
243        {
244            return false;
245        }
246        else
247        {
248            return ( ( string.charAt( index ) | 0x20 ) & car ) == car;
249        }
250    }
251
252
253    /**
254     * Test if the current character is equal to a specific character.
255     *
256     * @param bytes The String which contains the data
257     * @param index Current position in the string
258     * @param car The character we want to compare with the current string
259     *            position
260     * @return <code>true</code> if the current character equals the given
261     *         character.
262     */
263    public static boolean isICharASCII( byte[] bytes, int index, char car )
264    {
265        if ( bytes == null )
266        {
267            return false;
268        }
269
270        int length = bytes.length;
271
272        if ( ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
273        {
274            return false;
275        }
276        else
277        {
278            return ( ( bytes[index] | 0x20 ) & car ) == car;
279        }
280    }
281
282
283    /**
284     * Test if the current byte is an Alpha character :
285     * &lt;alpha> ::= [0x41-0x5A] | [0x61-0x7A]
286     *
287     * @param c The byte to test
288     *
289     * @return <code>true</code> if the byte is an Alpha
290     *         character
291     */
292    public static boolean isAlpha( byte c )
293    {
294        return ( ( c > 0 ) && ( c <= 127 ) && ALPHA[c] );
295    }
296
297
298    /**
299     * Test if the current character is an Alpha character :
300     * &lt;alpha> ::= [0x41-0x5A] | [0x61-0x7A]
301     *
302     * @param c The char to test
303     *
304     * @return <code>true</code> if the character is an Alpha
305     *         character
306     */
307    public static boolean isAlpha( char c )
308    {
309        return ( ( c > 0 ) && ( c <= 127 ) && ALPHA[c] );
310    }
311
312
313    /**
314     * Test if the current character is an Alpha character : &lt;alpha> ::=
315     * [0x41-0x5A] | [0x61-0x7A]
316     *
317     * @param bytes The buffer which contains the data
318     * @param index Current position in the buffer
319     * @return <code>true</code> if the current character is an Alpha
320     *         character
321     */
322    public static boolean isAlphaASCII( byte[] bytes, int index )
323    {
324        if ( ( bytes == null ) || ( bytes.length == 0 ) || ( index < 0 ) || ( index >= bytes.length ) )
325        {
326            return false;
327        }
328        else
329        {
330            byte c = bytes[index];
331
332            if ( ( ( c | 0x7F ) != 0x7F ) || !ALPHA[c] )
333            {
334                return false;
335            }
336            else
337            {
338                return true;
339            }
340        }
341    }
342
343
344    /**
345     * Test if the current character is an Alpha character : &lt;alpha> ::=
346     * [0x41-0x5A] | [0x61-0x7A]
347     *
348     * @param chars The buffer which contains the data
349     * @param index Current position in the buffer
350     * @return <code>true</code> if the current character is an Alpha
351     *         character
352     */
353    public static boolean isAlphaASCII( char[] chars, int index )
354    {
355        if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) || ( index >= chars.length ) )
356        {
357            return false;
358        }
359        else
360        {
361            char c = chars[index];
362
363            if ( ( c > 127 ) || !ALPHA[c] )
364            {
365                return false;
366            }
367            else
368            {
369                return true;
370            }
371        }
372    }
373
374
375    /**
376     * Test if the current character is an Alpha character : &lt;alpha> ::=
377     * [0x41-0x5A] | [0x61-0x7A]
378     *
379     * @param string The string which contains the data
380     * @param index Current position in the string
381     * @return <code>true</code> if the current character is an Alpha
382     *         character
383     */
384    public static boolean isAlphaASCII( String string, int index )
385    {
386        if ( string == null )
387        {
388            return false;
389        }
390
391        int length = string.length();
392
393        if ( ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
394        {
395            return false;
396        }
397        else
398        {
399            char c = string.charAt( index );
400
401            if ( ( c > 127 ) || !ALPHA[c] )
402            {
403                return false;
404            }
405            else
406            {
407                return true;
408            }
409        }
410    }
411
412
413    /**
414     * Test if the current character is a lowercased Alpha character : <br/>
415     * &lt;alpha> ::= [0x61-0x7A]
416     *
417     * @param string The string which contains the data
418     * @param index Current position in the string
419     * @return <code>true</code> if the current character is a lower Alpha
420     *         character
421     */
422    public static boolean isAlphaLowercaseASCII( String string, int index )
423    {
424        if ( string == null )
425        {
426            return false;
427        }
428
429        int length = string.length();
430
431        if ( ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
432        {
433            return false;
434        }
435        else
436        {
437            char c = string.charAt( index );
438
439            if ( ( c > 127 ) || !ALPHA_LOWER_CASE[c] )
440            {
441                return false;
442            }
443            else
444            {
445                return true;
446            }
447        }
448    }
449
450
451    /**
452     * Test if the current character is a uppercased Alpha character : <br/>
453     * &lt;alpha> ::= [0x61-0x7A]
454     *
455     * @param string The string which contains the data
456     * @param index Current position in the string
457     * @return <code>true</code> if the current character is a lower Alpha
458     *         character
459     */
460    public static boolean isAlphaUppercaseASCII( String string, int index )
461    {
462        if ( string == null )
463        {
464            return false;
465        }
466
467        int length = string.length();
468
469        if ( ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
470        {
471            return false;
472        }
473        else
474        {
475            char c = string.charAt( index );
476
477            if ( ( c > 127 ) || !ALPHA_UPPER_CASE[c] )
478            {
479                return false;
480            }
481            else
482            {
483                return true;
484            }
485        }
486    }
487
488
489    /**
490     * Check if the current character is an 7 bits ASCII CHAR (between 0 and
491     * 127).
492     * &lt;char> ::= &lt;alpha> | &lt;digit>
493     *
494     * @param string The string which contains the data
495     * @param index Current position in the string
496     * @return The position of the next character, if the current one is a CHAR.
497     */
498    public static boolean isAlphaDigit( String string, int index )
499    {
500        if ( string == null )
501        {
502            return false;
503        }
504
505        int length = string.length();
506
507        if ( ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
508        {
509            return false;
510        }
511        else
512        {
513            char c = string.charAt( index );
514
515            if ( ( c > 127 ) || !ALPHA_DIGIT[c] )
516            {
517                return false;
518            }
519            else
520            {
521                return true;
522            }
523        }
524    }
525
526
527    /**
528     * Check if the current character is an 7 bits ASCII CHAR (between 0 and
529     * 127). &lt;char> ::= &lt;alpha> | &lt;digit> | '-'
530     *
531     * @param bytes The buffer which contains the data
532     * @param index Current position in the buffer
533     * @return The position of the next character, if the current one is a CHAR.
534     */
535    public static boolean isAlphaDigitMinus( byte[] bytes, int index )
536    {
537        if ( ( bytes == null ) || ( bytes.length == 0 ) || ( index < 0 ) || ( index >= bytes.length ) )
538        {
539            return false;
540        }
541        else
542        {
543            byte c = bytes[index];
544
545            if ( ( ( c | 0x7F ) != 0x7F ) || !CHAR[c] )
546            {
547                return false;
548            }
549            else
550            {
551                return true;
552            }
553        }
554    }
555
556
557    /**
558     * Check if the current character is an 7 bits ASCII CHAR (between 0 and
559     * 127). &lt;char> ::= &lt;alpha> | &lt;digit> | '-'
560     *
561     * @param chars The buffer which contains the data
562     * @param index Current position in the buffer
563     * @return The position of the next character, if the current one is a CHAR.
564     */
565    public static boolean isAlphaDigitMinus( char[] chars, int index )
566    {
567        if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) || ( index >= chars.length ) )
568        {
569            return false;
570        }
571        else
572        {
573            char c = chars[index];
574
575            if ( ( c > 127 ) || !CHAR[c] )
576            {
577                return false;
578            }
579            else
580            {
581                return true;
582            }
583        }
584    }
585
586
587    /**
588     * Check if the current character is an 7 bits ASCII CHAR (between 0 and
589     * 127). &lt;char> ::= &lt;alpha> | &lt;digit> | '-'
590     *
591     * @param string The string which contains the data
592     * @param index Current position in the string
593     * @return The position of the next character, if the current one is a CHAR.
594     */
595    public static boolean isAlphaDigitMinus( String string, int index )
596    {
597        if ( string == null )
598        {
599            return false;
600        }
601
602        int length = string.length();
603
604        if ( ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
605        {
606            return false;
607        }
608        else
609        {
610            char c = string.charAt( index );
611
612            if ( ( c > 127 ) || !CHAR[c] )
613            {
614                return false;
615            }
616            else
617            {
618                return true;
619            }
620        }
621    }
622
623
624    /**
625     * Test if the current character is a bit, ie 0 or 1.
626     *
627     * @param string
628     *            The String which contains the data
629     * @param index
630     *            Current position in the string
631     * @return <code>true</code> if the current character is a bit (0 or 1)
632     */
633    public static boolean isBit( String string, int index )
634    {
635        if ( string == null )
636        {
637            return false;
638        }
639
640        int length = string.length();
641
642        if ( ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
643        {
644            return false;
645        }
646        else
647        {
648            char c = string.charAt( index );
649            return ( ( c == '0' ) || ( c == '1' ) );
650        }
651    }
652
653
654    /**
655     * Test if the current character is a digit &lt;digit> ::= '0' | '1' | '2' |
656     * '3' | '4' | '5' | '6' | '7' | '8' | '9'
657     *
658     * @param bytes The buffer which contains the data
659     * @return <code>true</code> if the current character is a Digit
660     */
661    public static boolean isDigit( byte[] bytes )
662    {
663        if ( ( bytes == null ) || ( bytes.length == 0 ) )
664        {
665            return false;
666        }
667        else
668        {
669            return ( ( ( ( bytes[0] | 0x7F ) != 0x7F ) || !DIGIT[bytes[0]] ) ? false : true );
670        }
671    }
672
673
674    /**
675     * Test if the current character is a digit &lt;digit> ::= '0' | '1' | '2' |
676     * '3' | '4' | '5' | '6' | '7' | '8' | '9'
677     *
678     * @param car the character to test
679     *
680     * @return <code>true</code> if the character is a Digit
681     */
682    public static boolean isDigit( char car )
683    {
684        return ( car >= '0' ) && ( car <= '9' );
685    }
686
687
688    /**
689     * Test if the current byte is a digit &lt;digit> ::= '0' | '1' | '2' |
690     * '3' | '4' | '5' | '6' | '7' | '8' | '9'
691     *
692     * @param car the byte to test
693     *
694     * @return <code>true</code> if the character is a Digit
695     */
696    public static boolean isDigit( byte car )
697    {
698        return ( car >= '0' ) && ( car <= '9' );
699    }
700
701
702    /**
703     * Test if the current character is a digit &lt;digit> ::= '0' | '1' | '2' |
704     * '3' | '4' | '5' | '6' | '7' | '8' | '9'
705     *
706     * @param bytes The buffer which contains the data
707     * @param index Current position in the buffer
708     * @return <code>true</code> if the current character is a Digit
709     */
710    public static boolean isDigit( byte[] bytes, int index )
711    {
712        if ( ( bytes == null ) || ( bytes.length == 0 ) || ( index < 0 ) || ( index >= bytes.length ) )
713        {
714            return false;
715        }
716        else
717        {
718            return ( ( ( ( bytes[index] | 0x7F ) != 0x7F ) || !DIGIT[bytes[index]] ) ? false : true );
719        }
720    }
721
722
723    /**
724     * Test if the current character is a digit &lt;digit> ::= '0' | '1' | '2' |
725     * '3' | '4' | '5' | '6' | '7' | '8' | '9'
726     *
727     * @param chars The buffer which contains the data
728     * @param index Current position in the buffer
729     * @return <code>true</code> if the current character is a Digit
730     */
731    public static boolean isDigit( char[] chars, int index )
732    {
733        if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) || ( index >= chars.length ) )
734        {
735            return false;
736        }
737        else
738        {
739            return ( ( ( chars[index] > 127 ) || !DIGIT[chars[index]] ) ? false : true );
740        }
741    }
742
743
744    /**
745     * Test if the current character is a digit &lt;digit> ::= '0' | '1' | '2' |
746     * '3' | '4' | '5' | '6' | '7' | '8' | '9'
747     *
748     * @param string The string which contains the data
749     * @param index Current position in the string
750     * @return <code>true</code> if the current character is a Digit
751     */
752    public static boolean isDigit( String string, int index )
753    {
754        if ( string == null )
755        {
756            return false;
757        }
758
759        int length = string.length();
760
761        if ( ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
762        {
763            return false;
764        }
765        else
766        {
767            char c = string.charAt( index );
768            return ( ( ( c > 127 ) || !DIGIT[c] ) ? false : true );
769        }
770    }
771
772
773    /**
774     * Test if the current character is a digit &lt;digit> ::= '0' | '1' | '2' |
775     * '3' | '4' | '5' | '6' | '7' | '8' | '9'
776     *
777     * @param chars The buffer which contains the data
778     * @return <code>true</code> if the current character is a Digit
779     */
780    public static boolean isDigit( char[] chars )
781    {
782        if ( ( chars == null ) || ( chars.length == 0 ) )
783        {
784            return false;
785        }
786        else
787        {
788            return ( ( ( chars[0] > 127 ) || !DIGIT[chars[0]] ) ? false : true );
789        }
790    }
791
792
793    /**
794     * Check if the current byte is an Hex Char
795     * &lt;hex> ::= [0x30-0x39] | [0x41-0x46] | [0x61-0x66]
796     *
797     * @param b The byte we want to check
798     * @return <code>true</code> if the current byte is a Hex byte
799     */
800    public static boolean isHex( byte b )
801    {
802        return ( ( b | 0x7F ) == 0x7F ) || HEX[b];
803    }
804
805
806    /**
807     * Check if the current character is an Hex Char &lt;hex> ::= [0x30-0x39] |
808     * [0x41-0x46] | [0x61-0x66]
809     *
810     * @param bytes The buffer which contains the data
811     * @param index Current position in the buffer
812     * @return <code>true</code> if the current character is a Hex Char
813     */
814    public static boolean isHex( byte[] bytes, int index )
815    {
816        if ( ( bytes == null ) || ( bytes.length == 0 ) || ( index < 0 ) || ( index >= bytes.length ) )
817        {
818            return false;
819        }
820        else
821        {
822            byte c = bytes[index];
823
824            if ( ( ( c | 0x7F ) != 0x7F ) || !HEX[c] )
825            {
826                return false;
827            }
828            else
829            {
830                return true;
831            }
832        }
833    }
834
835
836    /**
837     * Check if the current character is an Hex Char &lt;hex> ::= [0x30-0x39] |
838     * [0x41-0x46] | [0x61-0x66]
839     *
840     * @param chars The buffer which contains the data
841     * @param index Current position in the buffer
842     * @return <code>true</code> if the current character is a Hex Char
843     */
844    public static boolean isHex( char[] chars, int index )
845    {
846        if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) || ( index >= chars.length ) )
847        {
848            return false;
849        }
850        else
851        {
852            char c = chars[index];
853
854            if ( ( c > 127 ) || !HEX[c] )
855            {
856                return false;
857            }
858            else
859            {
860                return true;
861            }
862        }
863    }
864
865
866    /**
867     * Check if the current character is an Hex Char &lt;hex> ::= [0x30-0x39] |
868     * [0x41-0x46] | [0x61-0x66]
869     *
870     * @param string The string which contains the data
871     * @param index Current position in the string
872     * @return <code>true</code> if the current character is a Hex Char
873     */
874    public static boolean isHex( String string, int index )
875    {
876        if ( string == null )
877        {
878            return false;
879        }
880
881        int length = string.length();
882
883        if ( ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
884        {
885            return false;
886        }
887        else
888        {
889            char c = string.charAt( index );
890
891            if ( ( c > 127 ) || !HEX[c] )
892            {
893                return false;
894            }
895            else
896            {
897                return true;
898            }
899        }
900    }
901    
902    /**
903     * Check if the current character is the ASCII character underscore 0x5F.
904     *
905     * @param bytes The buffer which contains the data
906     * @param index Current position in the buffer
907     * @return <code>true</code> if the current character is a the underscore
908     */
909    public static boolean isUnderscore( byte[] bytes, int index )
910    {
911        if ( ( bytes == null ) || ( bytes.length == 0 ) || ( index < 0 ) || ( index >= bytes.length ) )
912        {
913            return false;
914        }
915        else
916        {
917            byte c = bytes[index];
918
919            return c == 0x5F;
920        }
921    }
922
923}