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    private 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    private 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    private 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    private 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    private 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    private 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    private 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    private Chars()
172    {
173    }
174
175
176    /**
177    * Test if the current character is equal to a specific character.
178    *
179    * @param chars The buffer which contains the data
180    * @param index
181    *            Current position in the buffer
182    * @param car The character we want to compare with the current buffer position
183    * @return <code>true</code> if the current character equals the given character.
184    */
185    public static boolean isCharASCII( char[] chars, int index, char car )
186    {
187        if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) || ( index >= chars.length ) )
188        {
189            return false;
190        }
191        else
192        {
193            return ( ( chars[index] == car ) ? true : false );
194        }
195    }
196
197
198    /**
199     * Test if the current character is equal to a specific character.
200     *
201     * @param string The String which contains the data
202     * @param index Current position in the string
203     * @param car The character we want to compare with the current string
204     *            position
205     * @return <code>true</code> if the current character equals the given
206     *         character.
207     */
208    public static boolean isCharASCII( String string, int index, char car )
209    {
210        if ( string == null )
211        {
212            return false;
213        }
214
215        int length = string.length();
216
217        if ( ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
218        {
219            return false;
220        }
221        else
222        {
223            return string.charAt( index ) == car;
224        }
225    }
226
227
228    /**
229     * Test if the current character is equal to a specific character.
230     *
231     * @param string The String which contains the data
232     * @param index Current position in the string
233     * @param car The character we want to compare with the current string
234     *            position
235     * @return <code>true</code> if the current character equals the given
236     *         character.
237     */
238    public static boolean isICharASCII( String string, int index, char car )
239    {
240        if ( string == null )
241        {
242            return false;
243        }
244
245        int length = string.length();
246
247        if ( ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
248        {
249            return false;
250        }
251        else
252        {
253            return ( ( string.charAt( index ) | 0x20 ) & car ) == car;
254        }
255    }
256
257
258    /**
259     * Test if the current character is equal to a specific character.
260     *
261     * @param bytes The String which contains the data
262     * @param index Current position in the string
263     * @param car The character we want to compare with the current string
264     *            position
265     * @return <code>true</code> if the current character equals the given
266     *         character.
267     */
268    public static boolean isICharASCII( byte[] bytes, int index, char car )
269    {
270        if ( bytes == null )
271        {
272            return false;
273        }
274
275        int length = bytes.length;
276
277        if ( ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
278        {
279            return false;
280        }
281        else
282        {
283            return ( ( bytes[index] | 0x20 ) & car ) == car;
284        }
285    }
286
287
288    /**
289     * Test if the current byte is an Alpha character :
290     * &lt;alpha> ::= [0x41-0x5A] | [0x61-0x7A]
291     *
292     * @param c The byte to test
293     *
294     * @return <code>true</code> if the byte is an Alpha
295     *         character
296     */
297    public static boolean isAlpha( byte c )
298    {
299        return ( ( c > 0 ) && ( c <= 127 ) && ALPHA[c] );
300    }
301
302
303    /**
304     * Test if the current character is an Alpha character :
305     * &lt;alpha> ::= [0x41-0x5A] | [0x61-0x7A]
306     *
307     * @param c The char to test
308     *
309     * @return <code>true</code> if the character is an Alpha
310     *         character
311     */
312    public static boolean isAlpha( char c )
313    {
314        return ( ( c > 0 ) && ( c <= 127 ) && ALPHA[c] );
315    }
316
317
318    /**
319     * Test if the current character is an Alpha character : &lt;alpha> ::=
320     * [0x41-0x5A] | [0x61-0x7A]
321     *
322     * @param bytes The buffer which contains the data
323     * @param index Current position in the buffer
324     * @return <code>true</code> if the current character is an Alpha
325     *         character
326     */
327    public static boolean isAlphaASCII( byte[] bytes, int index )
328    {
329        if ( ( bytes == null ) || ( bytes.length == 0 ) || ( index < 0 ) || ( index >= bytes.length ) )
330        {
331            return false;
332        }
333        else
334        {
335            byte c = bytes[index];
336
337            if ( ( ( c | 0x7F ) != 0x7F ) || !ALPHA[c] )
338            {
339                return false;
340            }
341            else
342            {
343                return true;
344            }
345        }
346    }
347
348
349    /**
350     * Test if the current character is an Alpha character : &lt;alpha> ::=
351     * [0x41-0x5A] | [0x61-0x7A]
352     *
353     * @param chars The buffer which contains the data
354     * @param index Current position in the buffer
355     * @return <code>true</code> if the current character is an Alpha
356     *         character
357     */
358    public static boolean isAlphaASCII( char[] chars, int index )
359    {
360        if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) || ( index >= chars.length ) )
361        {
362            return false;
363        }
364        else
365        {
366            char c = chars[index];
367
368            if ( ( c > 127 ) || !ALPHA[c] )
369            {
370                return false;
371            }
372            else
373            {
374                return true;
375            }
376        }
377    }
378
379
380    /**
381     * Test if the current character is an Alpha character : &lt;alpha> ::=
382     * [0x41-0x5A] | [0x61-0x7A]
383     *
384     * @param string The string which contains the data
385     * @param index Current position in the string
386     * @return <code>true</code> if the current character is an Alpha
387     *         character
388     */
389    public static boolean isAlphaASCII( String string, int index )
390    {
391        if ( string == null )
392        {
393            return false;
394        }
395
396        int length = string.length();
397
398        if ( ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
399        {
400            return false;
401        }
402        else
403        {
404            char c = string.charAt( index );
405
406            if ( ( c > 127 ) || !ALPHA[c] )
407            {
408                return false;
409            }
410            else
411            {
412                return true;
413            }
414        }
415    }
416
417
418    /**
419     * Test if the current character is a lowercased Alpha character : <br/>
420     * &lt;alpha> ::= [0x61-0x7A]
421     *
422     * @param string The string which contains the data
423     * @param index Current position in the string
424     * @return <code>true</code> if the current character is a lower Alpha
425     *         character
426     */
427    public static boolean isAlphaLowercaseASCII( String string, int index )
428    {
429        if ( string == null )
430        {
431            return false;
432        }
433
434        int length = string.length();
435
436        if ( ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
437        {
438            return false;
439        }
440        else
441        {
442            char c = string.charAt( index );
443
444            if ( ( c > 127 ) || !ALPHA_LOWER_CASE[c] )
445            {
446                return false;
447            }
448            else
449            {
450                return true;
451            }
452        }
453    }
454
455
456    /**
457     * Test if the current character is a uppercased Alpha character : <br/>
458     * &lt;alpha> ::= [0x61-0x7A]
459     *
460     * @param string The string which contains the data
461     * @param index Current position in the string
462     * @return <code>true</code> if the current character is a lower Alpha
463     *         character
464     */
465    public static boolean isAlphaUppercaseASCII( String string, int index )
466    {
467        if ( string == null )
468        {
469            return false;
470        }
471
472        int length = string.length();
473
474        if ( ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
475        {
476            return false;
477        }
478        else
479        {
480            char c = string.charAt( index );
481
482            if ( ( c > 127 ) || !ALPHA_UPPER_CASE[c] )
483            {
484                return false;
485            }
486            else
487            {
488                return true;
489            }
490        }
491    }
492
493
494    /**
495     * Check if the current character is an 7 bits ASCII CHAR (between 0 and
496     * 127).
497     * &lt;char> ::= &lt;alpha> | &lt;digit>
498     *
499     * @param string The string which contains the data
500     * @param index Current position in the string
501     * @return The position of the next character, if the current one is a CHAR.
502     */
503    public static boolean isAlphaDigit( String string, int index )
504    {
505        if ( string == null )
506        {
507            return false;
508        }
509
510        int length = string.length();
511
512        if ( ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
513        {
514            return false;
515        }
516        else
517        {
518            char c = string.charAt( index );
519
520            if ( ( c > 127 ) || !ALPHA_DIGIT[c] )
521            {
522                return false;
523            }
524            else
525            {
526                return true;
527            }
528        }
529    }
530
531
532    /**
533     * Check if the current character is an 7 bits ASCII CHAR (between 0 and
534     * 127). &lt;char> ::= &lt;alpha> | &lt;digit> | '-'
535     *
536     * @param bytes The buffer which contains the data
537     * @param index Current position in the buffer
538     * @return The position of the next character, if the current one is a CHAR.
539     */
540    public static boolean isAlphaDigitMinus( byte[] bytes, int index )
541    {
542        if ( ( bytes == null ) || ( bytes.length == 0 ) || ( index < 0 ) || ( index >= bytes.length ) )
543        {
544            return false;
545        }
546        else
547        {
548            byte c = bytes[index];
549
550            if ( ( ( c | 0x7F ) != 0x7F ) || !CHAR[c] )
551            {
552                return false;
553            }
554            else
555            {
556                return true;
557            }
558        }
559    }
560
561
562    /**
563     * Check if the current character is an 7 bits ASCII CHAR (between 0 and
564     * 127). &lt;char> ::= &lt;alpha> | &lt;digit> | '-'
565     *
566     * @param chars The buffer which contains the data
567     * @param index Current position in the buffer
568     * @return The position of the next character, if the current one is a CHAR.
569     */
570    public static boolean isAlphaDigitMinus( char[] chars, int index )
571    {
572        if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) || ( index >= chars.length ) )
573        {
574            return false;
575        }
576        else
577        {
578            char c = chars[index];
579
580            if ( ( c > 127 ) || !CHAR[c] )
581            {
582                return false;
583            }
584            else
585            {
586                return true;
587            }
588        }
589    }
590
591
592    /**
593     * Check if the current character is an 7 bits ASCII CHAR (between 0 and
594     * 127). &lt;char> ::= &lt;alpha> | &lt;digit> | '-'
595     *
596     * @param string The string which contains the data
597     * @param index Current position in the string
598     * @return The position of the next character, if the current one is a CHAR.
599     */
600    public static boolean isAlphaDigitMinus( String string, int index )
601    {
602        if ( string == null )
603        {
604            return false;
605        }
606
607        int length = string.length();
608
609        if ( ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
610        {
611            return false;
612        }
613        else
614        {
615            char c = string.charAt( index );
616
617            if ( ( c > 127 ) || !CHAR[c] )
618            {
619                return false;
620            }
621            else
622            {
623                return true;
624            }
625        }
626    }
627
628
629    /**
630     * Check if the current character is an 7 bits ASCII CHAR (between 0 and
631     * 127). &lt;char> ::= &lt;alpha> | &lt;digit> | '-'
632     *
633     * @param c The char we want to check
634     * @return The position of the next character, if the current one is a CHAR.
635     */
636    public static boolean isAlphaDigitMinus( char c )
637    {
638        return ( ( c & 0x007F ) == c ) && CHAR[c];
639    }
640
641
642    /**
643     * Test if the current character is a bit, ie 0 or 1.
644     *
645     * @param string
646     *            The String which contains the data
647     * @param index
648     *            Current position in the string
649     * @return <code>true</code> if the current character is a bit (0 or 1)
650     */
651    public static boolean isBit( String string, int index )
652    {
653        if ( string == null )
654        {
655            return false;
656        }
657
658        int length = string.length();
659
660        if ( ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
661        {
662            return false;
663        }
664        else
665        {
666            char c = string.charAt( index );
667            return ( ( c == '0' ) || ( c == '1' ) );
668        }
669    }
670
671
672    /**
673     * Test if the current character is a digit &lt;digit> ::= '0' | '1' | '2' |
674     * '3' | '4' | '5' | '6' | '7' | '8' | '9'
675     *
676     * @param bytes The buffer which contains the data
677     * @return <code>true</code> if the current character is a Digit
678     */
679    public static boolean isDigit( byte[] bytes )
680    {
681        if ( ( bytes == null ) || ( bytes.length == 0 ) )
682        {
683            return false;
684        }
685        else
686        {
687            return ( ( ( ( bytes[0] | 0x7F ) != 0x7F ) || !DIGIT[bytes[0]] ) ? false : true );
688        }
689    }
690
691
692    /**
693     * Test if the current character is a digit &lt;digit> ::= '0' | '1' | '2' |
694     * '3' | '4' | '5' | '6' | '7' | '8' | '9'
695     *
696     * @param car the character to test
697     *
698     * @return <code>true</code> if the character is a Digit
699     */
700    public static boolean isDigit( char car )
701    {
702        return ( car >= '0' ) && ( car <= '9' );
703    }
704
705
706    /**
707     * Test if the current byte is a digit &lt;digit> ::= '0' | '1' | '2' |
708     * '3' | '4' | '5' | '6' | '7' | '8' | '9'
709     *
710     * @param car the byte to test
711     *
712     * @return <code>true</code> if the character is a Digit
713     */
714    public static boolean isDigit( byte car )
715    {
716        return ( car >= '0' ) && ( car <= '9' );
717    }
718
719
720    /**
721     * Test if the current character is a digit &lt;digit> ::= '0' | '1' | '2' |
722     * '3' | '4' | '5' | '6' | '7' | '8' | '9'
723     *
724     * @param bytes The buffer which contains the data
725     * @param index Current position in the buffer
726     * @return <code>true</code> if the current character is a Digit
727     */
728    public static boolean isDigit( byte[] bytes, int index )
729    {
730        if ( ( bytes == null ) || ( bytes.length == 0 ) || ( index < 0 ) || ( index >= bytes.length ) )
731        {
732            return false;
733        }
734        else
735        {
736            return ( ( ( ( bytes[index] | 0x7F ) != 0x7F ) || !DIGIT[bytes[index]] ) ? false : true );
737        }
738    }
739
740
741    /**
742     * Test if the current character is a digit &lt;digit> ::= '0' | '1' | '2' |
743     * '3' | '4' | '5' | '6' | '7' | '8' | '9'
744     *
745     * @param chars The buffer which contains the data
746     * @param index Current position in the buffer
747     * @return <code>true</code> if the current character is a Digit
748     */
749    public static boolean isDigit( char[] chars, int index )
750    {
751        if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) || ( index >= chars.length ) )
752        {
753            return false;
754        }
755        else
756        {
757            return ( ( ( chars[index] > 127 ) || !DIGIT[chars[index]] ) ? false : true );
758        }
759    }
760
761
762    /**
763     * Test if the current character is a digit &lt;digit> ::= '0' | '1' | '2' |
764     * '3' | '4' | '5' | '6' | '7' | '8' | '9'
765     *
766     * @param string The string which contains the data
767     * @param index Current position in the string
768     * @return <code>true</code> if the current character is a Digit
769     */
770    public static boolean isDigit( String string, int index )
771    {
772        if ( string == null )
773        {
774            return false;
775        }
776
777        int length = string.length();
778
779        if ( ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
780        {
781            return false;
782        }
783        else
784        {
785            char c = string.charAt( index );
786            return ( ( ( c > 127 ) || !DIGIT[c] ) ? false : true );
787        }
788    }
789
790
791    /**
792     * Test if the current character is a digit &lt;digit> ::= '0' | '1' | '2' |
793     * '3' | '4' | '5' | '6' | '7' | '8' | '9'
794     *
795     * @param chars The buffer which contains the data
796     * @return <code>true</code> if the current character is a Digit
797     */
798    public static boolean isDigit( char[] chars )
799    {
800        if ( ( chars == null ) || ( chars.length == 0 ) )
801        {
802            return false;
803        }
804        else
805        {
806            return ( ( ( chars[0] > 127 ) || !DIGIT[chars[0]] ) ? false : true );
807        }
808    }
809
810
811    /**
812     * Check if the current char is an Hex Char
813     * &lt;hex> ::= [0x30-0x39] | [0x41-0x46] | [0x61-0x66]
814     *
815     * @param c The char we want to check
816     * @return <code>true</code> if the current char is a Hex char
817     */
818    public static boolean isHex( char c )
819    {
820        return ( ( c | 0x007F ) == 0x007F ) && HEX[c];
821    }
822
823
824    /**
825     * Check if the current byte is an Hex Char
826     * &lt;hex> ::= [0x30-0x39] | [0x41-0x46] | [0x61-0x66]
827     *
828     * @param b The byte we want to check
829     * @return <code>true</code> if the current byte is a Hex byte
830     */
831    public static boolean isHex( byte b )
832    {
833        return ( ( b | 0x7F ) == 0x7F ) && HEX[b];
834    }
835
836
837    /**
838     * Check if the current character is an Hex Char &lt;hex> ::= [0x30-0x39] |
839     * [0x41-0x46] | [0x61-0x66]
840     *
841     * @param bytes The buffer which contains the data
842     * @param index Current position in the buffer
843     * @return <code>true</code> if the current character is a Hex Char
844     */
845    public static boolean isHex( byte[] bytes, int index )
846    {
847        if ( ( bytes == null ) || ( bytes.length == 0 ) || ( index < 0 ) || ( index >= bytes.length ) )
848        {
849            return false;
850        }
851        else
852        {
853            byte c = bytes[index];
854
855            return ( ( ( c | 0x7F ) == 0x7F ) && HEX[c] );
856        }
857    }
858
859
860    /**
861     * Check if the current character is an Hex Char &lt;hex> ::= [0x30-0x39] |
862     * [0x41-0x46] | [0x61-0x66]
863     *
864     * @param chars The buffer which contains the data
865     * @param index Current position in the buffer
866     * @return <code>true</code> if the current character is a Hex Char
867     */
868    public static boolean isHex( char[] chars, int index )
869    {
870        if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) || ( index >= chars.length ) )
871        {
872            return false;
873        }
874        else
875        {
876            char c = chars[index];
877
878            return ( ( ( c | 0x007F ) == 0x007F ) && HEX[c] );
879        }
880    }
881
882
883    /**
884     * Check if the current character is an Hex Char &lt;hex> ::= [0x30-0x39] |
885     * [0x41-0x46] | [0x61-0x66]
886     *
887     * @param string The string which contains the data
888     * @param index Current position in the string
889     * @return <code>true</code> if the current character is a Hex Char
890     */
891    public static boolean isHex( String string, int index )
892    {
893        if ( string == null )
894        {
895            return false;
896        }
897
898        int length = string.length();
899
900        if ( ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
901        {
902            return false;
903        }
904        else
905        {
906            char c = string.charAt( index );
907
908            return ( ( ( c | 0x007F ) == 0x007F ) && HEX[c] );
909        }
910    }
911    
912    
913    /**
914     * Check if the current character is the ASCII character underscore 0x5F.
915     *
916     * @param bytes The buffer which contains the data
917     * @param index Current position in the buffer
918     * @return <code>true</code> if the current character is a the underscore
919     */
920    public static boolean isUnderscore( byte[] bytes, int index )
921    {
922        if ( ( bytes == null ) || ( bytes.length == 0 ) || ( index < 0 ) || ( index >= bytes.length ) )
923        {
924            return false;
925        }
926        else
927        {
928            byte c = bytes[index];
929
930            return c == 0x5F;
931        }
932    }
933
934}