directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r1538150 - in /directory/shared/trunk: integ/src/test/java/org/apache/directory/api/ldap/model/name/ ldap/model/src/main/java/org/apache/directory/api/ldap/model/entry/ ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/ ld...
Date Sat, 02 Nov 2013 08:28:57 GMT
Author: elecharny
Date: Sat Nov  2 08:28:57 2013
New Revision: 1538150

URL: http://svn.apache.org/r1538150
Log:
o Added a different serialization for StringValue, AVA and RDN, based on a byte[]
o Added a StringValue constructor which takes an AttributeType parameter
o Added a Serializer helper class

Added:
    directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/Serialize.java
Modified:
    directory/shared/trunk/integ/src/test/java/org/apache/directory/api/ldap/model/name/SchemaAwareAvaSerializationTest.java
    directory/shared/trunk/integ/src/test/java/org/apache/directory/api/ldap/model/name/SchemaAwareRdnSerializationTest.java
    directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/entry/StringValue.java
    directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/FilterParser.java
    directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/name/Ava.java
    directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/name/Rdn.java
    directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/entry/ValueSerializationTest.java

Modified: directory/shared/trunk/integ/src/test/java/org/apache/directory/api/ldap/model/name/SchemaAwareAvaSerializationTest.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/integ/src/test/java/org/apache/directory/api/ldap/model/name/SchemaAwareAvaSerializationTest.java?rev=1538150&r1=1538149&r2=1538150&view=diff
==============================================================================
--- directory/shared/trunk/integ/src/test/java/org/apache/directory/api/ldap/model/name/SchemaAwareAvaSerializationTest.java (original)
+++ directory/shared/trunk/integ/src/test/java/org/apache/directory/api/ldap/model/name/SchemaAwareAvaSerializationTest.java Sat Nov  2 08:28:57 2013
@@ -31,16 +31,12 @@ import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 
 import org.apache.directory.api.ldap.model.exception.LdapException;
-import org.apache.directory.api.ldap.model.name.Ava;
 import org.apache.directory.api.ldap.model.schema.SchemaManager;
 import org.apache.directory.api.ldap.schemamanager.impl.DefaultSchemaManager;
 import org.apache.directory.api.util.Strings;
 import org.junit.BeforeClass;
+import org.junit.Ignore;
 import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import com.mycila.junit.concurrent.Concurrency;
-import com.mycila.junit.concurrent.ConcurrentJunitRunner;
 
 
 /**
@@ -48,11 +44,8 @@ import com.mycila.junit.concurrent.Concu
  *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
-@RunWith(ConcurrentJunitRunner.class)
-@Concurrency()
 public class SchemaAwareAvaSerializationTest
 {
-
     private static SchemaManager schemaManager;
 
 
@@ -88,6 +81,25 @@ public class SchemaAwareAvaSerialization
     }
 
 
+    /**
+     * Test serialization of a simple ATAV
+     */
+    @Test
+    public void testStringAtavSerializationBytes() throws LdapException, IOException, ClassNotFoundException
+    {
+        byte[] buffer = new byte[128];
+        Ava atav = new Ava( schemaManager, "CN", "Test" );
+
+        int pos1 = atav.serialize( buffer, 0 );
+
+        Ava atav2 = new Ava( schemaManager );
+        int pos2 = atav2.deserialize( buffer, 0 );
+
+        assertEquals( pos1, pos2 );
+        assertEquals( atav, atav2 );
+    }
+
+
     @Test
     public void testBinaryAtavSerialization() throws LdapException, IOException, ClassNotFoundException
     {
@@ -112,6 +124,25 @@ public class SchemaAwareAvaSerialization
     }
 
 
+    @Ignore
+    @Test
+    public void testBinaryAtavSerializationBytes() throws LdapException, IOException, ClassNotFoundException
+    {
+        byte[] buffer = new byte[128];
+        byte[] normValue = Strings.getBytesUtf8( "Test" );
+
+        Ava atav = new Ava( schemaManager, "userPKCS12", normValue );
+
+        int pos1 = atav.serialize( buffer, 0 );
+
+        Ava atav2 = new Ava( schemaManager );
+        int pos2 = atav2.deserialize( buffer, 0 );
+
+        assertEquals( pos1, pos2 );
+        assertEquals( atav, atav2 );
+    }
+
+
     /**
      * Test serialization of a simple ATAV
      */
@@ -135,6 +166,27 @@ public class SchemaAwareAvaSerialization
     }
 
 
+    /**
+     * Test serialization of a simple ATAV
+     */
+    @Test
+    public void testNullAtavSerializationBytes() throws LdapException, IOException, ClassNotFoundException
+    {
+        byte[] buffer = new byte[128];
+        Ava atav = new Ava( schemaManager );
+
+        try
+        {
+            atav.serialize( buffer, 0 );
+            fail();
+        }
+        catch ( IOException ioe )
+        {
+            assertTrue( true );
+        }
+    }
+
+
     @Test
     public void testNullUpValueSerialization() throws LdapException, IOException, ClassNotFoundException
     {
@@ -157,6 +209,25 @@ public class SchemaAwareAvaSerialization
 
 
     @Test
+    public void testNullUpValueSerializationBytes() throws LdapException, IOException, ClassNotFoundException
+    {
+        byte[] buffer = new byte[128];
+        Ava atav = new Ava( schemaManager, "dc", ( String ) null );
+
+        try
+        {
+            atav.serialize( buffer, 0 );
+            fail();
+        }
+        catch ( IOException ioe )
+        {
+            String message = ioe.getMessage();
+            assertEquals( "Cannot serialize an wrong ATAV, the upValue should not be null", message );
+        }
+    }
+
+
+    @Test
     public void testEmptyNormValueSerialization() throws LdapException, IOException, ClassNotFoundException
     {
         Ava atav = new Ava( schemaManager, "DC", "" );
@@ -178,6 +249,22 @@ public class SchemaAwareAvaSerialization
     }
 
 
+    @Test
+    public void testEmptyNormValueSerializationBytes() throws LdapException, IOException, ClassNotFoundException
+    {
+        byte[] buffer = new byte[128];
+        Ava atav = new Ava( schemaManager, "DC", "" );
+
+        int pos1 = atav.serialize( buffer, 0 );
+
+        Ava atav2 = new Ava( schemaManager );
+        int pos2 = atav2.deserialize( buffer, 0 );
+
+        assertEquals( pos1, pos2 );
+        assertEquals( atav, atav2 );
+    }
+
+
     /**
      * Test serialization of a simple ATAV
      */
@@ -203,6 +290,25 @@ public class SchemaAwareAvaSerialization
     }
 
 
+    /**
+     * Test serialization of a simple ATAV
+     */
+    @Test
+    public void testStringAtavStaticSerializationBytes() throws LdapException, IOException, ClassNotFoundException
+    {
+        byte[] buffer = new byte[128];
+        Ava atav = new Ava( schemaManager, "CN", "Test" );
+
+        int pos1 = atav.serialize( buffer, 0 );
+
+        Ava atav2 = new Ava( schemaManager );
+        int pos2 = atav2.deserialize( buffer, 0 );
+
+        assertEquals( pos1, pos2 );
+        assertEquals( atav, atav2 );
+    }
+
+
     @Test
     public void testBinaryAtavStaticSerialization() throws LdapException, IOException, ClassNotFoundException
     {
@@ -227,6 +333,25 @@ public class SchemaAwareAvaSerialization
     }
 
 
+    @Ignore
+    @Test
+    public void testBinaryAtavStaticSerializationBytes() throws LdapException, IOException, ClassNotFoundException
+    {
+        byte[] buffer = new byte[128];
+        byte[] upValue = Strings.getBytesUtf8( "  Test  " );
+
+        Ava atav = new Ava( schemaManager, "userPKCS12", upValue );
+
+        int pos1 = atav.serialize( buffer, 0 );
+
+        Ava atav2 = new Ava( schemaManager );
+        int pos2 = atav2.deserialize( buffer, 0 );
+
+        assertEquals( pos1, pos2 );
+        assertEquals( atav, atav2 );
+    }
+
+
     /**
      * Test static serialization of a simple ATAV
      */
@@ -250,9 +375,41 @@ public class SchemaAwareAvaSerialization
     }
 
 
+    /**
+     * Test static serialization of a simple ATAV
+     */
+    @Test
+    public void testNullAtavStaticSerializationBytes() throws LdapException, IOException, ClassNotFoundException
+    {
+        byte[] buffer = new byte[128];
+        Ava atav = new Ava( schemaManager );
+
+        try
+        {
+            atav.serialize( buffer, 0 );
+            fail();
+        }
+        catch ( IOException ioe )
+        {
+            assertTrue( true );
+        }
+    }
+
+
     @Test(expected = IOException.class)
     public void testNullNormValueStaticSerialization() throws LdapException, IOException, ClassNotFoundException
     {
+        byte[] buffer = new byte[128];
+        Ava atav = new Ava( schemaManager, "DC", ( String ) null );
+
+        atav.serialize( buffer, 0 );
+        fail();
+    }
+
+
+    @Test(expected = IOException.class)
+    public void testNullNormValueStaticSerializationBytes() throws LdapException, IOException, ClassNotFoundException
+    {
         Ava atav = new Ava( schemaManager, "DC", ( String ) null );
 
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -266,7 +423,7 @@ public class SchemaAwareAvaSerialization
     @Test
     public void testEmptyNormValueStaticSerialization() throws LdapException, IOException, ClassNotFoundException
     {
-        Ava atav = new Ava( schemaManager, "DC", ( String ) "" );
+        Ava atav = new Ava( schemaManager, "DC", "" );
 
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         ObjectOutputStream out = new ObjectOutputStream( baos );
@@ -283,4 +440,74 @@ public class SchemaAwareAvaSerialization
 
         assertEquals( atav, atav2 );
     }
+
+
+    @Test
+    public void testEmptyNormValueStaticSerializationBytes() throws LdapException, IOException, ClassNotFoundException
+    {
+        byte[] buffer = new byte[128];
+        Ava atav = new Ava( schemaManager, "DC", "" );
+
+        int pos1 = atav.serialize( buffer, 0 );
+
+        Ava atav2 = new Ava( schemaManager );
+        int pos2 = atav2.deserialize( buffer, 0 );
+
+        assertEquals( pos1, pos2 );
+        assertEquals( atav, atav2 );
+    }
+
+
+    @Ignore
+    @Test
+    public void testStringAtavSerializationPerf() throws IOException, LdapException,
+        ClassNotFoundException
+    {
+        Ava atav = new Ava( schemaManager, "CN", "Test" );
+        Ava atav2 = new Ava( schemaManager );
+
+        long t0 = System.currentTimeMillis();
+
+        for ( int i = 0; i < 10000000; i++ )
+        {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream out = new ObjectOutputStream( baos );
+
+            atav.writeExternal( out );
+
+            ObjectInputStream in = null;
+
+            byte[] data = baos.toByteArray();
+            in = new ObjectInputStream( new ByteArrayInputStream( data ) );
+
+            atav2.readExternal( in );
+        }
+
+        long t1 = System.currentTimeMillis();
+
+        System.out.println( "Delta ser slow = " + ( t1 - t0 ) );
+    }
+
+
+    @Ignore
+    @Test
+    public void testStringAtavSerializationBytesPerf() throws IOException, LdapException,
+        ClassNotFoundException
+    {
+        Ava atav = new Ava( schemaManager, "CN", "Test" );
+        Ava atav2 = new Ava( schemaManager );
+
+        long t0 = System.currentTimeMillis();
+
+        for ( int i = 0; i < 10000000; i++ )
+        {
+            byte[] buffer = new byte[128];
+            atav.serialize( buffer, 0 );
+            atav2.deserialize( buffer, 0 );
+        }
+
+        long t1 = System.currentTimeMillis();
+
+        System.out.println( "Delta ser fast = " + ( t1 - t0 ) );
+    }
 }

Modified: directory/shared/trunk/integ/src/test/java/org/apache/directory/api/ldap/model/name/SchemaAwareRdnSerializationTest.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/integ/src/test/java/org/apache/directory/api/ldap/model/name/SchemaAwareRdnSerializationTest.java?rev=1538150&r1=1538149&r2=1538150&view=diff
==============================================================================
--- directory/shared/trunk/integ/src/test/java/org/apache/directory/api/ldap/model/name/SchemaAwareRdnSerializationTest.java (original)
+++ directory/shared/trunk/integ/src/test/java/org/apache/directory/api/ldap/model/name/SchemaAwareRdnSerializationTest.java Sat Nov  2 08:28:57 2013
@@ -29,10 +29,10 @@ import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 
 import org.apache.directory.api.ldap.model.exception.LdapException;
-import org.apache.directory.api.ldap.model.name.Rdn;
 import org.apache.directory.api.ldap.model.schema.SchemaManager;
 import org.apache.directory.api.ldap.schemamanager.impl.DefaultSchemaManager;
 import org.junit.BeforeClass;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -85,6 +85,22 @@ public class SchemaAwareRdnSerialization
 
 
     @Test
+    public void testRdnFullSerializationBytes() throws IOException, LdapException, ClassNotFoundException
+    {
+        byte[] buffer = new byte[256];
+        Rdn rdn1 = new Rdn( schemaManager, "gn=john + cn=doe" );
+
+        int pos1 = rdn1.serialize( buffer, 0 );
+
+        Rdn rdn2 = new Rdn( schemaManager );
+        int pos2 = rdn2.deserialize( buffer, 0 );
+
+        assertEquals( pos1, pos2 );
+        assertEquals( rdn1, rdn2 );
+    }
+
+
+    @Test
     public void testRdnEmptySerialization() throws IOException, LdapException, ClassNotFoundException
     {
         Rdn rdn1 = new Rdn( schemaManager );
@@ -107,6 +123,22 @@ public class SchemaAwareRdnSerialization
 
 
     @Test
+    public void testRdnEmptySerializationBytes() throws IOException, LdapException, ClassNotFoundException
+    {
+        byte[] buffer = new byte[256];
+        Rdn rdn1 = new Rdn( schemaManager );
+
+        int pos1 = rdn1.serialize( buffer, 0 );
+
+        Rdn rdn2 = new Rdn( schemaManager );
+        int pos2 = rdn2.deserialize( buffer, 0 );
+
+        assertEquals( pos1, pos2 );
+        assertEquals( rdn1, rdn2 );
+    }
+
+
+    @Test
     public void testRdnSimpleSerialization() throws IOException, LdapException, ClassNotFoundException
     {
         Rdn rdn1 = new Rdn( schemaManager, "cn=Doe" );
@@ -128,4 +160,74 @@ public class SchemaAwareRdnSerialization
         assertEquals( "doe", rdn2.getValue( "cn" ) );
         assertEquals( "Doe", rdn2.getValue().getString() );
     }
+
+
+    @Test
+    public void testRdnSimpleSerializationBytes() throws IOException, LdapException, ClassNotFoundException
+    {
+        byte[] buffer = new byte[256];
+        Rdn rdn1 = new Rdn( schemaManager, "cn=Doe" );
+
+        int pos1 = rdn1.serialize( buffer, 0 );
+
+        Rdn rdn2 = new Rdn( schemaManager );
+        int pos2 = rdn2.deserialize( buffer, 0 );
+
+        assertEquals( pos1, pos2 );
+        assertEquals( rdn1, rdn2 );
+        assertEquals( "doe", rdn2.getValue( "cn" ) );
+        assertEquals( "Doe", rdn2.getValue().getString() );
+    }
+
+
+    @Ignore
+    @Test
+    public void testRdnFullSerializationPerf() throws IOException, LdapException, ClassNotFoundException
+    {
+        Rdn rdn1 = new Rdn( schemaManager, "gn=john + cn=doe" );
+        Rdn rdn2 = new Rdn( schemaManager );
+
+        long t0 = System.currentTimeMillis();
+
+        for ( int i = 0; i < 5000000; i++ )
+        {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream out = new ObjectOutputStream( baos );
+
+            rdn1.writeExternal( out );
+
+            ObjectInputStream in = null;
+
+            byte[] data = baos.toByteArray();
+            in = new ObjectInputStream( new ByteArrayInputStream( data ) );
+
+            rdn2.readExternal( in );
+        }
+
+        long t1 = System.currentTimeMillis();
+
+        System.out.println( "Delta ser slow = " + ( t1 - t0 ) );
+    }
+
+
+    @Ignore
+    @Test
+    public void testRdnFullSerializationBytesPerf() throws IOException, LdapException, ClassNotFoundException
+    {
+        Rdn rdn1 = new Rdn( schemaManager, "gn=john + cn=doe" );
+        Rdn rdn2 = new Rdn( schemaManager );
+
+        long t0 = System.currentTimeMillis();
+
+        for ( int i = 0; i < 5000000; i++ )
+        {
+            byte[] buffer = new byte[256];
+            rdn1.serialize( buffer, 0 );
+            rdn2.deserialize( buffer, 0 );
+        }
+
+        long t1 = System.currentTimeMillis();
+
+        System.out.println( "Delta ser fast = " + ( t1 - t0 ) );
+    }
 }

Modified: directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/entry/StringValue.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/entry/StringValue.java?rev=1538150&r1=1538149&r2=1538150&view=diff
==============================================================================
--- directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/entry/StringValue.java (original)
+++ directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/entry/StringValue.java Sat Nov  2 08:28:57 2013
@@ -30,6 +30,7 @@ import org.apache.directory.api.ldap.mod
 import org.apache.directory.api.ldap.model.schema.AttributeType;
 import org.apache.directory.api.ldap.model.schema.MatchingRule;
 import org.apache.directory.api.ldap.model.schema.Normalizer;
+import org.apache.directory.api.util.Serialize;
 import org.apache.directory.api.util.Strings;
 import org.apache.directory.api.util.exception.NotImplementedException;
 
@@ -59,7 +60,7 @@ public class StringValue extends Abstrac
      *
      * @param attributeType the schema attribute type associated with this StringValue
      */
-    /* No protection*/StringValue( AttributeType attributeType )
+    public StringValue( AttributeType attributeType )
     {
         if ( attributeType != null )
         {
@@ -572,6 +573,191 @@ public class StringValue extends Abstrac
 
 
     /**
+     * Serialize the StringValue into a buffer at the given position.
+     * 
+     * @param buffer The buffer which will contain the serialized StringValue
+     * @param pos The position in the buffer for the serialized value
+     * @return The new position in the buffer
+     */
+    public int serialize( byte[] buffer, int pos )
+    {
+        // Compute the length
+        int length = 1 + 1 + 1 + 4; // The value type, the wrappedValue presence flag,
+                                    // the normalizedValue presence flag and the hash length.
+
+        byte[] wrappedValueBytes = null;
+        byte[] normalizedValueBytes = null;
+
+        if ( wrappedValue != null )
+        {
+            wrappedValueBytes = Strings.getBytesUtf8( wrappedValue );
+            length += 4 + wrappedValueBytes.length;
+        }
+
+        if ( attributeType != null )
+        {
+            if ( normalizedValue != null )
+            {
+                normalizedValueBytes = Strings.getBytesUtf8( normalizedValue );
+                length += 1 + 4 + normalizedValueBytes.length;
+            }
+            else
+            {
+                length += 1;
+            }
+        }
+
+        // Check that we will be able to store the data in the buffer
+        if ( buffer.length - pos < length )
+        {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+
+        // The STRING flag
+        buffer[pos] = Serialize.TRUE;
+        pos++;
+
+        // Write the wrapped value, if it's not null
+        if ( wrappedValue != null )
+        {
+            buffer[pos++] = Serialize.TRUE;
+            pos = Serialize.serialize( wrappedValueBytes, buffer, pos );
+        }
+        else
+        {
+            buffer[pos++] = Serialize.FALSE;
+        }
+
+        // Write the isNormalized flag
+        if ( attributeType != null )
+        {
+            // This flag is present to tell that we have a normalized value different
+            // from the upValue
+
+            buffer[pos++] = Serialize.TRUE;
+
+            // Write the normalized value, if not null
+            if ( normalizedValue != null )
+            {
+                buffer[pos++] = Serialize.TRUE;
+                pos = Serialize.serialize( normalizedValueBytes, buffer, pos );
+            }
+            else
+            {
+                buffer[pos++] = Serialize.FALSE;
+            }
+        }
+        else
+        {
+            // No normalized value
+            buffer[pos++] = Serialize.FALSE;
+        }
+
+        // Write the hashCode
+        pos = Serialize.serialize( h, buffer, pos );
+
+        return pos;
+    }
+
+
+    /**
+     * Deserialize a StringValue from a byte[], starting at a given position
+     * 
+     * @param buffer The buffer containing the StringValue
+     * @param pos The position in the buffer
+     * @return The new position
+     * @throws IOException If the serialized value is not a StringValue
+     */
+    public int deserialize( byte[] buffer, int pos ) throws IOException
+    {
+        if ( ( pos < 0 ) || ( pos >= buffer.length ) )
+        {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+
+        // Read the STRING flag
+        boolean isHR = Serialize.deserializeBoolean( buffer, pos );
+        pos++;
+
+        if ( !isHR )
+        {
+            throw new IOException( "The serialized value is not a String value" );
+        }
+
+        // Read the wrapped value, if it's not null
+        boolean hasWrappedValue = Serialize.deserializeBoolean( buffer, pos );
+        pos++;
+
+        if ( hasWrappedValue )
+        {
+            byte[] wrappedValueBytes = Serialize.deserializeBytes( buffer, pos );
+            pos += 4 + wrappedValueBytes.length;
+            wrappedValue = Strings.utf8ToString( wrappedValueBytes );
+        }
+
+        // Read the isNormalized flag
+        boolean hasAttributeType = Serialize.deserializeBoolean( buffer, pos );
+        pos++;
+
+        if ( hasAttributeType )
+        {
+            // Read the normalized value, if not null
+            boolean hasNormalizedValue = Serialize.deserializeBoolean( buffer, pos );
+            pos++;
+
+            if ( hasNormalizedValue )
+            {
+                byte[] normalizedValueBytes = Serialize.deserializeBytes( buffer, pos );
+                pos += 4 + normalizedValueBytes.length;
+                normalizedValue = Strings.utf8ToString( normalizedValueBytes );
+            }
+        }
+        else
+        {
+            if ( attributeType != null )
+            {
+                try
+                {
+                    MatchingRule equality = attributeType.getEquality();
+
+                    if ( equality == null )
+                    {
+                        normalizedValue = wrappedValue;
+                    }
+                    else
+                    {
+                        Normalizer normalizer = equality.getNormalizer();
+
+                        if ( normalizer != null )
+                        {
+                            normalizedValue = normalizer.normalize( wrappedValue );
+                        }
+                        else
+                        {
+                            normalizedValue = wrappedValue;
+                        }
+                    }
+                }
+                catch ( LdapException le )
+                {
+                    normalizedValue = wrappedValue;
+                }
+            }
+            else
+            {
+                normalizedValue = wrappedValue;
+            }
+        }
+
+        // The hashCode
+        h = Serialize.deserializeInt( buffer, pos );
+        pos += 4;
+
+        return pos;
+    }
+
+
+    /**
      * {@inheritDoc}
      */
     public void writeExternal( ObjectOutput out ) throws IOException

Modified: directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/FilterParser.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/FilterParser.java?rev=1538150&r1=1538149&r2=1538150&view=diff
==============================================================================
--- directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/FilterParser.java (original)
+++ directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/FilterParser.java Sat Nov  2 08:28:57 2013
@@ -319,7 +319,7 @@ public class FilterParser
 
                 if ( attributeType.getEquality().getSyntax().isHumanReadable() )
                 {
-                    return new StringValue( null );
+                    return new StringValue( ( String ) null );
                 }
                 else
                 {

Modified: directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/name/Ava.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/name/Ava.java?rev=1538150&r1=1538149&r2=1538150&view=diff
==============================================================================
--- directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/name/Ava.java (original)
+++ directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/name/Ava.java Sat Nov  2 08:28:57 2013
@@ -38,6 +38,7 @@ import org.apache.directory.api.ldap.mod
 import org.apache.directory.api.ldap.model.schema.LdapComparator;
 import org.apache.directory.api.ldap.model.schema.MatchingRule;
 import org.apache.directory.api.ldap.model.schema.SchemaManager;
+import org.apache.directory.api.util.Serialize;
 import org.apache.directory.api.util.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -735,6 +736,249 @@ public class Ava implements Externalizab
 
 
     /**
+     * Serialize the AVA into a buffer at the given position.
+     * 
+     * @param buffer The buffer which will contain the serialized Ava
+     * @param pos The position in the buffer for the serialized value
+     * @return The new position in the buffer
+     */
+    public int serialize( byte[] buffer, int pos ) throws IOException
+    {
+        if ( Strings.isEmpty( upName )
+            || Strings.isEmpty( upType )
+            || Strings.isEmpty( normType )
+            || ( upValue.isNull() )
+            || ( normValue.isNull() ) )
+        {
+            String message = "Cannot serialize an wrong ATAV, ";
+
+            if ( Strings.isEmpty( upName ) )
+            {
+                message += "the upName should not be null or empty";
+            }
+            else if ( Strings.isEmpty( upType ) )
+            {
+                message += "the upType should not be null or empty";
+            }
+            else if ( Strings.isEmpty( normType ) )
+            {
+                message += "the normType should not be null or empty";
+            }
+            else if ( upValue.isNull() )
+            {
+                message += "the upValue should not be null";
+            }
+            else if ( normValue.isNull() )
+            {
+                message += "the value should not be null";
+            }
+
+            LOG.error( message );
+            throw new IOException( message );
+        }
+
+        int length = 0;
+
+        // The upName
+        byte[] upNameBytes = null;
+
+        if ( upName != null )
+        {
+            upNameBytes = Strings.getBytesUtf8( upName );
+            length += 1 + 4 + upNameBytes.length;
+        }
+
+        // The upType
+        byte[] upTypeBytes = null;
+
+        if ( upType != null )
+        {
+            upTypeBytes = Strings.getBytesUtf8( upType );
+            length += 1 + 4 + upTypeBytes.length;
+        }
+
+        // The normType
+        byte[] normTypeBytes = null;
+
+        if ( normType != null )
+        {
+            normTypeBytes = Strings.getBytesUtf8( normType );
+            length += 1 + 4 + normTypeBytes.length;
+        }
+
+        // Is HR
+        length++;
+
+        // The hash code
+        length += 4;
+
+        // Check that we will be able to store the data in the buffer
+        if ( buffer.length - pos < length )
+        {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+
+        // Write the upName
+        if ( upName != null )
+        {
+            buffer[pos++] = Serialize.TRUE;
+            pos = Serialize.serialize( upNameBytes, buffer, pos );
+        }
+        else
+        {
+            buffer[pos++] = Serialize.FALSE;
+        }
+
+        // Write the upType
+        if ( upType != null )
+        {
+            buffer[pos++] = Serialize.TRUE;
+            pos = Serialize.serialize( upTypeBytes, buffer, pos );
+        }
+        else
+        {
+            buffer[pos++] = Serialize.FALSE;
+        }
+
+        // Write the normType
+        if ( normType != null )
+        {
+            buffer[pos++] = Serialize.TRUE;
+            pos = Serialize.serialize( normTypeBytes, buffer, pos );
+        }
+        else
+        {
+            buffer[pos++] = Serialize.FALSE;
+        }
+
+        // Write the isHR flag
+        if ( normValue.isHumanReadable() )
+        {
+            buffer[pos++] = Serialize.TRUE;
+        }
+        else
+        {
+            buffer[pos++] = Serialize.FALSE;
+        }
+
+        // Write the upValue
+        if ( upValue.isHumanReadable() )
+        {
+            pos = ( ( StringValue ) upValue ).serialize( buffer, pos );
+        }
+        else
+        {
+            //pos = ( ( BinaryValue ) upValue ).serialize( buffer, pos );
+
+        }
+
+        // Write the normValue
+        if ( normValue.isHumanReadable() )
+        {
+            pos = ( ( StringValue ) normValue ).serialize( buffer, pos );
+        }
+        else
+        {
+            //pos = ( ( BinaryValue ) normValue ).serialize( buffer, pos );
+        }
+
+        // Write the hash code
+        pos = Serialize.serialize( h, buffer, pos );
+
+        return pos;
+    }
+
+
+    /**
+     * Deserialize an AVA from a byte[], starting at a given position
+     * 
+     * @param buffer The buffer containing the AVA
+     * @param pos The position in the buffer
+     * @return The new position
+     * @throws IOException If the serialized value is not an AVA
+     * @throws LdapInvalidAttributeValueException If the serialized AVA is invalid
+     */
+    public int deserialize( byte[] buffer, int pos ) throws IOException, LdapInvalidAttributeValueException
+    {
+        if ( ( pos < 0 ) || ( pos >= buffer.length ) )
+        {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+
+        // Read the upName value, if it's not null
+        boolean hasUpName = Serialize.deserializeBoolean( buffer, pos );
+        pos++;
+
+        if ( hasUpName )
+        {
+            byte[] wrappedValueBytes = Serialize.deserializeBytes( buffer, pos );
+            pos += 4 + wrappedValueBytes.length;
+            upName = Strings.utf8ToString( wrappedValueBytes );
+        }
+
+        // Read the upType value, if it's not null
+        boolean hasUpType = Serialize.deserializeBoolean( buffer, pos );
+        pos++;
+
+        if ( hasUpType )
+        {
+            byte[] upTypeBytes = Serialize.deserializeBytes( buffer, pos );
+            pos += 4 + upTypeBytes.length;
+            upType = Strings.utf8ToString( upTypeBytes );
+        }
+
+        // Read the normType value, if it's not null
+        boolean hasNormType = Serialize.deserializeBoolean( buffer, pos );
+        pos++;
+
+        if ( hasNormType )
+        {
+            byte[] normTypeBytes = Serialize.deserializeBytes( buffer, pos );
+            pos += 4 + normTypeBytes.length;
+            normType = Strings.utf8ToString( normTypeBytes );
+        }
+
+        // Update the AtributeType
+        if ( schemaManager != null )
+        {
+            if ( !Strings.isEmpty( upType ) )
+            {
+                attributeType = schemaManager.getAttributeType( upType );
+            }
+            else
+            {
+                attributeType = schemaManager.getAttributeType( normType );
+            }
+        }
+
+        // Read the isHR flag
+        boolean isHR = Serialize.deserializeBoolean( buffer, pos );
+        pos++;
+
+        if ( isHR )
+        {
+            // Read the upValue
+            upValue = new StringValue( attributeType );
+            pos = ( ( StringValue ) upValue ).deserialize( buffer, pos );
+
+            // Read the normValue
+            normValue = new StringValue( attributeType );
+            pos = ( ( StringValue ) normValue ).deserialize( buffer, pos );
+        }
+        else
+        {
+            // TODO
+        }
+
+        // Read the hashCode
+        h = Serialize.deserializeInt( buffer, pos );
+        pos += 4;
+
+        return pos;
+    }
+
+
+    /**
      * 
      * An Ava is composed of  a type and a value.
      * The data are stored following the structure :

Modified: directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/name/Rdn.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/name/Rdn.java?rev=1538150&r1=1538149&r2=1538150&view=diff
==============================================================================
--- directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/name/Rdn.java (original)
+++ directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/name/Rdn.java Sat Nov  2 08:28:57 2013
@@ -35,12 +35,14 @@ import org.apache.directory.api.i18n.I18
 import org.apache.directory.api.ldap.model.entry.StringValue;
 import org.apache.directory.api.ldap.model.entry.Value;
 import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
 import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
 import org.apache.directory.api.ldap.model.schema.AttributeType;
 import org.apache.directory.api.ldap.model.schema.SchemaManager;
 import org.apache.directory.api.ldap.model.schema.normalizers.OidNormalizer;
 import org.apache.directory.api.util.Chars;
 import org.apache.directory.api.util.Hex;
+import org.apache.directory.api.util.Serialize;
 import org.apache.directory.api.util.StringConstants;
 import org.apache.directory.api.util.Strings;
 import org.apache.directory.api.util.Unicode;
@@ -1520,6 +1522,148 @@ public class Rdn implements Cloneable, E
 
 
     /**
+     * Serialize a RDN into a byte[]
+     * 
+     * @return a byte[] containing a RDN
+     */
+    public int serialize( byte[] buffer, int pos ) throws IOException
+    {
+        int length = 4 + 4; // The nbAvas and the HashCode length
+
+        // The NnbAvas
+        pos = Serialize.serialize( nbAvas, buffer, pos );
+
+        // The upName
+        byte[] upNameBytes = Strings.getBytesUtf8( upName );
+        length += 4 + upNameBytes.length;
+
+        byte[] normNameBytes = Strings.EMPTY_BYTES;
+        length += 4;
+
+        if ( !upName.equals( normName ) )
+        {
+            normNameBytes = Strings.getBytesUtf8( normName );
+            length += 4 + normNameBytes.length;
+        }
+
+        // Check that we will be able to store the data in the buffer
+        if ( buffer.length - pos < length )
+        {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+
+        // Write the upName
+        pos = Serialize.serialize( upNameBytes, buffer, pos );
+
+        // Write the normName
+        pos = Serialize.serialize( normNameBytes, buffer, pos );
+
+        // Write the AVAs
+        switch ( nbAvas )
+        {
+            case 0:
+                break;
+
+            case 1:
+                pos = ava.serialize( buffer, pos );
+
+                break;
+
+            default:
+                for ( Ava localAva : avas )
+                {
+                    pos = localAva.serialize( buffer, pos );
+                }
+
+                break;
+        }
+
+        // The hash code
+        pos = Serialize.serialize( h, buffer, pos );
+
+        return pos;
+    }
+
+
+    /**
+     * Deserialize a RDN from a byte[], starting at a given position
+     * 
+     * @param buffer The buffer containing the RDN
+     * @param pos The position in the buffer
+     * @return The new position
+     * @throws IOException If the serialized value is not a RDN
+     * @throws LdapInvalidAttributeValueException If the serialized RDN is invalid
+     */
+    public int deserialize( byte[] buffer, int pos ) throws IOException, LdapInvalidAttributeValueException
+    {
+        if ( ( pos < 0 ) || ( pos >= buffer.length ) )
+        {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+
+        // Read the nbAvas
+        nbAvas = Serialize.deserializeInt( buffer, pos );
+        pos += 4;
+
+        // Read the upName
+        byte[] upNameBytes = Serialize.deserializeBytes( buffer, pos );
+        pos += 4 + upNameBytes.length;
+        upName = Strings.utf8ToString( upNameBytes );
+
+        // Read the normName
+        byte[] normNameBytes = Serialize.deserializeBytes( buffer, pos );
+        pos += 4 + normNameBytes.length;
+
+        if ( normNameBytes.length == 0 )
+        {
+            normName = upName;
+        }
+        else
+        {
+            normName = Strings.utf8ToString( normNameBytes );
+        }
+
+        // Read the AVAs
+        switch ( nbAvas )
+        {
+            case 0:
+                break;
+
+            case 1:
+                ava = new Ava( schemaManager );
+                pos = ava.deserialize( buffer, pos );
+                avaType = ava.getNormType();
+
+                break;
+
+            default:
+                avas = new ArrayList<Ava>();
+
+                avaTypes = new MultiValueMap();
+
+                for ( int i = 0; i < nbAvas; i++ )
+                {
+                    Ava ava = new Ava( schemaManager );
+                    pos = ava.deserialize( buffer, pos );
+                    avas.add( ava );
+                    avaTypes.put( ava.getNormType(), ava );
+                }
+
+                ava = null;
+                avaType = null;
+
+                break;
+        }
+
+        // Read the hashCode
+        h = Serialize.deserializeInt( buffer, pos );
+        pos += 4;
+
+        return pos;
+    }
+
+
+    /**
      * A Rdn is composed of on to many Avas (AttributeType And Value).
      * We should write all those Avas sequencially, following the
      * structure :

Modified: directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/entry/ValueSerializationTest.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/entry/ValueSerializationTest.java?rev=1538150&r1=1538149&r2=1538150&view=diff
==============================================================================
--- directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/entry/ValueSerializationTest.java (original)
+++ directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/entry/ValueSerializationTest.java Sat Nov  2 08:28:57 2013
@@ -38,6 +38,7 @@ import org.apache.directory.api.ldap.mod
 import org.apache.directory.api.util.StringConstants;
 import org.apache.directory.api.util.Strings;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -344,7 +345,7 @@ public class ValueSerializationTest
         byte[] data = baos.toByteArray();
         in = new ObjectInputStream( new ByteArrayInputStream( data ) );
 
-        StringValue svDeser = new StringValue( ( AttributeType ) null );
+        StringValue svDeser = new StringValue( ats );
         svDeser.readExternal( in );
 
         assertEquals( sv1n, svDeser );
@@ -366,7 +367,7 @@ public class ValueSerializationTest
         byte[] data = baos.toByteArray();
         in = new ObjectInputStream( new ByteArrayInputStream( data ) );
 
-        StringValue svDeser = new StringValue( ( AttributeType ) null );
+        StringValue svDeser = new StringValue( ats );
         svDeser.readExternal( in );
 
         assertEquals( sv2n, svDeser );
@@ -388,9 +389,161 @@ public class ValueSerializationTest
         byte[] data = baos.toByteArray();
         in = new ObjectInputStream( new ByteArrayInputStream( data ) );
 
-        StringValue svDeser = new StringValue( ( AttributeType ) null );
+        StringValue svDeser = new StringValue( ats );
         svDeser.readExternal( in );
 
         assertEquals( sv3n, svDeser );
     }
+
+
+    @Test
+    public void testStringValueWithDataNormalizedSerializationBytes() throws IOException, LdapException,
+        ClassNotFoundException
+    {
+        byte[] buffer = new byte[128];
+        sv1n.apply( ats );
+
+        int pos = sv1n.serialize( buffer, 0 );
+
+        StringValue svDeser = new StringValue( ats );
+
+        int pos2 = svDeser.deserialize( buffer, 0 );
+
+        assertEquals( pos, pos2 );
+        assertEquals( sv1n, svDeser );
+    }
+
+
+    @Test
+    public void testStringValueWithEmptyDataNormalizedSerializationBytes() throws IOException, LdapException,
+        ClassNotFoundException
+    {
+        byte[] buffer = new byte[128];
+        sv2n.apply( ats );
+
+        int pos = sv2n.serialize( buffer, 0 );
+
+        StringValue svDeser = new StringValue( ats );
+
+        int pos2 = svDeser.deserialize( buffer, 0 );
+
+        assertEquals( pos, pos2 );
+        assertEquals( sv2n, svDeser );
+    }
+
+
+    @Test
+    public void testStringValueNoDataNormalizedSerializationBytes() throws IOException, LdapException,
+        ClassNotFoundException
+    {
+        byte[] buffer = new byte[128];
+        sv3n.apply( ats );
+
+        int pos = sv3n.serialize( buffer, 0 );
+
+        StringValue svDeser = new StringValue( ats );
+        int pos2 = svDeser.deserialize( buffer, 0 );
+
+        assertEquals( pos, pos2 );
+        assertEquals( sv3n, svDeser );
+    }
+
+
+    @Test
+    public void testStringValueWithDataSerializationBytes() throws IOException, ClassNotFoundException
+    {
+        byte[] buffer = new byte[128];
+
+        int pos = sv1.serialize( buffer, 0 );
+
+        StringValue svDeser = new StringValue( ( AttributeType ) null );
+
+        int pos2 = svDeser.deserialize( buffer, 0 );
+
+        assertEquals( pos, pos2 );
+        assertEquals( sv1, svDeser );
+    }
+
+
+    @Test
+    public void testStringValueWithEmptyDataSerializationBytes() throws IOException, ClassNotFoundException
+    {
+        byte[] buffer = new byte[128];
+
+        int pos = sv2.serialize( buffer, 0 );
+
+        StringValue svDeser = new StringValue( ( AttributeType ) null );
+
+        int pos2 = svDeser.deserialize( buffer, 0 );
+
+        assertEquals( pos, pos2 );
+        assertEquals( sv2, svDeser );
+    }
+
+
+    @Test
+    public void testStringValueNoDataSerializationBytes() throws IOException, ClassNotFoundException
+    {
+        byte[] buffer = new byte[128];
+
+        int pos = sv3.serialize( buffer, 0 );
+
+        StringValue svDeser = new StringValue( ( AttributeType ) null );
+
+        int pos2 = svDeser.deserialize( buffer, 0 );
+
+        assertEquals( pos, pos2 );
+        assertEquals( sv3, svDeser );
+    }
+
+
+    @Ignore
+    @Test
+    public void testStringValueWithDataNormalizedSerializationPerf() throws IOException, LdapException,
+        ClassNotFoundException
+    {
+        sv1n.apply( ats );
+        StringValue svDeser = new StringValue( ats );
+
+        long t0 = System.currentTimeMillis();
+
+        for ( int i = 0; i < 10000000; i++ )
+        {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream out = new ObjectOutputStream( baos );
+            sv1n.writeExternal( out );
+            out.close();
+            byte[] data = baos.toByteArray();
+            ObjectInputStream in = new ObjectInputStream( new ByteArrayInputStream( data ) );
+            svDeser.readExternal( in );
+            in.close();
+        }
+
+        long t1 = System.currentTimeMillis();
+
+        System.out.println( "Delta ser slow = " + ( t1 - t0 ) );
+    }
+
+
+    @Ignore
+    @Test
+    public void testStringValueWithDataNormalizedSerializationBytesPerf() throws IOException, LdapException,
+        ClassNotFoundException
+    {
+        sv1n.apply( ats );
+        StringValue svDeser = new StringValue( ats );
+
+        long t0 = System.currentTimeMillis();
+
+        for ( int i = 0; i < 10000000; i++ )
+        {
+            byte[] buffer = new byte[128];
+            sv1n.serialize( buffer, 0 );
+            svDeser.deserialize( buffer, 0 );
+        }
+
+        long t1 = System.currentTimeMillis();
+
+        System.out.println( "Delta ser fast = " + ( t1 - t0 ) );
+    }
 }

Added: directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/Serialize.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/Serialize.java?rev=1538150&view=auto
==============================================================================
--- directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/Serialize.java (added)
+++ directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/Serialize.java Sat Nov  2 08:28:57 2013
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directory.api.util;
+
+
+/**
+ * A class containing static methods used to serialize and deserialize base types
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class Serialize
+{
+    public final static byte TRUE = 0x01;
+    public final static byte FALSE = 0x00;
+
+
+    /**
+     * Write an integer into a buffer at a given position
+     * 
+     * @param value The value to serialize
+     * @param buffer The buffer to store the value into
+     * @param pos The position where we serialize the integer
+     */
+    public static int serialize( int value, byte[] buffer, int pos )
+    {
+        if ( buffer.length - pos < 4 )
+        {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+
+        buffer[pos++] = ( byte ) ( ( value >>> 24 ) & 0xFF );
+        buffer[pos++] = ( byte ) ( ( value >>> 16 ) & 0xFF );
+        buffer[pos++] = ( byte ) ( ( value >>> 8 ) & 0xFF );
+        buffer[pos++] = ( byte ) ( ( value >>> 0 ) & 0xFF );
+
+        return pos;
+    }
+
+
+    /**
+     * Write a byte[] into a buffer at a given position
+     * 
+     * @param value The value to serialize
+     * @param buffer The buffer to store the value into
+     * @param pos The position where we serialize the byte[]
+     */
+    public static int serialize( byte[] value, byte[] buffer, int pos )
+    {
+        if ( buffer.length - pos < 4 + value.length )
+        {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+
+        buffer[pos++] = ( byte ) ( ( value.length >>> 24 ) & 0xFF );
+        buffer[pos++] = ( byte ) ( ( value.length >>> 16 ) & 0xFF );
+        buffer[pos++] = ( byte ) ( ( value.length >>> 8 ) & 0xFF );
+        buffer[pos++] = ( byte ) ( ( value.length >>> 0 ) & 0xFF );
+
+        System.arraycopy( value, 0, buffer, pos, value.length );
+
+        return pos + value.length;
+    }
+
+
+    /**
+     * Read an integer from a buffer at a given position
+     * 
+     * @param buffer The buffer containing the serialized integer
+     * @param pos The position from which we will read an integer
+     * @return the deserialized integer
+     */
+    public static int deserializeInt( byte[] buffer, int pos )
+    {
+        if ( buffer.length - pos < 4 )
+        {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+
+        return ( buffer[pos] << 24 ) + ( buffer[pos + 1] << 16 ) + ( buffer[pos + 2] << 8 ) + ( buffer[pos + 3] << 0 );
+    }
+
+
+    /**
+     * Read a byte[] from a buffer at a given position
+     * 
+     * @param buffer The buffer containing the serialized byte[]
+     * @param pos The position from which we will read a byte[]
+     * @return the deserialized byte[]
+     */
+    public static byte[] deserializeBytes( byte[] buffer, int pos )
+    {
+        if ( buffer.length - pos < 4 )
+        {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+
+        int len = deserializeInt( buffer, pos );
+        pos += 4;
+
+        if ( len > 0 )
+        {
+            if ( buffer.length - pos < len )
+            {
+                throw new ArrayIndexOutOfBoundsException();
+            }
+
+            byte[] result = new byte[len];
+
+            System.arraycopy( buffer, pos, result, 0, len );
+
+            return result;
+        }
+        else
+        {
+            return Strings.EMPTY_BYTES;
+        }
+    }
+
+
+    /**
+     * Read a boolean from a buffer at a given position
+     * 
+     * @param buffer The buffer containing the serialized boolean
+     * @param pos The position from which we will read a boolean
+     * @return the deserialized boolean
+     */
+    public static boolean deserializeBoolean( byte[] buffer, int pos )
+    {
+        if ( buffer.length - pos < 1 )
+        {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+
+        byte value = buffer[pos];
+
+        return ( value != 0x00 );
+    }
+}



Mime
View raw message