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 2005/02/07 09:06:01 UTC

svn commit: r151709 - in incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1: ./ tag/ tuples/

Author: akarasulu
Date: Mon Feb  7 00:05:54 2005
New Revision: 151709

URL: http://svn.apache.org/viewcvs?view=rev&rev=151709
Log:
changes ...

 o added the hierarchy of tuples discussed

notes ...

 o at this point this is an experiment to play around with some interfaces and
   see it it leads to a more coherent, maintainable and a faster runtime


Added:
    incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TagConsumer.java
    incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TagDecoder.java
      - copied, changed from r151199, incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/ber/Tag.java
    incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TagProducer.java
    incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TagUtils.java
    incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TypeClass.java
      - copied, changed from r151199, incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/ber/TypeClass.java
Modified:
    incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/BufferConsumer.java
    incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/TupleConsumer.java
    incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/AbstractTuple.java
    incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/BufferedTuple.java
    incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/ConstructedTuple.java
    incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/DefinateLengthTuple.java
    incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/IndefinateLengthTuple.java
    incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/PrimitiveTuple.java
    incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/StreamedTuple.java
    incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/Tuple.java

Modified: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/BufferConsumer.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/BufferConsumer.java?view=diff&r1=151708&r2=151709
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/BufferConsumer.java (original)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/BufferConsumer.java Mon Feb  7 00:05:54 2005
@@ -20,6 +20,8 @@
 import java.nio.ByteBuffer;
 import java.util.List;
 
+import org.apache.asn1.codec.DecoderException;
+
 
 /**
  * A ByteBuffer consumer.

Modified: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/TupleConsumer.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/TupleConsumer.java?view=diff&r1=151708&r2=151709
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/TupleConsumer.java (original)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/TupleConsumer.java Mon Feb  7 00:05:54 2005
@@ -17,6 +17,9 @@
 package org.apache.asn1;
 
 
+import org.apache.asn1.tuples.Tuple;
+
+
 /**
  * A Tuple consumer.
  *

Added: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TagConsumer.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TagConsumer.java?view=auto&rev=151709
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TagConsumer.java (added)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TagConsumer.java Mon Feb  7 00:05:54 2005
@@ -0,0 +1,29 @@
+/*
+ *   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.asn1.tag;
+
+
+/**
+ * Document this class.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public interface TagConsumer
+{
+    void consume( Tag tag );
+}

Copied: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TagDecoder.java (from r151199, incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/ber/Tag.java)
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TagDecoder.java?view=diff&rev=151709&p1=incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/ber/Tag.java&r1=151199&p2=incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TagDecoder.java&r2=151709
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/ber/Tag.java (original)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TagDecoder.java Mon Feb  7 00:05:54 2005
@@ -14,105 +14,112 @@
  *   limitations under the License.
  *
  */
-package org.apache.asn1.ber ;
+package org.apache.asn1.tag;
 
 
-import org.apache.asn1.codec.DecoderException ;
+import java.util.List;
+import java.nio.ByteBuffer;
+
+import org.apache.asn1.BufferConsumer;
 
 
 /**
- * The Tag component of a BER TLV Tuple.
+ * A TLV Tuple's tag decoder.  This Tag decoder should work for BER/DER/CER
+ * encodings.
  *
- * @author <a href="mailto:directory-dev@incubator.apache.org">
- * Apache Directory Project</a>
+ * @author <a href="mailto:directory-dev@incubator.apache.org"> Apache Directory Project</a>
  * @version $Rev$
  */
-public class Tag
+public class TagDecoder implements BufferConsumer, TagProducer
 {
-    /** tag flag for the primitive/constructed bit - 0010 0000 - 0x20 */
-    private static final int CONSTRUCTED_FLAG = 0x20 ;
-    /** tag mask for the primitive/constructed bit - 1101 1111 - 0xDF */
-    // private static final int CONSTRUCTED_MASK = ~CONSTRUCTED_FLAG ;
-
-    /** tag mask for the short tag format - 0001 1111 - 0x1F */
-    static final int SHORT_MASK = 0x1F ;
-    /** tag mask for the long tag format - 0111 1111 - 0x7F */
-    static final int LONG_MASK = 0x7F ;
-    /** tag flag indicating the use of the long tag encoding form */
-    private static final int LONG_FLAG = 0x80 ;
-
-    /** the max id size with one tag octet */
-    private static final int ONE_OCTET_IDMAX = 30 ;
-    /** the max id size with two tag octets */
-    private static final int TWO_OCTET_IDMAX = (1<<7)-1 ;
-    /** the max id size with three tag octets */
-    private static final int THREE_OCTET_IDMAX = (1<<14)-1 ;
-    /** the max id size with four tag octets */
-    private static final int FOUR_OCTET_IDMAX = (1<<21)-1 ;
-
-    /** tag id */
-    private int id = 0 ;
-    /** whether or not this tag represents a primitive type */
-    private boolean isPrimitive = true ;
-    /** whether or not this tag has been fixated */
-    private boolean isFixated = false ;
-    /** the type class of this tag */
-    private TypeClass typeClass = TypeClass.APPLICATION ;
-    /** buffer backed by a Java int to collect the arriving tag octets */
-    private final TagOctetCollector buf = new TagOctetCollector() ;
+    /**
+     * tag flag indicating the use of the long tag encoding form
+     */
+    private static final int LONG_FLAG = 0x80;
+
+    /**
+     * buffer backed by a Java int to collect the arriving tag octets
+     */
+    private final TagOctetCollector octets = new TagOctetCollector();
+
+    /**
+     * the id of the tag being decoded
+     */
+    private int id = 0;
+    /**
+     * whether or not this tag represents a primitive type
+     */
+    private boolean isPrimitive = true;
+    /**
+     * whether or not this tag has been fixated
+     */
+    private boolean isFixated = false;
+    /**
+     * the type class of the tag being decoded
+     */
+    private TypeClass typeClass = TypeClass.APPLICATION;
+    /**
+     * the tag consumer we send the constructed Tag to
+     */
+    private TagConsumer tagConsumer;
 
 
     /**
-     * Clears this tag's data of all bytes and values calculated so all is as it
-     * was when this instance was created.
+     * Clears this tag decoder's data of all bytes and values calculated so all
+     * is as it was when this instance was created.
      */
     void clear()
     {
-        id = 0 ;
-        isFixated = false ;
-        isPrimitive = true ;
-        typeClass = TypeClass.APPLICATION ;
-        buf.clear() ;
-    }
-    
-    
-    /**
-     * Fixates the data within this Tag calculating all the derived 
-     * properties from the existing set of octets.  While fixated octets
-     * cannot be added.
-     * 
-     * @throws DecoderException if this Tag is invalid
-     */
-    void fixate() throws DecoderException
-    {
-        isFixated = true ;
-        id = getTagId( buf ) ;
-        isPrimitive = isPrimitive( buf.get( 0 ) ) ;
-        typeClass = TypeClass.getTypeClass( buf.get( 0 ) ) ;
-    }
-    
-    
-    /**
-     * Adds an octet to this Tag and as a size effect may fixate the Tag if
-     * all the expected data has arrived.
-     * 
+        id = 0;
+
+        isFixated = false;
+
+        isPrimitive = true;
+
+        typeClass = TypeClass.APPLICATION;
+
+        octets.clear();
+    }
+
+
+    /**
+     * Fixates the data within this TagDecoder calculating all the derived
+     * properties from the existing set of octets.  While fixated octets cannot
+     * be added.
+     */
+    void fixate()
+    {
+        isFixated = true;
+
+        id = TagUtils.getTagId( octets );
+
+        isPrimitive = TagUtils.isPrimitive( octets.get( 0 ) );
+
+        typeClass = TypeClass.getTypeClass( octets.get( 0 ) );
+    }
+
+
+    /**
+     * Adds an octet to this TagDecoder and as a size effect may fixate the
+     * decoder if all the expected data has arrived.
+     *
      * @param octet the 8 bit byte to add
      */
-    void add( byte octet ) throws DecoderException
+    void add( byte octet )
     {
         if ( isFixated )
-        {  
-            throw new IllegalStateException( "data added to fixated tag" ) ;
+        {
+            throw new IllegalStateException( "data added to fixated tag" );
         }
-        
-        buf.put( octet ) ;
-        
-        if ( buf.size() == 1 )
+
+        octets.put( octet );
+
+        if ( octets.size() == 1 )
         {
             // if its the short form so we just fixate now!
-            if ( ( SHORT_MASK & octet ) != SHORT_MASK )
+            if ( ( TagUtils.SHORT_MASK & octet ) != TagUtils.SHORT_MASK )
             {
-                fixate() ;
+                fixate();
             }
         }
         
@@ -121,331 +128,150 @@
          * terminating octet for the long form uses a 0 for the most 
          * significant bit to flag the end of the train of octets for the 
          * tag id.
-         */ 
+         */
         else if ( ( octet & LONG_FLAG ) == 0 )
         {
-            fixate() ;
+            fixate();
         }
     }
-    
-    
+
+
     /**
-     * Gets a copy of the octets composing this Tag.
-     * 
-     * @return the octets representing this Tag
+     * Gets a copy of the octets present within this TagDecoder.
+     *
+     * @return the octets present within this TagDecoder
      */
     public byte[] getOctets()
     {
-        return buf.toArray() ;
+        return octets.toArray();
     }
-    
-    
+
+
     /**
-     * Gets the number of octets in this Tag.
-     * 
-     * @return the number of octets within this Tag
+     * Gets the number of octets in this TagDecoder.
+     *
+     * @return the number of octets within this TagDecoder
      */
     public int size()
     {
-        return buf.size() ;
+        return octets.size();
     }
 
-    
+
     /**
      * Gets the id.
-     * 
+     *
      * @return the id
      */
     public int getId()
     {
-        return id ;
+        return id;
     }
-    
-    
+
+
     /**
      * Gets the raw tag as it is stuffed into a primitive int.
-     * 
+     *
      * @return a primitive int stuffed with the first four octets of the tag
      */
     public int getRawTag()
     {
-        return buf.getIntValue() ;
+        return octets.getIntValue();
     }
-    
-    
+
+
     /**
-     * Checks to see if the tag represented by this Tag is primitive or 
+     * Checks to see if the tag represented by this Tag is primitive or
      * constructed.
-     * 
+     *
      * @return true if it is primitive, false if it is constructed
      */
     public boolean isPrimitive()
     {
-        return isPrimitive ;
+        return isPrimitive;
     }
-    
-    
+
+
     /**
      * Checks to see if the tag has been fixated.
-     * 
+     *
      * @return true if it is fixated, false if not
      */
     public boolean isFixated()
     {
-        return isFixated ;
+        return isFixated;
     }
-    
-    
+
+
     /**
      * Gets the type class for this Tag.
-     * 
+     *
      * @return the typeClass for this Tag
      */
     public TypeClass getTypeClass()
     {
-        return typeClass ;
+        return typeClass;
     }
 
 
     // ------------------------------------------------------------------------
-    // Utility Methods For Dealing With Tags and Tag Octets
+    // BufferConsumer interface methods
     // ------------------------------------------------------------------------
 
 
-    /**
-     * Sets the id of a tag encoded as a Java primitive integer.
-     *
-     * @param encodedTag the tag encoded as a Java primitive integer
-     * @param id the new tag id to set within the encodedTag
-     * @return the modified Java primitive int encoded tag with the new tag id
-     */
-    public final static int setIntEncodedId( int encodedTag, int id )
+    public void consume( List bbs )
     {
-        if ( id <= ONE_OCTET_IDMAX )
-        {
-            encodedTag |= ( id << 24 ) ;
-        }
-        else if ( id <= TWO_OCTET_IDMAX )
-        {
-            encodedTag |= ( SHORT_MASK << 24 ) ;
-            encodedTag |= ( id & 0x0000007F ) << 16 ;
-        }
-        else if ( id <= THREE_OCTET_IDMAX )
-        {
-            encodedTag |= ( SHORT_MASK << 24 ) ;
-            encodedTag |= ( id & 0x00003F80 ) << 9 ;
-            encodedTag |= ( id & 0x0000007F ) << 8 ;
-            encodedTag |= 0x00800000 ;
-        }
-        else if ( id <= FOUR_OCTET_IDMAX )
+        for ( int ii = 0; ii < bbs.size(); ii++ )
         {
-            encodedTag |= ( SHORT_MASK << 24 ) ;
-            encodedTag |= ( id & 0x001FC000 ) << 2 ;
-            encodedTag |= ( id & 0x00003F80 ) << 1 ;
-            encodedTag |= ( id & 0x0000007F ) ;
-            encodedTag |= 0x00808000 ;
-        }
-        else
-        {
-            String msg = "Id argument value of " + id
-                    + " was greater than the maximum supported id of "
-                    + FOUR_OCTET_IDMAX ;
-            throw new IllegalArgumentException( msg ) ;
-        }
-
-        return encodedTag;
-    }
+            ByteBuffer bb = ( ByteBuffer ) bbs.get( ii );
 
+            consume( bb );
 
-    /**
-     * Assembles the Java primitive int based encoding for a tag using a set
-     * of parameters.
-     *
-     * @param type
-     * @param id
-     * @param isConstructed
-     * @return
-     */
-    public final static int
-            getIntEncodedTag( TypeClass type, int id, boolean isConstructed )
-    {
-        int value = type.getValue() << 24 ;
-
-        if ( isConstructed )
-        {
-            value |= ( CONSTRUCTED_FLAG << 24 ) ;
+            if ( this.isFixated )
+            {
+                return;
+            }
         }
-
-        value = setIntEncodedId( value, id );
-
-        return value ;
     }
 
 
-    /**
-     * Gets the tag id of a TLV from tag octets.
-     *
-     * @param octets the set of octets needed to determine the tag value
-     *      (a.k.a identifier octets)
-     * @return the tag id
-     * @throws DecoderException if the id cannot be determined due to
-     *      type limitations of this method's return type.
-     */
-    public final static int getTagId( byte[] octets )
-        throws DecoderException
+    public void consume( ByteBuffer bb )
     {
-        if ( octets.length > 4 )
+        while( bb.hasRemaining() || this.isFixated )
         {
-            /*
-             * If this exception is ever thrown which is highly unlikely, then
-             * we need to switch to another data type to return because after
-             * 4 bytes the int can no longer hold the number.
-             */
-            throw new DecoderException( "Tag number is too large." ) ;
+            add( bb.get() );
         }
 
-        int id = octets[0] & SHORT_MASK ;
-
-        // if bits are not all 1's then return the value which is less than 31
-        if ( id != SHORT_MASK && octets.length == 1 )
+        if ( this.isFixated )
         {
-            return id ;
-        }
-
-        // clear the id now
-        id = 0 ;
 
-        // calculate tag value w/ long tag format
-        for( int ii = 1 ; ii < octets.length; ii++ )
-        {
-            int shift = ( ii - 1 ) * 7 ;
-            id |= ( octets[ii] & LONG_MASK ) << shift ;
         }
-
-        return id ;
     }
 
 
-    /**
-     * Gets the tag id of a TLV from tag octets encoded as a Java primitive int.
-     *
-     * @param octets the tag octets encoded as a Java primitive int
-     * @return the tag id
-     */
-    public final static int getTagId( int octets )
+    public void consume( ByteBuffer[] bbs )
     {
-        // set id to the most significant octet in the int
-        int id = ( octets >> 24 ) & SHORT_MASK;
-
-        // if bits are not all 1's then return the value which is less than 31
-        if ( id != SHORT_MASK )
-        {
-            return id;
-        }
-
-        // clear the id now to prepare for long tag form
-        id = 0;
-
-        // get the second most significant octet from int and apply it to the id
-        int octet = ( octets & 0x00ff0000 ) >> 16;
-        id |= octet & LONG_MASK ;
-
-        // if this is the last octet in long form return
-        if ( ( octet & 0x80 ) == 0 )
-        {
-            return id ;
-        }
-
-        // clear octet and get the third most significant octet and apply it
-        octet = 0;
-        octet = ( octets & 0x0000ff00 ) >> 8;
-
-        if ( octet == 0 )
+        for ( int ii = 0; ii < bbs.length; ii++ )
         {
-            return id << 7 ;
-        }
-
-        id <<= 7;
-        id |= octet & LONG_MASK;
-
-        // if this is the last octet in long form return
-        if ( ( octet & 0x80 ) == 0 )
-        {
-            return id ;
-        }
-
-        // clear octet and get the least significant octet and apply it
-        octet = 0;
-        octet = octets & 0x000000ff;
-        id <<= 7;
-        id |= octet & LONG_MASK;
-
-        return id ;
-    }
+            ByteBuffer bb = ( ByteBuffer ) bbs[ii];
 
+            consume( bb );
 
-    /**
-     * Gets the tag id of a TLV from the tag octets.
-     * 
-     * @param octets the set of octets needed to determine the tag value 
-     *      (a.k.a identifier octets)
-     * @return the tag id
-     */
-    public final static int getTagId( TagOctetCollector octets )
-    {
-        int id = octets.get( 0 ) & SHORT_MASK ;
-        
-        // if bits are not all 1's then return the value which is less than 31
-        if ( id != SHORT_MASK && octets.size() == 1 )
-        {
-            return id ;
-        }
-        
-        // clear the id now
-        id = 0 ;
-    
-        // calculate tag value w/ long tag format
-        for( int ii = 1 ; ii < octets.size(); ii++ )
-        {    
-            int shift = ( ii - 1 ) * 7 ;
-            id |= ( octets.get( ii ) & LONG_MASK ) << shift ;
+            if ( this.isFixated )
+            {
+                return;
+            }
         }
-        
-        return id ;
     }
 
 
-    /**
-     * Checks to see if the tag is a primitive.
-     * 
-     * @param octet the first octet of the tag
-     * @return true if this tag is of the simple type, false if constructed
-     */
-    public final static boolean isPrimitive( int octet )
-    {
-        return ( octet & CONSTRUCTED_FLAG ) == 0 ;
-    }
-
-
-    /**
-     * Checks to see if the tag is constructed.
-     * 
-     * @param octet the first octet of the tag
-     * @return true if constructed, false if primitive
-     */
-    public final static boolean isConstructed( int octet )
-    {
-        return ( octet & CONSTRUCTED_FLAG ) == CONSTRUCTED_FLAG ;
-    }
+    // ------------------------------------------------------------------------
+    // TagProducer interface methods
+    // ------------------------------------------------------------------------
 
 
-    public static boolean isRawTagConstructed( int rawTag )
+    public void setTagConsumer( TagConsumer tagConsumer )
     {
-        if ( ( rawTag & 0x20000000 ) > 0 )
-        {
-            return true;
-        }
-
-        return false;
+        this.tagConsumer = tagConsumer;
     }
 }

Added: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TagProducer.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TagProducer.java?view=auto&rev=151709
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TagProducer.java (added)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TagProducer.java Mon Feb  7 00:05:54 2005
@@ -0,0 +1,29 @@
+/*
+ *   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.asn1.tag;
+
+
+/**
+ * Document this class.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public interface TagProducer
+{
+    void setTagConsumer( TagConsumer consumer );
+}

Added: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TagUtils.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TagUtils.java?view=auto&rev=151709
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TagUtils.java (added)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TagUtils.java Mon Feb  7 00:05:54 2005
@@ -0,0 +1,320 @@
+/*
+ *   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.asn1.tag;
+
+
+import org.apache.asn1.codec.DecoderException;
+
+
+/**
+ * Utility methods dealing with Tags.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class TagUtils
+{
+    /**
+     * the max id size with one tag octet
+     */
+    private static final int ONE_OCTET_IDMAX = 30;
+    /**
+     * the max id size with two tag octets
+     */
+    private static final int TWO_OCTET_IDMAX = ( 1 << 7 ) - 1;
+    /**
+     * the max id size with three tag octets
+     */
+    private static final int THREE_OCTET_IDMAX = ( 1 << 14 ) - 1;
+    /**
+     * the max id size with four tag octets
+     */
+    private static final int FOUR_OCTET_IDMAX = ( 1 << 21 ) - 1;
+
+    /**
+     * tag flag for the primitive/constructed bit - 0010 0000 - 0x20
+     */
+    static final int CONSTRUCTED_FLAG = 0x20;
+    /**
+     * tag mask for the long tag format - 0111 1111 - 0x7F
+     */
+    static final int LONG_MASK = 0x7F;
+    /**
+     * tag mask for the short tag format - 0001 1111 - 0x1F
+     */
+    static final int SHORT_MASK = 0x1F;
+
+
+    /**
+     * Sets the id of a tag encoded as a Java primitive integer.
+     *
+     * @param encodedTag the tag encoded as a Java primitive integer
+     * @param id         the new tag id to set within the encodedTag
+     * @return the modified Java primitive int encoded tag with the new tag id
+     */
+    public final static int setIntEncodedId( int encodedTag, int id )
+    {
+        if ( id <= ONE_OCTET_IDMAX )
+        {
+            encodedTag |= ( id << 24 );
+        }
+        else if ( id <= TWO_OCTET_IDMAX )
+        {
+            encodedTag |= ( SHORT_MASK << 24 );
+
+            encodedTag |= ( id & 0x0000007F ) << 16;
+        }
+        else if ( id <= THREE_OCTET_IDMAX )
+        {
+            encodedTag |= ( SHORT_MASK << 24 );
+
+            encodedTag |= ( id & 0x00003F80 ) << 9;
+
+            encodedTag |= ( id & 0x0000007F ) << 8;
+
+            encodedTag |= 0x00800000;
+        }
+        else if ( id <= FOUR_OCTET_IDMAX )
+        {
+            encodedTag |= ( SHORT_MASK << 24 );
+
+            encodedTag |= ( id & 0x001FC000 ) << 2;
+
+            encodedTag |= ( id & 0x00003F80 ) << 1;
+
+            encodedTag |= ( id & 0x0000007F );
+
+            encodedTag |= 0x00808000;
+        }
+        else
+        {
+            String msg = "Id argument value of " + id;
+
+            msg += " was greater than the maximum supported id of " + FOUR_OCTET_IDMAX;
+
+            throw new IllegalArgumentException( msg );
+        }
+
+        return encodedTag;
+    }
+
+
+    /**
+     * Assembles the Java primitive int based encoding for a tag using a set of
+     * parameters.
+     *
+     * @param type
+     * @param id
+     * @param isConstructed
+     * @return
+     */
+    public final static int getIntEncodedTag( TypeClass type, int id, boolean isConstructed )
+    {
+        int value = type.getValue() << 24;
+
+        if ( isConstructed )
+        {
+            value |= ( CONSTRUCTED_FLAG << 24 );
+        }
+
+        value = setIntEncodedId( value, id );
+
+        return value;
+    }
+
+
+    /**
+     * Gets the tag id of a TLV from tag octets.
+     *
+     * @param octets the set of octets needed to determine the tag value (a.k.a
+     *               identifier octets)
+     * @return the tag id
+     * @throws org.apache.asn1.codec.DecoderException if the id cannot be determined due to type
+     *                          limitations of this method's return type.
+     */
+    public final static int getTagId( byte[] octets ) throws DecoderException
+    {
+        if ( octets.length > 4 )
+        {
+            /*
+             * If this exception is ever thrown which is highly unlikely, then
+             * we need to switch to another data type to return because after
+             * 4 bytes the int can no longer hold the number.
+             */
+            throw new DecoderException( "Tag number is too large." );
+        }
+
+        int id = octets[0] & SHORT_MASK;
+
+        // if bits are not all 1's then return the value which is less than 31
+        if ( id != SHORT_MASK && octets.length == 1 )
+        {
+            return id;
+        }
+
+        // clear the id now
+        id = 0;
+
+        // calculate tag value w/ long tag format
+        for ( int ii = 1; ii < octets.length; ii++ )
+        {
+            int shift = ( ii - 1 ) * 7;
+
+            id |= ( octets[ii] & LONG_MASK ) << shift;
+        }
+
+        return id;
+    }
+
+
+    /**
+     * Gets the tag id of a TLV from tag octets encoded as a Java primitive
+     * int.
+     *
+     * @param octets the tag octets encoded as a Java primitive int
+     * @return the tag id
+     */
+    public final static int getTagId( int octets )
+    {
+        // set id to the most significant octet in the int
+        int id = ( octets >> 24 ) & SHORT_MASK;
+
+        // if bits are not all 1's then return the value which is less than 31
+        if ( id != SHORT_MASK )
+        {
+            return id;
+        }
+
+        // clear the id now to prepare for long tag form
+        id = 0;
+
+        // get the second most significant octet from int and apply it to the id
+        int octet = ( octets & 0x00ff0000 ) >> 16;
+
+        id |= octet & LONG_MASK;
+
+        // if this is the last octet in long form return
+        if ( ( octet & 0x80 ) == 0 )
+        {
+            return id;
+        }
+
+        // clear octet and get the third most significant octet and apply it
+        octet = 0;
+
+        octet = ( octets & 0x0000ff00 ) >> 8;
+
+        if ( octet == 0 )
+        {
+            return id << 7;
+        }
+
+        id <<= 7;
+
+        id |= octet & LONG_MASK;
+
+        // if this is the last octet in long form return
+        if ( ( octet & 0x80 ) == 0 )
+        {
+            return id;
+        }
+
+        // clear octet and get the least significant octet and apply it
+        octet = 0;
+
+        octet = octets & 0x000000ff;
+
+        id <<= 7;
+
+        id |= octet & LONG_MASK;
+
+        return id;
+    }
+
+
+    /**
+     * Gets the tag id of a TLV from the tag octets.
+     *
+     * @param octets the set of octets needed to determine the tag value (a.k.a
+     *               identifier octets)
+     * @return the tag id
+     */
+    public final static int getTagId( TagOctetCollector octets )
+    {
+        int id = octets.get( 0 ) & SHORT_MASK;
+
+        // if bits are not all 1's then return the value which is less than 31
+        if ( id != SHORT_MASK && octets.size() == 1 )
+        {
+            return id;
+        }
+
+        // clear the id now
+        id = 0;
+
+        // calculate tag value w/ long tag format
+        for ( int ii = 1; ii < octets.size(); ii++ )
+        {
+            int shift = ( ii - 1 ) * 7;
+
+            id |= ( octets.get( ii ) & LONG_MASK ) << shift;
+        }
+
+        return id;
+    }
+
+
+    /**
+     * Checks to see if the tag is a primitive.
+     *
+     * @param octet the first octet of the tag
+     * @return true if this tag is of the simple type, false if constructed
+     */
+    public final static boolean isPrimitive( int octet )
+    {
+        return ( octet & CONSTRUCTED_FLAG ) == 0;
+    }
+
+
+    /**
+     * Checks to see if the tag is constructed.
+     *
+     * @param octet the first octet of the tag
+     * @return true if constructed, false if primitive
+     */
+    public final static boolean isConstructed( int octet )
+    {
+        return ( octet & CONSTRUCTED_FLAG ) == CONSTRUCTED_FLAG;
+    }
+
+
+    /**
+     * Checks to see if a raw tag value is constructed.
+     *
+     * @param rawTag the raw tag value collected into a primitive int
+     * @return true if the tag is constructed, false otherwise
+     */
+    public static boolean isRawTagConstructed( int rawTag )
+    {
+        if ( ( rawTag & 0x20000000 ) > 0 )
+        {
+            return true;
+        }
+
+        return false;
+    }
+}

Copied: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TypeClass.java (from r151199, incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/ber/TypeClass.java)
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TypeClass.java?view=diff&rev=151709&p1=incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/ber/TypeClass.java&r1=151199&p2=incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TypeClass.java&r2=151709
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/ber/TypeClass.java (original)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tag/TypeClass.java Mon Feb  7 00:05:54 2005
@@ -14,71 +14,77 @@
  *   limitations under the License.
  *
  */
-package org.apache.asn1.ber ;
+package org.apache.asn1.tag;
 
 
-import java.util.Map ;
-import java.util.List ;
+import java.util.List;
+import java.util.Map;
 
-import org.apache.asn1.util.ValuedEnum;
 import org.apache.asn1.util.EnumUtils;
+import org.apache.asn1.util.ValuedEnum;
 
 
 /**
- * Type safe enum for an ASN.1 type class.  This can be take one of the 
- * following four values: 
- * <ul>
- * <li>UNIVERSAL</li>
- * <li>APPLICATION</li>
- * <li>CONTEXT_SPECIFIC</li>
- * <li>PRIVATE</li>
- * </ul>
- * 
- * @author <a href="mailto:directory-dev@incubator.apache.org">
- * Apache Directory Project</a>
+ * Type safe enum for an ASN.1 type class.  This can be take one of the
+ * following four values: <ul> <li>UNIVERSAL</li> <li>APPLICATION</li>
+ * <li>CONTEXT_SPECIFIC</li> <li>PRIVATE</li> </ul>
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org"> Apache Directory
+ *         Project</a>
  * @version $Rev$
  */
 public class TypeClass extends ValuedEnum
 {
-    /** value for the universal type class */
-    public static final int UNIVERSAL_VAL = 0 ;
-    /** value for the application type class */
-    public static final int APPLICATION_VAL = 0x40 ;
-    /** value for the context specific type class */
-    public static final int CONTEXT_SPECIFIC_VAL = 0x80 ;
-    /** value for the private type class */
-    public static final int PRIVATE_VAL = 0xc0 ;
-
-    /** enum for the universal type class */
-    public static final TypeClass UNIVERSAL = 
-        new TypeClass( "UNIVERSAL", UNIVERSAL_VAL ) ;
-    /** enum for the application type class */
-    public static final TypeClass APPLICATION = 
-        new TypeClass( "APPLICATION", APPLICATION_VAL ) ;
-    /** enum for the context specific type class  */
-    public static final TypeClass CONTEXT_SPECIFIC = 
-        new TypeClass( "CONTEXT_SPECIFIC", CONTEXT_SPECIFIC_VAL ) ;
-    /** enum for the private type class  */
-    public static final TypeClass PRIVATE = 
-        new TypeClass( "PRIVATE", PRIVATE_VAL ) ;
+    /**
+     * value for the universal type class
+     */
+    public static final int UNIVERSAL_VAL = 0;
+    /**
+     * value for the application type class
+     */
+    public static final int APPLICATION_VAL = 0x40;
+    /**
+     * value for the context specific type class
+     */
+    public static final int CONTEXT_SPECIFIC_VAL = 0x80;
+    /**
+     * value for the private type class
+     */
+    public static final int PRIVATE_VAL = 0xc0;
+    /**
+     * enum for the universal type class
+     */
+    public static final TypeClass UNIVERSAL = new TypeClass( "UNIVERSAL", UNIVERSAL_VAL );
+    /**
+     * enum for the application type class
+     */
+    public static final TypeClass APPLICATION = new TypeClass( "APPLICATION", APPLICATION_VAL );
+    /**
+     * enum for the context specific type class
+     */
+    public static final TypeClass CONTEXT_SPECIFIC = new TypeClass( "CONTEXT_SPECIFIC", CONTEXT_SPECIFIC_VAL );
+    /**
+     * enum for the private type class
+     */
+    public static final TypeClass PRIVATE = new TypeClass( "PRIVATE", PRIVATE_VAL );
+
 
-    
     /**
      * Private constructor so no other instances can be created other than the
      * public static constants in this class.
      *
-     * @param name a string name for the enumeration value.
+     * @param name  a string name for the enumeration value.
      * @param value the integer value of the enumeration.
      */
     private TypeClass( final String name, final int value )
     {
-        super( name, value ) ;
+        super( name, value );
     }
-    
-    
+
+
     /**
      * Gets the enumeration type for the type class regardless of case.
-     * 
+     *
      * @param className the type class name
      * @return the TypeClass for the name
      */
@@ -87,96 +93,106 @@
         // check first using == since it will be the predominate use case
         if ( className == APPLICATION.getName() )
         {
-            return APPLICATION ;
+            return APPLICATION;
         }
         else if ( className == CONTEXT_SPECIFIC.getName() )
         {
-            return CONTEXT_SPECIFIC ;
+            return CONTEXT_SPECIFIC;
         }
         else if ( className == PRIVATE.getName() )
         {
-            return PRIVATE ;
+            return PRIVATE;
         }
         else if ( className == UNIVERSAL.getName() )
         {
-            return UNIVERSAL ;
+            return UNIVERSAL;
         }
-        
+
         if ( className.equalsIgnoreCase( TypeClass.PRIVATE.getName() ) )
         {
-            return TypeClass.PRIVATE ;
+            return TypeClass.PRIVATE;
         }
-        
+
         if ( className.equalsIgnoreCase( TypeClass.UNIVERSAL.getName() ) )
         {
-            return TypeClass.UNIVERSAL ;
+            return TypeClass.UNIVERSAL;
         }
-        
+
         if ( className.equalsIgnoreCase( TypeClass.APPLICATION.getName() ) )
         {
-            return TypeClass.APPLICATION ;
+            return TypeClass.APPLICATION;
         }
-        
-        if ( className.equalsIgnoreCase( 
-                        TypeClass.CONTEXT_SPECIFIC.getName() ) )
+
+        if ( className.equalsIgnoreCase( TypeClass.CONTEXT_SPECIFIC.getName() ) )
         {
-            return TypeClass.CONTEXT_SPECIFIC ;
+            return TypeClass.CONTEXT_SPECIFIC;
         }
-        
-        throw new IllegalArgumentException( "Unknown type class name"
-            + className ) ;
+
+        throw new IllegalArgumentException( "Unknown type class name" + className );
     }
-    
-    
+
+
     /**
      * Gets a List of the enumerations for ASN.1 type classes.
-     * 
+     *
      * @return the List of enumerations possible for ASN.1 type classes
      */
     public static List list()
     {
-        return EnumUtils.getEnumList( TypeClass.class ) ;
+        return EnumUtils.getEnumList( TypeClass.class );
     }
-    
-    
+
+
     /**
      * Gets the Map of TypeClass objects by name using the TypeClass class.
-     * 
+     *
      * @return the Map by name of TypeClass
      */
     public static Map map()
     {
-        return EnumUtils.getEnumMap( TypeClass.class ) ;
+        return EnumUtils.getEnumMap( TypeClass.class );
     }
 
 
     /**
      * Gets the ASN.1 type's class using a TLV tag.
-     * 
+     *
      * @param octet the first octet of the TLV
      * @return the TypeClass enumeration for the ASN.1 type's class
      */
     public static TypeClass getTypeClass( int octet )
     {
-        TypeClass tc = null ;
-        int l_value = octet & PRIVATE_VAL ;
-        
-        switch ( l_value )
-        {
-            case( UNIVERSAL_VAL ):
-                tc = UNIVERSAL ;
-                break ;
-            case( APPLICATION_VAL ):
-                tc = APPLICATION ;
-                break ;
-            case( CONTEXT_SPECIFIC_VAL ):
-                tc = CONTEXT_SPECIFIC ;
-                break ;
-            case( PRIVATE_VAL ):
-                tc = PRIVATE ;
-                break ;
+        TypeClass tc = null;
+
+        int value = octet & PRIVATE_VAL;
+
+        switch ( value )
+        {
+            case ( UNIVERSAL_VAL ):
+
+                tc = UNIVERSAL;
+
+                break;
+
+            case ( APPLICATION_VAL ):
+
+                tc = APPLICATION;
+
+                break;
+
+            case ( CONTEXT_SPECIFIC_VAL ):
+
+                tc = CONTEXT_SPECIFIC;
+
+                break;
+
+            case ( PRIVATE_VAL ):
+
+                tc = PRIVATE;
+
+                break;
         }
-        
-        return tc ;
+
+        return tc;
     }
 }

Modified: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/AbstractTuple.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/AbstractTuple.java?view=diff&r1=151708&r2=151709
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/AbstractTuple.java (original)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/AbstractTuple.java Mon Feb  7 00:05:54 2005
@@ -17,6 +17,9 @@
 package org.apache.asn1.tuples;
 
 
+import org.apache.asn1.tag.Tag;
+
+
 /**
  * An abstract base for a Tag, Length, Value tuple.
  *

Modified: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/BufferedTuple.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/BufferedTuple.java?view=diff&r1=151708&r2=151709
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/BufferedTuple.java (original)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/BufferedTuple.java Mon Feb  7 00:05:54 2005
@@ -23,6 +23,8 @@
 
 import java.nio.ByteBuffer;
 
+import org.apache.asn1.tag.Tag;
+
 
 /**
  * A Tag, Length, Value Tuple whose Value is kept in memory.

Modified: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/ConstructedTuple.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/ConstructedTuple.java?view=diff&r1=151708&r2=151709
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/ConstructedTuple.java (original)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/ConstructedTuple.java Mon Feb  7 00:05:54 2005
@@ -17,6 +17,9 @@
 package org.apache.asn1.tuples;
 
 
+import org.apache.asn1.tag.Tag;
+
+
 /**
  * Document this class.
  *

Modified: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/DefinateLengthTuple.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/DefinateLengthTuple.java?view=diff&r1=151708&r2=151709
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/DefinateLengthTuple.java (original)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/DefinateLengthTuple.java Mon Feb  7 00:05:54 2005
@@ -17,6 +17,9 @@
 package org.apache.asn1.tuples;
 
 
+import org.apache.asn1.tag.Tag;
+
+
 /**
  * Document this class.
  *

Modified: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/IndefinateLengthTuple.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/IndefinateLengthTuple.java?view=diff&r1=151708&r2=151709
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/IndefinateLengthTuple.java (original)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/IndefinateLengthTuple.java Mon Feb  7 00:05:54 2005
@@ -17,6 +17,9 @@
 package org.apache.asn1.tuples;
 
 
+import org.apache.asn1.tag.Tag;
+
+
 /**
  * Document this class.
  *

Modified: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/PrimitiveTuple.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/PrimitiveTuple.java?view=diff&r1=151708&r2=151709
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/PrimitiveTuple.java (original)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/PrimitiveTuple.java Mon Feb  7 00:05:54 2005
@@ -17,6 +17,9 @@
 package org.apache.asn1.tuples;
 
 
+import org.apache.asn1.tag.Tag;
+
+
 /**
  * A primitive TLV Tuple.
  *

Modified: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/StreamedTuple.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/StreamedTuple.java?view=diff&r1=151708&r2=151709
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/StreamedTuple.java (original)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/StreamedTuple.java Mon Feb  7 00:05:54 2005
@@ -19,6 +19,8 @@
 
 import java.io.InputStream;
 
+import org.apache.asn1.tag.Tag;
+
 
 /**
  * Document this class.

Modified: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/Tuple.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/Tuple.java?view=diff&r1=151708&r2=151709
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/Tuple.java (original)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/tuples/Tuple.java Mon Feb  7 00:05:54 2005
@@ -17,6 +17,9 @@
 package org.apache.asn1.tuples;
 
 
+import org.apache.asn1.tag.Tag;
+
+
 /**
  * A minimal interface for a Tag, Length, Value tuple used for various
  * encodings.