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() );
}
}