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/14 21:52:39 UTC

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

Author: akarasulu
Date: Sun Mar 14 12:52:39 2004
New Revision: 9467

Added:
   incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/BERDecoderMonitor.java
   incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/SnickersDecoderTest.java
   incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/EncodeDecodeTests.java
Modified:
   incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/SnickersDecoder.java
   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/DefaultMutableTupleNode.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/TupleTreeDecoder.java
   incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/LdapMessageTests.java
   incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/TupleTest.java
Log:
adding some more stuff but tests broke - prep before branching

Modified: incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/SnickersDecoder.java
==============================================================================
--- incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/SnickersDecoder.java	(original)
+++ incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/SnickersDecoder.java	Sun Mar 14 12:52:39 2004
@@ -18,7 +18,6 @@
 
 
 import java.nio.ByteBuffer ;
-import java.nio.channels.Pipe ;
 import java.io.ByteArrayInputStream ;
 
 import org.apache.commons.codec.DecoderException ;
@@ -99,7 +98,6 @@
      */
     public synchronized Message decode( TupleNode root ) throws DecoderException
     {
-        Pipe pipe = null ;
         ByteBuffer buf = ByteBuffer.allocate( root.size() ) ;
         root.encode( buf ) ;
         buf.flip() ;

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	Sun Mar 14 12:52:39 2004
@@ -324,7 +324,12 @@
     {
         assertEquals( this, cb ) ;
         assertEquals( this.decoder, decoder ) ;
-        assertTrue( this.decoder.getCurrentTuple().equals( decoded ) ) ;
+        Tuple t = ( Tuple ) decoded ;
+        assertNotNull( t ) ;
+        if ( t.isPrimitive )
+        {    
+            assertTrue( this.decoder.getCurrentTuple().equals( decoded ) ) ;
+        }
     }
 
     

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	Sun Mar 14 12:52:39 2004
@@ -58,11 +58,6 @@
  */
 public class BERDecoder implements StatefulDecoder
 {
-    /** used to mark indices as undefined */ 
-    public static final int UNDEFINED = -1 ;
-    /** used to mark lengths and indices and indefinate */
-    public static final int INDEFINATE = -2 ;
-    
     public static final BERDecoderCallback DEFAULT_CALLBACK = 
         new BERDecoderCallbackAdapter() ;
     public static final DecoderMonitor DEFAULT_MONITOR =
@@ -202,13 +197,11 @@
                 
                 // its the short form so we get the id, switch state & return
                 tlv.id = id ;
-                tagBuffer.clear() ;
-                cb.tagDecoded( tlv ) ;
+                fireTagDecoded() ;
                 state = state.getNext( tlv.isPrimitive ) ;
                 
                 // we moved by one byte so we update stack indices by 1
                 updateStack( 1 ) ;
-
                 return ;
             }
             
@@ -221,14 +214,11 @@
             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 ) ;
+                fireTagDecoded() ;
                 state = state.getNext( tlv.isPrimitive ) ;
                 
+                // we moved by many bytes so we update stack accordingly
+                updateStack( tagBuffer.size() ) ;
                 return ;
             }
         }
@@ -257,36 +247,40 @@
                 {
                     lengthOfLength = 0 ;
                     tlv.length = octet ;
-                    lengthBuffer.clear() ;
-                    tlv.valueIndex = UNDEFINED ;
-                    cb.lengthDecoded( tlv ) ;
+                    tlv.valueIndex = Tuple.UNDEFINED ;
 
                     if ( tlv.isPrimitive )
                     {
-                        state = BERDecoderState.VALUE ;
                         tlv.value = new byte[tlv.length] ;
+                        fireLengthDecoded() ;
+                        state = BERDecoderState.VALUE ;
+                        // we moved by one byte so we update stack indices by 1
+                        updateStack( 1 ) ;
                     }
                     else 
                     {
+                        // We moved by one byte so we update stack indices by 1
+                        // need to do this here so we do not double update the
+                        // current tuple after pushing it onto the stack.
+                        updateStack( 1 ) ;
+
                         tlvStack.push( tlv.clone() ) ;
+                        fireLengthDecoded() ;
                         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
                 else if ( lengthOfLength == 0 )
                 {
-                    lengthOfLength = INDEFINATE ;
-                    tlv.index = INDEFINATE ;
-                    tlv.length = INDEFINATE ;
-                    tlv.valueIndex = UNDEFINED ;
-                    cb.lengthDecoded( tlv ) ;
-                    lengthBuffer.clear() ;
+                    lengthOfLength = Tuple.INDEFINATE ;
+                    tlv.index = Tuple.INDEFINATE ;
+                    tlv.length = Tuple.INDEFINATE ;
+                    tlv.valueIndex = Tuple.UNDEFINED ;
+                    fireLengthDecoded() ;
                     tlvStack.push( tlv.clone() ) ;
                     tlv.clear() ;
                     state = BERDecoderState.TAG ;
@@ -305,18 +299,18 @@
             {
                 lengthOfLength = 0 ;
                 tlv.length = BERUtils.getLength( lengthBuffer ) ;
-                tlv.valueIndex = UNDEFINED ;
-                lengthBuffer.clear() ;
-                cb.lengthDecoded( tlv ) ;
+                tlv.valueIndex = Tuple.UNDEFINED ;
                 
                 if ( tlv.isPrimitive )
                 {
-                    state = BERDecoderState.VALUE ;
                     tlv.value = new byte[tlv.length] ;
+                    fireLengthDecoded() ;
+                    state = BERDecoderState.VALUE ;
                 }
                 else
                 {
                     tlvStack.push( tlv.clone() ) ;
+                    fireLengthDecoded() ;
                     tlv.clear() ;
                     state = BERDecoderState.TAG ;
                 }
@@ -332,57 +326,6 @@
     }
 
     
-    private void handleIndefinateTerminator()
-    {
-        /*
-         * Check for a INDEFINATE length TLV when tlv is primitive with 
-         * zero length and a type class of UNIVERSAL which is reserved
-         * for use by encoding rules.
-         */
-        if ( tlv.id == 0 && tlv.length == 0 && 
-                tlv.typeClass == TypeClass.UNIVERSAL )
-        {
-            String msg = "expected indefinate length TLV on the stack" ;
-
-            if ( tlvStack.isEmpty() )
-            {
-                IllegalStateException e = new IllegalStateException(
-                         msg + " but the stack is empty" ) ;
-                    
-                if ( monitor != null )
-                {
-                    monitor.fatalError( this, e ) ;
-                }
-                    
-                throw e ;
-            }
-
-            Tuple top = ( Tuple ) tlvStack.peek() ;
-            if ( top.length != INDEFINATE )
-            {
-                IllegalStateException e = new IllegalStateException(
-                         msg + " but TLV on top has a definate length" ) ;
-                    
-                if ( monitor == null )
-                {
-                    throw e ;
-                }
-                else
-                {
-                    monitor.fatalError( this, e ) ;
-                }
-                    
-                return ;
-            }
-                
-            tlvStack.pop() ;
-            cb.decodeOccurred( this, top ) ;
-            tlv.clear() ;
-            state = BERDecoderState.TAG ;
-        }
-    }
-    
-    
     /**
      * Extracts the value portion from the buffer for a primitive type.
      * 
@@ -391,8 +334,8 @@
     private void decodeValue( ByteBuffer buf ) throws DecoderException
     {
         byte[] value = ( byte [] ) tlv.value ;
-        int offset = UNDEFINED ;
-        int needToRead = UNDEFINED ;
+        int offset = Tuple.UNDEFINED ;
+        int needToRead = Tuple.UNDEFINED ;
 
         if ( ! tlv.isPrimitive )
         {
@@ -419,7 +362,7 @@
         /*
          * setup to start decoding the value
          */
-        if ( tlv.valueIndex == UNDEFINED )
+        if ( tlv.valueIndex == Tuple.UNDEFINED )
         {
             needToRead = tlv.length ;
             offset = 0 ;
@@ -439,36 +382,8 @@
             buf.get( value, offset, needToRead ) ;
             tlv.valueIndex = tlv.length ;
             tlv.index += needToRead ;
-            cb.decodeOccurred( this, tlv ) ;
-            
-            if ( tlvStack.isEmpty() )
-            {
-                tlv.clear() ;
-                state = BERDecoderState.TAG ;
-                return ;
-            }
-
-            updateStack( tlv.index + 1 ) ;
-            
-            do
-            {
-                Tuple top = ( Tuple ) tlvStack.peek() ;
-                
-                if ( top.length == INDEFINATE )
-                {
-                    break ;
-                }
-                if ( top.valueIndex >= top.length )
-                {
-                    tlvStack.pop() ;
-                    cb.decodeOccurred( this, top ) ;
-                }
-                else
-                {
-                    break ;
-                }
-            } while( tlvStack.size() > 0 ) ;
-
+            fireDecodeOccurred( tlv ) ;
+            updateStack( needToRead ) ;
             tlv.clear() ;
             state = BERDecoderState.TAG ;
         }
@@ -480,7 +395,7 @@
          */
         else
         {
-            if ( tlv.valueIndex == UNDEFINED )
+            if ( tlv.valueIndex == Tuple.UNDEFINED )
             {
                 tlv.valueIndex = 0 ;
             }
@@ -493,6 +408,79 @@
     }
     
     
+    // ------------------------------------------------------------------------
+    // private utility methods
+    // ------------------------------------------------------------------------
+    
+    
+    /**
+     * Fires a tag decoded event by making the appropriate calls to the 
+     * callback and the monitor.   If the monitor is a BERDecoderMonitor with
+     * extended reporting, then those methods are invoked.
+     * 
+     * Also as a side-effect this method clears the tag buffer once it has 
+     * finished notifying the monitor and calling the callback. 
+     */
+    private void fireTagDecoded()
+    {
+        if ( cb != null )
+        {
+            cb.tagDecoded( tlv ) ;
+        }
+        
+        if ( monitor != null && monitor instanceof BERDecoderMonitor )
+        {
+            BERDecoderMonitor berMonitor = ( BERDecoderMonitor ) monitor ;
+            berMonitor.tagDecoded( tlv, tagBuffer.toArray() ) ;
+        }
+        
+        tagBuffer.clear() ;
+    }
+    
+    
+    /**
+     * Fires a length decoded event by making the appropriate calls to the 
+     * callback and the monitor.   If the monitor is a BERDecoderMonitor with
+     * extended reporting, then those methods are invoked.
+     * 
+     * Also as a side-effect this method clears the length buffer once it has 
+     * finished notifying the monitor and calling the callback. 
+     */
+    private void fireLengthDecoded()
+    {
+        if ( cb != null )
+        {
+            cb.lengthDecoded( tlv ) ;
+        }
+        
+        if ( monitor != null && monitor instanceof BERDecoderMonitor )
+        {
+            BERDecoderMonitor berMonitor = ( BERDecoderMonitor ) monitor ;
+            berMonitor.lengthDecoded( tlv, lengthBuffer.toArray() ) ;
+        }
+        
+        lengthBuffer.clear() ;
+    }
+    
+    
+    /**
+     * Fires a complete TLV decoded event by making the appropriate calls to 
+     * the callback and the monitor.
+     */
+    private void fireDecodeOccurred( Tuple tlv )
+    {
+        if ( cb != null )
+        {
+            cb.decodeOccurred( this, tlv ) ;
+        }
+        
+        if ( monitor != null )
+        {
+            monitor.callbackOccured( this, cb, tlv ) ;
+        }
+    }
+
+    
     /**
      * Increments the indices of constructed TLV's within the TLV Stack.
      * 
@@ -506,16 +494,91 @@
                 
             t.index += increment ;
                 
-            if ( t.valueIndex == UNDEFINED )
+            if ( t.valueIndex == Tuple.UNDEFINED )
             {
                 t.valueIndex = 0 ;
             }
                 
             t.valueIndex += increment ;
         }
+        
+        if ( tlvStack.isEmpty() )
+        {
+            return ;
+        }
+        
+        do
+        {
+            Tuple top = ( Tuple ) tlvStack.peek() ;
+                
+            if ( top.isIndefinate() )
+            {
+                break ;
+            }
+            if ( top.valueIndex >= top.length )
+            {
+                tlvStack.pop() ;
+                fireDecodeOccurred( top ) ;
+            }
+            else
+            {
+                break ;
+            }
+        } while( tlvStack.size() > 0 ) ;
     }
     
 
+    private void handleIndefinateTerminator()
+    {
+        /*
+         * Check for a INDEFINATE length TLV when tlv is primitive with 
+         * zero length and a type class of UNIVERSAL which is reserved
+         * for use by encoding rules.
+         */
+        if ( tlv.id == 0 && tlv.length == 0 && 
+                tlv.typeClass == TypeClass.UNIVERSAL )
+        {
+            String msg = "expected indefinate length TLV on the stack" ;
+
+            if ( tlvStack.isEmpty() )
+            {
+                IllegalStateException e = new IllegalStateException(
+                         msg + " but the stack is empty" ) ;
+                    
+                if ( monitor != null )
+                {
+                    monitor.fatalError( this, e ) ;
+                }
+                    
+                throw e ;
+            }
+
+            Tuple top = ( Tuple ) tlvStack.peek() ;
+            if ( top.length != Tuple.INDEFINATE )
+            {
+                IllegalStateException e = new IllegalStateException(
+                         msg + " but TLV on top has a definate length" ) ;
+                    
+                if ( monitor == null )
+                {
+                    throw e ;
+                }
+                else
+                {
+                    monitor.fatalError( this, e ) ;
+                }
+                    
+                return ;
+            }
+                
+            tlvStack.pop() ;
+            fireDecodeOccurred( top ) ;
+            tlv.clear() ;
+            state = BERDecoderState.TAG ;
+        }
+    }
+    
+    
     // ------------------------------------------------------------------------
     // Methods used for testing
     // ------------------------------------------------------------------------

Added: incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/BERDecoderMonitor.java
==============================================================================
--- (empty file)
+++ incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/BERDecoderMonitor.java	Sun Mar 14 12:52:39 2004
@@ -0,0 +1,35 @@
+/*
+ *   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 org.apache.commons.codec.stateful.DecoderMonitor ;
+
+
+/**
+ * A monitor designed for extended BER decoder functionality with greater 
+ * detail to specific BER decoder events.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">
+ * Apache Directory Project</a>
+ * @version $Rev$
+ */
+public interface BERDecoderMonitor extends DecoderMonitor
+{
+    void tagDecoded( Tuple tlv, byte[] tagData ) ;
+    void lengthDecoded( Tuple tlv, byte[] lengthData ) ;
+}

Modified: incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/DefaultMutableTupleNode.java
==============================================================================
--- incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/DefaultMutableTupleNode.java	(original)
+++ incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/DefaultMutableTupleNode.java	Sun Mar 14 12:52:39 2004
@@ -17,7 +17,8 @@
 package org.apache.snickers.ber ;
 
 
-import java.nio.ByteBuffer;
+import java.nio.ByteBuffer ;
+
 import java.util.Iterator ;
 import java.util.ArrayList ;
 import java.util.Enumeration ;
@@ -40,7 +41,7 @@
     implements MutableTupleNode, MutableTreeNode
 {
     private Tuple tuple ;
-    private ArrayList children = new ArrayList();
+    private ArrayList children = new ArrayList() ;
     private DefaultMutableTupleNode parent ;
     
     
@@ -261,14 +262,14 @@
     }
     
     
+    /*
+     * Prinsts some informative information regarding the tlv node. 
+     * 
+     * (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
     public String toString()
     {
-        /**
-        StringBuffer buf = new StringBuffer() ;
-        printDepthFirst( buf, 0 ) ;
-        return buf.toString() ;
-        **/
-
         StringBuffer buf = new StringBuffer() ;
         buf.append( tuple.getId() ) ;
         buf.append( ' ' ).append( tuple.typeClass ) ;
@@ -279,7 +280,36 @@
         return buf.toString() ;
     }
     
+
+    /**
+     * Generates a depth first traversal of this node.
+     * 
+     * @return a depth first traversal print out for this node
+     */
+    public String toDepthFirstString()
+    {
+        StringBuffer buf = new StringBuffer() ;
+        printDepthFirst( buf, 0 ) ;
+        return buf.toString() ;
+    }
+    
     
+    /**
+     * Start analyzing the tree rooted at this node.
+     */
+    public void analyze()
+    {
+        TupleTreeAnalyzer analyzer = new TupleTreeAnalyzer( this ) ;
+        analyzer.startup() ;
+    }
+    
+    
+    /**
+     * Generates a depth first traversal of this node.
+     * 
+     * @param buf the buffer to capture the traversal into
+     * @param level the level down into the tree
+     */
     public void printDepthFirst( StringBuffer buf, int level )
     {
         DefaultMutableTupleNode child = null ;

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	Sun Mar 14 12:52:39 2004
@@ -33,20 +33,25 @@
  */
 public class Tuple
 {
+    /** used to mark lengths and indices and indefinate */
+    public static final int INDEFINATE = -2 ;
+    /** used to mark indices as undefined */ 
+    public static final int UNDEFINED = -1 ;
+
     /** precalculated left shift of 1 by 7 places */
-    public static final int BIT_6 = 1 << 7 ;
+    static final int BIT_6 = 1 << 7 ;
     /** precalculated left shift of 1 by 8 places */
-    public static final int BIT_7 = 1 << 8 ;
+    static final int BIT_7 = 1 << 8 ;
     /** precalculated left shift of 1 by 14 places */
-    public static final int BIT_13 = 1 << 14 ;
+    static final int BIT_13 = 1 << 14 ;
     /** precalculated left shift of 1 by 16 places */
-    public static final int BIT_15 = 1 << 16 ;
+    static final int BIT_15 = 1 << 16 ;
     /** precalculated left shift of 1 by 21 places */
-    public static final int BIT_20 = 1 << 21 ;
+    static final int BIT_20 = 1 << 21 ;
     /** precalculated left shift of 1 by 24 places */
-    public static final int BIT_23 = 1 << 24 ;
+    static final int BIT_23 = 1 << 24 ;
     /** precalculated left shift of 1 by 28 places */
-    public static final int BIT_27 = 1 << 28 ;
+    static final int BIT_27 = 1 << 28 ;
     
     /** the tag id for this TLV tuple */
     int id = 0 ;
@@ -60,9 +65,9 @@
     Object value = ArrayUtils.EMPTY_BYTE_ARRAY ;
     
     /** tlv byte index */
-    int index = BERDecoder.UNDEFINED ;
+    int index = Tuple.UNDEFINED ;
     /** tlv value index for how far into the value we have read */
-    int valueIndex = BERDecoder.UNDEFINED ;
+    int valueIndex = Tuple.UNDEFINED ;
     
     
     // ------------------------------------------------------------------------
@@ -156,7 +161,7 @@
         this.id = id ;
         this.isPrimitive = false ;
         value = ArrayUtils.EMPTY_BYTE_ARRAY ;
-        length = BERDecoder.INDEFINATE ;
+        length = Tuple.INDEFINATE ;
         
         if ( typeClass != null )
         {
@@ -216,7 +221,7 @@
      */
     public boolean isIndefinate()
     {
-        return length == BERDecoder.INDEFINATE ;
+        return length == Tuple.INDEFINATE ;
     }
     
 
@@ -287,7 +292,7 @@
      */
     public int size()
     {
-        if ( this.length == BERDecoder.INDEFINATE )
+        if ( this.length == Tuple.INDEFINATE )
         {    
             return getTagLength() + getLengthLength() ;
         }
@@ -311,10 +316,10 @@
         this.id = 0 ;
         this.index = 0 ;
         this.isPrimitive = true ;
-        this.length = BERDecoder.UNDEFINED ;
+        this.length = Tuple.UNDEFINED ;
         this.typeClass = TypeClass.APPLICATION ;
         this.value = ArrayUtils.EMPTY_BYTE_ARRAY ;
-        this.valueIndex = BERDecoder.UNDEFINED ;
+        this.valueIndex = Tuple.UNDEFINED ;
     }
 
     
@@ -553,7 +558,7 @@
      */
     void setLength( byte[] octets, int offset, int lengthBytes )
     {
-        if ( length == BERDecoder.INDEFINATE )
+        if ( length == Tuple.INDEFINATE )
         {
             octets[offset] |= BIT_6 ;
             return ;
@@ -653,7 +658,7 @@
      */
     public int getLengthLength()
     {
-        if ( length == BERDecoder.INDEFINATE )
+        if ( length == Tuple.INDEFINATE )
         {
             return 1 ;
         }

Modified: incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/TupleTreeDecoder.java
==============================================================================
--- incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/TupleTreeDecoder.java	(original)
+++ incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/TupleTreeDecoder.java	Sun Mar 14 12:52:39 2004
@@ -17,9 +17,11 @@
 package org.apache.snickers.ber ;
 
 
+import java.nio.ByteBuffer;
 import java.util.Stack ;
 
 import org.apache.commons.codec.DecoderException ;
+import org.apache.commons.codec.stateful.CallbackHistory;
 import org.apache.commons.codec.stateful.DecoderMonitor ;
 import org.apache.commons.codec.stateful.DecoderCallback ;
 import org.apache.commons.codec.stateful.StatefulDecoder ;
@@ -64,7 +66,15 @@
                     parent = ( MutableTupleNode ) stack.peek() ;
                     child = new DefaultMutableTupleNode( cloned ) ;
                     child.setParent( parent ) ;
-                    parent.insert( child, 0 ) ;
+                    
+                    int index = parent.getChildCount() - 1 ;
+                    
+                    if ( index < 0 )
+                    {
+                        index = 0 ;
+                    }
+                    
+                    parent.insert( child, index ) ;
                     stack.push( child ) ;
                 }
             }
@@ -94,7 +104,14 @@
             {    
                 MutableTupleNode parent = ( MutableTupleNode ) stack.peek() ;
                 node.setParent( parent ) ;
-                parent.insert( node, 0 ) ;
+                int index = parent.getChildCount() - 1 ;
+                
+                if ( index < 0 ) 
+                {
+                    index = 0 ; 
+                }
+                
+                parent.insert( node, index ) ;
             }
             
             return ;
@@ -116,6 +133,23 @@
     public void decode( Object encoded ) throws DecoderException
     {
         decoder.decode( encoded ) ;
+    }
+    
+    
+    public static TupleNode treeDecode( ByteBuffer buf ) throws DecoderException
+    {
+        TupleTreeDecoder decoder = new TupleTreeDecoder() ;
+        CallbackHistory history = new CallbackHistory( 1 ) ;
+        
+        decoder.setCallback( history ) ;
+        decoder.decode( buf ) ;
+        
+        if ( history.isEmpty() )
+        {
+            return null ;
+        }
+        
+        return ( TupleNode ) history.getMostRecent() ;
     }
     
     

Added: incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/SnickersDecoderTest.java
==============================================================================
--- (empty file)
+++ incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/SnickersDecoderTest.java	Sun Mar 14 12:52:39 2004
@@ -0,0 +1,337 @@
+/*
+ *   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 ;
+
+
+import java.util.ArrayList ;
+
+import java.math.BigInteger ;
+
+import java.nio.ByteBuffer ;
+
+import javax.naming.directory.Attributes ;
+
+import org.apache.commons.codec.stateful.DecoderMonitor ;
+import org.apache.commons.codec.stateful.DecoderCallback ;
+import org.apache.commons.codec.stateful.StatefulDecoder ;
+
+import org.apache.ldap.common.message.Message ;
+import org.apache.ldap.common.message.ScopeEnum ;
+import org.apache.ldap.common.filter.PresenceNode ;
+import org.apache.ldap.common.message.MessageEncoder ;
+import org.apache.ldap.common.message.AddRequestImpl ;
+import org.apache.ldap.common.message.BindRequestImpl ;
+import org.apache.ldap.common.message.DerefAliasesEnum ;
+import org.apache.ldap.common.message.DeleteRequestImpl ;
+import org.apache.ldap.common.message.SearchRequestImpl ;
+import org.apache.ldap.common.message.ModifyRequestImpl ;
+import org.apache.ldap.common.message.AbandonRequestImpl ;
+import org.apache.ldap.common.message.CompareRequestImpl ;
+import org.apache.ldap.common.message.ExtendedRequestImpl ;
+import org.apache.ldap.common.message.ModifyDnRequestImpl ;
+import org.apache.ldap.common.message.LockableAttributesImpl ;
+import org.apache.snickers.ber.TupleNode;
+import org.apache.snickers.ber.TupleTreeDecoder;
+
+import junit.framework.TestCase ;
+
+
+/**
+ * Tests the SnickersDecoder.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">
+ * Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class SnickersDecoderTest extends TestCase 
+    implements DecoderCallback, DecoderMonitor
+{
+    private SnickersDecoder decoder = null ;
+    private ArrayList msgList = new ArrayList() ;
+    
+    
+    /* (non-Javadoc)
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+        
+        decoder = new SnickersDecoder( this ) ;
+        decoder.setDecoderMonitor( this ) ;
+    }
+
+    
+    /* (non-Javadoc)
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception
+    {
+        super.tearDown();
+
+        msgList.clear() ;
+        decoder = null ;
+    }
+    
+    
+    /*
+     * Class to test for Message decode(TupleNode)
+     */
+    public void testDecodeTupleNode() throws Exception
+    {
+        TupleNode node = null ;
+        
+        AddRequestImpl request = new AddRequestImpl( BigInteger.ONE ) ;
+        request.setName( "uid=akarasulu,dc=example,dc=com" ) ;
+        
+        Attributes attrs = new LockableAttributesImpl() ;
+        attrs.put( "attr0", "val0" ) ;
+        attrs.put( "attr0", "val1" ) ;
+        attrs.put( "attr0", "val2" ) ;
+        attrs.put( "attr1", "val0" ) ;
+        attrs.put( "attr2", "val0" ) ;
+        attrs.put( "attr2", "val1" ) ;
+        
+        request.setEntry( attrs ) ;
+        MessageEncoder encoder = new MessageEncoder() ;
+        byte[] bites = encoder.encode( request ) ;
+        ByteBuffer buf = ByteBuffer.wrap( bites ) ;
+        TupleTreeDecoder ttd = new TupleTreeDecoder() ;
+        
+        final ArrayList list = new ArrayList() ;
+        ttd.setCallback( new DecoderCallback(){
+            public void decodeOccurred(StatefulDecoder arg0, Object arg1)
+            {
+                list.add( arg1 ) ;
+            }}) ;
+
+        ttd.decode( buf ) ;
+        node = ( TupleNode ) list.get( 0 ) ;
+        Message msg = decoder.decode( node ) ;
+        assertNotNull( msg ) ;
+    }
+    
+
+    public void decode( Message msg ) throws Exception
+    {
+        MessageEncoder encoder = new MessageEncoder() ;
+        ByteBuffer buf = ByteBuffer.wrap( encoder.encode( msg ) ) ;
+        decoder.decode( buf ) ;
+    }
+    
+
+    public void testBindMessage() throws Exception
+    {
+        BindRequestImpl request = new BindRequestImpl( BigInteger.ONE ) ;
+        request.setName( "uid=akarasulu,dc=example,dc=com" ) ;
+        request.setSimple( true ) ;
+        request.setCredentials( "password".getBytes() ) ;
+        request.setVersion3( true ) ;
+        decode( request ) ;
+        assertFalse( msgList.isEmpty() ) ;
+    }
+
+
+    public void testAddMessage() throws Exception
+    {
+        AddRequestImpl request = new AddRequestImpl( BigInteger.ONE ) ;
+        request.setName( "uid=akarasulu,dc=example,dc=com" ) ;
+        
+        Attributes attrs = new LockableAttributesImpl() ;
+        attrs.put( "attr0", "val0" ) ;
+        attrs.put( "attr0", "val1" ) ;
+        attrs.put( "attr0", "val2" ) ;
+        attrs.put( "attr1", "val0" ) ;
+        attrs.put( "attr2", "val0" ) ;
+        attrs.put( "attr2", "val1" ) ;
+        
+        request.setEntry( attrs ) ;
+        decode( request ) ;
+        assertFalse( msgList.isEmpty() ) ;
+    }
+
+
+    public void testDeleteMessage() throws Exception
+    {
+        DeleteRequestImpl request = new DeleteRequestImpl( BigInteger.ONE ) ;
+        request.setName( "uid=akarasulu,dc=example,dc=com" ) ;
+        decode( request ) ;
+        assertFalse( msgList.isEmpty() ) ;
+    }
+
+
+    public void testAbandonMessage() throws Exception
+    {
+        AbandonRequestImpl request = new AbandonRequestImpl( BigInteger.ONE ) ;
+        request.setAbandoned( new BigInteger( "3" ) ) ;
+        decode( request ) ;
+        assertFalse( msgList.isEmpty() ) ;
+    }
+
+
+    public void testCompareMessage() throws Exception
+    {
+        CompareRequestImpl request = new CompareRequestImpl( BigInteger.ONE ) ;
+        request.setAssertionValue( "testvalue" ) ;
+        request.setAttributeId( "testattr" ) ;
+        request.setName( "uid=akarasulu,dc=example,dc=com" ) ;
+        decode( request ) ;
+        assertFalse( msgList.isEmpty() ) ;
+    }
+
+
+    public void testExtendedMessage() throws Exception
+    {
+        ExtendedRequestImpl request = new ExtendedRequestImpl( BigInteger.ONE ) ;
+        request.setOid( "1234.1234.1324" ) ;
+        request.setPayload( "Hello World".getBytes() ) ;
+        decode( request ) ;
+        assertFalse( msgList.isEmpty() ) ;
+    }
+
+
+    public void testModifyDnMessage() throws Exception
+    {
+        ModifyDnRequestImpl request = new ModifyDnRequestImpl( BigInteger.ONE ) ;
+        request.setDeleteOldRdn(true) ;
+        request.setName( "uid=akarasulu,dc=example,dc=com" ) ;
+        request.setNewRdn( "uid=aok" ) ;
+        request.setNewSuperior( "dc=example,dc=com" ) ;
+        decode( request ) ;
+        assertFalse( msgList.isEmpty() ) ;
+    }
+
+
+    public void testModifyMessage() throws Exception
+    {
+        ModifyRequestImpl request = new ModifyRequestImpl( BigInteger.ONE ) ;
+        request.setName( "uid=akarasulu,dc=example,dc=com" ) ;
+        decode( request ) ;
+        assertFalse( msgList.isEmpty() ) ;
+    }
+
+
+    public void testSearchMessage() throws Exception
+    {
+        SearchRequestImpl request = new SearchRequestImpl( BigInteger.ONE ) ;
+        request.setBase( "uid=akarasulu,dc=example,dc=com" ) ;
+        request.setDerefAliases( DerefAliasesEnum.DEREFALWAYS ) ;
+        PresenceNode node = new PresenceNode( "attrib0" ) ;
+        request.setFilter( node ) ;
+        request.setScope( ScopeEnum.BASEOBJECT ) ;
+        request.setSizeLimit( BigInteger.ZERO ) ;
+        request.setTimeLimit( BigInteger.ZERO ) ;
+        decode( request ) ;
+        assertFalse( msgList.isEmpty() ) ;
+    }
+
+    
+    public void testSetCallback()
+    {
+        decoder.setCallback( this ) ;
+    }
+    
+
+    public void testSetDecoderMonitor()
+    {
+        decoder.setDecoderMonitor( this ) ;
+        assertNotNull( decoder ) ;
+    }
+
+    
+    /* (non-Javadoc)
+     * @see org.apache.commons.codec.stateful.DecoderCallback#decodeOccurred(
+     * org.apache.commons.codec.stateful.StatefulDecoder, java.lang.Object)
+     */
+    public void decodeOccurred( StatefulDecoder arg0, Object message )
+    {
+        msgList.add( message ) ;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.commons.codec.stateful.DecoderMonitor#callbackOccured(
+     * org.apache.commons.codec.stateful.StatefulDecoder, 
+     * org.apache.commons.codec.stateful.DecoderCallback, java.lang.Object)
+     */
+    public void callbackOccured( StatefulDecoder decoder, DecoderCallback cb,
+            Object decoded )
+    {
+        assertSame( decoder, this.decoder ) ;
+        assertSame( this, cb ) ;
+        assertNotNull( decoded ) ;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.commons.codec.stateful.DecoderMonitor#callbackSet(
+     * org.apache.commons.codec.stateful.StatefulDecoder, 
+     * org.apache.commons.codec.stateful.DecoderCallback, 
+     * org.apache.commons.codec.stateful.DecoderCallback)
+     */
+    public void callbackSet( StatefulDecoder decoder, DecoderCallback cb,
+            DecoderCallback ncb )
+    {
+        assertSame(this.decoder, decoder) ;
+        assertNotNull(cb) ;
+        assertNotNull(ncb) ;
+    } 
+
+
+    /* (non-Javadoc)
+     * @see org.apache.commons.codec.stateful.DecoderMonitor#error(
+     * org.apache.commons.codec.stateful.StatefulDecoder, java.lang.Exception)
+     */
+    public void error( StatefulDecoder decoder, Exception e )
+    {
+        assertSame( decoder, this.decoder ) ;
+        assertNotNull( e ) ;
+    }
+    
+    
+    /* (non-Javadoc)
+     * @see org.apache.commons.codec.stateful.DecoderMonitor#fatalError(
+     * org.apache.commons.codec.stateful.StatefulDecoder, java.lang.Exception)
+     */
+    public void fatalError( StatefulDecoder decoder, Exception e )
+    {
+        assertSame( decoder, this.decoder ) ;
+    }
+    
+    
+    /* (non-Javadoc)
+     * @see org.apache.commons.codec.stateful.DecoderMonitor#monitorSet(
+     * org.apache.commons.codec.stateful.StatefulDecoder, 
+     * org.apache.commons.codec.stateful.DecoderMonitor)
+     */
+    public void monitorSet( StatefulDecoder decoder, DecoderMonitor monitor )
+    {
+        assertSame( decoder, this.decoder ) ;
+        assertNotNull( monitor ) ;
+    }
+    
+    
+    /* (non-Javadoc)
+     * @see org.apache.commons.codec.stateful.DecoderMonitor#warning(
+     * org.apache.commons.codec.stateful.StatefulDecoder, java.lang.Exception)
+     */
+    public void warning( StatefulDecoder decoder, Exception e )
+    {
+        assertSame( this.decoder, decoder ) ;
+        assertNotNull( e ) ;
+    }
+}

Added: incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/EncodeDecodeTests.java
==============================================================================
--- (empty file)
+++ incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/EncodeDecodeTests.java	Sun Mar 14 12:52:39 2004
@@ -0,0 +1,80 @@
+/*
+ *   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.nio.ByteBuffer ;
+import java.math.BigInteger ;
+import java.io.ByteArrayInputStream ;
+
+import org.apache.commons.codec.binary.Hex ;
+import org.apache.ldap.common.message.AbandonRequest ;
+import org.apache.ldap.common.message.MessageDecoder ;
+import org.apache.ldap.common.message.MessageEncoder ;
+import org.apache.ldap.common.message.AbandonRequestImpl ;
+
+import junit.framework.TestCase ;
+
+
+/**
+ * Testing out round trip encode decode.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">
+ * Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class EncodeDecodeTests extends TestCase
+{
+    public void testAbandonRequest() throws Exception
+    {
+        DefaultMutableTupleNode root = null ;
+        ByteBuffer buf = null ;
+        AbandonRequestImpl request = new AbandonRequestImpl( BigInteger.ONE ) ;
+        request.setAbandoned( new BigInteger( "3" ) ) ;
+        
+        MessageEncoder encoder = new MessageEncoder() ;
+        byte[] snaccBytes = encoder.encode( request ) ;
+        
+        String snaccEncoded = new String( Hex.encodeHex( snaccBytes ) ) ;
+        System.out.println( "snacc encoded = [" + snaccEncoded + "][" 
+                + snaccBytes.length + "]" ) ;
+        
+        MessageDecoder decoder = new MessageDecoder() ;
+        AbandonRequest msg = ( AbandonRequest ) decoder.decode( null, 
+                new ByteArrayInputStream( snaccBytes ) ) ;
+        assertTrue( msg.getMessageId().equals( request.getMessageId() ) ) ;
+        
+        System.out.println( "snacc decoded = " + msg ) ;
+        
+        root = ( DefaultMutableTupleNode ) 
+            TupleTreeDecoder.treeDecode( ByteBuffer.wrap( snaccBytes ) ) ;
+        //root.analyze() ;
+        
+        if ( root == null )
+        {
+            System.out.println( "nothing decoded" ) ;
+            return ;
+        }
+        
+        buf = ByteBuffer.allocate( root.size() ) ;
+        root.encode( buf ) ;
+        buf.flip() ;
+        byte[] snickersBytes = new byte[buf.remaining()] ;
+        buf.get( snickersBytes ) ;
+        String snickersEncoded = new String( Hex.encodeHex( snickersBytes ) ) ;
+    }
+}

Modified: incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/LdapMessageTests.java
==============================================================================
--- incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/LdapMessageTests.java	(original)
+++ incubator/directory/snickers/trunk/ber/src/test/org/apache/snickers/ber/LdapMessageTests.java	Sun Mar 14 12:52:39 2004
@@ -135,7 +135,8 @@
 
     public void testModifyMessage() throws Exception
     {
-        ModifyRequestImpl request = new ModifyRequestImpl( BigInteger.ONE ) ;
+        ModifyRequestImpl request = 
+            new ModifyRequestImpl( new BigInteger( "17" ) ) ;
         request.setName( "uid=akarasulu,dc=example,dc=com" ) ;
         decode( request ) ;
         assertFalse( tlvList.isEmpty() ) ;

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	Sun Mar 14 12:52:39 2004
@@ -200,14 +200,14 @@
         assertEquals( 2, t.getId() ) ;
         assertEquals( TypeClass.PRIVATE, t.getTypeClass() ) ;
         assertEquals( false, t.isPrimitive() ) ;
-        assertEquals( BERDecoder.INDEFINATE, t.getLength() ) ;
+        assertEquals( Tuple.INDEFINATE, t.getLength() ) ;
         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( Tuple.INDEFINATE, t.getLength() ) ;
         assertEquals( ArrayUtils.EMPTY_BYTE_ARRAY, t.getValue() ) ;
     }
 
@@ -252,7 +252,7 @@
     {
         Tuple t = new Tuple() ;
         assertFalse( t.isIndefinate() ) ;
-        t.length = BERDecoder.INDEFINATE ;
+        t.length = Tuple.INDEFINATE ;
         assertTrue( t.isIndefinate() ) ;
     }
     
@@ -321,7 +321,7 @@
         t.length = 12 ;
         assertEquals( 12, t.length ) ;
         t.clear() ;
-        assertEquals( BERDecoder.UNDEFINED, t.length ) ;
+        assertEquals( Tuple.UNDEFINED, t.length ) ;
 
         t.index = 12 ;
         assertEquals( 12, t.index ) ;
@@ -346,7 +346,7 @@
         t.valueIndex = 12 ;
         assertEquals( 12, t.valueIndex ) ;
         t.clear() ;
-        assertEquals( BERDecoder.UNDEFINED, t.valueIndex ) ;
+        assertEquals( Tuple.UNDEFINED, t.valueIndex ) ;
 
     }