You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2004/03/12 07:39:34 UTC

svn commit: rev 9379 - in incubator/directory/snickers/trunk/ber: . src/java/org/apache/snickers/ber src/test/org/apache/snickers/ber

Author: akarasulu
Date: Thu Mar 11 22:39:34 2004
New Revision: 9379

Added:
   incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/BERDecoderStateTest.java
   incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/TypeClassTest.java
Modified:
   incubator/directory/snickers/trunk/ber/project.xml
   incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/AbstractDecoderTestCase.java
   incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/BERDecoder.java
   incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/BERDecoderState.java
   incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/Tuple.java
   incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/TypeClass.java
   incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/BERDecoderTest.java
   incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/ConstructedTLVTests.java
   incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/MultiByteLengthTests.java
   incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/MultiByteTagTests.java
   incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/SimplePrimitiveTLVTests.java
   incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/SingleByteLengthTests.java
   incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/SingleByteTagTests.java
   incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/TupleTest.java
   incubator/directory/snickers/trunk/ber/todo.txt
Log:
* Tried to the best of our ability to write sophisticated unit tests to test 
  every aspect of the decoder using these new overloads.  Added many more
  test cases - gots lots o coverage now.
  



Modified: incubator/directory/snickers/trunk/ber/project.xml
==============================================================================
--- incubator/directory/snickers/trunk/ber/project.xml	(original)
+++ incubator/directory/snickers/trunk/ber/project.xml	Thu Mar 11 22:39:34 2004
@@ -3,6 +3,7 @@
   <extend>${basedir}/../project.xml</extend>
   <groupId>directory</groupId>
   <id>snickers-ber-api</id>
+  <version>1.0</version>
   
   <name>Snickers BER API</name>
   <package>org.apache.snickers.ber</package>

Modified: incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/AbstractDecoderTestCase.java
==============================================================================
--- incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/AbstractDecoderTestCase.java	(original)
+++ incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/AbstractDecoderTestCase.java	Thu Mar 11 22:39:34 2004
@@ -17,6 +17,7 @@
 package org.apache.snickers.ber ;
 
 
+import java.util.Stack ;
 import java.nio.ByteBuffer ;
 import java.util.ArrayList ;
 
@@ -41,31 +42,12 @@
 public abstract class AbstractDecoderTestCase extends TestCase 
     implements BERDecoderCallback, DecoderMonitor
 {
+    /** list of encountered TLV's as we recieve completed decode callbacks */
     protected ArrayList tlvList = new ArrayList() ;
+    /** the decoder that is constructed every time */
     protected BERDecoder decoder = null ;
     
 
-    /**
-     * Arguments should be concrete junit testcase classes.
-     * 
-     * @param args concrete junit testcase classes.
-     */
-    public static void main( String[] args )
-    {
-        try 
-        {
-            for ( int ii = 0; ii < args.length; ii++ )
-            {    
-                junit.textui.TestRunner.run( Class.forName( args[ii] ) ) ;
-            }
-        }
-        catch ( ClassNotFoundException e )
-        {
-            e.printStackTrace() ;
-        }
-    }
-
-    
     /*
      * @see TestCase#setUp()
      */
@@ -74,6 +56,7 @@
         super.setUp() ;
         decoder = new BERDecoder() ;
         decoder.setCallback( this ) ;
+        decoder.setDecoderMonitor( this ) ;
     }
 
     
@@ -99,6 +82,53 @@
     
     
     /**
+     * Fragments an array of bytes into multiple arrays 'attempting' to keep 
+     * them the same size however the last fragment will be an array 
+     * bites.length%size which may or may not be of the requested fragment size.
+     * However it will never be greater.  Use this method to break appart TLV 
+     * byte arrays to feed them into the decoder for testing.
+     * 
+     * @param bites the bites to fragment
+     * @param size the maximum size of a fragment
+     * @return the array of byte[] fragments
+     */
+    public byte[][] fragment( byte[] bites, int size )
+    {
+        byte[][] fragments = null ;
+        int wholeFrags = bites.length/size ;
+        int partialFragSize = bites.length % size ; 
+
+        /*
+         * Allocate what we need depending on the size of our remainder
+         */
+        if ( partialFragSize == 0 ) 
+        {
+            fragments = new byte[wholeFrags][] ;
+        }
+        else
+        {
+            fragments = new byte[wholeFrags+1][] ;
+            fragments[wholeFrags] = new byte[partialFragSize] ;
+        }
+        
+        for ( int ii = 0; ii < wholeFrags; ii++ )
+        {
+            fragments[ii] = new byte[size] ;
+            System.arraycopy( bites, ii * size, fragments[ii], 0, size ) ;
+        }
+        
+        if ( partialFragSize != 0 )
+        {
+            int srcPos = wholeFrags * size ;
+            byte[] src = fragments[wholeFrags] ;
+            System.arraycopy( bites, srcPos, src, 0, partialFragSize ) ;
+        }
+        
+        return fragments ;
+    }
+    
+    
+    /**
      * BER decodes a string of 0's and 1's.
      * 
      * @param bitString a string of ascii 0's and 1's
@@ -181,7 +211,16 @@
         
         if ( tlvList.isEmpty() || tlvList.size() == lastSize )
         {
-            return decoder.getCurrentTuple() ;
+            Stack stack = decoder.getTupleStack() ;
+            
+            if ( stack.isEmpty() )
+            {    
+                return decoder.getCurrentTuple() ;
+            }
+            else
+            {
+                return ( Tuple ) stack.peek() ;
+            }
         }
         
         return ( Tuple ) tlvList.get( tlvList.size() - 1 ) ;

Modified: incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/BERDecoder.java
==============================================================================
--- incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/BERDecoder.java	(original)
+++ incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/BERDecoder.java	Thu Mar 11 22:39:34 2004
@@ -116,12 +116,14 @@
         {
             String msg = "ignoring null argument to decode()" ;
             monitor.warning( this, new IllegalArgumentException( msg ) ) ;
+            return ;
         }
 
         if ( buf.remaining() == 0 && monitor != null )
         {
             String msg = "ignoring empty buffer" ;
             monitor.warning( this, new IllegalArgumentException( msg ) ) ;
+            return ;
         }
         
         /*
@@ -137,10 +139,13 @@
             {
                 case( BERDecoderState.TAG_VAL ):
                     decodeTag( buf ) ;
+                    break ;
                 case( BERDecoderState.LENGTH_VAL ):
                     decodeLength( buf ) ;
+                    break ;
                 case( BERDecoderState.VALUE_VAL ):
                     decodeValue( buf ) ;
+                    break ;
             }
         }
     }
@@ -200,6 +205,10 @@
                 tagBuffer.clear() ;
                 cb.tagDecoded( tlv ) ;
                 state = state.getNext( tlv.isPrimitive ) ;
+                
+                // we moved by one byte so we update stack indices by 1
+                updateStack( 1 ) ;
+
                 return ;
             }
             
@@ -212,9 +221,14 @@
             if ( ( octet & Binary.BIT_7 ) == 0 )
             {
                 tlv.id = BERUtils.getTagId( tagBuffer ) ;
+
+                // we moved by many bytes so we update stack accordingly
+                updateStack( tagBuffer.size() ) ;
+
                 tagBuffer.clear() ;
                 cb.tagDecoded( tlv ) ;
                 state = state.getNext( tlv.isPrimitive ) ;
+                
                 return ;
             }
         }
@@ -258,7 +272,10 @@
                         tlv.clear() ;
                         state = BERDecoderState.TAG ;
                     }
-                    
+
+                    // we moved by one byte so we update stack indices by 1
+                    updateStack( 1 ) ;
+                    handleIndefinateTerminator() ;
                     return ;
                 }
                 // the indefinate form of the length
@@ -273,6 +290,9 @@
                     tlvStack.push( tlv.clone() ) ;
                     tlv.clear() ;
                     state = BERDecoderState.TAG ;
+
+                    // we moved by one byte so we update stack indices by 1
+                    updateStack( 1 ) ;
                     return ;
                 }
             }
@@ -301,57 +321,19 @@
                     state = BERDecoderState.TAG ;
                 }
                 
+                /*
+                 * we moved by one byte + lengthOfLength so we update stack 
+                 * indices by lengthOfLength + 1 
+                 */
+                updateStack( lengthOfLength + 1 ) ;
                 return ;
             }
         }
     }
+
     
-    
-    /**
-     * Extracts the value portion from the buffer for a primitive type.
-     * 
-     * @param buf the byte byffer containing BER encoded data 
-     */
-    private void decodeValue( ByteBuffer buf ) throws DecoderException
+    private void handleIndefinateTerminator()
     {
-        byte[] value = ( byte [] ) tlv.value ;
-        int offset = UNDEFINED ;
-        int needToRead = UNDEFINED ;
-
-        if ( ! tlv.isPrimitive )
-        {
-            IllegalStateException e = new IllegalStateException( 
-                    "should only be working with primitive tlv" ) ;
-            
-            if ( monitor == null )
-            {    
-                throw e ;
-            }
-            else
-            {
-                monitor.fatalError( this, e ) ;
-            }
-            
-            return ;
-        }
-        
-        if ( buf == null )
-        {
-            IllegalArgumentException e = new IllegalArgumentException(
-                    "got null buffer" ) ;
-            
-            if ( monitor == null )
-            {    
-                throw e ;
-            }
-            else
-            {
-                monitor.warning( this, e ) ;
-            }
-            
-            return ;
-        }
-        
         /*
          * Check for a INDEFINATE length TLV when tlv is primitive with 
          * zero length and a type class of UNIVERSAL which is reserved
@@ -366,16 +348,12 @@
                 IllegalStateException e = new IllegalStateException(
                          msg + " but the stack is empty" ) ;
                     
-                if ( monitor == null )
-                {
-                    throw e ;
-                }
-                else
+                if ( monitor != null )
                 {
                     monitor.fatalError( this, e ) ;
                 }
                     
-                return ;
+                throw e ;
             }
 
             Tuple top = ( Tuple ) tlvStack.peek() ;
@@ -400,13 +378,25 @@
             cb.decodeOccurred( this, top ) ;
             tlv.clear() ;
             state = BERDecoderState.TAG ;
-            return ;
         }
-        
-        if ( ! buf.hasRemaining() )
+    }
+    
+    
+    /**
+     * Extracts the value portion from the buffer for a primitive type.
+     * 
+     * @param buf the byte byffer containing BER encoded data 
+     */
+    private void decodeValue( ByteBuffer buf ) throws DecoderException
+    {
+        byte[] value = ( byte [] ) tlv.value ;
+        int offset = UNDEFINED ;
+        int needToRead = UNDEFINED ;
+
+        if ( ! tlv.isPrimitive )
         {
-            IllegalArgumentException e = new IllegalArgumentException(
-                    "got an empty buffer" ) ;
+            IllegalStateException e = new IllegalStateException( 
+                    "should only be working with primitive tlv" ) ;
             
             if ( monitor == null )
             {    
@@ -414,16 +404,20 @@
             }
             else
             {
-                monitor.warning( this, e ) ;
+                monitor.fatalError( this, e ) ;
             }
             
             return ;
         }
         
+        if ( ! buf.hasRemaining() )
+        {
+            return ;
+        }
+
         /*
-         * Start decoding the value now:
+         * setup to start decoding the value
          */
-        
         if ( tlv.valueIndex == UNDEFINED )
         {
             needToRead = tlv.length ;
@@ -431,15 +425,19 @@
         }
         else
         {
-            needToRead = tlv.length - tlv.valueIndex - 1 ;
+            needToRead = tlv.length - tlv.valueIndex ;
             offset = tlv.valueIndex ;
         }
         
+        /*
+         * check if we have the remainder of the value to complete the 
+         * TLV within the current buffer - if so we read all of it
+         */
         if ( buf.remaining() >= needToRead )
         {
             buf.get( value, offset, needToRead ) ;
             tlv.valueIndex = tlv.length ;
-            tlv.index += tlv.length ;
+            tlv.index += needToRead ;
             cb.decodeOccurred( this, tlv ) ;
             
             if ( tlvStack.isEmpty() )
@@ -449,24 +447,7 @@
                 return ;
             }
 
-            /*
-             * This is where we update all nested tlv indices and their 
-             * valueIndices.  Also we pop the stack and fire and event if we 
-             * have completed the value of a nested tlv.
-             */
-            for ( int ii = 0; ii < tlvStack.size(); ii++ )
-            {
-                Tuple t = ( Tuple ) tlvStack.get( ii ) ;
-                
-                t.index += tlv.index + 1 ;
-                
-                if ( t.valueIndex == UNDEFINED )
-                {
-                    t.valueIndex = 0 ;
-                }
-                
-                t.valueIndex += tlv.index + 1 ;
-            }
+            updateStack( tlv.index + 1 ) ;
             
             do
             {
@@ -490,15 +471,50 @@
             tlv.clear() ;
             state = BERDecoderState.TAG ;
         }
+        
+        /*
+         * the buffer does not contain the rest of the value we need in order
+         * to complete the current TLV - the value is fragmented so we read
+         * what we can and update indices by that amount.
+         */
         else
         {
+            if ( tlv.valueIndex == UNDEFINED )
+            {
+                tlv.valueIndex = 0 ;
+            }
+            
             int remaining = buf.remaining() ;
             buf.get( value, offset, remaining ) ;
             tlv.valueIndex += remaining ;
+            updateStack( remaining ) ;
         }
     }
     
     
+    /**
+     * Increments the indices of constructed TLV's within the TLV Stack.
+     * 
+     * @param increment the amount to increment indices by.
+     */
+    private void updateStack( int increment )
+    {
+        for ( int ii = 0; ii < tlvStack.size(); ii++ )
+        {
+            Tuple t = ( Tuple ) tlvStack.get( ii ) ;
+                
+            t.index += increment ;
+                
+            if ( t.valueIndex == UNDEFINED )
+            {
+                t.valueIndex = 0 ;
+            }
+                
+            t.valueIndex += increment ;
+        }
+    }
+    
+
     // ------------------------------------------------------------------------
     // Methods used for testing
     // ------------------------------------------------------------------------

Modified: incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/BERDecoderState.java
==============================================================================
--- incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/BERDecoderState.java	(original)
+++ incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/BERDecoderState.java	Thu Mar 11 22:39:34 2004
@@ -159,7 +159,7 @@
      * @param stateName the name of the state
      * @return the BERDecoderState enum for the state name 
      */
-    public final static BERDecoderState getTypeClass( String stateName )
+    public final static BERDecoderState getState( String stateName )
     {
         /*
          * First try and see if a quick reference lookup will resolve the
@@ -238,7 +238,7 @@
      * @param value the value of the state
      * @return the BERDecoderState for the decoder state value
      */
-    public final static BERDecoderState getTypeClass( int value )
+    public final static BERDecoderState getState( int value )
     {
         switch ( value )
         {

Modified: incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/Tuple.java
==============================================================================
--- incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/Tuple.java	(original)
+++ incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/Tuple.java	Thu Mar 11 22:39:34 2004
@@ -199,7 +199,9 @@
     
     
     /**
-     * @return the id
+     * Gets the tag id for this TLV Tuple.
+     * 
+     * @return the tag id
      */
     public int getId()
     {
@@ -208,7 +210,9 @@
     
 
     /**
-     * @return the isPrimitive
+     * Gets whether or not this TLV tuple is primitive or constructed.
+     * 
+     * @return true if it is primitive, false if it is constructed
      */
     public boolean isPrimitive()
     {
@@ -217,16 +221,20 @@
 
     
     /**
-     * @return the length
+     * Gets the value length for this TLV Tuple.
+     * 
+     * @return the length in bytes of the value field for this TLV tuple
      */
-    public int getLength()
+    public int getValueLength()
     {
         return length ;
     }
 
     
     /**
-     * @return the typeClass
+     * Gets the BER TLV TypeClass for this TLV Tuple.
+     * 
+     * @return the BER TLV TypeClass for this TLV Tuple
      */
     public TypeClass getTypeClass()
     {
@@ -235,7 +243,9 @@
 
     
     /**
-     * @return the value
+     * Gets the value field for this TLV Tuple.
+     * 
+     * @return the value field for this TLV Tuple
      */
     public Object getValue()
     {
@@ -243,6 +253,19 @@
     }
     
     
+    /**
+     * Gets the total size of this TLV tuple in bytes.  This includes the
+     * length of the tag field, the length of the length field and the length
+     * of the value filed.
+     * 
+     * @return the total TLV size in bytes
+     */
+    public int size()
+    {
+        return getTagLength() + getLengthLength() + length ;
+    }
+    
+    
     // ------------------------------------------------------------------------
     // Utility methods and java.lang.Object overrides
     // ------------------------------------------------------------------------
@@ -251,7 +274,7 @@
     /**
      * Clears the values of this tuple.
      */
-    public void clear()
+    void clear()
     {
         this.id = 0 ;
         this.index = 0 ;
@@ -498,7 +521,12 @@
      */
     void setLength( byte[] octets, int offset, int lengthBytes )
     {
-        if ( lengthBytes == 1 )
+        if ( length == BERDecoder.INDEFINATE )
+        {
+            octets[offset] |= BIT_6 ;
+            return ;
+        }
+        else if ( lengthBytes == 1 )
         {
             octets[offset] |= length ;
         }
@@ -593,6 +621,11 @@
      */
     public int getLengthLength()
     {
+        if ( length == BERDecoder.INDEFINATE )
+        {
+            return 1 ;
+        }
+        
         if ( length < 0 )
         {
             throw new IllegalArgumentException( "integer overflow makes id " 

Modified: incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/TypeClass.java
==============================================================================
--- incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/TypeClass.java	(original)
+++ incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/TypeClass.java	Thu Mar 11 22:39:34 2004
@@ -35,8 +35,8 @@
  * <li>PRIVATE</li>
  * </ul>
  * 
- * @author <a href="mailto:akarasulu@apache.org">Alex Karasulu</a>
- * @author $Author: akarasulu $
+ * @author <a href="mailto:directory-dev@incubator.apache.org">
+ * Apache Directory Project</a>
  * @version $Rev$
  */
 public class TypeClass extends ValuedEnum
@@ -68,46 +68,64 @@
      * Private constructor so no other instances can be created other than the
      * public static constants in this class.
      *
-     * @param a_name a string name for the enumeration value.
-     * @param a_value the integer value of the enumeration.
+     * @param name a string name for the enumeration value.
+     * @param value the integer value of the enumeration.
      */
-    private TypeClass( final String a_name, final int a_value )
+    private TypeClass( final String name, final int value )
     {
-        super( a_name, a_value ) ;
+        super( name, value ) ;
     }
     
     
     /**
      * Gets the enumeration type for the type class regardless of case.
      * 
-     * @param a_className the type class name
+     * @param className the type class name
      * @return the TypeClass for the name
      */
-    public static TypeClass getTypeClass( String a_className )
+    public static TypeClass getTypeClass( String className )
     {
-        if ( a_className.equalsIgnoreCase( TypeClass.PRIVATE.getName() ) )
+        // check first using == since it will be the predominate use case
+        if ( className == APPLICATION.getName() )
+        {
+            return APPLICATION ;
+        }
+        else if ( className == CONTEXT_SPECIFIC.getName() )
+        {
+            return CONTEXT_SPECIFIC ;
+        }
+        else if ( className == PRIVATE.getName() )
+        {
+            return PRIVATE ;
+        }
+        else if ( className == UNIVERSAL.getName() )
+        {
+            return UNIVERSAL ;
+        }
+        
+        if ( className.equalsIgnoreCase( TypeClass.PRIVATE.getName() ) )
         {
             return TypeClass.PRIVATE ;
         }
         
-        if ( a_className.equalsIgnoreCase( TypeClass.UNIVERSAL.getName() ) )
+        if ( className.equalsIgnoreCase( TypeClass.UNIVERSAL.getName() ) )
         {
             return TypeClass.UNIVERSAL ;
         }
         
-        if ( a_className.equalsIgnoreCase( TypeClass.APPLICATION.getName() ) )
+        if ( className.equalsIgnoreCase( TypeClass.APPLICATION.getName() ) )
         {
             return TypeClass.APPLICATION ;
         }
         
-        if ( a_className.equalsIgnoreCase( 
+        if ( className.equalsIgnoreCase( 
                         TypeClass.CONTEXT_SPECIFIC.getName() ) )
         {
             return TypeClass.CONTEXT_SPECIFIC ;
         }
         
         throw new IllegalArgumentException( "Unknown type class name"
-            + a_className ) ;
+            + className ) ;
     }
     
     
@@ -136,12 +154,12 @@
     /**
      * Gets the ASN.1 type's class using a TLV tag.
      * 
-     * @param a_octet the first octet of the TLV
+     * @param octet the first octet of the TLV
      * @return the TypeClass enumeration for the ASN.1 type's class
      */
-    public static TypeClass getTypeClass( int a_octet )
+    public static TypeClass getTypeClass( int octet )
     {
-        int l_value = a_octet & PRIVATE_VAL ;
+        int l_value = octet & PRIVATE_VAL ;
         
         switch ( l_value )
         {

Added: incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/BERDecoderStateTest.java
==============================================================================
--- (empty file)
+++ incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/BERDecoderStateTest.java	Thu Mar 11 22:39:34 2004
@@ -0,0 +1,171 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.snickers.ber ;
+
+
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase ;
+
+
+/**
+ * Tests the 
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">
+ * Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class BERDecoderStateTest extends TestCase
+{
+
+    public static void main(String[] args)
+    {
+        junit.textui.TestRunner.run(BERDecoderStateTest.class);
+    }
+
+    /*
+     * @see TestCase#setUp()
+     */
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+    }
+
+    /*
+     * @see TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception
+    {
+        super.tearDown();
+    }
+
+    /**
+     * Constructor for BERDecoderStateTest.
+     * @param arg0
+     */
+    public BERDecoderStateTest(String arg0)
+    {
+        super(arg0);
+    }
+
+    public void testGetNext()
+    {
+        BERDecoderState state = BERDecoderState.getStartState() ;
+        
+        assertEquals( BERDecoderState.TAG, state ) ;
+        state = state.getNext( true ) ;
+        assertEquals( BERDecoderState.LENGTH, state ) ;
+        state = state.getNext( true ) ;
+        assertEquals( BERDecoderState.VALUE, state ) ;
+
+        state = state.getNext( true ) ;
+        assertEquals( BERDecoderState.TAG, state ) ;
+        state = state.getNext( true ) ;
+        assertEquals( BERDecoderState.LENGTH, state ) ;
+        state = state.getNext( false ) ;
+        assertEquals( BERDecoderState.TAG, state ) ;
+    }
+
+    public void testIsEndState()
+    {
+        assertFalse( BERDecoderState.TAG.isEndState( true ) ) ;
+        assertFalse( BERDecoderState.TAG.isEndState( false ) ) ;
+        assertFalse( BERDecoderState.LENGTH.isEndState( true ) ) ;
+        assertTrue( BERDecoderState.LENGTH.isEndState( false ) ) ;
+        assertTrue( BERDecoderState.VALUE.isEndState( true ) ) ;
+        assertTrue( BERDecoderState.VALUE.isEndState( false ) ) ;
+    }
+
+    public void testGetStartState()
+    {
+        assertEquals( BERDecoderState.TAG, BERDecoderState.getStartState() ) ;
+    }
+
+    /*
+     * Class to test for BERDecoderState getTypeClass(String)
+     */
+    public void testGetStateString()
+    {
+        assertEquals( BERDecoderState.LENGTH, 
+                BERDecoderState.getState(BERDecoderState.LENGTH.getName()) ) ;
+        assertEquals( BERDecoderState.TAG, 
+                BERDecoderState.getState(BERDecoderState.TAG.getName()) ) ;
+        assertEquals( BERDecoderState.VALUE, 
+                BERDecoderState.getState(BERDecoderState.VALUE.getName()) ) ;
+        
+        assertEquals( BERDecoderState.LENGTH, 
+                BERDecoderState.getState("length") ) ;
+        assertEquals( BERDecoderState.TAG, 
+                BERDecoderState.getState("TAG") ) ;
+        assertEquals( BERDecoderState.VALUE, 
+                BERDecoderState.getState("value") ) ;
+        
+        try
+        {
+            BERDecoderState.getState("asdf") ;
+            fail( "should not be reached due to thrown exception" ) ;
+        }
+        catch ( Throwable t )
+        {
+            assertNotNull( t ) ;
+        }
+    }
+
+    public void testList()
+    {
+        List list = BERDecoderState.list() ;
+        assertNotNull( list ) ;
+        assertEquals( 3, list.size() ) ;
+        assertTrue( list.contains( BERDecoderState.LENGTH ) ) ;
+        assertTrue( list.contains( BERDecoderState.TAG ) ) ;
+        assertTrue( list.contains( BERDecoderState.VALUE ) ) ;
+    }
+
+    public void testMap()
+    {
+        Map map = BERDecoderState.map() ;
+        assertNotNull( map ) ;
+        assertEquals( 3, map.size() ) ;
+        assertTrue( map.containsKey( BERDecoderState.VALUE.getName() ) ) ;
+        assertTrue( map.containsKey( BERDecoderState.LENGTH.getName() ) ) ;
+        assertTrue( map.containsKey( BERDecoderState.TAG.getName() ) ) ;
+    }
+
+    /*
+     * Class to test for BERDecoderState getTypeClass(int)
+     */
+    public void testGetStateint()
+    {
+        assertEquals( BERDecoderState.LENGTH, 
+                BERDecoderState.getState(BERDecoderState.LENGTH_VAL) ) ;
+        assertEquals( BERDecoderState.TAG, 
+                BERDecoderState.getState(BERDecoderState.TAG_VAL) ) ;
+        assertEquals( BERDecoderState.VALUE, 
+                BERDecoderState.getState(BERDecoderState.VALUE_VAL) ) ;
+        
+        try
+        {
+            BERDecoderState.getState( 293847 ) ;
+            fail( "should not be reached due to thrown exception" ) ;
+        }
+        catch ( Throwable t )
+        {
+            assertNotNull( t ) ;
+        }
+    }
+}

Modified: incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/BERDecoderTest.java
==============================================================================
--- incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/BERDecoderTest.java	(original)
+++ incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/BERDecoderTest.java	Thu Mar 11 22:39:34 2004
@@ -17,6 +17,9 @@
 package org.apache.snickers.ber ;
 
 
+import java.nio.ByteBuffer;
+
+import org.apache.commons.codec.stateful.DecoderMonitorAdapter;
 import org.apache.commons.lang.ArrayUtils ;
 import org.apache.commons.lang.RandomStringUtils ;
 
@@ -29,7 +32,7 @@
  * Apache Directory Project</a>
  * @version $Rev$
  */
-public class BERDecoderTest extends BERDecoderTestCase
+public class BERDecoderTest extends AbstractDecoderTestCase
 {
     public BERDecoderTest()
     {
@@ -37,6 +40,14 @@
     }
     
     
+    public void testBasisCases() throws Exception
+    {
+        decoder.setDecoderMonitor( new DecoderMonitorAdapter() ) ;
+        decoder.decode( null ) ;
+        decoder.decode( ByteBuffer.wrap( ArrayUtils.EMPTY_BYTE_ARRAY ) ) ;
+    }
+    
+    
     public void testPrimitives() throws Exception
     {
         byte[] bites = null ;
@@ -56,5 +67,90 @@
         assertTrue( decoded.equals( t ) ) ;
         assertEquals( mesg, new String( (byte[]) 
                         decoded.getValue() ) ) ;
+    }
+    
+    
+    public void testConstructedIndefinate() throws Exception
+    {
+        Tuple top = new Tuple( 1, TypeClass.APPLICATION ) ;
+        Tuple t0 = new Tuple( 2, "Hello".getBytes() ) ;
+        Tuple t1 = new Tuple( 3, "World".getBytes() ) ;
+        Tuple terminator = new Tuple( 0, TypeClass.UNIVERSAL, true, 
+                ArrayUtils.EMPTY_BYTE_ARRAY ) ;
+        assertTrue( decode( top ).equals( top ) ) ;
+
+        Tuple decoded = decode( t0 ) ; 
+        assertTrue( decoded.equals( t0 ) ) ;
+        assertEquals( "Hello", new String( ( byte[] ) decoded.getValue() ) ) ;
+        
+        decoded = decode( t1 ) ; 
+        assertTrue( decoded.equals( t1 ) ) ;
+        assertEquals( "World", new String( ( byte[] ) decoded.getValue() ) ) ;
+        
+        decoded = decode( terminator ) ;
+        assertTrue( decoded.equals( top ) ) ;
+    }
+    
+    
+    public void testConstructedLongLengthForm() throws Exception
+    {
+        String str0 = RandomStringUtils.randomAlphanumeric(10000) ;
+        Tuple t0 = new Tuple( 2, str0.getBytes() ) ;
+        String str1 = RandomStringUtils.randomAlphanumeric(10000) ;
+        Tuple t1 = new Tuple( 3, str1.getBytes() ) ;
+        Tuple top = new Tuple( 1, t0.size() + t1.size() ) ;
+        assertTrue( decode( top ).equals( top ) ) ;
+
+        Tuple decoded = decode( t0 ) ; 
+        assertTrue( decoded.equals( t0 ) ) ;
+        assertEquals( str0, new String( ( byte[] ) decoded.getValue() ) ) ;
+        
+        // automatically set to top because after t1 is delivered top is 
+        decoded = decode( t1 ) ; 
+        assertTrue( decoded.equals( top ) ) ;
+    }
+
+
+    public void testConstructedShortLengthForm() throws Exception
+    {
+        Tuple t0 = new Tuple( 2, "Hello".getBytes() ) ;
+        Tuple t1 = new Tuple( 3, "World".getBytes() ) ;
+        Tuple top = new Tuple( 1, t0.size() + t1.size() ) ;
+        assertTrue( decode( top ).equals( top ) ) ;
+
+        Tuple decoded = decode( t0 ) ; 
+        assertTrue( decoded.equals( t0 ) ) ;
+        assertEquals( "Hello", new String( ( byte[] ) decoded.getValue() ) ) ;
+        
+        // automatically set to top because after t1 is delivered top is 
+        decoded = decode( t1 ) ; 
+        assertTrue( decoded.equals( top ) ) ;
+    }
+    
+    
+    public void testFragmentedValue() throws Exception
+    {
+        String str0 = RandomStringUtils.randomAlphanumeric(20) ;
+        Tuple t0 = new Tuple( 2, str0.getBytes() ) ;
+        String str1 = RandomStringUtils.randomAlphanumeric(20) ;
+        Tuple t1 = new Tuple( 3, str1.getBytes() ) ;
+        Tuple top = new Tuple( 1, t0.size() + t1.size() ) ;
+        assertTrue( decode( top ).equals( top ) ) ;
+
+        byte[] all = t0.encode() ;
+        byte[][] fragments = fragment( all, 10 ) ;
+        Tuple decoded = null ;
+        
+        for ( int ii = 0; ii < fragments.length; ii++ )
+        {
+            decoded = decode( fragments[ii] ) ;
+        }
+        
+        assertTrue( decoded.equals( t0 ) ) ;
+        assertEquals( str0, new String( ( byte[] ) decoded.getValue() ) ) ;
+        
+        // automatically set to top because after t1 is delivered top is 
+        decoded = decode( t1 ) ; 
+        assertTrue( decoded.equals( top ) ) ;
     }
 }

Modified: incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/ConstructedTLVTests.java
==============================================================================
--- incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/ConstructedTLVTests.java	(original)
+++ incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/ConstructedTLVTests.java	Thu Mar 11 22:39:34 2004
@@ -24,7 +24,7 @@
  * Apache Directory Project</a>
  * @version $Rev$
  */
-public class ConstructedTLVTests extends BERDecoderTestCase
+public class ConstructedTLVTests extends AbstractDecoderTestCase
 {
 
     /**
@@ -72,6 +72,8 @@
 
     public void testMultipleIndefinateTLV() throws Exception
     {
+        // --------------------------------------------------------------------
+        
         // decode tag
         Tuple outter = decode( "01100001" ) ;
         assertEquals( 1, outter.id ) ;
@@ -83,6 +85,10 @@
         // decode length 
         outter = decode( "10000000" ) ;
         assertEquals( BERDecoderState.TAG, decoder.getState() ) ;
+
+        
+        // --------------------------------------------------------------------
+
         
         // decode tag
         Tuple tlv = decode( "01000001" ) ;
@@ -105,7 +111,10 @@
         assertNotNull( tlv.value ) ;
         assertEquals( 0x0055, 0x00ff & ( int ) ( (byte[]) tlv.value)[0] ) ;
 
-    
+        
+        // --------------------------------------------------------------------
+
+
         // decode tag
         tlv = decode( "01000001" ) ;
         assertEquals( 1, tlv.id ) ;
@@ -127,6 +136,9 @@
         assertEquals( 0x0055, 0x00ff & ( int ) ( (byte[]) tlv.value)[0] ) ;
 
     
+        // --------------------------------------------------------------------
+
+
         // decode tag
         tlv = decode( "01000001" ) ;
         assertEquals( 1, tlv.id ) ;
@@ -152,5 +164,37 @@
         
         assertEquals( 4, tlvList.size() ) ;
         assertEquals( BERDecoderState.TAG, decoder.getState() ) ;
+    }
+
+
+    public void testIllegalState() throws Exception
+    {
+        try 
+        {
+            decode( "00000000" ) ;
+            decode( "00000000" ) ;
+            fail( "should throw an exception before getting here" ) ;
+        }
+        catch( Throwable e ) 
+        {
+            assertNotNull( e ) ;
+        }
+    }
+
+
+    public void testIllegalStateNoMonitor() throws Exception
+    {
+        decoder.setDecoderMonitor( null ) ;
+        
+        try 
+        {
+            decode( "00000000" ) ;
+            decode( "00000000" ) ;
+            fail( "should throw an exception before getting here" ) ;
+        }
+        catch( Throwable e ) 
+        {
+            assertNotNull( e ) ;
+        }
     }
 }

Modified: incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/MultiByteLengthTests.java
==============================================================================
--- incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/MultiByteLengthTests.java	(original)
+++ incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/MultiByteLengthTests.java	Thu Mar 11 22:39:34 2004
@@ -24,7 +24,7 @@
  * Apache Directory Project</a>
  * @version $Rev$
  */
-public class MultiByteLengthTests extends BERDecoderTestCase
+public class MultiByteLengthTests extends AbstractDecoderTestCase
 {
     /**
      * Creates a single byte lenth test case.

Modified: incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/MultiByteTagTests.java
==============================================================================
--- incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/MultiByteTagTests.java	(original)
+++ incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/MultiByteTagTests.java	Thu Mar 11 22:39:34 2004
@@ -25,7 +25,7 @@
  * Apache Directory Project</a>
  * @version $Rev$
  */
-public class MultiByteTagTests extends BERDecoderTestCase
+public class MultiByteTagTests extends AbstractDecoderTestCase
 {
 
     /**

Modified: incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/SimplePrimitiveTLVTests.java
==============================================================================
--- incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/SimplePrimitiveTLVTests.java	(original)
+++ incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/SimplePrimitiveTLVTests.java	Thu Mar 11 22:39:34 2004
@@ -24,7 +24,7 @@
  * Apache Directory Project</a>
  * @version $Rev$
  */
-public class SimplePrimitiveTLVTests extends BERDecoderTestCase
+public class SimplePrimitiveTLVTests extends AbstractDecoderTestCase
 {
 
     /**

Modified: incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/SingleByteLengthTests.java
==============================================================================
--- incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/SingleByteLengthTests.java	(original)
+++ incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/SingleByteLengthTests.java	Thu Mar 11 22:39:34 2004
@@ -24,7 +24,7 @@
  * Apache Directory Project</a>
  * @version $Rev$
  */
-public class SingleByteLengthTests extends BERDecoderTestCase
+public class SingleByteLengthTests extends AbstractDecoderTestCase
 {
     /**
      * Creates a single byte lenth test case.

Modified: incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/SingleByteTagTests.java
==============================================================================
--- incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/SingleByteTagTests.java	(original)
+++ incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/SingleByteTagTests.java	Thu Mar 11 22:39:34 2004
@@ -25,7 +25,7 @@
  * Apache Directory Project</a>
  * @version $Rev$
  */
-public class SingleByteTagTests extends BERDecoderTestCase
+public class SingleByteTagTests extends AbstractDecoderTestCase
 {
 
     /**
@@ -72,14 +72,26 @@
     
     public void testUniTypeClass() throws Exception
     {
-        Tuple tlv = decode( "00000001" ) ;
+        Tuple tlv = decode( "01000001" ) ;
         assertEquals( 1, tlv.id ) ;
         assertEquals( 0, tlvList.size() ) ;
         assertEquals( true, tlv.isPrimitive ) ;
-        assertEquals( TypeClass.UNIVERSAL, tlv.typeClass ) ;
+        assertEquals( TypeClass.APPLICATION, tlv.typeClass ) ;
         assertEquals( BERDecoderState.LENGTH, decoder.getState() ) ;
-    }
 
+    }
+    
+    public void testIllegalStateWithUniTypeClass() throws Exception
+    {
+        try
+        {
+            Tuple tlv = decode( "00000001" ) ;
+        }
+        catch( IllegalStateException e ) 
+        {
+            assertNotNull( e ) ;
+        }
+    }
 
     public void testId1() throws Exception
     {

Modified: incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/TupleTest.java
==============================================================================
--- incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/TupleTest.java	(original)
+++ incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/TupleTest.java	Thu Mar 11 22:39:34 2004
@@ -123,14 +123,14 @@
         assertEquals( 2, t.getId() ) ;
         assertEquals( TypeClass.PRIVATE, t.getTypeClass() ) ;
         assertEquals( true, t.isPrimitive() ) ;
-        assertEquals( 0, t.getLength() ) ;
+        assertEquals( 0, t.getValueLength() ) ;
         assertEquals( ArrayUtils.EMPTY_BYTE_ARRAY, t.getValue() ) ;
 
         t = new Tuple( 2, TypeClass.PRIVATE, true, null ) ;
         assertEquals( 2, t.getId() ) ;
         assertEquals( TypeClass.PRIVATE, t.getTypeClass() ) ;
         assertEquals( true, t.isPrimitive() ) ;
-        assertEquals( 0, t.getLength() ) ;
+        assertEquals( 0, t.getValueLength() ) ;
         assertEquals( ArrayUtils.EMPTY_BYTE_ARRAY, t.getValue() ) ;
 
         byte[] bites = new byte[7] ;
@@ -138,14 +138,14 @@
         assertEquals( 2, t.getId() ) ;
         assertEquals( TypeClass.APPLICATION, t.getTypeClass() ) ;
         assertEquals( false, t.isPrimitive() ) ;
-        assertEquals( 7, t.getLength() ) ;
+        assertEquals( 7, t.getValueLength() ) ;
         assertEquals( bites, t.getValue() ) ;
         
         t = new Tuple( 2, null, false,  null ) ; 
         assertEquals( 2, t.getId() ) ;
         assertEquals( TypeClass.APPLICATION, t.getTypeClass() ) ;
         assertEquals( false, t.isPrimitive() ) ;
-        assertEquals( 0, t.getLength() ) ;
+        assertEquals( 0, t.getValueLength() ) ;
         assertEquals( ArrayUtils.EMPTY_BYTE_ARRAY, t.getValue() ) ;
     }
 
@@ -158,15 +158,15 @@
         assertEquals( 2, t.getId() ) ;
         assertEquals( TypeClass.APPLICATION, t.getTypeClass() ) ;
         assertEquals( true, t.isPrimitive() ) ;
-        assertEquals( 0, t.getLength() ) ;
+        assertEquals( 0, t.getValueLength() ) ;
         assertEquals( ArrayUtils.EMPTY_BYTE_ARRAY, t.getValue() ) ;
         
         byte[] bites = new byte[5] ;
-        t = new Tuple( 2, ArrayUtils.EMPTY_BYTE_ARRAY ) ;
+        t = new Tuple( 2, bites ) ;
         assertEquals( 2, t.getId() ) ;
         assertEquals( TypeClass.APPLICATION, t.getTypeClass() ) ;
         assertEquals( true, t.isPrimitive() ) ;
-        assertEquals( 5, t.getLength() ) ;
+        assertEquals( 5, t.getValueLength() ) ;
         assertEquals( bites, t.getValue() ) ;
     }
 
@@ -179,15 +179,15 @@
         assertEquals( 2, t.getId() ) ;
         assertEquals( TypeClass.APPLICATION, t.getTypeClass() ) ;
         assertEquals( false, t.isPrimitive() ) ;
-        assertEquals( 0, t.getLength() ) ;
+        assertEquals( 0, t.getValueLength() ) ;
         assertEquals( ArrayUtils.EMPTY_BYTE_ARRAY, t.getValue() ) ;
         
         byte[] bites = new byte[5] ;
-        t = new Tuple( 2, false, ArrayUtils.EMPTY_BYTE_ARRAY ) ;
+        t = new Tuple( 2, false, bites ) ;
         assertEquals( 2, t.getId() ) ;
         assertEquals( TypeClass.APPLICATION, t.getTypeClass() ) ;
         assertEquals( false, t.isPrimitive() ) ;
-        assertEquals( 5, t.getLength() ) ;
+        assertEquals( 5, t.getValueLength() ) ;
         assertEquals( bites, t.getValue() ) ;
     }
 
@@ -200,14 +200,14 @@
         assertEquals( 2, t.getId() ) ;
         assertEquals( TypeClass.PRIVATE, t.getTypeClass() ) ;
         assertEquals( false, t.isPrimitive() ) ;
-        assertEquals( BERDecoder.INDEFINATE, t.getLength() ) ;
+        assertEquals( BERDecoder.INDEFINATE, t.getValueLength() ) ;
         assertEquals( ArrayUtils.EMPTY_BYTE_ARRAY, t.getValue() ) ;
 
         t = new Tuple( 2, (TypeClass) null ) ;
         assertEquals( 2, t.getId() ) ;
         assertEquals( TypeClass.APPLICATION, t.getTypeClass() ) ;
         assertEquals( false, t.isPrimitive() ) ;
-        assertEquals( BERDecoder.INDEFINATE, t.getLength() ) ;
+        assertEquals( BERDecoder.INDEFINATE, t.getValueLength() ) ;
         assertEquals( ArrayUtils.EMPTY_BYTE_ARRAY, t.getValue() ) ;
     }
 
@@ -232,11 +232,11 @@
     public void testGetLength()
     {
         Tuple t = new Tuple() ;
-        assertEquals( 0, t.getLength() ) ;
+        assertEquals( 0, t.getValueLength() ) ;
         t = new Tuple( 1, 2 ) ;
-        assertEquals( 2, t.getLength() ) ;
+        assertEquals( 2, t.getValueLength() ) ;
         t.length = 21 ;
-        assertEquals( 21, t.getLength() ) ;
+        assertEquals( 21, t.getValueLength() ) ;
     }
 
     public void testGetTypeClass()
@@ -325,12 +325,15 @@
         t1 = ( Tuple ) t0.clone() ;
         assertTrue( t0.equals( t1 ) ) ;
 
+        // indices are not taken into account in Tuple.equals(Object)
         t0.index = 23 ;
-        assertFalse( t0.equals( t1 ) ) ;
+        t1.index = 33 ;
+        assertTrue( t0.equals( t1 ) ) ;
         t1 = ( Tuple ) t0.clone() ;
         assertTrue( t0.equals( t1 ) ) ;
 
         t0.isPrimitive = false ;
+        t1.isPrimitive = true ;
         assertFalse( t0.equals( t1 ) ) ;
         t1 = ( Tuple ) t0.clone() ;
         assertTrue( t0.equals( t1 ) ) ;
@@ -341,16 +344,20 @@
         assertTrue( t0.equals( t1 ) ) ;
 
         t0.typeClass = TypeClass.PRIVATE ;
+        t1.typeClass = TypeClass.UNIVERSAL ;
         assertFalse( t0.equals( t1 ) ) ;
         t1 = ( Tuple ) t0.clone() ;
         assertTrue( t0.equals( t1 ) ) ;
 
+        // indices are not taken into account in Tuple.equals(Object)
         t0.valueIndex = 23 ;
-        assertFalse( t0.equals( t1 ) ) ;
+        t1.valueIndex = 3 ;
+        assertTrue( t0.equals( t1 ) ) ;
         t1 = ( Tuple ) t0.clone() ;
         assertTrue( t0.equals( t1 ) ) ;
 
         t0.value = new byte[4] ;
+        t1.value = null ;
         assertFalse( t0.equals( t1 ) ) ;
         t1 = ( Tuple ) t0.clone() ;
         assertTrue( t0.equals( t1 ) ) ;

Added: incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/TypeClassTest.java
==============================================================================
--- (empty file)
+++ incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/TypeClassTest.java	Thu Mar 11 22:39:34 2004
@@ -0,0 +1,146 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.snickers.ber ;
+
+
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase ;
+
+
+/**
+ * Tests TypeClass class.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">
+ * Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class TypeClassTest extends TestCase
+{
+
+    public static void main(String[] args)
+    {
+        junit.textui.TestRunner.run(TypeClassTest.class);
+    }
+
+    /*
+     * @see TestCase#setUp()
+     */
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+    }
+
+    /*
+     * @see TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception
+    {
+        super.tearDown();
+    }
+
+    /**
+     * Constructor for TypeClassTest.
+     * @param arg0
+     */
+    public TypeClassTest(String arg0)
+    {
+        super(arg0);
+    }
+
+    /*
+     * Class to test for TypeClass getTypeClass(String)
+     */
+    public void testGetTypeClassString()
+    {
+        assertEquals( TypeClass.APPLICATION, TypeClass.getTypeClass( 
+                        TypeClass.APPLICATION.getName() ) ) ;
+        assertEquals( TypeClass.UNIVERSAL, TypeClass.getTypeClass( 
+                        TypeClass.UNIVERSAL.getName() ) ) ;
+        assertEquals( TypeClass.PRIVATE, TypeClass.getTypeClass( 
+                        TypeClass.PRIVATE.getName() ) ) ;
+        assertEquals( TypeClass.CONTEXT_SPECIFIC, TypeClass.getTypeClass( 
+                        TypeClass.CONTEXT_SPECIFIC.getName() ) ) ;
+
+        assertEquals( TypeClass.APPLICATION, TypeClass.getTypeClass( 
+                        "application") ) ;
+        assertEquals( TypeClass.UNIVERSAL, TypeClass.getTypeClass( 
+                        "Universal" ) ) ;
+        assertEquals( TypeClass.PRIVATE, TypeClass.getTypeClass( 
+                        "PRivatE" ) ) ;
+        assertEquals( TypeClass.CONTEXT_SPECIFIC, TypeClass.getTypeClass( 
+                        "context_specific" ) ) ;
+        
+        try
+        {
+            TypeClass.getTypeClass( "asdf" ) ;
+            fail( "exception should prevent this failure" ) ;
+        }
+        catch ( Throwable t )
+        { 
+            assertNotNull( t ) ;
+        }
+    }
+
+    public void testList()
+    {
+        List list = TypeClass.list() ;
+        assertNotNull( list ) ;
+        assertEquals( 4, list.size() ) ;
+        assertTrue( list.contains( TypeClass.PRIVATE ) ) ;
+        assertTrue( list.contains( TypeClass.UNIVERSAL ) ) ;
+        assertTrue( list.contains( TypeClass.APPLICATION ) ) ;
+        assertTrue( list.contains( TypeClass.CONTEXT_SPECIFIC ) ) ;
+    }
+
+    public void testMap()
+    {
+        Map map = TypeClass.map() ;
+        assertNotNull( map ) ;
+        assertEquals( 4, map.size() ) ;
+        assertTrue( map.containsKey( TypeClass.PRIVATE.getName() ) ) ;
+        assertTrue( map.containsKey( TypeClass.UNIVERSAL.getName() ) ) ;
+        assertTrue( map.containsKey( TypeClass.APPLICATION.getName() ) ) ;
+        assertTrue( map.containsKey( TypeClass.CONTEXT_SPECIFIC.getName() ) ) ;
+    }
+
+    /*
+     * Class to test for TypeClass getTypeClass(int)
+     */
+    public void testGetTypeClassint()
+    {
+        assertEquals( TypeClass.APPLICATION, TypeClass.getTypeClass( 
+                        TypeClass.APPLICATION_VAL ) ) ;
+        assertEquals( TypeClass.PRIVATE, TypeClass.getTypeClass( 
+                        TypeClass.PRIVATE_VAL ) ) ;
+        assertEquals( TypeClass.UNIVERSAL, TypeClass.getTypeClass( 
+                        TypeClass.UNIVERSAL_VAL ) ) ;
+        assertEquals( TypeClass.CONTEXT_SPECIFIC, TypeClass.getTypeClass( 
+                        TypeClass.CONTEXT_SPECIFIC_VAL ) ) ;
+        
+        try
+        {
+            TypeClass.getTypeClass( 35 ) ;
+            fail( "exception should prevent this failure" ) ;
+        }
+        catch( Throwable t )
+        {
+            assertNotNull( t ) ;
+        }
+    }
+}

Modified: incubator/directory/snickers/trunk/ber/todo.txt
==============================================================================
--- incubator/directory/snickers/trunk/ber/todo.txt	(original)
+++ incubator/directory/snickers/trunk/ber/todo.txt	Thu Mar 11 22:39:34 2004
@@ -3,9 +3,6 @@
                                 T O D O   L I S T 
                                 =================
 
-* Try to the best of our ability to write sophisticated unit tests to test 
-  every aspect of the decoder using these new overloads.
-  
 * Create a TupleNode interface to nest TLV's to easily generate constructed
   TLV's.