Return-Path: Delivered-To: apmail-incubator-directory-cvs-archive@www.apache.org Received: (qmail 41911 invoked from network); 15 Mar 2004 05:51:12 -0000 Received: from daedalus.apache.org (HELO mail.apache.org) (208.185.179.12) by minotaur-2.apache.org with SMTP; 15 Mar 2004 05:51:12 -0000 Received: (qmail 60411 invoked by uid 500); 15 Mar 2004 05:50:51 -0000 Delivered-To: apmail-incubator-directory-cvs-archive@incubator.apache.org Received: (qmail 60375 invoked by uid 500); 15 Mar 2004 05:50:51 -0000 Mailing-List: contact directory-cvs-help@incubator.apache.org; run by ezmlm Precedence: bulk Reply-To: directory-dev@incubator.apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list directory-cvs@incubator.apache.org Received: (qmail 60360 invoked from network); 15 Mar 2004 05:50:51 -0000 Received: from unknown (HELO minotaur.apache.org) (209.237.227.194) by daedalus.apache.org with SMTP; 15 Mar 2004 05:50:51 -0000 Received: (qmail 41874 invoked by uid 65534); 15 Mar 2004 05:51:11 -0000 Date: 15 Mar 2004 05:51:11 -0000 Message-ID: <20040315055111.41867.qmail@minotaur.apache.org> From: akarasulu@apache.org To: directory-cvs@incubator.apache.org Subject: svn commit: rev 9483 - in incubator/directory/snickers/branches/refactoring/ber/src: java/org/apache/snickers/asn java/org/apache/snickers/ber test/org/apache/snickers/ber X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N Author: akarasulu Date: Sun Mar 14 21:51:10 2004 New Revision: 9483 Added: incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/Length.java incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/LengthDecoder.java incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/Tag.java Modified: incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/asn/TLV.java incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/asn/TLVParsingUtility.java incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/BERDecoder.java incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/BERUtils.java incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/TagDecoder.java incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/Tuple.java incubator/directory/snickers/branches/refactoring/ber/src/test/org/apache/snickers/ber/BERUtilsTest.java incubator/directory/snickers/branches/refactoring/ber/src/test/org/apache/snickers/ber/TupleTest.java Log: started major refactoring Modified: incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/asn/TLV.java ============================================================================== --- incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/asn/TLV.java (original) +++ incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/asn/TLV.java Sun Mar 14 21:51:10 2004 @@ -53,7 +53,7 @@ import java.util.Collection; import org.apache.commons.codec.binary.Binary; -import org.apache.snickers.ber.BERUtils; +import org.apache.snickers.ber.Tag; import org.apache.snickers.ber.TypeClass; /** @@ -208,7 +208,7 @@ * @return the type class */ public TypeClass getTypeClass() { - return BERUtils.getTypeClass( (byte) tag ); + return TypeClass.getTypeClass( (byte) tag ); } /** @@ -231,7 +231,7 @@ * @return true if the value is a primative, else false. */ public boolean isPrimative() { - return BERUtils.isPrimitive( tag ); + return Tag.isPrimitive( tag ); } /** Modified: incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/asn/TLVParsingUtility.java ============================================================================== --- incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/asn/TLVParsingUtility.java (original) +++ incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/asn/TLVParsingUtility.java Sun Mar 14 21:51:10 2004 @@ -102,8 +102,8 @@ count++; int id = tag & (Binary.BIT_4 | Binary.BIT_3 | Binary.BIT_2 | Binary.BIT_1 | Binary.BIT_0 ); - boolean primative = BERUtils.isPrimitive(tag); - TypeClass tc = BERUtils.getTypeClass((byte)tag); + boolean primative = Tag.isPrimitive(tag); + TypeClass tc = TypeClass.getTypeClass((byte)tag); System.out.println( strIndent + ">>>>>>>>>>>>>> TLV <<<<<<<<<<<<<" ); System.out.println( strIndent + "Tag: " + toBits(tag) ); Modified: incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/BERDecoder.java ============================================================================== --- incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/BERDecoder.java (original) +++ incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/BERDecoder.java Sun Mar 14 21:51:10 2004 @@ -185,12 +185,12 @@ if ( tagBuffer.size() == 1 ) { - int id = BERUtils.SHORT_TAG_MASK & octet ; - tlv.isPrimitive = BERUtils.isPrimitive( octet ) ; - tlv.typeClass = BERUtils.getTypeClass( octet ) ; + int id = Tag.SHORT_MASK & octet ; + tlv.isPrimitive = Tag.isPrimitive( octet ) ; + tlv.typeClass = TypeClass.getTypeClass( octet ) ; // continue to collect more octets if this is the long Tag form - if ( id == BERUtils.SHORT_TAG_MASK ) + if ( id == Tag.SHORT_MASK ) { continue ; } @@ -213,7 +213,7 @@ */ if ( ( octet & Binary.BIT_7 ) == 0 ) { - tlv.id = BERUtils.getTagId( tagBuffer ) ; + tlv.id = Tag.getTagId( tagBuffer ) ; fireTagDecoded() ; state = state.getNext( tlv.isPrimitive ) ; @@ -240,14 +240,14 @@ if ( lengthBuffer.size() == 1 ) { - lengthOfLength = octet & BERUtils.LONG_TAG_MASK ; + lengthOfLength = octet & Tag.LONG_MASK ; // handle the short form of the length here if ( ( octet & Binary.BIT_7 ) == 0 ) { lengthOfLength = 0 ; tlv.length = octet ; - tlv.valueIndex = Tuple.UNDEFINED ; + tlv.valueIndex = Length.UNDEFINED ; if ( tlv.isPrimitive ) { @@ -276,10 +276,10 @@ // the indefinate form of the length else if ( lengthOfLength == 0 ) { - lengthOfLength = Tuple.INDEFINATE ; - tlv.index = Tuple.INDEFINATE ; - tlv.length = Tuple.INDEFINATE ; - tlv.valueIndex = Tuple.UNDEFINED ; + lengthOfLength = Length.INDEFINATE ; + tlv.index = Length.INDEFINATE ; + tlv.length = Length.INDEFINATE ; + tlv.valueIndex = Length.UNDEFINED ; fireLengthDecoded() ; tlvStack.push( tlv.clone() ) ; tlv.clear() ; @@ -298,8 +298,8 @@ if ( lengthBuffer.size() == lengthOfLength + 1 ) { lengthOfLength = 0 ; - tlv.length = BERUtils.getLength( lengthBuffer ) ; - tlv.valueIndex = Tuple.UNDEFINED ; + tlv.length = Length.getLength( lengthBuffer ) ; + tlv.valueIndex = Length.UNDEFINED ; if ( tlv.isPrimitive ) { @@ -334,8 +334,8 @@ private void decodeValue( ByteBuffer buf ) throws DecoderException { byte[] value = ( byte [] ) tlv.value ; - int offset = Tuple.UNDEFINED ; - int needToRead = Tuple.UNDEFINED ; + int offset = Length.UNDEFINED ; + int needToRead = Length.UNDEFINED ; if ( ! tlv.isPrimitive ) { @@ -362,7 +362,7 @@ /* * setup to start decoding the value */ - if ( tlv.valueIndex == Tuple.UNDEFINED ) + if ( tlv.valueIndex == Length.UNDEFINED ) { needToRead = tlv.length ; offset = 0 ; @@ -395,7 +395,7 @@ */ else { - if ( tlv.valueIndex == Tuple.UNDEFINED ) + if ( tlv.valueIndex == Length.UNDEFINED ) { tlv.valueIndex = 0 ; } @@ -494,7 +494,7 @@ t.index += increment ; - if ( t.valueIndex == Tuple.UNDEFINED ) + if ( t.valueIndex == Length.UNDEFINED ) { t.valueIndex = 0 ; } @@ -554,7 +554,7 @@ } Tuple top = ( Tuple ) tlvStack.peek() ; - if ( top.length != Tuple.INDEFINATE ) + if ( top.length != Length.INDEFINATE ) { IllegalStateException e = new IllegalStateException( msg + " but TLV on top has a definate length" ) ; Modified: incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/BERUtils.java ============================================================================== --- incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/BERUtils.java (original) +++ incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/BERUtils.java Sun Mar 14 21:51:10 2004 @@ -17,11 +17,6 @@ package org.apache.snickers.ber ; -import org.apache.commons.codec.binary.Binary ; -import org.apache.commons.codec.DecoderException ; -import org.apache.commons.collections.primitives.ArrayByteList ; - - /** * Basic Encoding Rule (BER) utility functions. * @@ -31,212 +26,4 @@ */ public final class BERUtils { - /** mask for the tag value of a short tag value format in a single octet */ - public static final int SHORT_TAG_MASK = Binary.BIT_0 | Binary.BIT_1 | - Binary.BIT_2 | Binary.BIT_3 | Binary.BIT_4 ; - /** mask for the tag value of long tag value format in more than 1 octet */ - public static final int LONG_TAG_MASK = Binary.BIT_0 | Binary.BIT_1 | - Binary.BIT_2 | Binary.BIT_3 | Binary.BIT_4 | Binary.BIT_5 | - Binary.BIT_6 ; - - - /** - * 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 final static TypeClass getTypeClass( byte octet ) - { - return TypeClass.getTypeClass( octet ) ; - } - - - /** - * Checks to see if the TLV is constructed. - * - * @param octet the first octet of the TLV - * @return true if this TLV contains more TLVs, false if it's a simple type - */ - public final static boolean isConstructed( byte octet ) - { - return ( octet & Binary.BIT_5 ) == Binary.BIT_5 ; - } - - - /** - * Checks to see if the TLV is constructed. - * - * @param octet the first octet of the TLV - * @return true if this TLV contains more TLVs, false if it's a simple type - */ - public final static boolean isConstructed( int octet ) - { - return ( octet & Binary.BIT_5 ) == Binary.BIT_5 ; - } - - - /** - * Checks to see if the TLV is a primitive. - * - * @param octet the first octet of the TLV - * @return true if this TLV is a simple type, false if it contains TLVs - */ - public final static boolean isPrimitive( byte octet ) - { - return ( octet & Binary.BIT_5 ) == 0 ; - } - - - /** - * Checks to see if the TLV is a primitive. - * - * @param octet the first octet of the TLV - * @return true if this TLV is a simple type, false if it contains TLVs - */ - public final static boolean isPrimitive( int octet ) - { - return ( octet & Binary.BIT_5 ) == 0 ; - } - - - /** - * 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 - * @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 - { - if ( octets.length > 6 ) - { - /* - * If this exception is ever thrown which is highly unlikely, then - * we need to switch to another data type to return because after - * 5 bytes the int can no longer hold the number. - */ - throw new DecoderException( "Tag number is too large." ) ; - } - - int id = octets[0] & SHORT_TAG_MASK ; - - // if bits are not all 1's then return the value which is less than 31 - if ( id != SHORT_TAG_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 ; - if ( shift > 0 ) - { - id |= ( octets[ii] & LONG_TAG_MASK ) << shift ; - } - else - { - id |= ( octets[ii] & LONG_TAG_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 - * @throws DecoderException if the id cannot be determined due to - * type limitations of this method's return type. - */ - public final static int getTagId( ArrayByteList octets ) - throws DecoderException - { - if ( octets.size() > 6 ) - { - /* - * If this exception is ever thrown which is highly unlikely, then - * we need to switch to another data type to return because after - * 5 bytes the int can no longer hold the number. - */ - throw new DecoderException( "Tag number is too large." ) ; - } - - int id = octets.get( 0 ) & SHORT_TAG_MASK ; - - // if bits are not all 1's then return the value which is less than 31 - if ( id != SHORT_TAG_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 ; - if ( shift > 0 ) - { - id |= ( octets.get( ii ) & LONG_TAG_MASK ) << shift ; - } - else - { - id |= ( octets.get( ii ) & LONG_TAG_MASK ) ; - } - } - - return id ; - } - - - /** - * Decodes the length of a value for a tlv using the Length field bytes. - * - * @param octets the length field bytes in the TLV - * @return the length of the TLV - * @throws DecoderException if the precision cannot hold the number - */ - public static int getLength( ArrayByteList octets ) throws DecoderException - { - if ( octets.size() >= 6 ) - { - /* - * If this exception is ever thrown which is highly unlikely, then - * we need to switch to another data type to return because after - * 5 bytes the int can no longer hold the number. - */ - throw new DecoderException( "Length number is too large." ) ; - } - - // if we are using the short form then just return the first octet - if ( ( octets.get( 0 ) & Binary.BIT_7 ) == 0 ) - { - return octets.get( 0 ) ; - } - - // clear the id now - int length = 0 ; - - // calculate tag value w/ long tag format - for( int ii = 1 ; ii < octets.size(); ii++ ) - { - int shift = ( ii - 1 ) * 8 ; - length |= ( 0x00ff & ( int ) octets.get( ii ) ) << shift ; - } - - return length ; - } } Added: incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/Length.java ============================================================================== --- (empty file) +++ incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/Length.java Sun Mar 14 21:51:10 2004 @@ -0,0 +1,193 @@ +/* + * 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.DecoderException ; +import org.apache.commons.collections.primitives.ArrayByteList ; + + +/** + * The length component of a BER TLV Tuple. + * + * @author + * Apache Directory Project + * @version $Rev$ + */ +public class Length +{ + /** used to mark length as indefinate */ + public static final int INDEFINATE = -2 ; + /** used to mark length as undefined */ + public static final int UNDEFINED = -1 ; + /** the end long form terminate bit flag mask */ + public static final int END_MASK = 0x80 ; + + /** the value for this tlv length */ + private int value = UNDEFINED ; + /** the number of octets needed to complete this length component */ + private int numOctets = UNDEFINED ; + /** whether or not this length has been fixated */ + private boolean isFixated = false ; + /** a byte buffer used to collect the arriving length octets */ + private final ArrayByteList buf = new ArrayByteList( 10 ) ; + + + + /** + * Checks to see if the length has been fixated. + * + * @return true if it is fixated, false if not + */ + public boolean isFixated() + { + return isFixated ; + } + + + /** + * Clears this tag's data of all bytes and values calculated so all is as it + * was when this instance was created. + */ + void clear() + { + isFixated = false ; + value = 0 ; + numOctets = 1 ; + 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 + { + value = getLength( buf ) ; + isFixated = true ; + } + + + /** + * Adds an octet to this Length component and as a side effect fixates the + * Length component if all the required length data has arrived. + * + * @param octet the 8 bit byte to add + */ + void add( byte octet ) throws DecoderException + { + if ( isFixated ) + { + throw new IllegalStateException( "data added to fixated length" ) ; + } + + buf.add( octet ) ; + + if ( buf.size() == 1 ) + { + // if its the long form + if ( END_MASK == ( octet & END_MASK ) && ( octet & 0x7F ) > 0 ) + { + // capture number of octets we need to compute length + numOctets = octet & 0x7F ; + } + else + { + fixate() ; + } + } + + /* + * if we have collected all the octets needed for computing the long + * form length so we need to calculate the length and just fixate + */ + else if ( buf.size() >= numOctets + 1 ) + { + fixate() ; + } + } + + + /** + * Gets a copy of the octets composing this Length component. + * + * @return the octets representing this Length component + */ + public byte[] getOctets() + { + return buf.toArray() ; + } + + + /** + * Gets the number of octets currently in this Length component. + * + * @return the number of octets currently within this Length component + */ + public int size() + { + return buf.size() ; + } + + + /** + * Decodes the length of a value for a tlv using the Length field bytes. + * + * @param octets the length field bytes in the TLV + * @return the length of the TLV + * @throws DecoderException if the precision cannot hold the number + */ + public static int getLength( ArrayByteList octets ) throws DecoderException + { + if ( octets.size() >= 6 ) + { + /* + * If this exception is ever thrown which is highly unlikely, then + * we need to switch to another data type to return because after + * 5 bytes the int can no longer hold the number. + */ + throw new DecoderException( "Length number is too large." ) ; + } + + // if we are using the short form then just return the first octet + if ( ( octets.get( 0 ) & END_MASK ) == 0 ) + { + return octets.get( 0 ) ; + } + // using the indefinate form + else if ( ( octets.get( 0 ) & 0x7F ) == 0 ) + { + return INDEFINATE ; + } + + // using the long form so we calculate the length from all octets + int length = 0 ; + + // calculate tag value w/ long tag format + for( int ii = 1 ; ii < octets.size(); ii++ ) + { + int shift = ( ii - 1 ) * 8 ; + length |= ( 0xFF & ( int ) octets.get( ii ) ) << shift ; + } + + return length ; + } +} Added: incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/LengthDecoder.java ============================================================================== --- (empty file) +++ incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/LengthDecoder.java Sun Mar 14 21:51:10 2004 @@ -0,0 +1,62 @@ +/* + * 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 org.apache.commons.codec.DecoderException ; +import org.apache.commons.codec.stateful.AbstractStatefulDecoder ; + + +/** + * A BER TLV Length component decoder. This decoder delivers a Length instance + * to its callback. For efficiency the same Length object is reused. Callback + * implementations should not copy the handle to the Length object delivered but + * should copy the data if they need it over the long term. + * + * @author + * Apache Directory Project + * @version $Rev: 9470 $ + */ +public class LengthDecoder extends AbstractStatefulDecoder +{ + /** the Length component decoded from a BER TLV Tuple */ + private final Length length = new Length() ; + + + /* (non-Javadoc) + * @see org.apache.commons.codec.stateful.StatefulDecoder#decode( + * java.lang.Object) + */ + public void decode( Object encoded ) throws DecoderException + { + ByteBuffer buf = ( ByteBuffer ) encoded ; + + while ( buf.hasRemaining() ) + { + byte octet = buf.get() ; + length.add( octet ) ; + + if ( length.isFixated() ) + { + decodeOccurred( length ) ; + length.clear() ; + } + } + } +} Added: incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/Tag.java ============================================================================== --- (empty file) +++ incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/Tag.java Sun Mar 14 21:51:10 2004 @@ -0,0 +1,296 @@ +/* + * 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.DecoderException ; +import org.apache.commons.collections.primitives.ArrayByteList ; + + +/** + * The Tag component of a BER TLV Tuple. + * + * @author + * Apache Directory Project + * @version $Rev$ + */ +public class Tag +{ + /** tag mask for the primitive/constructed bit - 0010 0000 - 0x20 */ + private static final int PRIMITIVE_MASK = 0x20; + /** tag mask for the short tag format - 0001 1111 - 0x1F */ + public static final int SHORT_MASK = 0x1F ; + /** tag mask for the long tag format - 0111 1111 - 0x7F */ + public static final int LONG_MASK = 0x7F ; + + /** 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 ; + /** a byte buffer used to collect the arriving tag octets */ + private final ArrayByteList buf = new ArrayByteList( 10 ) ; + + + /** + * Clears this tag'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 = Tag.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. + * + * @param octet the 8 bit byte to add + */ + void add( byte octet ) throws DecoderException + { + if ( isFixated ) + { + throw new IllegalStateException( "data added to fixated tag" ) ; + } + + buf.add( octet ) ; + + if ( buf.size() == 1 ) + { + // its the short form so we just fixate + if ( ( 0x1F & octet ) != 0x1F ) + { + fixate() ; + } + } + + /* + * From here on we're dealing with the long form of the tag. The + * 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 & 0x80 ) == 0 ) + { + fixate() ; + } + } + + + /** + * Gets a copy of the octets composing this Tag. + * + * @return the octets representing this Tag + */ + public byte[] getOctets() + { + return buf.toArray() ; + } + + + /** + * Gets the number of octets in this Tag. + * + * @return the number of octets within this Tag + */ + public int size() + { + return buf.size() ; + } + + + /** + * Gets the id. + * + * @return the id + */ + public int getId() + { + return id ; + } + + + /** + * 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 ; + } + + + /** + * Checks to see if the tag has been fixated. + * + * @return true if it is fixated, false if not + */ + public boolean isFixated() + { + return isFixated ; + } + + + /** + * Gets the type class for this Tag. + * + * @return the typeClass for this Tag + */ + public TypeClass getTypeClass() + { + return typeClass ; + } + + + /** + * 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 + * @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 + { + if ( octets.length > 6 ) + { + /* + * If this exception is ever thrown which is highly unlikely, then + * we need to switch to another data type to return because after + * 5 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 the 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( ArrayByteList octets ) + throws DecoderException + { + if ( octets.size() > 6 ) + { + /* + * If this exception is ever thrown which is highly unlikely, then + * we need to switch to another data type to return because after + * 5 bytes the int can no longer hold the number. + */ + throw new DecoderException( "Tag number is too large." ) ; + } + + 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 & PRIMITIVE_MASK ) == 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 & PRIMITIVE_MASK ) == PRIMITIVE_MASK ; + } +} Modified: incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/TagDecoder.java ============================================================================== --- incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/TagDecoder.java (original) +++ incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/TagDecoder.java Sun Mar 14 21:51:10 2004 @@ -17,47 +17,46 @@ package org.apache.snickers.ber ; +import java.nio.ByteBuffer ; + import org.apache.commons.codec.DecoderException ; -import org.apache.commons.codec.stateful.DecoderMonitor ; -import org.apache.commons.codec.stateful.DecoderCallback ; -import org.apache.commons.codec.stateful.StatefulDecoder ; +import org.apache.commons.codec.stateful.AbstractStatefulDecoder ; /** - * A BER Tag decoder. + * A BER TLV Tag component decoder. This decoder delivers a Tag instance + * to its callback. For efficiency the same Tag object is reused. Callback + * implementations should not copy the handle to the Tag object delivered but + * should copy the data if they need it over the long term. + * * * @author * Apache Directory Project * @version $Rev$ */ -public class TagDecoder implements StatefulDecoder +public class TagDecoder extends AbstractStatefulDecoder { + private final Tag tag = new Tag() ; - /* (non-Javadoc) * @see org.apache.commons.codec.stateful.StatefulDecoder#decode( * java.lang.Object) */ - public void decode( Object arg0 ) throws DecoderException - { - } - - - /* (non-Javadoc) - * @see org.apache.commons.codec.stateful.StatefulDecoder#setCallback( - * org.apache.commons.codec.stateful.DecoderCallback) - */ - public void setCallback( DecoderCallback cb ) - { - } - - - /* (non-Javadoc) - * @see org.apache.commons.codec.stateful.StatefulDecoder#setDecoderMonitor( - * org.apache.commons.codec.stateful.DecoderMonitor) - */ - public void setDecoderMonitor( DecoderMonitor monitor ) + public void decode( Object encoded ) throws DecoderException { + ByteBuffer buf = ( ByteBuffer ) encoded ; + + while ( buf.hasRemaining() ) + { + byte octet = buf.get() ; + tag.add( octet ) ; + + if ( tag.isFixated() ) + { + decodeOccurred( tag ) ; + tag.clear() ; + } + } } } Modified: incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/Tuple.java ============================================================================== --- incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/Tuple.java (original) +++ incubator/directory/snickers/branches/refactoring/ber/src/java/org/apache/snickers/ber/Tuple.java Sun Mar 14 21:51:10 2004 @@ -33,11 +33,6 @@ */ 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 */ static final int BIT_6 = 1 << 7 ; /** precalculated left shift of 1 by 8 places */ @@ -65,9 +60,9 @@ Object value = ArrayUtils.EMPTY_BYTE_ARRAY ; /** tlv byte index */ - int index = Tuple.UNDEFINED ; + int index = Length.UNDEFINED ; /** tlv value index for how far into the value we have read */ - int valueIndex = Tuple.UNDEFINED ; + int valueIndex = Length.UNDEFINED ; // ------------------------------------------------------------------------ @@ -161,7 +156,7 @@ this.id = id ; this.isPrimitive = false ; value = ArrayUtils.EMPTY_BYTE_ARRAY ; - length = Tuple.INDEFINATE ; + length = Length.INDEFINATE ; if ( typeClass != null ) { @@ -221,7 +216,7 @@ */ public boolean isIndefinate() { - return length == Tuple.INDEFINATE ; + return length == Length.INDEFINATE ; } @@ -292,7 +287,7 @@ */ public int size() { - if ( this.length == Tuple.INDEFINATE ) + if ( this.length == Length.INDEFINATE ) { return getTagLength() + getLengthLength() ; } @@ -316,10 +311,10 @@ this.id = 0 ; this.index = 0 ; this.isPrimitive = true ; - this.length = Tuple.UNDEFINED ; + this.length = Length.UNDEFINED ; this.typeClass = TypeClass.APPLICATION ; this.value = ArrayUtils.EMPTY_BYTE_ARRAY ; - this.valueIndex = Tuple.UNDEFINED ; + this.valueIndex = Length.UNDEFINED ; } @@ -458,7 +453,7 @@ } else { - octets[0] |= BERUtils.SHORT_TAG_MASK ; + octets[0] |= Tag.SHORT_MASK ; } if ( tagLength >= 2 ) @@ -558,7 +553,7 @@ */ void setLength( byte[] octets, int offset, int lengthBytes ) { - if ( length == Tuple.INDEFINATE ) + if ( length == Length.INDEFINATE ) { octets[offset] |= BIT_6 ; return ; @@ -658,7 +653,7 @@ */ public int getLengthLength() { - if ( length == Tuple.INDEFINATE ) + if ( length == Length.INDEFINATE ) { return 1 ; } Modified: incubator/directory/snickers/branches/refactoring/ber/src/test/org/apache/snickers/ber/BERUtilsTest.java ============================================================================== --- incubator/directory/snickers/branches/refactoring/ber/src/test/org/apache/snickers/ber/BERUtilsTest.java (original) +++ incubator/directory/snickers/branches/refactoring/ber/src/test/org/apache/snickers/ber/BERUtilsTest.java Sun Mar 14 21:51:10 2004 @@ -66,24 +66,24 @@ public void getTypeClass() { - assertEquals( TypeClass.UNIVERSAL, BERUtils.getTypeClass( (byte) 0 ) ) ; + assertEquals( TypeClass.UNIVERSAL, Tag.getTypeClass( (byte) 0 ) ) ; } public void testIsPrimitive() throws Exception { byte octet = Binary.BIT_5 ; - assertFalse( BERUtils.isPrimitive( octet ) ) ; - assertFalse( BERUtils.isPrimitive( Binary.BIT_5 ) ) ; + assertFalse( Tag.isPrimitive( octet ) ) ; + assertFalse( Tag.isPrimitive( Binary.BIT_5 ) ) ; - assertTrue( BERUtils.isPrimitive( 0 ) ) ; - assertTrue( BERUtils.isPrimitive( Binary.BIT_0 ) ) ; - assertTrue( BERUtils.isPrimitive( Binary.BIT_1 ) ) ; - assertTrue( BERUtils.isPrimitive( Binary.BIT_2 ) ) ; - assertTrue( BERUtils.isPrimitive( Binary.BIT_3 ) ) ; - assertTrue( BERUtils.isPrimitive( Binary.BIT_4 ) ) ; - assertTrue( BERUtils.isPrimitive( Binary.BIT_6 ) ) ; - assertTrue( BERUtils.isPrimitive( Binary.BIT_7 ) ) ; + assertTrue( Tag.isPrimitive( 0 ) ) ; + assertTrue( Tag.isPrimitive( Binary.BIT_0 ) ) ; + assertTrue( Tag.isPrimitive( Binary.BIT_1 ) ) ; + assertTrue( Tag.isPrimitive( Binary.BIT_2 ) ) ; + assertTrue( Tag.isPrimitive( Binary.BIT_3 ) ) ; + assertTrue( Tag.isPrimitive( Binary.BIT_4 ) ) ; + assertTrue( Tag.isPrimitive( Binary.BIT_6 ) ) ; + assertTrue( Tag.isPrimitive( Binary.BIT_7 ) ) ; } @@ -91,17 +91,17 @@ { byte octet = Binary.BIT_5 ; - assertTrue( BERUtils.isConstructed( octet ) ) ; - assertTrue( BERUtils.isConstructed( Binary.BIT_5 ) ) ; + assertTrue( Tag.isConstructed( octet ) ) ; + assertTrue( Tag.isConstructed( Binary.BIT_5 ) ) ; - assertFalse( BERUtils.isConstructed( 0 ) ) ; - assertFalse( BERUtils.isConstructed( Binary.BIT_0 ) ) ; - assertFalse( BERUtils.isConstructed( Binary.BIT_1 ) ) ; - assertFalse( BERUtils.isConstructed( Binary.BIT_2 ) ) ; - assertFalse( BERUtils.isConstructed( Binary.BIT_3 ) ) ; - assertFalse( BERUtils.isConstructed( Binary.BIT_4 ) ) ; - assertFalse( BERUtils.isConstructed( Binary.BIT_6 ) ) ; - assertFalse( BERUtils.isConstructed( Binary.BIT_7 ) ) ; + assertFalse( Tag.isConstructed( 0 ) ) ; + assertFalse( Tag.isConstructed( Binary.BIT_0 ) ) ; + assertFalse( Tag.isConstructed( Binary.BIT_1 ) ) ; + assertFalse( Tag.isConstructed( Binary.BIT_2 ) ) ; + assertFalse( Tag.isConstructed( Binary.BIT_3 ) ) ; + assertFalse( Tag.isConstructed( Binary.BIT_4 ) ) ; + assertFalse( Tag.isConstructed( Binary.BIT_6 ) ) ; + assertFalse( Tag.isConstructed( Binary.BIT_7 ) ) ; } @@ -115,11 +115,11 @@ if ( ii < 31 ) { - assertEquals( BERUtils.getTagId( octets ), ii ) ; + assertEquals( Tag.getTagId( octets ), ii ) ; } else { - assertTrue( BERUtils.getTagId( octets ) != ii ) ; + assertTrue( Tag.getTagId( octets ) != ii ) ; } } @@ -133,11 +133,11 @@ if ( ii < 128 ) { - assertEquals( BERUtils.getTagId( octets ), ii ) ; + assertEquals( Tag.getTagId( octets ), ii ) ; } else { - assertTrue( BERUtils.getTagId( octets ) != ii ) ; + assertTrue( Tag.getTagId( octets ) != ii ) ; } } @@ -148,16 +148,16 @@ for ( int ii = 128 ; ii < 20000; ii++ ) { - octets[1] = ( byte ) ( ii & BERUtils.LONG_TAG_MASK ) ; - octets[2] = ( byte ) ( ( ii >> 7 ) & BERUtils.LONG_TAG_MASK ) ; + octets[1] = ( byte ) ( ii & Tag.LONG_MASK ) ; + octets[2] = ( byte ) ( ( ii >> 7 ) & Tag.LONG_MASK ) ; if ( ii < 16384 ) { - assertEquals( BERUtils.getTagId( octets ), ii ) ; + assertEquals( Tag.getTagId( octets ), ii ) ; } else { - assertTrue( BERUtils.getTagId( octets ) != ii ) ; + assertTrue( Tag.getTagId( octets ) != ii ) ; } } @@ -171,23 +171,23 @@ for ( int ii = 16384 ; ii < 2100000 ; ii++ ) { - octets[1] = ( byte ) ( ii & BERUtils.LONG_TAG_MASK ) ; - octets[2] = ( byte ) ( ( ii >> 7 ) & BERUtils.LONG_TAG_MASK ) ; - octets[3] = ( byte ) ( ( ii >> 14 ) & BERUtils.LONG_TAG_MASK ) ; + octets[1] = ( byte ) ( ii & Tag.LONG_MASK ) ; + octets[2] = ( byte ) ( ( ii >> 7 ) & Tag.LONG_MASK ) ; + octets[3] = ( byte ) ( ( ii >> 14 ) & Tag.LONG_MASK ) ; if ( ii < 2097152 ) { - assertEquals( BERUtils.getTagId( octets ), ii ) ; + assertEquals( Tag.getTagId( octets ), ii ) ; } else { - assertTrue( BERUtils.getTagId( octets ) != ii ) ; + assertTrue( Tag.getTagId( octets ) != ii ) ; } } ArrayByteList list = new ArrayByteList() ; list.add( (byte)1) ; - assertEquals( 1, BERUtils.getTagId( list ) ) ; + assertEquals( 1, Tag.getTagId( list ) ) ; list.add( (byte)1) ; list.add( (byte)1) ; @@ -199,7 +199,7 @@ list.add( (byte)1) ; try { - BERUtils.getTagId( list ) ; + Tag.getTagId( list ) ; fail( "should fail before getting here" ) ; } catch ( Throwable t ) @@ -210,7 +210,7 @@ try { - BERUtils.getTagId( new byte[56] ) ; + Tag.getTagId( new byte[56] ) ; fail( "should fail before getting here" ) ; } catch ( Throwable t ) @@ -234,7 +234,7 @@ try { - BERUtils.getLength( list ) ; + Length.getLength( list ) ; fail( "should fail before we get here" ) ; } catch ( Throwable t ) @@ -245,6 +245,6 @@ list.clear() ; list.add(( byte ) 0x7 ) ; - assertEquals( 7, BERUtils.getLength( list ) ) ; + assertEquals( 7, Length.getLength( list ) ) ; } } Modified: incubator/directory/snickers/branches/refactoring/ber/src/test/org/apache/snickers/ber/TupleTest.java ============================================================================== --- incubator/directory/snickers/branches/refactoring/ber/src/test/org/apache/snickers/ber/TupleTest.java (original) +++ incubator/directory/snickers/branches/refactoring/ber/src/test/org/apache/snickers/ber/TupleTest.java Sun Mar 14 21:51:10 2004 @@ -200,14 +200,14 @@ assertEquals( 2, t.getId() ) ; assertEquals( TypeClass.PRIVATE, t.getTypeClass() ) ; assertEquals( false, t.isPrimitive() ) ; - assertEquals( Tuple.INDEFINATE, t.getLength() ) ; + assertEquals( Length.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( Tuple.INDEFINATE, t.getLength() ) ; + assertEquals( Length.INDEFINATE, t.getLength() ) ; assertEquals( ArrayUtils.EMPTY_BYTE_ARRAY, t.getValue() ) ; } @@ -252,7 +252,7 @@ { Tuple t = new Tuple() ; assertFalse( t.isIndefinate() ) ; - t.length = Tuple.INDEFINATE ; + t.length = Length.INDEFINATE ; assertTrue( t.isIndefinate() ) ; } @@ -321,7 +321,7 @@ t.length = 12 ; assertEquals( 12, t.length ) ; t.clear() ; - assertEquals( Tuple.UNDEFINED, t.length ) ; + assertEquals( Length.UNDEFINED, t.length ) ; t.index = 12 ; assertEquals( 12, t.index ) ; @@ -346,7 +346,7 @@ t.valueIndex = 12 ; assertEquals( 12, t.valueIndex ) ; t.clear() ; - assertEquals( Tuple.UNDEFINED, t.valueIndex ) ; + assertEquals( Length.UNDEFINED, t.valueIndex ) ; }