You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2005/09/27 08:52:00 UTC

svn commit: r291832 - in /directory/asn1/branches/asn1-NameComponent/ber-new/src: java/main/org/apache/asn1new/util/MutableString.java java/main/org/apache/asn1new/util/StringUtils.java test/org/apache/asn1new/util/MutableStringTest.java

Author: elecharny
Date: Mon Sep 26 23:51:51 2005
New Revision: 291832

URL: http://svn.apache.org/viewcvs?rev=291832&view=rev
Log:
- Fixed some bugs in MutableString and StringUtils
- Added some methods
- Added some tests

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
    directory/asn1/branches/asn1-NameComponent/ber-new/src/test/org/apache/asn1new/util/MutableStringTest.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=291832&r1=291831&r2=291832&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 Mon Sep 26 23:51:51 2005
@@ -30,8 +30,7 @@
     /** We also store the byte array for performance sake */
     private byte[] data;
     
-    /** Actual length of the string. Be aware that it's a number of bytes,
-     * not a number of chars ! */
+    /** Actual length of the string. Be aware that it's a number of chars */
     private int length;
     
     /** A null MutableString */
@@ -85,7 +84,33 @@
      */
     public MutableString(byte[] bytes) throws UnsupportedEncodingException
     {
-        setData( bytes );
+        setData( bytes, 0, bytes.length );
+    }
+    
+    /**
+     * Creates a MutableString with a value. The stored string
+     * is coded in Unicode, so the bytes *MUST* be valid !
+     *  
+     * @param bytes The value to store.
+     * @param start The position of the first byte to copy
+     * @param length The number of bytes to copy 
+     */
+    public MutableString(byte[] bytes, int start, int length) throws UnsupportedEncodingException
+    {
+        setData( bytes, start, length );
+    }
+    
+    /**
+     * Creates a MutableString with a value. The stored string
+     * is coded in Unicode, so the bytes *MUST* be valid !
+     *  
+     * @param chars The value to store.
+     * @param start The position of the first byte to copy
+     * @param length The number of bytes to copy 
+     */
+    public MutableString(char[] chars, int start, int length) throws UnsupportedEncodingException
+    {
+        setData( chars, start, length );
     }
     
     /**
@@ -94,10 +119,10 @@
      * 
      * @param bytes The string to store
      */
-    public void setData(byte[] bytes) throws UnsupportedEncodingException
+    public void setData(byte[] bytes, int start, int length) throws UnsupportedEncodingException
     {
-        data = bytes;
-        length = bytes.length;
+        data = new byte[length];
+        System.arraycopy( bytes, start, data, 0, length );
         int charLength = StringUtils.countChars(bytes);
         
         if ( charLength == StringUtils.BAD_CHAR_ENCODING )
@@ -106,11 +131,29 @@
         }
         
         string = new char[charLength];
+        this.length = charLength;
         
         StringUtils.decodeUTF8( string, bytes );
     }
     
     /**
+     * Set a new string in the MutableString. It will replace the old string,
+     * and reset the current length with the new one.
+     * 
+     * @param bytes The string to store
+     */
+    public void setData(char[] chars, int start, int length) throws UnsupportedEncodingException
+    {
+        string = new char[length];
+        System.arraycopy( chars, start, string, 0, length );
+        this.length = length;
+        
+        data = new byte[ StringUtils.countBytes( chars ) ];
+        
+        StringUtils.decodeUTF8( data, chars );
+    }
+    
+    /**
      * Store the char[] as a byte[]. The bye[] is supposed to be large enough to store the result.
      * 
      * @param string The char[] to transform
@@ -141,13 +184,88 @@
     {
         return data;
     }
+    
+    /**
+     * Test if the MutableString is null or empty
+     * @param str The MutableString to test
+     * @return <code>true</code> if the MutableString is null or empty
+     */
+    public static boolean isEmpty( MutableString str ) 
+    {
+        return ( str == null ) || ( str.length == 0 );
+    }
+
+    /**
+     * Test if the MutableString is not null or empty
+     * @param str The MutableString to test
+     * @return <code>true</code> if the MutableString is notnull and not empty
+     */
+    public static boolean isNotEmpty( MutableString str ) 
+    {
+        return ( str != null ) && ( str.length == 0 );
+    }
+    
+    /**
+     * Append a MutableString to the current MutableString
+     * 
+     * @param str The MutableString to append
+     * @return The result of the appending
+     */
+    public MutableString append( MutableString str )
+    {
+        if ( str.length == 0 )
+        {
+            return this;
+        }
+        
+        if (length == 0)
+        {
+            string = new char[ str.length ];
+            data = new byte[ str.data.length ];
+            System.arraycopy( str.string, 0, string, length, str.length );
+            System.arraycopy( str.data, 0, data, 0, str.data.length );
+            length = str.length;
+        }
+        else
+        {
+            int newLength = length + str.length;
+            
+            // Copy the chars
+            char[] newString = new char[ newLength ];
+            System.arraycopy( string, 0, newString, 0, length );
+            System.arraycopy( str.string, 0, newString, length, str.length );
+            string = newString;
+
+            // Copy the bytes
+            byte[] newData = new byte[ data.length + str.data.length ];
+            System.arraycopy( data, 0, newData, 0, data.length );
+            System.arraycopy( str.data, 0, newData, data.length, str.data.length );
+            data = newData;
+
+            // Set the length
+            length = newLength;
+        }
+        
+        return str;
+    }
+
+    /**
+     * Append a String to the current MutableString
+     * 
+     * @param str The String to append
+     * @return The result of the appending
+     */
+    public MutableString append( String str ) throws UnsupportedEncodingException
+    {
+        return append( new MutableString( str ) );
+    }
 
     /**
      * Trim the String to suppress leading and trailing spaces, if any.
      * 
      * @return The new trimmed MutableString
      */
-    public MutableString trim() throws UnsupportedEncodingException
+    public MutableString trim()
     {
         int start = 0;
         int end = length - 1;
@@ -180,13 +298,40 @@
         }
         
         int newLength = end - start + 1;
+        
+        // Don't need to compute the number of bytes, as white spaces
+        // are encoded on one byte.
         byte[] newData = new byte[ newLength ];
         
         System.arraycopy(data, start, newData, 0, newLength );
+        data = newData;
+
+        // Copy the string
+        char[] newString = new char[ newLength ];
+        System.arraycopy( string, start, newString, 0, newLength );
+        string = newString;
         
-        MutableString newString = new MutableString( newData );
+        length = newLength;
         
-        return newString;
+        return this;
+    }
+    
+    /**
+     * Trim the String to suppress leading and trailing spaces, if any.
+     * 
+     * @param the MutableString to trim
+     * @return The new trimmed MutableString
+     */
+    public static MutableString trim( MutableString str )
+    {
+        if ( isNotEmpty( str ) )
+        {
+            return str.trim();
+        }
+        else
+        {
+            return str;
+        }
     }
     
     /**
@@ -216,13 +361,22 @@
         }
         
         int newLength = length - start;
+        
+        // Don't need to compute the number of bytes, as white spaces
+        // are encoded on one byte.
         byte[] newData = new byte[ newLength ];
         
         System.arraycopy(data, start, newData, 0, newLength );
+        data = newData;
+
+        // Copy the string
+        char[] newString = new char[ newLength ];
+        System.arraycopy( string, start, newString, 0, newLength );
+        string = newString;
         
-        MutableString newString = new MutableString( newData );
+        length = newLength;
         
-        return newString;
+        return this;
     }
     
     /**
@@ -252,13 +406,22 @@
         }
         
         int newLength = end + 1;
+        
+        // Don't need to compute the number of bytes, as white spaces
+        // are encoded on one byte.
         byte[] newData = new byte[ newLength ];
         
         System.arraycopy(data, 0, newData, 0, newLength );
+        data = newData;
+
+        // Copy the string
+        char[] newString = new char[ newLength ];
+        System.arraycopy( string, 0, newString, 0, newLength );
+        string = newString;
         
-        MutableString newString = new MutableString( newData );
+        length = newLength;
         
-        return newString;
+        return this;
     }
     
     /**
@@ -294,6 +457,47 @@
     }
     
     /**
+     * Compares two MutableString.
+     * @param s1 The first MutableString
+     * @param s2 The second MutableString
+     * @return true if they are equal
+     */
+    public static boolean equals( MutableString s1, MutableString s2 )
+    {
+        if ( s1 == null )
+        {
+            return ( s2 == null );
+        }
+        
+        if ( s2 == null )
+        {
+            return false;
+        }
+        
+        if ( s1.length != s2.length )
+        {
+            return false;
+        }
+        
+        char[] c1 = s1.string;
+        char[] c2 = s2.string;
+        
+        for ( int i = 0; i < c1.length; i++ )
+        {
+            if ( c1[i] < c2[i] )
+            {
+                return false;
+            }
+            else if ( c1[i] > c2[i] )
+            {
+                return false;
+            }
+        }
+        
+        return true;
+    }
+    
+    /**
      * Return a native String representation of the MutableString.
      */
     public String toString()
@@ -304,14 +508,7 @@
         }
         else
         {
-            try
-            {
-                return new String(data, 0, length, "UTF8");
-            }
-            catch (UnsupportedEncodingException uee)
-            {
-                return "";
-            }
+            return new String( string, 0, length );
         }
     }
 }

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=291832&r1=291831&r2=291832&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 Mon Sep 26 23:51:51 2005
@@ -168,7 +168,7 @@
      * 
      * TODO : Should stop after the third byte, as a char is only 2 bytes long.
      */
-    public static int countBytesPerChar(byte[] bytes, int pos) throws UnsupportedEncodingException
+    public static int countCharNbBytes(byte[] bytes, int pos) throws UnsupportedEncodingException
     {
         if ((bytes[pos] & UTF8_MULTI_BYTES_MASK) == 0)
         {
@@ -364,7 +364,7 @@
         
         for ( int i = 0; i < bytes.length; i+= nbBytes )
         {
-            nbBytes = countBytesPerChar( bytes, i );
+            nbBytes = countCharNbBytes( bytes, i );
             
             if ( nbBytes < 4 )
             {
@@ -378,7 +378,29 @@
                 chars[pos++] = twoChars[1];
             }
         }
+    }
+    
+    public static void decodeUTF8( byte[] bytes, char[] chars ) throws UnsupportedEncodingException
+    {
+        int pos = 0;
+        int newPos = 0;
+        int nbChars = 0;
         
+        for ( int i = 0; i < chars.length; i+= nbChars )
+        {
+            newPos = charToBytes( chars[i], bytes, pos );
+            
+            if ( newPos - pos < 4 )
+            {
+                nbChars += 1;
+            }
+            else
+            {
+                nbChars += 2;
+            }
+            
+            pos = newPos;
+        }
     }
     
     /**
@@ -483,6 +505,46 @@
     }
     
     /**
+     * Return the number of bytes that hold an Unicode char.
+     * 
+     * @param car The character to be decoded
+     * @return The number of bytes to hold the char.
+     * 
+     * TODO : Should stop after the third byte, as a char is only 2 bytes long.
+     */
+    public static int countNbBytesPerChar( char car )
+    {
+        if ( ( car & CHAR_ONE_BYTE_MASK ) == 0 )
+        {
+            return 1;
+        }
+        else if ( ( car & CHAR_TWO_BYTES_MASK ) == 0 )
+        {
+            return 2;
+        }
+        else if ( ( car & CHAR_THREE_BYTES_MASK ) == 0 )
+        {
+            return 3;
+        }
+        else if ( ( car & CHAR_FOUR_BYTES_MASK ) == 0 )
+        {
+            return 4;
+        }
+        else if ( ( car & CHAR_FIVE_BYTES_MASK ) == 0 )
+        {
+            return 5;
+        }
+        else if ( ( car & CHAR_SIX_BYTES_MASK ) == 0 )
+        {
+            return 6;
+        } 
+        else
+        {
+            return -1;
+        }
+    }
+    
+    /**
      * Count the number of chars included in the given byte[].  
      * @param bytes The byte array to decode
      * @return The number of char in the byte array
@@ -494,7 +556,7 @@
         
         while (currentPos < bytes.length)
         {
-            int nbBytes = countBytesPerChar(bytes, currentPos);
+            int nbBytes = countCharNbBytes( bytes, currentPos );
             
             currentPos += nbBytes;
 
@@ -510,6 +572,29 @@
         }
 
         return nbChars;
+    }
+    
+    /**
+     * Count the number of bytes included in the given char[].  
+     * @param chars The char array to decode
+     * @return The number of bytes in the char array
+     */
+    public static int countBytes(char[] chars) throws UnsupportedEncodingException
+    {
+        int nbBytes = 0;
+        int currentPos = 0;
+        
+        while ( currentPos < chars.length )
+        {
+            int nbb = countNbBytesPerChar( chars[currentPos] );
+            
+            // If the number of bytes necessary to encode a character is
+            // above 3, we will need two UTF-16 chars
+            currentPos += (nbb < 4 ? 1 : 2 );
+            nbBytes += nbb;
+        }
+
+        return nbBytes;
     }
     
     /**

Modified: directory/asn1/branches/asn1-NameComponent/ber-new/src/test/org/apache/asn1new/util/MutableStringTest.java
URL: http://svn.apache.org/viewcvs/directory/asn1/branches/asn1-NameComponent/ber-new/src/test/org/apache/asn1new/util/MutableStringTest.java?rev=291832&r1=291831&r2=291832&view=diff
==============================================================================
--- directory/asn1/branches/asn1-NameComponent/ber-new/src/test/org/apache/asn1new/util/MutableStringTest.java (original)
+++ directory/asn1/branches/asn1-NameComponent/ber-new/src/test/org/apache/asn1new/util/MutableStringTest.java Mon Sep 26 23:51:51 2005
@@ -141,9 +141,89 @@
         String s = ms.toString();
         
         int msLength = ms.getLength();
-        int sLength = s.getBytes().length;
+        int sLength = s.length();
         
         Assert.assertEquals("Emmanuel Lécharny" , s);   
         Assert.assertEquals( sLength, msLength);
+    }
+
+    /**
+     * Test an append 
+     */
+    public void testAppend() throws UnsupportedEncodingException
+    {
+        MutableString str = new MutableString();
+        
+        str.append( new MutableString( "abc" ) );
+        
+        Assert.assertEquals( "abc", str.toString() );
+
+        str.append( new MutableString( "def" ) );
+        
+        Assert.assertEquals( "abcdef", str.toString() );
+    }
+
+    /**
+     * Test an empty append 
+     */
+    public void testAppendEmpty() throws UnsupportedEncodingException
+    {
+        MutableString str = new MutableString();
+        
+        str.append( new MutableString( "abc" ) );
+        
+        Assert.assertEquals( "abc", str.toString() );
+
+        str.append( new MutableString( "" ) );
+        
+        Assert.assertEquals( "abc", str.toString() );
+    }
+
+    /**
+     * Test an null append 
+     */
+    public void testAppendNull() throws UnsupportedEncodingException
+    {
+        MutableString str = new MutableString();
+        
+        str.append( new MutableString( "abc" ) );
+        
+        Assert.assertEquals( "abc", str.toString() );
+
+        str.append( new MutableString() );
+        
+        Assert.assertEquals( "abc", str.toString() );
+    }
+
+    /**
+     * Test an append with non Ascii characters 
+     */
+    public void testAppendNonAscii() throws UnsupportedEncodingException
+    {
+        MutableString str = new MutableString();
+        
+        str.append( new MutableString( "abc" ) );
+        
+        Assert.assertEquals( "abc", str.toString() );
+
+        str.append( new MutableString( "Jérôme" ) );
+        
+        Assert.assertEquals( "abcJérôme", str.toString() );
+    }
+
+    /**
+     * Test an append with non Ascii characters 
+     */
+    public void testAppendStringNonAscii() throws UnsupportedEncodingException
+    {
+        MutableString str = new MutableString();
+        
+        str.append( "abc" );
+        
+        Assert.assertEquals( "abc", str.toString() );
+
+        str.append( "Jérôme" );
+        
+        Assert.assertEquals( "abcJérôme", str.toString() );
     }
 }