You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2005/05/02 23:12:05 UTC
svn commit: r165688 -
/directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/primitives/BitString.java
Author: elecharny
Date: Mon May 2 14:12:04 2005
New Revision: 165688
URL: http://svn.apache.org/viewcvs?rev=165688&view=rev
Log:
Added the BitString primitive class
Added:
directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/primitives/BitString.java
Added: directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/primitives/BitString.java
URL: http://svn.apache.org/viewcvs/directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/primitives/BitString.java?rev=165688&view=auto
==============================================================================
--- directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/primitives/BitString.java (added)
+++ directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/primitives/BitString.java Mon May 2 14:12:04 2005
@@ -0,0 +1,347 @@
+/*
+ * Copyright 2005 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.primitives;
+
+import org.apache.asn1.DecoderException;
+import org.apache.asn1.util.pools.PoolObject;
+
+
+/**
+ * Implement the Bit String primitive type.
+ *
+ * A BitString is internally stored as an array of int.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class BitString extends PoolObject
+{
+ //~ Static fields/initializers -----------------------------------------------------------------
+
+ /** A null MutableString */
+ public static final BitString EMPTY_STRING = new BitString();
+
+ /** A flag to mark the OctetString as Streamed (for OctetString larger than 1024 chars) */
+ // TODO implement the streaming...
+ public static final boolean STREAMED = true;
+
+ /** The default length of an BitString */
+ private static final int DEFAULT_LENGTH = 8;
+
+ //~ Instance fields ----------------------------------------------------------------------------
+
+ /** The number of unused ints */
+ private int nbUnusedBits;
+
+ /** Tells if the OctetString is streamed or not */
+ private boolean isStreamed;
+
+ /** The string is stored in a int array */
+ private int[] ints;
+
+ /** Actual length of the int array */
+ private int nbInts;
+
+ /** Actual length of the bit string */
+ private int nbBits;
+
+ //~ Constructors -------------------------------------------------------------------------------
+
+ /**
+ * Creates a BitString, with a default length.
+ */
+ public BitString()
+ {
+ ints = new int[DEFAULT_LENGTH];
+ nbInts = 0;
+ isStreamed = false;
+ nbUnusedBits = 0;
+ nbBits = 0;
+ }
+
+ /**
+ * Creates a BitString with a specific length (length is the number
+ * of ints).
+ *
+ * @param length The BitString length (it's a byte number)
+ */
+ public BitString( int length )
+ {
+ nbBits = length;
+
+ // As we store values in an int, we must divide the length by 32
+ nbInts = ( length / 32 ) + ( ( ( length % 32 ) != 0 ) ? 1 : 0 );
+
+ nbUnusedBits = length % 8;
+
+ if ( nbInts > DEFAULT_LENGTH )
+ {
+
+ // TODO : implement the streaming
+ isStreamed = true;
+ ints = new int[nbInts];
+ }
+ else
+ {
+ isStreamed = false;
+ ints = new int[nbInts];
+ }
+ }
+
+ /**
+ * Creates a streamed BitString with a specific length.
+ * Actually, it's just a simple BitString.
+ * TODO Implement streaming.
+ *
+ * @param length The BitString length, in number of ints
+ * @param isStreamed Tells if the BitString must be streamed or not
+ */
+ public BitString( int length, boolean isStreamed )
+ {
+ nbBits = length;
+ this.isStreamed = isStreamed;
+ nbInts = ( length / 32 ) + ( ( ( length % 32 ) != 0 ) ? 1 : 0 );
+
+ nbUnusedBits = length % 8;
+
+ if ( isStreamed )
+ {
+
+ // TODO : implement the streaming
+ ints = new int[nbInts];
+ }
+ else
+ {
+ ints = new int[nbInts];
+ }
+ }
+
+ /**
+ * Creates a BitString with a value.
+ *
+ * @param bytes The value to store. The first byte contains the number
+ * of unused ints
+ */
+ public BitString( byte[] bytes )
+ {
+ nbInts = ( bytes.length / 4 ) + ( ( ( bytes.length % 4 ) != 0 ) ? 1 : 0 );
+
+ // The first byte contains the number of unused ints
+ nbUnusedBits = bytes[0] & 0x07;
+ nbBits = ( bytes.length * 8 ) - nbUnusedBits;
+
+ if ( nbInts > DEFAULT_LENGTH )
+ {
+ isStreamed = true;
+
+ // It will be a streamed OctetString.
+ // TODO : implement the streaming
+ ints = new int[nbInts];
+ }
+ else
+ {
+ isStreamed = false;
+
+ ints = new int[nbInts];
+ }
+
+ // We have to transfer the data from bytes to ints
+ int pos = 1;
+ int bytesPos = 1;
+
+ for ( int i = 0; i < nbInts; i++ )
+ {
+
+ for ( int j = 0; j < 4; j++ )
+ {
+
+ if ( bytesPos == ( nbInts - 1 ) )
+ {
+ ints[i] = ( ints[i] << ( 8 - nbUnusedBits ) ) +
+ ( bytes[bytesPos] >> nbUnusedBits );
+ break;
+ }
+ else
+ {
+ ints[i] = ( ints[i] << 8 ) + bytes[bytesPos++];
+ }
+ }
+ }
+ }
+
+ //~ Methods ------------------------------------------------------------------------------------
+
+ /**
+ * Set a new BitString in the BitString. It will replace the old BitString,
+ * and reset the current length with the new one.
+ *
+ * @param bytes The string to store
+ */
+ public void setData( byte[] bytes )
+ {
+
+ if ( ( bytes == null ) || ( bytes.length == 0 ) )
+ {
+ nbBits = -1;
+ return;
+ }
+
+ int nbBytes = bytes.length - 1;
+
+ int nbInts = ( nbBytes / 4 ) + ( ( ( nbBytes % 4 ) != 0 ) ? 1 : 0 );
+
+ // The first byte contains the number of unused ints
+ nbUnusedBits = bytes[0] & 0x07;
+ nbBits = ( nbBytes * 8 ) - nbUnusedBits;
+
+ if ( ( nbInts > DEFAULT_LENGTH ) && ( ints.length < nbInts ) )
+ {
+
+ // The current size is too small.
+ // We have to allocate more space
+ // TODO : implement the streaming
+ ints = new int[nbInts];
+ }
+
+ // We have to transfer the data from bytes to ints
+ int pos = 1;
+ int bytesPos = 1;
+
+ for ( int i = 0; i < ( nbInts - 1 ); i++ )
+ {
+ ints[i] =
+ ( ( bytes[( i * 4 ) + 1] & 0x00FF ) << 24 ) +
+ ( ( bytes[( i * 4 ) + 2] & 0x00FF ) << 16 ) +
+ ( ( bytes[( i * 4 ) + 3] & 0x00FF ) << 8 ) +
+ ( bytes[( i * 4 ) + 4] & 0x00FF );
+ }
+
+ switch ( nbBytes % 4 )
+ {
+
+ case 0 :
+ ints[nbInts - 1] = ( bytes[( ( nbInts - 1 ) * 4 ) + pos] & 0x00FF );
+ pos++;
+ // fallthrough
+
+ case 3 :
+ ints[nbInts - 1] = ( ints[nbInts - 1] << 8 ) +
+ ( bytes[( ( nbInts - 1 ) * 4 ) + pos] & 0x00FF );
+ pos++;
+ // fallthrough
+
+ case 2 :
+ ints[nbInts - 1] = ( ints[nbInts - 1] << 8 ) +
+ ( bytes[( ( nbInts - 1 ) * 4 ) + pos] & 0x00FF );
+ pos++;
+ // fallthrough
+
+ case 1 :
+ ints[nbInts - 1] = ( ints[nbInts - 1] << 8 ) +
+ ( bytes[( ( nbInts - 1 ) * 4 ) + pos] & 0x00FF );
+ pos++;
+ // fallthrough
+
+ default :
+ // Nothing to do...
+ }
+
+ ints[nbInts - 1] >>= nbUnusedBits;
+ }
+
+ /**
+ * Get the bit stored into the BitString at a specific position? The position start at 0,
+ * which is on the left :
+ * With '1001 000x', where x is an unused bit,
+ * ^ ^ ^^
+ * | | ||
+ * | | |+---- getBit(7) -> DecoderException
+ * | | +----- getBit(6) = 0
+ * | +---------- getBit(2) = 0
+ * +------------ getBit(0) = 1
+ * @param pos The position of the requested bit.
+ * @return <code>true</code> if the bit is set, <code>false</code> otherwise
+ */
+ public boolean getBit( int pos ) throws DecoderException
+ {
+
+ if ( pos > nbBits )
+ {
+ throw new DecoderException(
+ "Cannot get a bit at position " + pos + " when the BitString contains only " +
+ nbBits + " ints" );
+ }
+
+ int posInt = pos / 32;
+
+ if ( ( pos / 32 ) < ( nbBits / 32 ) )
+ {
+
+ int bitNumber = 31 - ( pos % 32 );
+ int res = ints[posInt] & ( 1 << bitNumber );
+ return res != 0;
+ }
+ else
+ {
+
+ int bitNumber = ( nbBits % 32 ) - ( pos % 32 );
+ return ( ints[posInt] & ( ( 0x01 << bitNumber ) - 1 ) ) != 0;
+ }
+
+ }
+
+ /**
+ * Return a native String representation of the BitString.
+ * @return A String representing the BitString
+ */
+ public String toString()
+ {
+
+ StringBuffer sb = new StringBuffer();
+
+ try
+ {
+
+ for ( int i = 0; i < nbBits; i++ )
+ {
+
+ if ( getBit( i ) )
+ {
+ sb.append( '1' );
+ }
+ else
+ {
+ sb.append( '0' );
+ }
+ }
+ }
+ catch ( DecoderException de )
+ {
+ return "Invalid BitString";
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Tells if the OctetString is streamed or not
+ * @return <code>true</code> if the OctetString is streamed.
+ */
+ public boolean isStreamed()
+ {
+ return isStreamed;
+ }
+}