Author: elecharny
Date: Sun Oct 25 23:19:25 2015
New Revision: 1710496
URL: http://svn.apache.org/viewvc?rev=1710496&view=rev
Log:
Fix for DIRAPI-261. There is still more fixes to push
Modified:
directory/shared/trunk/asn1/api/src/main/java/org/apache/directory/api/asn1/util/Oid.java
directory/shared/trunk/asn1/api/src/test/java/org/apache/directory/api/asn1/util/OidTest.java
Modified: directory/shared/trunk/asn1/api/src/main/java/org/apache/directory/api/asn1/util/Oid.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/asn1/api/src/main/java/org/apache/directory/api/asn1/util/Oid.java?rev=1710496&r1=1710495&r2=1710496&view=diff
==============================================================================
--- directory/shared/trunk/asn1/api/src/main/java/org/apache/directory/api/asn1/util/Oid.java (original)
+++ directory/shared/trunk/asn1/api/src/main/java/org/apache/directory/api/asn1/util/Oid.java Sun Oct 25 23:19:25 2015
@@ -23,9 +23,8 @@ package org.apache.directory.api.asn1.ut
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
+import java.math.BigInteger;
import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.Queue;
import org.apache.directory.api.asn1.DecoderException;
import org.apache.directory.api.i18n.I18n;
@@ -66,11 +65,11 @@ import org.apache.directory.api.i18n.I18
* are allocated from the root node, and at most 39 subsequent values from nodes
* reached by X = 0 and X = 1.</i></p>
*
- * <p>For example, the OID "2.123456.7" would be turned into a list of 2 values:
- * <code>[((2*80)+123456), 7]</code>. The first of which,
- * <code>123536</code>, would be encoded as the bytes
- * <code>[0x87, 0xC5, 0x10]</code>, the second would be <code>[0x07]</code>,
- * giving the final encoding <code>[0x87, 0xC5, 0x10, 0x07]</code>.</p>
+ * <p>For example, the OID "2.12.3456.7" would be turned into a list of 3 values:
+ * <code>[((2*40)+12), 3456, 7]</code>. The first of which,
+ * <code>92</code>, would be encoded as the bytes <code>0x5C</code>, the second
+ * would be <code>[0x9B, 0x00]</code>, and the third as <code>0x07</code>
+ * giving the final encoding <code>[0x5C, 0x9B, 0x00, 0x07]</code>.</p>
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
@@ -81,6 +80,76 @@ public final class Oid
/** The OID as a String */
private String oidString;
+
+ private static final BigInteger JOINT_ISO_ITU_T = new BigInteger( "80" );
+
+ /**
+ * The OID FSA states. We have the following Finite State Automaton :
+ *
+ * <pre>
+ * (Start) --['0','1']--> (A)
+ * (start) --['2']--> (F)
+ *
+ * (A) --['.']--> (B)
+ *
+ * (B) --['0']--> (D)
+ * (B) --['1'..'3']--> (C)
+ * (B) --['4'..'9']--> (E)
+ *
+ * (C) --[]--> (End)
+ * (C) --['.']--> (K)
+ * (C) --['0'..'9']--> (E)
+ *
+ * (D) --[]--> (End)
+ * (D) --['.']--> (K)
+ *
+ * (E) --[]--> (End)
+ * (E) --['.']--> (K)
+ *
+ * (F) --['.']--> (G)
+ *
+ * (G) --['0']--> (I)
+ * (G) --['1'..'9']--> (H)
+ *
+ * (H) --[]--> (End)
+ * (H) --['.']--> (K)
+ * (H) --['0'..'9']--> (J)
+ *
+ * (I) --[]--> (End)
+ * (I) --['.']--> (K)
+ *
+ * (J) --[]--> (End)
+ * (J) --['.']--> (K)
+ * (J) --['0'..'9']--> (J)
+ *
+ * (K) --['0']--> (M)
+ * (K) --['1'..'9']--> (L)
+ *
+ * (L) --[]--> (End)
+ * (L) --['.']--> (K)
+ * (L) --['0'..'9']--> (L)
+ *
+ * (M) --[]--> (End)
+ * (M) --['.']--> (K)
+ * </pre>
+ */
+ private enum OidFSAState
+ {
+ START,
+ STATE_A,
+ STATE_B,
+ STATE_C,
+ STATE_D,
+ STATE_E,
+ STATE_F,
+ STATE_G,
+ STATE_H,
+ STATE_I,
+ STATE_J,
+ STATE_K,
+ STATE_L,
+ STATE_M,
+ }
/**
@@ -117,7 +186,7 @@ public final class Oid
*/
public static Oid fromBytes( byte[] oidBytes ) throws DecoderException
{
- if ( oidBytes == null || oidBytes.length < 1 )
+ if ( ( oidBytes == null ) || ( oidBytes.length < 1 ) )
{
throw new DecoderException( I18n.err( I18n.ERR_00033_INVALID_OID, Arrays.toString( oidBytes ) ) );
}
@@ -189,8 +258,8 @@ public final class Oid
* @param oidString The string representation of the OID
* @return A new Oid
* @throws DecoderException When the OID is not valid
- */
- public static Oid fromString( String oidString ) throws DecoderException
+ *
+ public static Oid fromStringLong( String oidString ) throws DecoderException
{
if ( ( oidString == null ) || oidString.isEmpty() )
{
@@ -239,8 +308,1008 @@ public final class Oid
return new Oid( oidString, buffer.toByteArray() );
}
+
+ /**
+ * Process state A
+ * <pre>
+ * (Start) --['0','1']--> (A)
+ * (start) --['2']--> (F)
+ * </pre>
+ */
+ private static OidFSAState processStateStart( String oid, byte[] buffer, int pos ) throws DecoderException
+ {
+ char c = oid.charAt( pos );
+
+ switch ( c )
+ {
+ case '0' :
+ case '1' :
+ buffer[0] = ( byte ) ( ( c - '0' ) * 40 );
+ return OidFSAState.STATE_A;
+
+ case '2' :
+ return OidFSAState.STATE_F;
+
+ default :
+ // This is an error
+ throw new DecoderException( I18n.err( I18n.ERR_00033_INVALID_OID, "Should start with 0, 1 or 2" ) );
+ }
+ }
+
+
+ /**
+ * Process state B
+ * <pre>
+ * (A) --['.']--> (B)
+ * </pre>
+ */
+ private static OidFSAState processStateA( String oid, int pos ) throws DecoderException
+ {
+ if ( oid.charAt( pos ) != '.' )
+ {
+ // Expecting a Dot here
+ throw new DecoderException( I18n.err( I18n.ERR_00033_INVALID_OID, "a '.' is expected" ) );
+ }
+
+ return OidFSAState.STATE_B;
+ }
+
+
+ /**
+ * Process state B
+ * <pre>
+ * (B) --['0']--> (D)
+ * (B) --['1'..'3']--> (C)
+ * (B) --['4'..'9']--> (E)
+ * </pre>
+ */
+ private static OidFSAState processStateB( String oid, byte[] buffer, int pos ) throws DecoderException
+ {
+ char c = oid.charAt( pos );
+
+ switch ( c )
+ {
+ case '0' :
+ return OidFSAState.STATE_D;
+
+ case '1' :
+ case '2' :
+ case '3' :
+ // We may have a second digit. Atm, store the current one in the second psotion
+ buffer[1] = ( byte ) ( c - '0' );
+
+ return OidFSAState.STATE_C;
+
+ case '4' :
+ case '5' :
+ case '6' :
+ case '7' :
+ case '8' :
+ case '9' :
+ buffer[0] += ( byte ) ( c - '0' );
+ return OidFSAState.STATE_E;
+
+ default :
+ // Expecting a digit here
+ throw new DecoderException( I18n.err( I18n.ERR_00033_INVALID_OID, "a digit is expected" ) );
+ }
+ }
+
+
+ /**
+ * Process state C
+ * <pre>
+ * (C) --['.']--> (K)
+ * (C) --['0'..'9']--> (E)
+ * </pre>
+ */
+ private static OidFSAState processStateC( String oid, byte[] buffer, int pos ) throws DecoderException
+ {
+ char c = oid.charAt( pos );
+
+ switch ( c )
+ {
+ case '0' :
+ case '1' :
+ case '2' :
+ case '3' :
+ case '4' :
+ case '5' :
+ case '6' :
+ case '7' :
+ case '8' :
+ case '9' :
+ buffer[0] += ( byte ) ( buffer[1] * 10 + ( c - '0' ) );
+ buffer[1] = 0;
+ return OidFSAState.STATE_E;
+
+ case '.' :
+ buffer[0] += buffer[1];
+ buffer[1] = 0;
+ return OidFSAState.STATE_K;
+
+ default :
+ // Expecting a digit here
+ throw new DecoderException( I18n.err( I18n.ERR_00033_INVALID_OID, "a digit is expected" ) );
+ }
+ }
+
+
+ /**
+ * Process state D and E
+ * <pre>
+ * (D) --['.']--> (K)
+ * (E) --['.']--> (K)
+ * </pre>
+ */
+ private static OidFSAState processStateDE( String oid, byte[] buffer, int pos ) throws DecoderException
+ {
+ char c = oid.charAt( pos );
+
+ if ( c != '.' )
+ {
+ // Expecting a '.' here
+ throw new DecoderException( I18n.err( I18n.ERR_00033_INVALID_OID, "a dot is expected" ) );
+ }
+
+ // Store the first byte into it
+ buffer[0] = ( byte ) ( buffer[0] | buffer[1] );
+ buffer[1] = 0;
+
+ return OidFSAState.STATE_K;
+ }
+
+
+ /**
+ * Process state F
+ * <pre>
+ * (F) --['.']--> (G)
+ * </pre>
+ */
+ private static OidFSAState processStateF( String oid, int pos ) throws DecoderException
+ {
+ if ( oid.charAt( pos ) != '.' )
+ {
+ // Expecting a Dot here
+ throw new DecoderException( I18n.err( I18n.ERR_00033_INVALID_OID, "a '.' is expected" ) );
+ }
+
+ return OidFSAState.STATE_G;
+ }
+
+
+ /**
+ * Process state G
+ * <pre>
+ * (G) --['0']--> (I)
+ * (G) --['1'..'9']--> (H)
+ * </pre>
+ */
+ private static OidFSAState processStateG( String oid, byte[] buffer, int pos ) throws DecoderException
+ {
+ char c = oid.charAt( pos );
+
+ switch ( c )
+ {
+ case '0' :
+ buffer[0] = ( byte ) 80;
+ return OidFSAState.STATE_I;
+
+ case '1' :
+ case '2' :
+ case '3' :
+ case '4' :
+ case '5' :
+ case '6' :
+ case '7' :
+ case '8' :
+ case '9' :
+ // Store the read digit in the second position in the buffer
+ buffer[0] = ( byte ) ( c - '0' );
+ return OidFSAState.STATE_H;
+
+ default :
+ // Expecting a digit here
+ throw new DecoderException( I18n.err( I18n.ERR_00033_INVALID_OID, "a digit is expected" ) );
+ }
+ }
+
+
+ /**
+ * Process state H
+ * <pre>
+ * (H) --['.']--> (K)
+ * (H) --['0'..'9']--> (J)
+ * </pre>
+ */
+ private static OidFSAState processStateH( String oid, byte[] buffer, int pos ) throws DecoderException
+ {
+ char c = oid.charAt( pos );
+
+ switch ( c )
+ {
+ case '0' :
+ case '1' :
+ case '2' :
+ case '3' :
+ case '4' :
+ case '5' :
+ case '6' :
+ case '7' :
+ case '8' :
+ case '9' :
+ // Store the read digit in the first position in the buffer
+ buffer[1] = ( byte ) ( c - '0' );
+ return OidFSAState.STATE_J;
+
+ case '.' :
+ // The first 2 arcs are single digit, we can collapse them in one byte.
+ buffer[0] = ( byte ) ( 80 + buffer[0] );
+
+ return OidFSAState.STATE_K;
+
+ default :
+ // Expecting a digit here
+ throw new DecoderException( I18n.err( I18n.ERR_00033_INVALID_OID, "a digit is expected" ) );
+ }
+ }
+
+
+ /**
+ * Process state I
+ * <pre>
+ * (I) --['.']--> (K)
+ * </pre>
+ */
+ private static OidFSAState processStateI( String oid, byte[] buffer, int pos ) throws DecoderException
+ {
+ char c = oid.charAt( pos );
+
+ switch ( c )
+ {
+ case '.' :
+ // The first 2 arcs are single digit, we can collapse them in one byte.
+ buffer[0] = ( byte ) ( 80 + buffer[1] );
+ return OidFSAState.STATE_K;
+
+ default :
+ // Expecting a digit here
+ throw new DecoderException( I18n.err( I18n.ERR_00033_INVALID_OID, "a digit is expected" ) );
+ }
+ }
+
+
+ /**
+ * Process state J
+ * <pre>
+ * (J) --['.']--> (K)
+ * (J) --['0'..'9']--> (J)
+ * </pre>
+ */
+ private static OidFSAState processStateJ( String oid, byte[] buffer, int bufferPos, int pos ) throws DecoderException
+ {
+ char c = oid.charAt( pos );
+
+ switch ( c )
+ {
+ case '.' :
+ return OidFSAState.STATE_K;
+
+ case '0' :
+ case '1' :
+ case '2' :
+ case '3' :
+ case '4' :
+ case '5' :
+ case '6' :
+ case '7' :
+ case '8' :
+ case '9' :
+ // Store the new digit at the right position in the buffer
+ buffer[bufferPos] = ( byte ) ( c - '0' );
+ return OidFSAState.STATE_J;
+
+ default :
+ // Expecting a digit here
+ throw new DecoderException( I18n.err( I18n.ERR_00033_INVALID_OID, "a digit is expected" ) );
+ }
+ }
+
+
+ /**
+ * Process state J
+ * <pre>
+ * (K) --['0']--> (M)
+ * (K) --['1'..'9']--> (L)
+ * </pre>
+ */
+ private static OidFSAState processStateK( String oid, byte[] buffer, int bufferPos, int pos ) throws DecoderException
+ {
+ char c = oid.charAt( pos );
+
+ switch ( c )
+ {
+ case '0' :
+ buffer[bufferPos] = 0x00;
+ return OidFSAState.STATE_M;
+
+ case '1' :
+ case '2' :
+ case '3' :
+ case '4' :
+ case '5' :
+ case '6' :
+ case '7' :
+ case '8' :
+ case '9' :
+ // Store the new digit at the right position in the buffer
+ return OidFSAState.STATE_L;
+
+ default :
+ // Expecting a digit here
+ throw new DecoderException( I18n.err( I18n.ERR_00033_INVALID_OID, "a digit is expected" ) );
+ }
+ }
+
+
+ /**
+ * Process state J
+ * <pre>
+ * (L) --['.']--> (K)
+ * (L) --['0'..'9']--> (L)
+ * </pre>
+ */
+ private static OidFSAState processStateL( String oid, byte[] buffer, int bufferPos, int pos ) throws DecoderException
+ {
+ char c = oid.charAt( pos );
+
+ switch ( c )
+ {
+ case '.' :
+ return OidFSAState.STATE_K;
+
+ case '0' :
+ case '1' :
+ case '2' :
+ case '3' :
+ case '4' :
+ case '5' :
+ case '6' :
+ case '7' :
+ case '8' :
+ case '9' :
+ // Store the new digit at the right position in the buffer
+ buffer[bufferPos] = ( byte ) ( c - '0' );
+
+ return OidFSAState.STATE_L;
+
+ default :
+ // Expecting a digit here
+ throw new DecoderException( I18n.err( I18n.ERR_00033_INVALID_OID, "a digit or a dot is expected" ) );
+ }
+ }
+
+
+ /**
+ * Process state J
+ * <pre>
+ * (M) --['.']--> (K)
+ * </pre>
+ */
+ private static OidFSAState processStateM( String oid, int pos ) throws DecoderException
+ {
+ char c = oid.charAt( pos );
+
+ switch ( c )
+ {
+ case '.' :
+ return OidFSAState.STATE_K;
+
+ default :
+ // Expecting a '.' here
+ throw new DecoderException( I18n.err( I18n.ERR_00033_INVALID_OID, "a '.' is expected" ) );
+ }
+ }
+
+
+ /**
+ * Compute the number of bytes necessary to store a long
+ */
+ private int getNbBytes( long value )
+ {
+ if ( value > 0x00000000FFFFFFFFL )
+ {
+ if ( value > 0x0000FFFFFFFFFFFFL )
+ {
+ if ( value > 0x00FFFFFFFFFFFFFFL )
+ {
+ return 8;
+ }
+ else
+ {
+ return 7;
+ }
+ }
+ else
+ {
+ if ( value > 0x000000FFFFFFFFFFL )
+ {
+ return 6;
+ }
+ else
+ {
+ return 5;
+ }
+ }
+
+ }
+ else
+ {
+ if ( value > 0x00000000000000FFFFL )
+ {
+ if ( value > 0x0000000000FFFFFFL )
+ {
+ return 4;
+ }
+ else
+ {
+ return 3;
+ }
+ }
+ else
+ {
+ if ( value > 0x00000000000000FFL )
+ {
+ return 2;
+ }
+ else
+ {
+ return 1;
+ }
+
+ }
+ }
+ }
+
+
+ /**
+ * Get a bte[] that will hold the
+ * TODO getBytes.
+ *
+ * @param value
+ * @return
+ */
+ private byte[] getBytes( long value )
+ {
+ int nbBytes = getNbBytes( value );
+
+ return new byte[nbBytes];
+
+ }
/**
+ * Convert a list of digits to a list of 7 bits bytes. We must start by the end, and we don't
+ * know how many bytes we will need, except when we will be done with the conversion.
+ */
+ private static int convert( String oid, byte[] buffer, int start, int nbDigits, int posBuffer, boolean isJointIsoItuT )
+ {
+ if ( nbDigits < 3 )
+ {
+ // Speedup when we have a number in [0..99] : it's guaranteed to be hold
+ // by a single byte.
+ if ( isJointIsoItuT )
+ {
+ // Another special case : this is an OID that starts with '2.'
+ buffer[0] = ( byte ) ( 80 + ( oid.charAt( 2 ) - '0' ) * 10 + ( oid.charAt( 3 ) - '0' ) );
+
+ if ( buffer[0] < 0 )
+ {
+ // Here, we need 2 bytes
+ buffer[1] = ( byte ) ( buffer[0] & 0x007F );
+ buffer[0] = ( byte ) 0x81;
+
+ return 2;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ else
+ {
+ if ( nbDigits == 1 )
+ {
+ buffer[posBuffer] = ( byte ) ( oid.charAt( start ) - '0' );
+ }
+ else
+ {
+ buffer[posBuffer] = ( byte ) ( ( oid.charAt( start ) - '0' ) * 10 + ( oid.charAt( start + 1 ) - '0' ) );
+
+ }
+ return 1;
+ }
+
+ }
+ else if ( nbDigits < 19 )
+ {
+ // The value can be hold in a Long if it's up to 999999999999999999
+ // Convert the String to a long :
+ String number = oid.substring( start, start + nbDigits );
+
+ long value = Long.parseLong( number );
+
+ if ( isJointIsoItuT )
+ {
+ value += 80L;
+ }
+
+ // Convert the long to a byte array
+ if ( ( value & 0xFFFFFFFFFFFFFF80L ) == 0 )
+ {
+ // The value will be hold in one byte
+ buffer[posBuffer] = ( byte ) ( value );
+
+ return 1;
+ }
+
+ if ( ( value & 0xFFFFFFFFFFFFC000L ) == 0 )
+ {
+ // The value is between 0x80 and 0x3FFF : it will be hold in 2 bytes
+ buffer[posBuffer] = ( byte ) ( ( byte ) ( ( value & 0x0000000000003F80L ) >> 7 ) | 0x80 );
+ buffer[posBuffer + 1] = ( byte ) ( value & 0x000000000000007FL );
+
+ return 2;
+ }
+
+ if ( ( value & 0xFFFFFFFFFFE00000L ) == 0 )
+ {
+ // The value is between 0x4000 and 0x1FFFFF : it will be hold in 3 bytes
+ buffer[posBuffer] = ( byte ) ( ( byte ) ( ( value & 0x00000000001FC000L ) >> 14 ) | 0x80 );
+ buffer[posBuffer + 1] = ( byte ) ( ( byte ) ( ( value & 0x0000000000003F80L ) >> 7 ) | 0x80 );
+ buffer[posBuffer + 2] = ( byte ) ( value & 0x000000000000007FL );
+
+ return 3;
+ }
+
+ if ( ( value & 0xFFFFFFFFF0000000L ) == 0 )
+ {
+ // The value is between 0x200000 and 0xFFFFFFF : it will be hold in 4 bytes
+ buffer[posBuffer] = ( byte ) ( ( byte ) ( ( value & 0x000000000FE00000L ) >> 21 ) | 0x80 );
+ buffer[posBuffer + 1] = ( byte ) ( ( byte ) ( ( value & 0x00000000001FC000L ) >> 14 ) | 0x80 );
+ buffer[posBuffer + 2] = ( byte ) ( ( byte ) ( ( value & 0x0000000000003F80L ) >> 7 ) | 0x80 );
+ buffer[posBuffer + 3] = ( byte ) ( value & 0x000000000000007FL );
+
+ return 4;
+ }
+
+ if ( ( value & 0xFFFFFFF800000000L ) == 0 )
+ {
+ // The value is between 0x10000000 and 0x7FFFFFFFF : it will be hold in 5 bytes
+ buffer[posBuffer] = ( byte ) ( ( byte ) ( ( value & 0x00000007F0000000L ) >> 28 ) | 0x80 );
+ buffer[posBuffer + 1] = ( byte ) ( ( byte ) ( ( value & 0x000000000FE00000L ) >> 21 ) | 0x80 );
+ buffer[posBuffer + 2] = ( byte ) ( ( byte ) ( ( value & 0x00000000001FC000L ) >> 14 ) | 0x80 );
+ buffer[posBuffer + 3] = ( byte ) ( ( byte ) ( ( value & 0x0000000000003F80L ) >> 7 ) | 0x80 );
+ buffer[posBuffer + 4] = ( byte ) ( value & 0x000000000000007FL );
+
+ return 5;
+ }
+
+ if ( ( value & 0xFFFFFC0000000000L ) == 0 )
+ {
+ // The value is between 0x800000000 and 0x3FFFFFFFFFF : it will be hold in 6 bytes
+ buffer[posBuffer] = ( byte ) ( ( byte ) ( ( value & 0x000003F800000000L ) >> 35 ) | 0x80 );
+ buffer[posBuffer + 1] = ( byte ) ( ( byte ) ( ( value & 0x00000007F0000000L ) >> 28 ) | 0x80 );
+ buffer[posBuffer + 2] = ( byte ) ( ( byte ) ( ( value & 0x000000000FE00000L ) >> 21 ) | 0x80 );
+ buffer[posBuffer + 3] = ( byte ) ( ( byte ) ( ( value & 0x00000000001FC000L ) >> 14 ) | 0x80 );
+ buffer[posBuffer + 4] = ( byte ) ( ( byte ) ( ( value & 0x0000000000003F80L ) >> 7 ) | 0x80 );
+ buffer[posBuffer + 5] = ( byte ) ( value & 0x000000000000007FL );
+
+ return 6;
+ }
+
+ if ( ( value & 0xFFFE000000000000L ) == 0 )
+ {
+ // The value is between 0x40000000000 and 0x1FFFFFFFFFFFF : it will be hold in 7 bytes
+ buffer[posBuffer] = ( byte ) ( ( byte ) ( ( value & 0x0001FC0000000000L ) >> 42 ) | 0x80 );
+ buffer[posBuffer + 1] = ( byte ) ( ( byte ) ( ( value & 0x000003F800000000L ) >> 35 ) | 0x80 );
+ buffer[posBuffer + 2] = ( byte ) ( ( byte ) ( ( value & 0x00000007F0000000L ) >> 28 ) | 0x80 );
+ buffer[posBuffer + 3] = ( byte ) ( ( byte ) ( ( value & 0x000000000FE00000L ) >> 21 ) | 0x80 );
+ buffer[posBuffer + 4] = ( byte ) ( ( byte ) ( ( value & 0x00000000001FC000L ) >> 14 ) | 0x80 );
+ buffer[posBuffer + 5] = ( byte ) ( ( byte ) ( ( value & 0x0000000000003F80L ) >> 7 ) | 0x80 );
+ buffer[posBuffer + 6] = ( byte ) ( value & 0x000000000000007FL );
+
+ return 7;
+ }
+
+ if ( ( value & 0xFF00000000000000L ) == 0 )
+ {
+ // The value is between 0x2000000000000 and 0xFF000000000000 : it will be hold in 8 bytes
+ buffer[posBuffer] = ( byte ) ( ( byte ) ( ( value & 0x00FE000000000000L ) >> 49 ) | 0x80 );
+ buffer[posBuffer + 1] = ( byte ) ( ( byte ) ( ( value & 0x0001FC0000000000L ) >> 42 ) | 0x80 );
+ buffer[posBuffer + 2] = ( byte ) ( ( byte ) ( ( value & 0x000003F800000000L ) >> 35 ) | 0x80 );
+ buffer[posBuffer + 3] = ( byte ) ( ( byte ) ( ( value & 0x00000007F0000000L ) >> 28 ) | 0x80 );
+ buffer[posBuffer + 4] = ( byte ) ( ( byte ) ( ( value & 0x000000000FE00000L ) >> 21 ) | 0x80 );
+ buffer[posBuffer + 5] = ( byte ) ( ( byte ) ( ( value & 0x00000000001FC000L ) >> 14 ) | 0x80 );
+ buffer[posBuffer + 6] = ( byte ) ( ( byte ) ( ( value & 0x0000000000003F80L ) >> 7 ) | 0x80 );
+ buffer[posBuffer + 7] = ( byte ) ( value & 0x000000000000007FL );
+
+ return 8;
+ }
+ else
+ {
+ // The value is between 0x100000000000000 and 0x7F00000000000000 : it will be hold in 9 bytes
+ buffer[posBuffer] = ( byte ) ( ( byte ) ( ( value & 0x7F00000000000000L ) >> 56 ) | 0x80 );
+ buffer[posBuffer + 1] = ( byte ) ( ( byte ) ( ( value & 0x00FE000000000000L ) >> 49 ) | 0x80 );
+ buffer[posBuffer + 2] = ( byte ) ( ( byte ) ( ( value & 0x0001FC0000000000L ) >> 42 ) | 0x80 );
+ buffer[posBuffer + 3] = ( byte ) ( ( byte ) ( ( value & 0x000003F800000000L ) >> 35 ) | 0x80 );
+ buffer[posBuffer + 4] = ( byte ) ( ( byte ) ( ( value & 0x00000007F0000000L ) >> 28 ) | 0x80 );
+ buffer[posBuffer + 5] = ( byte ) ( ( byte ) ( ( value & 0x000000000FE00000L ) >> 21 ) | 0x80 );
+ buffer[posBuffer + 6] = ( byte ) ( ( byte ) ( ( value & 0x00000000001FC000L ) >> 14 ) | 0x80 );
+ buffer[posBuffer + 7] = ( byte ) ( ( byte ) ( ( value & 0x0000000000003F80L ) >> 7 ) | 0x80 );
+ buffer[posBuffer + 8] = ( byte ) ( value & 0x000000000000007FL );
+
+ return 9;
+ }
+ }
+ else
+ {
+ // The value is bigger than 9999999999999999999, we need to use a BigInteger
+ // First, get the number of bytes we need to store the value in base 16
+ String number = oid.substring( start, start + nbDigits );
+ BigInteger bigInteger = new BigInteger( number );
+
+ if ( isJointIsoItuT )
+ {
+ bigInteger = bigInteger.add( JOINT_ISO_ITU_T );
+ posBuffer = 0;
+ }
+
+ byte[] bytes = bigInteger.toByteArray();
+
+ // Now, convert this value to the ASN.1 OID format : we store the value
+ // as 7 bits bytes
+ int nbNeededBytes = ( bytes.length * 8 ) / 7;
+
+ switch ( ( bytes.length - 1 ) % 7 )
+ {
+ case 0 :
+ if ( ( bytes[0] & 0x0080 ) != 0 )
+ {
+ nbNeededBytes++;
+ }
+
+ break;
+
+ case 1 :
+ if ( ( bytes[0] & 0x00C0 ) != 0 )
+ {
+ nbNeededBytes++;
+ }
+
+ break;
+
+ case 2 :
+ if ( ( bytes[0] & 0x00E0 ) != 0 )
+ {
+ nbNeededBytes++;
+ }
+
+ break;
+
+ case 3 :
+ if ( ( bytes[0] & 0x00F0 ) != 0 )
+ {
+ nbNeededBytes++;
+ }
+
+ break;
+
+ case 4 :
+ if ( ( bytes[0] & 0x00F8 ) != 0 )
+ {
+ nbNeededBytes++;
+ }
+
+ break;
+
+ case 5 :
+ if ( ( bytes[0] & 0x00FC ) != 0 )
+ {
+ nbNeededBytes++;
+ }
+
+ break;
+
+ case 6 :
+ if ( ( bytes[0] & 0x00FE ) != 0 )
+ {
+ nbNeededBytes++;
+ }
+
+ break;
+
+ default :
+ // Exist to please checkstyle...
+ break;
+ }
+
+ byte[] converted = new byte[nbNeededBytes];
+
+ int posConverted = nbNeededBytes - 1;
+ int posBytes = bytes.length - 1;
+ int counter = 0;
+ byte reminder = 0;
+
+ while ( posBytes >= 0 )
+ {
+ byte newByte = ( byte ) ( ( bytes[posBytes] & 0x00FF ) << counter );
+ converted[posConverted] = ( byte ) ( reminder | newByte | 0x0080 );
+ reminder = ( byte ) ( ( bytes[posBytes] & 0x00FF ) >> ( 7 - counter ) );
+ counter = ( counter + 1 ) % 8;
+ posConverted--;
+
+ if ( counter != 0 )
+ {
+ posBytes--;
+ }
+ else
+ {
+ reminder = 0;
+ }
+ }
+
+ converted[nbNeededBytes - 1] &= 0x7F;
+
+ // Copy the converted bytes in the buffer
+ System.arraycopy( converted, 0, buffer, posBuffer, nbNeededBytes );
+
+ return nbNeededBytes;
+ }
+ }
+
+
+ /**
+ * Returns an OID object representing <code>oidString</code>.
+ *
+ * @param oidString The string representation of the OID
+ * @return A new Oid
+ * @throws DecoderException When the OID is not valid
+ */
+ public static Oid fromString( String oidString ) throws DecoderException
+ {
+ if ( ( oidString == null ) || oidString.isEmpty() )
+ {
+ throw new DecoderException( I18n.err( I18n.ERR_00033_INVALID_OID, "empty" ) );
+ }
+
+ // Create a buffer that is wide enough to contain all the values
+ byte[] buffer = new byte[oidString.length()];
+
+ OidFSAState state = OidFSAState.START;
+
+ // A counter of chars used for an arc. In 1.2.45345, this counter will be 5 for the '45345' arc.
+ int arcNbChars = 0;
+
+ // The position in the buffer where we accumulate the result.
+ int bufPos = 0;
+
+ // The position in the OID string where we started to read an arc
+ int startArc = 0;
+
+ // The number of bytes in the resulting OID byte[]
+ int nbBytes = 0;
+
+ boolean isJointIsoItuT = false;
+
+ for ( int i = 0; i < oidString.length(); i++ )
+ {
+ switch ( state )
+ {
+ case START :
+ // (Start) --['0'..'1']--> (A)
+ // (start) --['2']--> (F)
+ state = processStateStart( oidString, buffer, i );
+ break;
+
+ case STATE_A :
+ // (A) --['.']--> (B)
+ state = processStateA( oidString, i );
+
+
+ break;
+
+ case STATE_B :
+ // (B) --['0']--> (D)
+ // (B) --['1'..'3']--> (C)
+ // (B) --['4'..'9']--> (E)
+ state = processStateB( oidString, buffer, i );
+
+ break;
+
+ case STATE_C :
+ // (C) --['.']--> (K)
+ // (C) --['0'..'9']--> (E)
+ state = processStateC( oidString, buffer, i );
+
+ // the next arc will be store at position 1 in the buffer
+ bufPos = 1;
+
+ break;
+
+ case STATE_D :
+ // (D) --['.']--> (K)
+ // Fallthrough
+
+ case STATE_E :
+ // (E) --['.']--> (K)
+ state = processStateDE( oidString, buffer, i );
+
+ // the next arc will be store at position 1 in teh buffer
+ bufPos = 1;
+
+ break;
+
+ case STATE_F :
+ isJointIsoItuT = true;
+ // (F) --['.']--> (G)
+ state = processStateF( oidString, i );
+
+ break;
+
+ case STATE_G :
+ // (G) --['0']--> (I)
+ // (G) --['1'..'9']--> (H)
+ state = processStateG( oidString, buffer, i );
+ arcNbChars = 1;
+ startArc = i;
+
+ break;
+
+ case STATE_H :
+ // (H) --['.']--> (K)
+ // (H) --['0'..'9']--> (J)
+ state = processStateH( oidString, buffer, i );
+
+ if ( state == OidFSAState.STATE_J )
+ {
+ // We have already two digits
+ arcNbChars = 2;
+ bufPos = 0;
+ }
+
+ break;
+
+ case STATE_I :
+ // (I) --['.']--> (K)
+ state = processStateI( oidString, buffer, i );
+
+ // Set the arc position to buffer[1], we haven't yet accumulated digits.
+ bufPos = 1;
+
+ break;
+
+ case STATE_J :
+ // (J) --['.']--> (K)
+ // (J) --['0'..'9']--> (J)
+ state = processStateJ( oidString, buffer, arcNbChars + bufPos, i );
+
+ if ( state == OidFSAState.STATE_J )
+ {
+ // We can increment the number of digit for this arc
+ arcNbChars++;
+ }
+ else
+ {
+ // We are done with the first arc : convert it
+ bufPos += convert( oidString, buffer, bufPos, arcNbChars, 0, true );
+ }
+
+ break;
+
+ case STATE_K :
+ startArc = i;
+ state = processStateK( oidString, buffer, bufPos, i );
+
+ if ( state == OidFSAState.STATE_M )
+ {
+ bufPos++;
+ }
+ else
+ {
+ arcNbChars = 1;
+ }
+
+ break;
+
+ case STATE_L :
+ state = processStateL( oidString, buffer, arcNbChars + bufPos, i );
+
+ if ( state == OidFSAState.STATE_L )
+ {
+ arcNbChars++;
+ break;
+ }
+ else
+ {
+ // We are done with the arc : convert it
+ bufPos += convert( oidString, buffer, startArc, arcNbChars, bufPos, false );
+ }
+
+ break;
+
+ case STATE_M :
+ state = processStateM( oidString, i );
+ break;
+
+ default :
+ // Exist to please checkstyle...
+ break;
+ }
+ }
+
+ // End of the string : check that we are in a correct state for a completion
+ // The only valid exit states are :
+ // (C) --[]--> (End)
+ // (D) --[]--> (End)
+ // (E) --[]--> (End)
+ // (H) --[]--> (End)
+ // (I) --[]--> (End)
+ // (J) --[]--> (End)
+ // (L) --[]--> (End)
+ // (M) --[]--> (End)
+ switch ( state )
+ {
+ case STATE_C :
+ // (C) --[]--> (End)
+ // fallthrough
+
+ case STATE_D :
+ // (D) --[]--> (End)
+ // fallthrough
+
+ case STATE_E :
+ // (E) --[]--> (End)
+ // fallthrough
+
+ case STATE_H :
+ // (H) --[]--> (End)
+ // fallthrough
+
+ case STATE_I :
+ // (I) --[]--> (End)
+ byte[] bytes = new byte[1];
+ bytes[0] = ( byte ) ( buffer[0] | buffer[1] );
+
+ return new Oid( oidString, bytes );
+
+ case STATE_J :
+ // (J) --[]--> (End)
+ nbBytes = convert( oidString, buffer, 2, arcNbChars, 0, true );
+ bytes = new byte[nbBytes];
+ System.arraycopy( buffer, 0, bytes, 0, nbBytes );
+
+ return new Oid( oidString, bytes );
+
+ case STATE_L :
+ bufPos += convert( oidString, buffer, startArc, arcNbChars, bufPos, false );
+ bytes = new byte[bufPos];
+ System.arraycopy( buffer, 0, bytes, 0, bufPos );
+
+ return new Oid( oidString, bytes );
+
+ case STATE_M :
+ bytes = new byte[bufPos];
+ System.arraycopy( buffer, 0, bytes, 0, bufPos );
+
+ return new Oid( oidString, bytes );
+ default :
+ // This should never happen...
+ throw new DecoderException( I18n.err( I18n.ERR_00033_INVALID_OID, "Wrong OID" ) );
+ }
+ }
+
+
+ /**
* Returns the length of the encoded <code>byte[]</code> representation.
*
* @return The length of the byte[]
Modified: directory/shared/trunk/asn1/api/src/test/java/org/apache/directory/api/asn1/util/OidTest.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/asn1/api/src/test/java/org/apache/directory/api/asn1/util/OidTest.java?rev=1710496&r1=1710495&r2=1710496&view=diff
==============================================================================
--- directory/shared/trunk/asn1/api/src/test/java/org/apache/directory/api/asn1/util/OidTest.java (original)
+++ directory/shared/trunk/asn1/api/src/test/java/org/apache/directory/api/asn1/util/OidTest.java Sun Oct 25 23:19:25 2015
@@ -109,6 +109,35 @@ public class OidTest
assertEquals( expectedString, Oid.fromString( expectedString ).toString() );
}
+
+ /** Hex chars */
+ private static final byte[] HEX_CHAR = new byte[]
+ { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+ /**
+ * Helper function that dump an array of bytes in hex form
+ *
+ * @param buffer The bytes array to dump
+ * @return A string representation of the array of bytes
+ */
+ public static String dumpBytes( byte[] buffer )
+ {
+ if ( buffer == null )
+ {
+ return "";
+ }
+
+ StringBuffer sb = new StringBuffer();
+
+ for ( int i = 0; i < buffer.length; i++ )
+ {
+ sb.append( "0x" ).append( ( char ) ( HEX_CHAR[( buffer[i] & 0x00F0 ) >> 4] ) ).append(
+ ( char ) ( HEX_CHAR[buffer[i] & 0x000F] ) ).append( " " );
+ }
+
+ return sb.toString();
+ }
+
@Test
public void fromString() throws DecoderException
@@ -118,9 +147,10 @@ public class OidTest
{ // [0..2]
for ( int j = 0; j < 40; j++ )
{ // [0..39]
- assertTrue( Arrays.equals( new byte[]
- { ( byte ) ( i * 40 + j ) },
- Oid.fromString( i + "." + j ).toBytes() ) );
+ String oidStr = i + "." + j;
+ byte[] expected = new byte[]{ ( byte ) ( i * 40 + j ) };
+ byte[] oidBytes = Oid.fromString( oidStr ).toBytes();
+ assertTrue( Arrays.equals( expected, oidBytes ) );
}
}
@@ -350,13 +380,20 @@ public class OidTest
public void testNewOidStringBad()
{
assertFalse( Oid.isOid( "0" ) );
+ assertFalse( Oid.isOid( "1" ) );
assertFalse( Oid.isOid( "0." ) );
+ assertFalse( Oid.isOid( "1." ) );
+ assertFalse( Oid.isOid( "2." ) );
+ assertFalse( Oid.isOid( "2." ) );
assertFalse( Oid.isOid( "." ) );
assertFalse( Oid.isOid( "0.1.2." ) );
assertFalse( Oid.isOid( "3.1" ) );
assertFalse( Oid.isOid( "0..1" ) );
assertFalse( Oid.isOid( "0..12" ) );
assertFalse( Oid.isOid( "0.a.2" ) );
+ assertFalse( Oid.isOid( "0.40" ) );
+ assertFalse( Oid.isOid( "0.51" ) );
+ assertFalse( Oid.isOid( "0.01" ) );
assertFalse( Oid.isOid( "0.123456" ) );
assertFalse( Oid.isOid( "1.123456" ) );
}
@@ -384,6 +421,252 @@ public class OidTest
/**
+ * Test an OID with a node which does not fit in a long
+ * @throws DecoderException
+ */
+ @Test
+ public void testOidLongValue() throws DecoderException
+ {
+ // 2.0 -> expected 0x02
+ Oid oid = Oid.fromString( "2.0" );
+ byte[] oidBytes = oid.toBytes();
+ assertEquals( 1, oidBytes.length );
+ assertEquals( 80, oidBytes[0] );
+
+ // 2.40 -> expected 0x78
+ oid = Oid.fromString( "2.40" );
+ oidBytes = oid.toBytes();
+ assertEquals( 1, oidBytes.length );
+ assertEquals( 0x78, oidBytes[0] );
+
+ // 2.48 -> expected 0x80
+ oid = Oid.fromString( "2.48" );
+ oidBytes = oid.toBytes();
+ assertEquals( 2, oidBytes.length );
+ assertEquals( (byte)0x81, oidBytes[0] );
+ assertEquals( 0x00, oidBytes[1] );
+
+ // The second arc is below and equal to 16304 : 0x4000 - 0x50
+ oid = Oid.fromString( "2.16303" );
+ oidBytes = oid.toBytes();
+ assertEquals( 2, oidBytes.length );
+ assertEquals( (byte)0xFF, oidBytes[0] );
+ assertEquals( 0x7F, oidBytes[1] );
+
+ oid = Oid.fromString( "2.16304" );
+ oidBytes = oid.toBytes();
+ assertEquals( 3, oidBytes.length );
+ assertEquals( (byte)0x81, oidBytes[0] );
+ assertEquals( (byte)0x80, oidBytes[1] );
+ assertEquals( 0x00, oidBytes[2] );
+
+ // The second arc is below and equal to 2097072 : 0x200000 - 0x50
+ oid = Oid.fromString( "2.2097071" );
+ oidBytes = oid.toBytes();
+ assertEquals( 3, oidBytes.length );
+ assertEquals( (byte)0xFF, oidBytes[0] );
+ assertEquals( (byte)0xFF, oidBytes[1] );
+ assertEquals( 0x7F, oidBytes[2] );
+
+ oid = Oid.fromString( "2.2097072" );
+ oidBytes = oid.toBytes();
+ assertEquals( 4, oidBytes.length );
+ assertEquals( (byte)0x81, oidBytes[0] );
+ assertEquals( (byte)0x80, oidBytes[1] );
+ assertEquals( (byte)0x80, oidBytes[2] );
+ assertEquals( 0x00, oidBytes[3] );
+
+ // The second arc is below and equal to 268435376 : 0x10000000 - 0x50
+ oid = Oid.fromString( "2.268435375" );
+ oidBytes = oid.toBytes();
+ assertEquals( 4, oidBytes.length );
+ assertEquals( (byte)0xFF, oidBytes[0] );
+ assertEquals( (byte)0xFF, oidBytes[1] );
+ assertEquals( (byte)0xFF, oidBytes[2] );
+ assertEquals( 0x7F, oidBytes[3] );
+
+ oid = Oid.fromString( "2.268435376" );
+ oidBytes = oid.toBytes();
+ assertEquals( 5, oidBytes.length );
+ assertEquals( (byte)0x81, oidBytes[0] );
+ assertEquals( (byte)0x80, oidBytes[1] );
+ assertEquals( (byte)0x80, oidBytes[2] );
+ assertEquals( (byte)0x80, oidBytes[3] );
+ assertEquals( 0x00, oidBytes[4] );
+
+ // The second arc is below and equal to 34359738288 : 0x800000000 - 0x50
+ oid = Oid.fromString( "2.34359738287" );
+ oidBytes = oid.toBytes();
+ assertEquals( 5, oidBytes.length );
+ assertEquals( (byte)0xFF, oidBytes[0] );
+ assertEquals( (byte)0xFF, oidBytes[1] );
+ assertEquals( (byte)0xFF, oidBytes[2] );
+ assertEquals( (byte)0xFF, oidBytes[3] );
+ assertEquals( 0x7F, oidBytes[4] );
+
+ oid = Oid.fromString( "2.34359738288" );
+ oidBytes = oid.toBytes();
+ assertEquals( 6, oidBytes.length );
+ assertEquals( (byte)0x81, oidBytes[0] );
+ assertEquals( (byte)0x80, oidBytes[1] );
+ assertEquals( (byte)0x80, oidBytes[2] );
+ assertEquals( (byte)0x80, oidBytes[3] );
+ assertEquals( (byte)0x80, oidBytes[4] );
+ assertEquals( 0x00, oidBytes[5] );
+
+ // The second arc is below and equal to 4398046511024 : 0x40000000000 - 0x50
+ oid = Oid.fromString( "2.4398046511023" );
+ oidBytes = oid.toBytes();
+ assertEquals( 6, oidBytes.length );
+ assertEquals( (byte)0xFF, oidBytes[0] );
+ assertEquals( (byte)0xFF, oidBytes[1] );
+ assertEquals( (byte)0xFF, oidBytes[2] );
+ assertEquals( (byte)0xFF, oidBytes[3] );
+ assertEquals( (byte)0xFF, oidBytes[4] );
+ assertEquals( 0x7F, oidBytes[5] );
+
+ oid = Oid.fromString( "2.4398046511024" );
+ oidBytes = oid.toBytes();
+ assertEquals( 7, oidBytes.length );
+ assertEquals( (byte)0x81, oidBytes[0] );
+ assertEquals( (byte)0x80, oidBytes[1] );
+ assertEquals( (byte)0x80, oidBytes[2] );
+ assertEquals( (byte)0x80, oidBytes[3] );
+ assertEquals( (byte)0x80, oidBytes[4] );
+ assertEquals( (byte)0x80, oidBytes[5] );
+ assertEquals( 0x00, oidBytes[6] );
+
+ // The second arc is below and equal to 562949953421232 : 0x2000000000000 - 0x50
+ oid = Oid.fromString( "2.562949953421231" );
+ oidBytes = oid.toBytes();
+ assertEquals( 7, oidBytes.length );
+ assertEquals( (byte)0xFF, oidBytes[0] );
+ assertEquals( (byte)0xFF, oidBytes[1] );
+ assertEquals( (byte)0xFF, oidBytes[2] );
+ assertEquals( (byte)0xFF, oidBytes[3] );
+ assertEquals( (byte)0xFF, oidBytes[4] );
+ assertEquals( (byte)0xFF, oidBytes[5] );
+ assertEquals( 0x7F, oidBytes[6] );
+
+ oid = Oid.fromString( "2.562949953421232" );
+ oidBytes = oid.toBytes();
+ assertEquals( 8, oidBytes.length );
+ assertEquals( (byte)0x81, oidBytes[0] );
+ assertEquals( (byte)0x80, oidBytes[1] );
+ assertEquals( (byte)0x80, oidBytes[2] );
+ assertEquals( (byte)0x80, oidBytes[3] );
+ assertEquals( (byte)0x80, oidBytes[4] );
+ assertEquals( (byte)0x80, oidBytes[5] );
+ assertEquals( (byte)0x80, oidBytes[6] );
+ assertEquals( 0x00, oidBytes[7] );
+
+ // The second arc is below and equal to 72057594037927856 : 0x100000000000000 - 0x50
+ oid = Oid.fromString( "2.72057594037927855" );
+ oidBytes = oid.toBytes();
+ assertEquals( 8, oidBytes.length );
+ assertEquals( (byte)0xFF, oidBytes[0] );
+ assertEquals( (byte)0xFF, oidBytes[1] );
+ assertEquals( (byte)0xFF, oidBytes[2] );
+ assertEquals( (byte)0xFF, oidBytes[3] );
+ assertEquals( (byte)0xFF, oidBytes[4] );
+ assertEquals( (byte)0xFF, oidBytes[5] );
+ assertEquals( (byte)0xFF, oidBytes[6] );
+ assertEquals( 0x7F, oidBytes[7] );
+
+ oid = Oid.fromString( "2.72057594037927856" );
+ oidBytes = oid.toBytes();
+ assertEquals( 9, oidBytes.length );
+ assertEquals( (byte)0x81, oidBytes[0] );
+ assertEquals( (byte)0x80, oidBytes[1] );
+ assertEquals( (byte)0x80, oidBytes[2] );
+ assertEquals( (byte)0x80, oidBytes[3] );
+ assertEquals( (byte)0x80, oidBytes[4] );
+ assertEquals( (byte)0x80, oidBytes[5] );
+ assertEquals( (byte)0x80, oidBytes[6] );
+ assertEquals( (byte)0x80, oidBytes[7] );
+ assertEquals( 0x00, oidBytes[8] );
+
+ // The second arc is below and equal to 9223372036854775728 : 0x8000000000000000 - 0x50
+ oid = Oid.fromString( "2.9223372036854775727" );
+ oidBytes = oid.toBytes();
+ assertEquals( 9, oidBytes.length );
+ assertEquals( (byte)0xFF, oidBytes[0] );
+ assertEquals( (byte)0xFF, oidBytes[1] );
+ assertEquals( (byte)0xFF, oidBytes[2] );
+ assertEquals( (byte)0xFF, oidBytes[3] );
+ assertEquals( (byte)0xFF, oidBytes[4] );
+ assertEquals( (byte)0xFF, oidBytes[5] );
+ assertEquals( (byte)0xFF, oidBytes[6] );
+ assertEquals( (byte)0xFF, oidBytes[6] );
+ assertEquals( (byte)0xFF, oidBytes[7] );
+ assertEquals( 0x7F, oidBytes[8] );
+
+ oid = Oid.fromString( "2.9223372036854775728" );
+ oidBytes = oid.toBytes();
+ assertEquals( 10, oidBytes.length );
+ assertEquals( (byte)0x81, oidBytes[0] );
+ assertEquals( (byte)0x80, oidBytes[1] );
+ assertEquals( (byte)0x80, oidBytes[2] );
+ assertEquals( (byte)0x80, oidBytes[3] );
+ assertEquals( (byte)0x80, oidBytes[4] );
+ assertEquals( (byte)0x80, oidBytes[5] );
+ assertEquals( (byte)0x80, oidBytes[6] );
+ assertEquals( (byte)0x80, oidBytes[7] );
+ assertEquals( (byte)0x80, oidBytes[8] );
+ assertEquals( 0x00, oidBytes[9] );
+
+ // Check for 9999999999999999999 which is higher than Long.MAX_VALUE
+ oid = Oid.fromString( "2.9999999999999999999" );
+ oidBytes = oid.toBytes();
+ assertEquals( 10, oidBytes.length );
+ assertEquals( (byte)0x81, oidBytes[0] );
+ assertEquals( (byte)0x8A, oidBytes[1] );
+ assertEquals( (byte)0xE3, oidBytes[2] );
+ assertEquals( (byte)0xC8, oidBytes[3] );
+ assertEquals( (byte)0xE0, oidBytes[4] );
+ assertEquals( (byte)0xC8, oidBytes[5] );
+ assertEquals( (byte)0xCF, oidBytes[6] );
+ assertEquals( (byte)0xA0, oidBytes[7] );
+ assertEquals( (byte)0x80, oidBytes[8] );
+ assertEquals( (byte)0x4F, oidBytes[9] );
+
+ // A bigger one
+ oid = Oid.fromString( "2.81407072025111374527560065493494091452" );
+ oidBytes = oid.toBytes();
+ assertEquals( 18, oidBytes.length );
+ assertEquals( (byte)0xFA, oidBytes[0] );
+ assertEquals( (byte)0xBE, oidBytes[1] );
+ assertEquals( (byte)0xB7, oidBytes[2] );
+ assertEquals( (byte)0xA2, oidBytes[3] );
+ assertEquals( (byte)0x8E, oidBytes[4] );
+ assertEquals( (byte)0xF4, oidBytes[5] );
+ assertEquals( (byte)0xC0, oidBytes[6] );
+ assertEquals( (byte)0xC7, oidBytes[7] );
+ assertEquals( (byte)0xCB, oidBytes[8] );
+ assertEquals( (byte)0x9F, oidBytes[9] );
+ assertEquals( (byte)0xA0, oidBytes[10] );
+ assertEquals( (byte)0xC5, oidBytes[11] );
+ assertEquals( (byte)0xEA, oidBytes[12] );
+ assertEquals( (byte)0xDA, oidBytes[13] );
+ assertEquals( (byte)0x92, oidBytes[14] );
+ assertEquals( (byte)0x9D, oidBytes[15] );
+ assertEquals( (byte)0x9E, oidBytes[16] );
+ assertEquals( (byte)0x0C, oidBytes[17] );
+ }
+
+
+ /**
+ * Test an OID with 2 at the first position and a second node > 39
+ * @throws DecoderException
+ */
+ @Test
+ public void testOidNode2() throws DecoderException
+ {
+ Oid oid = Oid.fromString( "2.12345" );
+ }
+
+
+ /**
* Test Kerberos V5 NewOid
*/
@Test
@@ -419,7 +702,7 @@ public class OidTest
oid2 = Oid.fromBytes( oid.toBytes() );
assertEquals( oid.toString(), oid2.toString() );
- oid = Oid.fromString( "0.0.0.0.0" );
+ oid = Oid.fromString( "1.2.3.4.5" );
oid2 = Oid.fromBytes( oid.toBytes() );
assertEquals( oid.toString(), oid2.toString() );
|