directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r291504 - in /directory/asn1/branches/asn1-NameComponent/ber-new/src/java/main/org/apache/asn1new/util: MutableString.java StringUtils.java
Date Mon, 26 Sep 2005 01:09:37 GMT
Author: elecharny
Date: Sun Sep 25 18:09:31 2005
New Revision: 291504

URL: http://svn.apache.org/viewcvs?rev=291504&view=rev
Log:
Massive refactoring of the StringUtils, MutableString classes, and all the classes that uses them.

Modified:
    directory/asn1/branches/asn1-NameComponent/ber-new/src/java/main/org/apache/asn1new/util/MutableString.java
    directory/asn1/branches/asn1-NameComponent/ber-new/src/java/main/org/apache/asn1new/util/StringUtils.java

Modified: directory/asn1/branches/asn1-NameComponent/ber-new/src/java/main/org/apache/asn1new/util/MutableString.java
URL: http://svn.apache.org/viewcvs/directory/asn1/branches/asn1-NameComponent/ber-new/src/java/main/org/apache/asn1new/util/MutableString.java?rev=291504&r1=291503&r2=291504&view=diff
==============================================================================
--- directory/asn1/branches/asn1-NameComponent/ber-new/src/java/main/org/apache/asn1new/util/MutableString.java (original)
+++ directory/asn1/branches/asn1-NameComponent/ber-new/src/java/main/org/apache/asn1new/util/MutableString.java Sun Sep 25 18:09:31 2005
@@ -19,8 +19,7 @@
 import java.io.UnsupportedEncodingException;
 
 /**
- * A Mutable version of the String class. This mutable String can be
- * stored in a pool.
+ * A Mutable version of the String class. It stores only UTF-8 Strings.
  * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
@@ -54,9 +53,9 @@
     /**
      * Creates a MutableString.
      */
-    public MutableString(String string)
+    public MutableString(String string) throws UnsupportedEncodingException
     {
-        this( string.getBytes() );
+        this( string.getBytes( "UTF-8" ) );
     }
     
     /**
@@ -84,7 +83,7 @@
      * is coded in Unicode, so the bytes *MUST* be valid ! 
      * @param bytes The value to store.
      */
-    public MutableString(byte[] bytes)
+    public MutableString(byte[] bytes) throws UnsupportedEncodingException
     {
         setData( bytes );
     }
@@ -95,20 +94,34 @@
      * 
      * @param bytes The string to store
      */
-    public void setData(byte[] bytes)
+    public void setData(byte[] bytes) throws UnsupportedEncodingException
     {
         data = bytes;
         length = bytes.length;
         int charLength = StringUtils.countChars(bytes);
         
+        if ( charLength == StringUtils.BAD_CHAR_ENCODING )
+        {
+            throw new UnsupportedEncodingException( "Bad UTF-8 encoding" );
+        }
+        
         string = new char[charLength];
         
+        StringUtils.decodeUTF8( string, bytes );
+    }
+    
+    /**
+     * Store the char[] as a byte[]. The bye[] is supposed to be large enough to store the result.
+     * 
+     * @param string The char[] to transform
+     */
+    private void setData( char[] string )
+    {
         int pos = 0;
         
-        for ( int i = 0; i < charLength; i++ )
+        for ( int i = 0; i < string.length; i++ )
         {
-            string[i] = StringUtils.bytesToChar(bytes, pos);
-            pos += StringUtils.countBytesPerChar(bytes, pos); 
+            pos = StringUtils.charToBytes( string[i], data, pos );
         }
     }
     
@@ -130,24 +143,175 @@
     }
 
     /**
+     * Trim the String to suppress leading and trailing spaces, if any.
+     * 
+     * @return The new trimmed MutableString
+     */
+    public MutableString trim() throws UnsupportedEncodingException
+    {
+        int start = 0;
+        int end = length - 1;
+        
+        while ( (start < length ) && ( string[start] == ' ' ) )
+        {
+            start++;
+        }
+        
+        if ( start == length )
+        {
+            return EMPTY_STRING;
+        }
+        
+        while ( ( end > 0 ) && ( string[end] == ' ' ) )
+        {
+            end --;
+        }
+        
+        if ( end == -1 )
+        {
+            return EMPTY_STRING;
+        }
+        
+        if ( ( start == 0 ) && (end == length - 1) )
+        {
+            // Special case : we don't have any leading and trailing space.
+            // We can avoid creating a MutableString, then.
+            return this;
+        }
+        
+        int newLength = end - start + 1;
+        byte[] newData = new byte[ newLength ];
+        
+        System.arraycopy(data, start, newData, 0, newLength );
+        
+        MutableString newString = new MutableString( newData );
+        
+        return newString;
+    }
+    
+    /**
+     * Trim the String to suppress leading spaces, if any.
+     * 
+     * @return The new trimmed MutableString
+     */
+    public MutableString trimLeft() throws UnsupportedEncodingException
+    {
+        int start = 0;
+        
+        while ( (start < length ) && ( string[start] == ' ' ) )
+        {
+            start++;
+        }
+        
+        if (start == 0)
+        {
+            // Special case : we don't have any leading space.
+            // We can avoid creating a MutableString, then.
+            return this;
+        }
+        
+        if ( start == length )
+        {
+            return EMPTY_STRING;
+        }
+        
+        int newLength = length - start;
+        byte[] newData = new byte[ newLength ];
+        
+        System.arraycopy(data, start, newData, 0, newLength );
+        
+        MutableString newString = new MutableString( newData );
+        
+        return newString;
+    }
+    
+    /**
+     * Trim the String to suppress trailing spaces, if any.
+     * 
+     * @return The new trimmed MutableString
+     */
+    public MutableString trimRight() throws UnsupportedEncodingException
+    {
+        int end = length - 1;
+        
+        while ( ( end > 0 ) && ( string[end] == ' ' ) )
+        {
+            end --;
+        }
+        
+        if ( end == length - 1 )
+        {
+            // Special case : we don't have any trailing space.
+            // We can avoid creating a MutableString, then.
+            return this;
+        }
+        
+        if ( end == -1 )
+        {
+            return EMPTY_STRING;
+        }
+        
+        int newLength = end + 1;
+        byte[] newData = new byte[ newLength ];
+        
+        System.arraycopy(data, 0, newData, 0, newLength );
+        
+        MutableString newString = new MutableString( newData );
+        
+        return newString;
+    }
+    
+    /**
+     *  Converts all of the characters in this String to upper case.
+     */
+    public void toUpperCase()
+    {
+        for ( int i = 0; i < length; i++ )
+        {
+            if ( Character.isLowerCase( string[i] ) )
+            {
+                string[i] = Character.toUpperCase( string[i] );
+            }
+        }
+        
+        setData( string );
+    }
+    
+    /**
+     *  Converts all of the characters in this String to lower case.
+     */
+    public void toLowerCase()
+    {
+        for ( int i = 0; i < length; i++ )
+        {
+            if ( Character.isUpperCase( string[i] ) )
+            {
+                string[i] = Character.toLowerCase( string[i] );
+            }
+        }
+
+        setData( string );
+    }
+    
+    /**
      * Return a native String representation of the MutableString.
      */
     public String toString()
     {
-    	if ( length == 0 )
-    	{
-    		return "";
-    	}
-    	else
-    	{
-    		try
-    		{
-    			return new String(data, 0, length, "UTF8");
-    		}
-    		catch (UnsupportedEncodingException uee)
-    		{
-    			return "";
-    		}
-    	}
+        if ( length == 0 )
+        {
+            return "";
+        }
+        else
+        {
+            try
+            {
+                return new String(data, 0, length, "UTF8");
+            }
+            catch (UnsupportedEncodingException uee)
+            {
+                return "";
+            }
+        }
     }
 }

Modified: directory/asn1/branches/asn1-NameComponent/ber-new/src/java/main/org/apache/asn1new/util/StringUtils.java
URL: http://svn.apache.org/viewcvs/directory/asn1/branches/asn1-NameComponent/ber-new/src/java/main/org/apache/asn1new/util/StringUtils.java?rev=291504&r1=291503&r2=291504&view=diff
==============================================================================
--- directory/asn1/branches/asn1-NameComponent/ber-new/src/java/main/org/apache/asn1new/util/StringUtils.java (original)
+++ directory/asn1/branches/asn1-NameComponent/ber-new/src/java/main/org/apache/asn1new/util/StringUtils.java Sun Sep 25 18:09:31 2005
@@ -16,6 +16,8 @@
  */
 package org.apache.asn1new.util;
 
+import java.io.UnsupportedEncodingException;
+
 /**
  * Little helper class. Nothing that should stay here, but I need those 
  * to debug.
@@ -47,6 +49,22 @@
     private static int UTF8_SIX_BYTES_MASK = 0x00FE;
     private static int UTF8_SIX_BYTES = 0x00FC;
     
+    private static int CHAR_ONE_BYTE_MASK    = 0xFFFFFF80;
+    private static int CHAR_ONE_BYTE         = ~CHAR_ONE_BYTE_MASK;
+    
+    private static int CHAR_TWO_BYTES_MASK   = 0xFFFFF800;
+    
+    private static int CHAR_THREE_BYTES_MASK = 0xFFFF0000;
+    
+    private static int CHAR_FOUR_BYTES_MASK  = 0xFFE00000;
+    
+    private static int CHAR_FIVE_BYTES_MASK  = 0xFC000000;
+    
+    private static int CHAR_SIX_BYTES_MASK   = 0x80000000;
+    
+    /** A constant for a bad UTF-8 encoding */
+    public static final int BAD_CHAR_ENCODING = -1;
+    
     /** <alpha>    ::= [0x41-0x5A] | [0x61-0x7A] */
     public static final boolean[] ALPHA =
     {
@@ -141,17 +159,6 @@
     }
     
     /**
-     * Return the Unicode char which is coded in the bytes at position 0.
-     * 
-     * @param bytes The byte[] represntation of an Unicode string. 
-     * @return The first char found.
-     */
-    public static char bytesToChar(byte[] bytes)
-    {
-        return bytesToChar(bytes, 0);
-    }
-
-    /**
      * Count the number of bytes needed to return an Unicode char. This
      * can be from 1 to 6. 
      * @param bytes The bytes to read
@@ -161,154 +168,318 @@
      * 
      * TODO : Should stop after the third byte, as a char is only 2 bytes long.
      */
-    public static int countBytesPerChar(byte[] bytes, int pos)
+    public static int countBytesPerChar(byte[] bytes, int pos) throws UnsupportedEncodingException
     {
         if ((bytes[pos] & UTF8_MULTI_BYTES_MASK) == 0)
         {
             return 1;
-        } else if ((bytes[pos] & UTF8_TWO_BYTES_MASK) == UTF8_TWO_BYTES)
-    	{
+        } 
+        else if ((bytes[pos] & UTF8_TWO_BYTES_MASK) == UTF8_TWO_BYTES)
+        {
             return 2;
-    	}
-    	else if ((bytes[pos] & UTF8_THREE_BYTES_MASK) == UTF8_THREE_BYTES)
-    	{
-    	    return 3;
-    	}
-    	else if ((bytes[pos] & UTF8_FOUR_BYTES_MASK) == UTF8_FOUR_BYTES)
-    	{
-    	    return 4;
-    	}
-    	else if ((bytes[pos] & UTF8_FIVE_BYTES_MASK) == UTF8_FIVE_BYTES)
-    	{
-    	    return 5;
-    	}
-    	else if ((bytes[pos] & UTF8_SIX_BYTES_MASK) == UTF8_SIX_BYTES)
-    	{
-    	    return 6;
+        }
+        else if ((bytes[pos] & UTF8_THREE_BYTES_MASK) == UTF8_THREE_BYTES)
+        {
+            return 3;
+        }
+        else if ((bytes[pos] & UTF8_FOUR_BYTES_MASK) == UTF8_FOUR_BYTES)
+        {
+            return 4;
+        }
+        else if ((bytes[pos] & UTF8_FIVE_BYTES_MASK) == UTF8_FIVE_BYTES)
+        {
+            return 5;
+        }
+        else if ((bytes[pos] & UTF8_SIX_BYTES_MASK) == UTF8_SIX_BYTES)
+        {
+            return 6;
         } 
-    	else
-    	{
-    	    return -1;
-    	}
+        else
+        {
+            throw new UnsupportedEncodingException( "Cannot encode a character" );
+        }
+    }
+    
+    /**
+     * Return the Unicode char which is coded in the bytes at the given position. 
+     * This method suppose that the UTF-8 byte array is 3 bytes long, no more.
+     *  
+     * @param bytes The byte[] representation of an Unicode string. 
+     * @param pos The current position to start decoding the char
+     * @return The decoded char, or -1 if no char can be decoded
+     * 
+     * TODO : Should stop after the third byte, as a char is only 2 bytes long.
+     */
+    public static char bytesToChar(byte[] bytes, int pos) throws UnsupportedEncodingException
+    {
+        if ( ( bytes[pos] & UTF8_MULTI_BYTES_MASK ) == 0)
+        {
+            return (char)bytes[pos];
+        }
+        else
+        {
+            if ( ( ( bytes[pos] & UTF8_TWO_BYTES_MASK ) == UTF8_TWO_BYTES ) &&
+                 ( ( bytes[pos +1 ] & UTF8_TWO_BYTES ) == UTF8_MULTI_BYTES_MASK ) )
+            {
+                // Two bytes char
+                return (char)( 
+                        ( ( bytes[pos] & 0x1C ) << 6 ) +    // 110x-xxyy 10zz-zzzz -> 0000-0xxx 0000-0000
+                        ( ( bytes[pos] & 0x03 ) << 6 ) +    // 110x-xxyy 10zz-zzzz -> 0000-0000 yy00-0000
+                        ( bytes[pos + 1] & 0x3F )           // 110x-xxyy 10zz-zzzz -> 0000-0000 00zz-zzzz
+                        );                              //                     -> 0000-0xxx yyzz-zzzz (07FF)
+            }
+            else if ( ( ( bytes[pos] & UTF8_THREE_BYTES_MASK ) == UTF8_THREE_BYTES ) &&
+                      ( ( bytes[pos + 1] & UTF8_TWO_BYTES ) == UTF8_MULTI_BYTES_MASK ) &&
+                      ( ( bytes[pos + 2] & UTF8_TWO_BYTES ) == UTF8_MULTI_BYTES_MASK ) )
+            {
+                // Three bytes char
+                return (char)( 
+                        // 1110-tttt 10xx-xxyy 10zz-zzzz -> tttt-0000-0000-0000
+                        ( ( bytes[pos] & 0x0F) << 12 ) +    
+                        // 1110-tttt 10xx-xxyy 10zz-zzzz -> 0000-xxxx-0000-0000
+                        ( ( bytes[pos + 1] & 0x3C) << 6 ) +     
+                        // 1110-tttt 10xx-xxyy 10zz-zzzz -> 0000-0000-yy00-0000
+                        ( ( bytes[pos + 1] & 0x03) << 6 ) +     
+                        // 1110-tttt 10xx-xxyy 10zz-zzzz -> 0000-0000-00zz-zzzz
+                        ( bytes[pos + 2] & 0x3F )               
+                        //                               -> tttt-xxxx yyzz-zzzz (FF FF)
+                        );                               
+            }
+            else
+            {
+                throw new UnsupportedEncodingException( "Bad UTF-8 encoding" );
+            }
+        }
     }
     
     /**
      * Return the Unicode char which is coded in the bytes at the given position. 
-     * @param bytes The byte[] represntation of an Unicode string. 
+     * This method suppose that the UTF-8 byte array is 3 bytes long, no more.
+     *  
+     * @param bytes The byte[] representation of an Unicode string. 
      * @param pos The current position to start decoding the char
-     * @return The char found.
      * @return The decoded char, or -1 if no char can be decoded
      * 
      * TODO : Should stop after the third byte, as a char is only 2 bytes long.
      */
-    public static char bytesToChar(byte[] bytes, int pos)
+    public static void bytesToTwoChars(byte[] bytes, int pos, char[] chars ) throws UnsupportedEncodingException
+    {
+        int value = 0;
+        
+        if ( ( bytes[pos] & UTF8_FOUR_BYTES_MASK ) == UTF8_FOUR_BYTES )
+        {
+            value = 
+                    // 1111-0ttt 10uu-vvvv 10xx-xxyy 10zz-zzzz -> 000t-tt00 0000-0000 0000-0000
+                    ( ( bytes[pos] & 0x07) << 18 ) +
+                    // 1111-0ttt 10uu-vvvv 10xx-xxyy 10zz-zzzz -> 0000-00uu 0000-0000 0000-0000
+                    ( ( bytes[pos + 1] & 0x30) << 16 ) + 
+                    // 1111-0ttt 10uu-vvvv 10xx-xxyy 10zz-zzzz -> 0000-0000 vvvv-0000 0000-0000
+                    ( ( bytes[pos + 1] & 0x0F) << 12 ) + 
+                    // 1111-0ttt 10uu-vvvv 10xx-xxyy 10zz-zzzz -> 0000-0000 0000-xxxx 0000-0000
+                    ( ( bytes[pos + 2] & 0x3C) << 6 ) + 
+                    // 1111-0ttt 10uu-vvvv 10xx-xxyy 10zz-zzzz -> 0000-0000 0000-0000 yy00-0000
+                    ( ( bytes[pos + 2] & 0x03) << 6 ) +
+                    // 1111-0ttt 10uu-vvvv 10xx-xxyy 10zz-zzzz -> 0000-0000 0000-0000 00zz-zzzz
+                    ( bytes[pos + 3] & 0x3F );
+                    //                                         -> 000t-ttuu vvvv-xxxx yyzz-zzzz (1FFFFF)
+        }
+        else if ( ( ( bytes[pos] & UTF8_FIVE_BYTES_MASK ) == UTF8_FIVE_BYTES ) && 
+                ( ( bytes[pos + 1] & UTF8_TWO_BYTES ) == UTF8_MULTI_BYTES_MASK ) )
+        {
+            // Five bytes char
+            value =
+                    // 1111-10tt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz -> 0000-00tt 0000-0000 0000-0000 0000-0000
+                    ( ( bytes[pos] & 0x03) << 24 ) + 
+                    // 1111-10tt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz -> 0000-0000 uuuu-uu00 0000-0000 0000-0000
+                    ( ( bytes[pos + 1] & 0x3F) << 18 ) + 
+                    // 1111-10tt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz -> 0000-0000 0000-00vv 0000-0000 0000-0000
+                    ( ( bytes[pos + 2] & 0x30) << 12 ) + 
+                    // 1111-10tt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz -> 0000-0000 0000-0000 wwww-0000 0000-0000
+                    ( ( bytes[pos + 2] & 0x0F) << 12 ) + 
+                    // 1111-10tt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz -> 0000-0000 0000-0000 0000-xxxx 0000-0000
+                    ( ( bytes[pos + 3] & 0x3C) << 6 ) + 
+                    // 1111-10tt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz -> 0000-0000 0000-0000 0000-0000 yy00-0000
+                    ( ( bytes[pos + 3] & 0x03) << 6 ) + 
+                    // 1111-10tt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz -> 0000-0000 0000-0000 0000-0000 00zz-zzzz
+                    ( bytes[pos + 4] & 0x3F );
+                    // -> 0000-00tt uuuu-uuvv wwww-xxxx yyzz-zzzz (03 FF FF FF)
+        }
+        else if ( ( ( bytes[pos] & UTF8_FIVE_BYTES_MASK ) == UTF8_FIVE_BYTES ) &&
+                ( ( bytes[pos + 1] & UTF8_TWO_BYTES ) == UTF8_MULTI_BYTES_MASK ) &&
+                ( ( bytes[pos + 2] & UTF8_TWO_BYTES ) == UTF8_MULTI_BYTES_MASK ) )
+        {
+            // Six bytes char
+            value =
+                    // 1111-110s 10tt-tttt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz ->
+                    // 0s00-0000 0000-0000 0000-0000 0000-0000
+                    ( ( bytes[pos] & 0x01) << 30 ) + 
+                    // 1111-110s 10tt-tttt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz ->
+                    // 00tt-tttt 0000-0000 0000-0000 0000-0000
+                    ( ( bytes[pos + 1] & 0x3F) << 24 ) + 
+                    // 1111-110s 10tt-tttt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz ->
+                    // 0000-0000 uuuu-uu00 0000-0000 0000-0000
+                    ( ( bytes[pos + 2] & 0x3F) << 18 ) + 
+                    // 1111-110s 10tt-tttt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz ->
+                    // 0000-0000 0000-00vv 0000-0000 0000-0000
+                    ( ( bytes[pos + 3] & 0x30) << 12 ) + 
+                    // 1111-110s 10tt-tttt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz ->
+                    // 0000-0000 0000-0000 wwww-0000 0000-0000
+                    ( ( bytes[pos + 3] & 0x0F) << 12 ) + 
+                    // 1111-110s 10tt-tttt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz ->
+                    // 0000-0000 0000-0000 0000-xxxx 0000-0000
+                    ( ( bytes[pos + 4] & 0x3C) << 6 ) + 
+                    // 1111-110s 10tt-tttt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz ->
+                    // 0000-0000 0000-0000 0000-0000 yy00-0000
+                    ( ( bytes[pos + 4] & 0x03) << 6 ) + 
+                    // 1111-110s 10tt-tttt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz ->
+                    // 0000-0000 0000-0000 0000-0000 00zz-zzzz
+                    ( bytes[pos + 5] & 0x3F );
+                    // -> 0stt-tttt uuuu-uuvv wwww-xxxx yyzz-zzzz (7F FF FF FF)
+        } 
+        else
+        {
+            throw new UnsupportedEncodingException( "Bad UTF-8 encoding" );
+        }
+
+        // Compute the surrogates, decrementing the value by the number
+        // of chars encoded on one char (65536). The new value will then
+        // be 20 bits long max.
+        value -= 0x10000;
+        
+        // The lower value is 10 bits long
+        int lowValue = value & 0x03FF;
+        
+        // The higher value is 10 bits long
+        int highValue = value >> 10;
+        
+        chars[0] = (char)( 0xD800 & highValue );
+        chars[1] = (char)( 0xDC00 & lowValue );
+    }
+    
+    public static void decodeUTF8( char[] chars, byte[] bytes ) throws UnsupportedEncodingException
     {
-    	if ((bytes[pos] & UTF8_MULTI_BYTES_MASK) == 0)
-		{
-    		return (char)bytes[pos];
-		}
-    	else
-    	{
-    		if ((bytes[pos] & UTF8_TWO_BYTES_MASK) == UTF8_TWO_BYTES)
-    		{
-    			// Two bytes char
-    			return (char)( 
-    					( ( bytes[pos] & 0x1C ) << 6 ) + 	// 110x-xxyy 10zz-zzzz -> 0000-0xxx 0000-0000
-    					( ( bytes[pos] & 0x03 ) << 6 ) + 	// 110x-xxyy 10zz-zzzz -> 0000-0000 yy00-0000
-						( bytes[pos + 1] & 0x3F ) 		   	// 110x-xxyy 10zz-zzzz -> 0000-0000 00zz-zzzz
-						); 								//                     -> 0000-0xxx yyzz-zzzz (07FF)
-    		}
-    		else if ((bytes[pos] & UTF8_THREE_BYTES_MASK) == UTF8_THREE_BYTES)
-    		{
-    			// Three bytes char
-    			return (char)( 
-    					// 1110-tttt 10xx-xxyy 10zz-zzzz -> tttt-0000-0000-0000
-    					( ( bytes[pos] & 0x0F) << 12 ) + 	
-						// 1110-tttt 10xx-xxyy 10zz-zzzz -> 0000-xxxx-0000-0000
-    					( ( bytes[pos + 1] & 0x3C) << 6 ) + 	
-						// 1110-tttt 10xx-xxyy 10zz-zzzz -> 0000-0000-yy00-0000
-    					( ( bytes[pos + 1] & 0x03) << 6 ) + 	
-						// 1110-tttt 10xx-xxyy 10zz-zzzz -> 0000-0000-00zz-zzzz
-						( bytes[pos + 2] & 0x3F )				
-						//                               -> tttt-xxxx yyzz-zzzz (FF FF)
-						);   							 
-    		}
-    		else if ((bytes[pos] & UTF8_FOUR_BYTES_MASK) == UTF8_FOUR_BYTES)
-    		{
-    			// Four bytes char
-    			return (char)(
-    					// 1111-0ttt 10uu-vvvv 10xx-xxyy 10zz-zzzz -> 000t-tt00 0000-0000 0000-0000
-    					( ( bytes[pos] & 0x07) << 18 ) +
-						// 1111-0ttt 10uu-vvvv 10xx-xxyy 10zz-zzzz -> 0000-00uu 0000-0000 0000-0000
-    					( ( bytes[pos + 1] & 0x30) << 16 ) + 
-						// 1111-0ttt 10uu-vvvv 10xx-xxyy 10zz-zzzz -> 0000-0000 vvvv-0000 0000-0000
-    					( ( bytes[pos + 1] & 0x0F) << 12 ) + 
-						// 1111-0ttt 10uu-vvvv 10xx-xxyy 10zz-zzzz -> 0000-0000 0000-xxxx 0000-0000
-    					( ( bytes[pos + 2] & 0x3C) << 6 ) + 
-						// 1111-0ttt 10uu-vvvv 10xx-xxyy 10zz-zzzz -> 0000-0000 0000-0000 yy00-0000
-    					( ( bytes[pos + 2] & 0x03) << 6 ) +
-						// 1111-0ttt 10uu-vvvv 10xx-xxyy 10zz-zzzz -> 0000-0000 0000-0000 00zz-zzzz
-						( bytes[pos + 3] & 0x3F )
-						//                                         -> 000t-ttuu vvvv-xxxx yyzz-zzzz (1FFFFF)
-						);   
-    		}
-    		else if ((bytes[pos] & UTF8_FIVE_BYTES_MASK) == UTF8_FIVE_BYTES)
-    		{
-    			// Five bytes char
-    			return (char)( 
-    					// 1111-10tt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz -> 0000-00tt 0000-0000 0000-0000 0000-0000
-    					( ( bytes[pos] & 0x03) << 24 ) + 
-    					// 1111-10tt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz -> 0000-0000 uuuu-uu00 0000-0000 0000-0000
-    					( ( bytes[pos + 1] & 0x3F) << 18 ) + 
-    					// 1111-10tt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz -> 0000-0000 0000-00vv 0000-0000 0000-0000
-    					( ( bytes[pos + 2] & 0x30) << 12 ) + 
-    					// 1111-10tt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz -> 0000-0000 0000-0000 wwww-0000 0000-0000
-    					( ( bytes[pos + 2] & 0x0F) << 12 ) + 
-    					// 1111-10tt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz -> 0000-0000 0000-0000 0000-xxxx 0000-0000
-    					( ( bytes[pos + 3] & 0x3C) << 6 ) + 
-    					// 1111-10tt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz -> 0000-0000 0000-0000 0000-0000 yy00-0000
-    					( ( bytes[pos + 3] & 0x03) << 6 ) + 
-						// 1111-10tt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz -> 0000-0000 0000-0000 0000-0000 00zz-zzzz
-						( bytes[pos + 4] & 0x3F )
-						// -> 0000-00tt uuuu-uuvv wwww-xxxx yyzz-zzzz (03 FF FF FF)
-						);   
-    		}
-    		else if ((bytes[pos] & UTF8_FIVE_BYTES_MASK) == UTF8_FIVE_BYTES)
-    		{
-    			// Six bytes char
-    			return (char)( 
-    			        // 1111-110s 10tt-tttt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz ->
-    			        // 0s00-0000 0000-0000 0000-0000 0000-0000
-    					( ( bytes[pos] & 0x01) << 30 ) + 
-    			        // 1111-110s 10tt-tttt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz ->
-    			        // 00tt-tttt 0000-0000 0000-0000 0000-0000
-    					( ( bytes[pos + 1] & 0x3F) << 24 ) + 
-    			        // 1111-110s 10tt-tttt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz ->
-    			        // 0000-0000 uuuu-uu00 0000-0000 0000-0000
-    					( ( bytes[pos + 2] & 0x3F) << 18 ) + 
-    			        // 1111-110s 10tt-tttt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz ->
-    			        // 0000-0000 0000-00vv 0000-0000 0000-0000
-    					( ( bytes[pos + 3] & 0x30) << 12 ) + 
-    			        // 1111-110s 10tt-tttt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz ->
-    			        // 0000-0000 0000-0000 wwww-0000 0000-0000
-    					( ( bytes[pos + 3] & 0x0F) << 12 ) + 
-    			        // 1111-110s 10tt-tttt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz ->
-    					// 0000-0000 0000-0000 0000-xxxx 0000-0000
-    					( ( bytes[pos + 4] & 0x3C) << 6 ) + 
-    			        // 1111-110s 10tt-tttt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz ->
-    					// 0000-0000 0000-0000 0000-0000 yy00-0000
-    					( ( bytes[pos + 4] & 0x03) << 6 ) + 
-    			        // 1111-110s 10tt-tttt 10uu-uuuu 10vv-wwww 10xx-xxyy 10zz-zzzz ->
-    					// 0000-0000 0000-0000 0000-0000 00zz-zzzz
-						( bytes[pos + 5] & 0x3F )
-    			        // -> 0stt-tttt uuuu-uuvv wwww-xxxx yyzz-zzzz (7F FF FF FF)
-						);   
-    		} 
-    		else
-    		{
-    		    return (char)-1;
-    		}
-    	}
+        int pos = 0;
+        char[] twoChars = new char[2];
+        int nbBytes = 0;
+        
+        for ( int i = 0; i < bytes.length; i+= nbBytes )
+        {
+            nbBytes = countBytesPerChar( bytes, i );
+            
+            if ( nbBytes < 4 )
+            {
+                chars[pos] = bytesToChar( bytes, i );
+                pos++;
+            }
+            else
+            {
+                bytesToTwoChars( bytes, i, twoChars );
+                chars[pos++] = twoChars[0];
+                chars[pos++] = twoChars[1];
+            }
+        }
+        
+    }
+    
+    /**
+     * Return the bytes that hold an Unicode char.
+     * 
+     * The result is stored in the given byte[], starting at position pos.
+     * If the byte[] is not large enough to store the result, a runtime
+     * exception will be generated. It is the caller responsability to
+     * provide a byte[] that can store up to 6 bytes.
+     *
+     * @param car The character to be decoded
+     * @param bytes The byte[] where to store the result 
+     * @param pos The position where to store the result in the byte[] 
+     * @return The current position in the byte[].
+     * 
+     * TODO : Should stop after the third byte, as a char is only 2 bytes long.
+     */
+    public static int charToBytes(char car, byte[] bytes, int pos)
+    {
+        if ( ( car & CHAR_ONE_BYTE_MASK ) == 0 )
+        {
+            bytes[ pos++ ] = (byte)( car & CHAR_ONE_BYTE );
+            return pos;
+        }
+        else
+        {
+            if ( ( car & CHAR_TWO_BYTES_MASK ) == 0 )
+            {
+                // Two bytes char
+                // 0000-0xxx yyzz-zzzz -> 110x xxyy
+                bytes[ pos++ ] = (byte)( 0x00C0 | ( ( car & 0x07C0 ) >> 6 ) );
+                // 0000-0xxx yyzz-zzzz -> 10zz zzzz
+                bytes[ pos++ ] = (byte)( 0x0080 | ( car & 0x003F ) ); 
+
+                return pos;
+            }
+            else if ( ( car & CHAR_THREE_BYTES_MASK ) == 0 )
+            {
+                // Three bytes char
+                // tttt-0000-0000-0000 -> 1110-tttt
+                bytes[ pos++ ] = (byte)( 0x00E0 | ( ( car & 0xF000 ) >> 12 ) );
+                // 0000-xxxx-yy00-0000 -> 10xx-xxyy
+                bytes[ pos++ ] = (byte)( 0x0080 | ( ( car & 0x0FC0 ) >> 6 ) ); 
+                // 0000-0000-00zz-zzzz -> 10zz zzzz
+                bytes[ pos++ ] = (byte)( 0x0080 | ( car & 0x003F ) ); 
+
+                return pos;
+            }
+            else if ( ( car & CHAR_FOUR_BYTES_MASK ) == 0 )
+            {
+                // Four bytes char
+                // 000t-tt00 0000-0000 0000-0000 -> 1111-0ttt
+                bytes[ pos++ ] = (byte)( 0x00F8 | ( ( car & 0x1C0000 ) >> 18 ) );
+                // 0000-00uu vvvv-0000 0000-0000 -> 10uu-vvvv
+                bytes[ pos++ ] = (byte)( 0x0080 | ( ( car & 0x3F000 ) >> 12 ) ); 
+                // 0000-0000 0000-xxxx yy00-0000 -> 10xx xxyy
+                bytes[ pos++ ] = (byte)( 0x0080 | ( car & 0xFC0 ) >> 6); 
+                // 0000-0000 0000-0000 00zz-zzzz -> 10zz zzzz
+                bytes[ pos++ ] = (byte)( 0x0080 | ( car & 0x3F ) ); 
+
+                return pos;
+            }
+            else if ( ( car & CHAR_FIVE_BYTES_MASK ) == 0 )
+            {
+                // Five bytes char
+                // 0000-00tt 0000-0000 0000-0000 0000-0000 -> 1111-10tt
+                bytes[ pos++ ] = (byte)( 0x00FC | ( ( car & 0x03000000 ) >> 24 ) );
+                // 0000-0000 uuuu-uu00 0000-0000 0000-0000 -> 10uu-uuuu
+                bytes[ pos++ ] = (byte)( 0x0080 | ( ( car & 0xFC0000 ) >> 18 ) ); 
+                // 0000-0000 0000-00vv wwww-0000 0000-0000 -> 10vv wwww
+                bytes[ pos++ ] = (byte)( 0x0080 | ( car & 0x3F000 ) >> 12); 
+                // 0000-0000 0000-0000 0000-xxxx yy00-0000 -> 10xx xxyy
+                bytes[ pos++ ] = (byte)( 0x0080 | ( car & 0xFC0 ) >> 6); 
+                // 0000-0000 0000-0000 0000-0000 00zz-zzzz -> 10zz zzzz
+                bytes[ pos++ ] = (byte)( 0x0080 | ( car & 0x3F ) ); 
+
+                return pos;
+            }
+            else if ( ( car & CHAR_SIX_BYTES_MASK ) == 0 )
+            {
+                // Six bytes char
+                // 0s00-0000 0000-0000 0000-0000 0000-0000 -> 1111-110s
+                bytes[ pos++ ] = (byte)( 0x00FC | ( ( car & 0x40000000 ) >> 30 ) );
+                // 00tt-tttt 0000-0000 0000-0000 0000-0000 -> 10tt-tttt
+                bytes[ pos++ ] = (byte)( 0x0080 | ( ( car & 0x3F000000 ) >> 24 ) ); 
+                // 0000-0000 uuuu-uu00 0000-0000 0000-0000 -> 10uu uuuu
+                bytes[ pos++ ] = (byte)( 0x0080 | ( car & 0xFC0000 ) >> 18); 
+                // 0000-0000 0000-00vv wwww-0000 0000-0000 -> 10vv wwww
+                bytes[ pos++ ] = (byte)( 0x0080 | ( car & 0x3F000 ) >> 12); 
+                // 0000-0000 0000-0000 0000-xxxx yy00-0000 -> 10xx xxyy
+                bytes[ pos++ ] = (byte)( 0x0080 | ( car & 0xFC0 ) >> 6); 
+                // 0000-0000 0000-0000 0000-0000 00zz-zzzz -> 10zz zzzz
+                bytes[ pos++ ] = (byte)( 0x0080 | ( car & 0x3F ) ); 
+
+                return pos;
+            } 
+            else
+            {
+                return -1;
+            }
+        }
     }
     
     /**
@@ -316,15 +487,26 @@
      * @param bytes The byte array to decode
      * @return The number of char in the byte array
      */
-    public static int countChars(byte[] bytes)
+    public static int countChars(byte[] bytes) throws UnsupportedEncodingException
     {
         int nbChars = 0;
         int currentPos = 0;
         
         while (currentPos < bytes.length)
         {
-            currentPos += countBytesPerChar(bytes, currentPos);
-            nbChars ++;
+            int nbBytes = countBytesPerChar(bytes, currentPos);
+            
+            currentPos += nbBytes;
+
+            if ( currentPos > bytes.length )
+            {
+                throw new UnsupportedEncodingException( "Byte array too short to be decoded" );
+            }
+            
+            
+            // Ig the number of bytes necessary to encode a character is
+            // above 3, we will need two UTF-16 chars
+            nbChars += ( nbBytes > 3 ? 2 : 1 );
         }
 
         return nbChars;
@@ -339,18 +521,49 @@
      *
      * @return <code>true</code> if the buffer contains the text.
      */
-    public static int areEquals( byte[] byteArray, int index, String text )
+    public static int areEquals( char[] chars, int index, String text )
     {
-        if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( byteArray.length <= index ) ||
+        if ( ( chars == null ) || ( chars.length == 0 ) || ( chars.length <= index ) ||
                 ( index < 0 ) || ( text == null ) )
         {
             return -1;
         }
         else
         {
-            byte[] data = text.getBytes();
+            char[] data = text.toCharArray();
 
-            return areEquals( byteArray, index, data );
+            return areEquals( chars, index, data );
+        }
+    }
+
+    /**
+     * Check if a text is present at the current position in a buffer.
+     *
+     * @param byteArray The buffer which contains the data
+     * @param index Current position in the buffer
+     * @param text The text we want to check
+     *
+     * @return <code>true</code> if the buffer contains the text.
+     */
+    public static int areEquals( byte[] bytes, int index, String text )
+    {
+        if ( ( bytes == null ) || ( bytes.length == 0 ) || ( bytes.length <= index ) ||
+                ( index < 0 ) || ( text == null ) )
+        {
+            return -1;
+        }
+        else
+        {
+            try
+            {
+                byte[] data = text.getBytes( "UTF-8" );
+
+                return areEquals( bytes, index, data );
+            }
+            catch ( UnsupportedEncodingException uee )
+            {
+                return -1;
+            }
         }
     }
 
@@ -428,26 +641,48 @@
 
     /**
      * Test if the current character is equal to a specific character.
+     * 
+     *
+     * @param byteArray The buffer which contains the data
+     * @param index Current position in the buffer
+     * @param car The character we want to compare with the current buffer position
+     *
+     * @return <code>true</code> if the current character equals the given character.
+     */
+    public static boolean isCharASCII( char[] chars, int index, char car )
+    {
+        if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) ||
+                ( index >= chars.length ) )
+        {
+            return false;
+        }
+        else
+        {
+            return ( ( chars[index] == car ) ? true : false );
+        }
+    }
+
+    /**
+     * Test if the current character is equal to a specific character.
      * This function works only for character between 0 and 127, as it
      * does compare a byte and a char (which is 16 bits wide)
      * 
-     *
      * @param byteArray The buffer which contains the data
      * @param index Current position in the buffer
      * @param car The character we want to compare with the current buffer position
      *
      * @return <code>true</code> if the current character equals the given character.
      */
-    public static boolean isCharASCII( byte[] byteArray, int index, char car )
+    public static boolean isCharASCII( byte[] bytes, int index, char car )
     {
-        if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( index < 0 ) ||
-                ( index >= byteArray.length ) )
+        if ( ( bytes == null ) || ( bytes.length == 0 ) || ( index < 0 ) ||
+                ( index >= bytes.length ) )
         {
             return false;
         }
         else
         {
-            return ( ( byteArray[index] == car ) ? true : false );
+            return ( ( bytes[index] == car ) ? true : false );
         }
     }
 
@@ -460,16 +695,47 @@
      *
      * @return <code>true</code> if the current character is a Hex Char
      */
-    public static boolean isHex( byte[] byteArray, int index )
+    public static boolean isHex( char[] chars, int index )
     {
-        if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( index < 0 ) ||
-                ( index >= byteArray.length ) )
+        if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) ||
+                ( index >= chars.length ) )
         {
             return false;
         }
         else
         {
-            byte c = byteArray[index];
+            char c = chars[index];
+
+            if ( ( c > 127 ) || ( StringUtils.HEX[c] == false ) )
+            {
+                return false;
+            }
+            else
+            {
+                return true;
+            }
+        }
+    }
+
+    /**
+     * Check if the current character is an Hex Char
+     *  <hex>    ::= [0x30-0x39] | [0x41-0x46] | [0x61-0x66]
+     * 
+     * @param byteArray The buffer which contains the data
+     * @param index Current position in the buffer
+     *
+     * @return <code>true</code> if the current character is a Hex Char
+     */
+    public static boolean isHex( byte[] bytes, int index )
+    {
+        if ( ( bytes == null ) || ( bytes.length == 0 ) || ( index < 0 ) ||
+                ( index >= bytes.length ) )
+        {
+            return false;
+        }
+        else
+        {
+            byte c = bytes[index];
 
             if ( ( c > 127 ) || ( StringUtils.HEX[c] == false ) )
             {
@@ -490,15 +756,35 @@
      *
      * @return <code>true</code> if the current character is a Digit
      */
-    public static boolean isDigit( byte[] byteArray )
+    public static boolean isDigit( char[] chars )
     {
-        if ( ( byteArray == null ) || ( byteArray.length == 0 ) )
+        if ( ( chars == null ) || ( chars.length == 0 ) )
         {
             return false;
         }
         else
         {
-            return ( ( ( byteArray[0] > 127 ) || ! StringUtils.DIGIT[byteArray[0]] ) ? false : true );
+            return ( ( ( chars[0] > 127 ) || ! StringUtils.DIGIT[chars[0]] ) ? false : true );
+        }
+    }
+
+    /**
+     * Test if the current character is a digit
+     * <digit>    ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
+     *
+     * @param bytes The buffer which contains the data
+     *
+     * @return <code>true</code> if the current character is a Digit
+     */
+    public static boolean isDigit( byte[] bytes )
+    {
+        if ( ( bytes == null ) || ( bytes.length == 0 ) )
+        {
+            return false;
+        }
+        else
+        {
+            return ( ( ( bytes[0] > 127 ) || ! StringUtils.DIGIT[bytes[0]] ) ? false : true );
         }
     }
 
@@ -506,21 +792,52 @@
      * Test if the current character is an Alpha character :
      *  <alpha>    ::= [0x41-0x5A] | [0x61-0x7A]
      * 
-     * @param byteArray The buffer which contains the data
+     * @param chars The buffer which contains the data
      * @param index Current position in the buffer
      *
      * @return <code>true</code> if the current character is an Alpha character
      */
-    public static boolean isAlphaASCII( byte[] byteArray, int index )
+    public static boolean isAlphaASCII( char[] chars, int index )
     {
-        if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( index < 0 ) ||
-                ( index >= byteArray.length ) )
+        if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) ||
+                ( index >= chars.length ) )
         {
             return false;
         }
         else
         {
-            byte c = byteArray[index++];
+            char c = chars[index++];
+
+            if ( ( c > 127 ) || ( StringUtils.ALPHA[c] == false ) )
+            {
+                return false;
+            }
+            else
+            {
+                return true;
+            }
+        }
+    }
+
+    /**
+     * Test if the current character is an Alpha character :
+     *  <alpha>    ::= [0x41-0x5A] | [0x61-0x7A]
+     * 
+     * @param chars The buffer which contains the data
+     * @param index Current position in the buffer
+     *
+     * @return <code>true</code> if the current character is an Alpha character
+     */
+    public static boolean isAlphaASCII( byte[] bytes, int index )
+    {
+        if ( ( bytes == null ) || ( bytes.length == 0 ) || ( index < 0 ) ||
+                ( index >= bytes.length ) )
+        {
+            return false;
+        }
+        else
+        {
+            byte c = bytes[index++];
 
             if ( ( c > 127 ) || ( StringUtils.ALPHA[c] == false ) )
             {
@@ -542,16 +859,38 @@
      *
      * @return <code>true</code> if the current character is a Digit
      */
-    public static boolean isDigit( byte[] byteArray, int index )
+    public static boolean isDigit( char[] chars, int index )
+    {
+        if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) ||
+                ( index >= chars.length ) )
+        {
+            return false;
+        }
+        else
+        {
+            return ( ( ( chars[index] > 127 ) || ! StringUtils.DIGIT[chars[index]] ) ? false : true );
+        }
+    }
+
+    /**
+     * Test if the current character is a digit
+     * <digit>    ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
+     *
+     * @param bytes The buffer which contains the data
+     * @param index Current position in the buffer
+     *
+     * @return <code>true</code> if the current character is a Digit
+     */
+    public static boolean isDigit( byte[] bytes, int index )
     {
-        if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( index < 0 ) ||
-                ( index >= byteArray.length ) )
+        if ( ( bytes == null ) || ( bytes.length == 0 ) || ( index < 0 ) ||
+                ( index >= bytes.length ) )
         {
             return false;
         }
         else
         {
-            return ( ( ( byteArray[index] > 127 ) || ! StringUtils.DIGIT[byteArray[index]] ) ? false : true );
+            return ( ( ( bytes[index] > 127 ) || ! StringUtils.DIGIT[bytes[index]] ) ? false : true );
         }
     }
 
@@ -564,16 +903,16 @@
      *
      * @return The position of the next character, if the current one is a CHAR.
      */
-    public static boolean isAlphaDigitMinus( byte[] byteArray, int index )
+    public static boolean isAlphaDigitMinus( char[] chars, int index )
     {
-        if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( index < 0 ) ||
-                ( index >= byteArray.length ) )
+        if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) ||
+                ( index >= chars.length ) )
         {
             return false;
         }
         else
         {
-            byte c = byteArray[index++];
+            char c = chars[index++];
 
             if ( ( c > 127 ) || ( StringUtils.CHAR[c] == false ) )
             {
@@ -585,6 +924,333 @@
             }
         }
     }
+    
+    /**
+     * Check if the current character is an 7 bits ASCII CHAR (between 0 and 127).
+     *   <char>    ::= <alpha> | <digit> | '-'
+     *
+     * @param byteArray The buffer which contains the data
+     * @param index Current position in the buffer
+     *
+     * @return The position of the next character, if the current one is a CHAR.
+     */
+    public static boolean isAlphaDigitMinus( byte[] bytes, int index )
+    {
+        if ( ( bytes == null ) || ( bytes.length == 0 ) || ( index < 0 ) ||
+                ( index >= bytes.length ) )
+        {
+            return false;
+        }
+        else
+        {
+            byte c = bytes[index++];
 
+            if ( ( c > 127 ) || ( StringUtils.CHAR[c] == false ) )
+            {
+                return false;
+            }
+            else
+            {
+                return true;
+            }
+        }
+    }
     
+    // The following methods are taken from org.apache.commons.lang.StringUtils
+    
+    /**
+     * The empty String <code>""</code>.
+     * @since 2.0
+     */
+    public static final String EMPTY = "";
+
+    // Empty checks
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Checks if a String is empty ("") or null.</p>
+     *
+     * <pre>
+     * StringUtils.isEmpty(null)      = true
+     * StringUtils.isEmpty("")        = true
+     * StringUtils.isEmpty(" ")       = false
+     * StringUtils.isEmpty("bob")     = false
+     * StringUtils.isEmpty("  bob  ") = false
+     * </pre>
+     *
+     * <p>NOTE: This method changed in Lang version 2.0.
+     * It no longer trims the String.
+     * That functionality is available in isBlank().</p>
+     *
+     * @param str  the String to check, may be null
+     * @return <code>true</code> if the String is empty or null
+     */
+    public static boolean isEmpty(String str) {
+        return str == null || str.length() == 0;
+    }
+
+    /**
+     * <p>Checks if a String is not empty ("") and not null.</p>
+     *
+     * <pre>
+     * StringUtils.isNotEmpty(null)      = false
+     * StringUtils.isNotEmpty("")        = false
+     * StringUtils.isNotEmpty(" ")       = true
+     * StringUtils.isNotEmpty("bob")     = true
+     * StringUtils.isNotEmpty("  bob  ") = true
+     * </pre>
+     *
+     * @param str  the String to check, may be null
+     * @return <code>true</code> if the String is not empty and not null
+     */
+    public static boolean isNotEmpty(String str) {
+        return str != null && str.length() > 0;
+    }
+
+    /**
+     * <p>Removes spaces (char &lt;= 32) from both start and
+     * ends of this String, handling <code>null</code> by returning
+     * <code>null</code>.</p>
+     *
+     * Trim removes start and end characters &lt;= 32.
+     *
+     * <pre>
+     * StringUtils.trim(null)          = null
+     * StringUtils.trim("")            = ""
+     * StringUtils.trim("     ")       = ""
+     * StringUtils.trim("abc")         = "abc"
+     * StringUtils.trim("    abc    ") = "abc"
+     * </pre>
+     *
+     * @param str  the String to be trimmed, may be null
+     * @return the trimmed string, <code>null</code> if null String input
+     */
+    public static String trim(String str) {
+        if ( isEmpty( str ) )
+        {
+            return str;
+        }
+        
+        char[] array = str.toCharArray();
+        int start = 0;
+        int end = array.length;
+        
+        while ( ( start < end ) && ( array[start] == ' ' ) )
+        {
+            start++;
+        }
+        
+        while ( ( end > start ) && ( array[end - 1] == ' ' ) )
+        {
+            end--;
+        }
+        
+        return new String( array, start, ( end - start ) );
+    }
+
+    /**
+     * <p>Removes spaces (char &lt;= 32) from start
+     * of this String, handling <code>null</code> by returning
+     * <code>null</code>.</p>
+     *
+     * Trim removes start characters &lt;= 32.
+     *
+     * <pre>
+     * StringUtils.trim(null)          = null
+     * StringUtils.trim("")            = ""
+     * StringUtils.trim("     ")       = ""
+     * StringUtils.trim("abc")         = "abc"
+     * StringUtils.trim("    abc    ") = "abc    "
+     * </pre>
+     *
+     * @param str  the String to be trimmed, may be null
+     * @return the trimmed string, <code>null</code> if null String input
+     */
+    public static String trimLeft( String str ) {
+        if ( isEmpty( str ) )
+        {
+            return str;
+        }
+        
+        char[] array = str.toCharArray();
+        int end = array.length;
+        
+        while ( ( end > 0 ) && ( array[end - 1] == ' ' ) )
+        {
+            end--;
+        }
+        
+        return new String( array, 0, end );
+    }
+
+    /**
+     * <p>Removes spaces (char &lt;= 32) from end
+     * of this String, handling <code>null</code> by returning
+     * <code>null</code>.</p>
+     *
+     * Trim removes start characters &lt;= 32.
+     *
+     * <pre>
+     * StringUtils.trim(null)          = null
+     * StringUtils.trim("")            = ""
+     * StringUtils.trim("     ")       = ""
+     * StringUtils.trim("abc")         = "abc"
+     * StringUtils.trim("    abc    ") = "    abc"
+     * </pre>
+     *
+     * @param str  the String to be trimmed, may be null
+     * @return the trimmed string, <code>null</code> if null String input
+     */
+    public static String trimRight( String str ) {
+        if ( isEmpty( str ) )
+        {
+            return str;
+        }
+        
+        char[] array = str.toCharArray();
+        int start = 0;
+        int end = array.length;
+        
+        while ( ( start < end ) && ( array[start] == ' ' ) )
+        {
+            start++;
+        }
+        
+        return new String( array, start, ( end - start ) );
+    }
+
+    /**
+     * <p>Removes spaces (char &lt;= 32) from start
+     * of this array, handling <code>null</code> by returning
+     * <code>null</code>.</p>
+     *
+     * Trim removes start characters &lt;= 32.
+     *
+     * <pre>
+     * StringUtils.trim(null)          = null
+     * StringUtils.trim("")            = ""
+     * StringUtils.trim("     ")       = ""
+     * StringUtils.trim("abc")         = "abc"
+     * StringUtils.trim("    abc    ") = "abc    "
+     * </pre>
+     *
+     * @param chars  the chars array to be trimmed, may be null
+     * @return the position of the first char which is not a space,
+     * or the last position of the array.
+     */
+    public static int trimLeft( char[] chars, int pos ) {
+        if ( chars == null )
+        {
+            return pos;
+        }
+        
+        while ( ( pos < chars.length ) && ( chars[pos] == ' ' ) )
+        {
+            pos++;
+        }
+        
+        return pos;
+    }
+
+    /**
+     * <p>Removes spaces (char &lt;= 32) from start
+     * of this array, handling <code>null</code> by returning
+     * <code>null</code>.</p>
+     *
+     * Trim removes start characters &lt;= 32.
+     *
+     * <pre>
+     * StringUtils.trim(null)          = null
+     * StringUtils.trim("")            = ""
+     * StringUtils.trim("     ")       = ""
+     * StringUtils.trim("abc")         = "abc"
+     * StringUtils.trim("    abc    ") = "abc    "
+     * </pre>
+     *
+     * @param bytes  the byte array to be trimmed, may be null
+     * @return the position of the first byte which is not a space,
+     * or the last position of the array.
+     */
+    public static int trimLeft( byte[] bytes, int pos ) {
+        if ( bytes == null )
+        {
+            return pos;
+        }
+        
+        while ( ( pos < bytes.length ) && ( bytes[pos] == ' ' ) )
+        {
+            pos++;
+        }
+        
+        return pos;
+    }
+
+    // Case conversion
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Converts a String to upper case as per {@link String#toUpperCase()}.</p>
+     *
+     * <p>A <code>null</code> input String returns <code>null</code>.</p>
+     *
+     * <pre>
+     * StringUtils.upperCase(null)  = null
+     * StringUtils.upperCase("")    = ""
+     * StringUtils.upperCase("aBc") = "ABC"
+     * </pre>
+     *
+     * @param str  the String to upper case, may be null
+     * @return the upper cased String, <code>null</code> if null String input
+     */
+    public static String upperCase(String str) {
+        if (str == null) {
+            return null;
+        }
+        return str.toUpperCase();
+    }
+
+    /**
+     * <p>Converts a String to lower case as per {@link String#toLowerCase()}.</p>
+     *
+     * <p>A <code>null</code> input String returns <code>null</code>.</p>
+     *
+     * <pre>
+     * StringUtils.lowerCase(null)  = null
+     * StringUtils.lowerCase("")    = ""
+     * StringUtils.lowerCase("aBc") = "abc"
+     * </pre>
+     *
+     * @param str  the String to lower case, may be null
+     * @return the lower cased String, <code>null</code> if null String input
+     */
+    public static String lowerCase(String str) {
+        if (str == null) {
+            return null;
+        }
+        return str.toLowerCase();
+    }
+
+    // Equals
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Compares two Strings, returning <code>true</code> if they are equal.</p>
+     *
+     * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
+     * references are considered to be equal. The comparison is case sensitive.</p>
+     *
+     * <pre>
+     * StringUtils.equals(null, null)   = true
+     * StringUtils.equals(null, "abc")  = false
+     * StringUtils.equals("abc", null)  = false
+     * StringUtils.equals("abc", "abc") = true
+     * StringUtils.equals("abc", "ABC") = false
+     * </pre>
+     *
+     * @see java.lang.String#equals(Object)
+     * @param str1  the first String, may be null
+     * @param str2  the second String, may be null
+     * @return <code>true</code> if the Strings are equal, case sensitive, or
+     *  both <code>null</code>
+     */
+    public static boolean equals(String str1, String str2) {
+        return str1 == null ? str2 == null : str1.equals(str2);
+    }
 }



Mime
View raw message