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