in asn1/api/src/main/java/org/apache/directory/api/asn1/util/Oid.java [316:494]
public static Oid fromBytes( byte[] oidBytes ) throws DecoderException
{
if ( ( oidBytes == null ) || ( oidBytes.length < 1 ) )
{
throw new DecoderException( I18n.err( I18n.ERR_00003_INVALID_OID, Arrays.toString( oidBytes ) ) );
}
StringBuilder builder = new StringBuilder();
long value = 0;
int valStart = 0;
int valLength = 0;
boolean firstArc = true;
for ( int i = 0; i < oidBytes.length; i++ )
{
value |= oidBytes[i] & 0x7F;
if ( oidBytes[i] < 0 )
{
// leading 1, so value continues
value = value << 7;
valLength++;
}
else
{
valLength++;
if ( valLength > 8 )
{
// Above 9 bytes, we won't be able to store the value in a long...
// Compute the number of necessary bytes
int nbBytes = valLength * 7 / 8;
if ( valLength % 7 != 0 )
{
nbBytes++;
}
byte[] result = new byte[nbBytes];
// Now iterate on the incoming bytes
int pos = nbBytes - 1;
int valEnd = valStart + valLength - 1;
int j = 0;
while ( j < valLength - 8 )
{
result[pos--] = ( byte ) ( ( oidBytes[valEnd - j - 1] << 7 ) | ( oidBytes[valEnd - j] & 0x7F ) );
result[pos--] = ( byte ) ( ( oidBytes[valEnd - j - 2] << 6 ) | ( ( oidBytes[valEnd - j - 1] & 0x7E ) >> 1 ) );
result[pos--] = ( byte ) ( ( oidBytes[valEnd - j - 3] << 5 ) | ( ( oidBytes[valEnd - j - 2] & 0x7C ) >> 2 ) );
result[pos--] = ( byte ) ( ( oidBytes[valEnd - j - 4] << 4 ) | ( ( oidBytes[valEnd - j - 3] & 0x78 ) >> 3 ) );
result[pos--] = ( byte ) ( ( oidBytes[valEnd - j - 5] << 3 ) | ( ( oidBytes[valEnd - j - 4] & 0x70 ) >> 4 ) );
result[pos--] = ( byte ) ( ( oidBytes[valEnd - j - 6] << 2 ) | ( ( oidBytes[valEnd - j - 5] & 0x60 ) >> 5 ) );
result[pos--] = ( byte ) ( ( oidBytes[valEnd - j - 7] << 1 ) | ( ( oidBytes[valEnd - j - 6] & 0x40 ) >> 6 ) );
j += 8;
}
switch ( valLength - j )
{
case 7 :
result[pos--] = ( byte ) ( ( oidBytes[5] << 7 ) | ( oidBytes[6] & 0x7F ) );
result[pos--] = ( byte ) ( ( oidBytes[4] << 6 ) | ( ( oidBytes[5] & 0x7E ) >> 1 ) );
result[pos--] = ( byte ) ( ( oidBytes[3] << 5 ) | ( ( oidBytes[4] & 0x7C ) >> 2 ) );
result[pos--] = ( byte ) ( ( oidBytes[2] << 4 ) | ( ( oidBytes[3] & 0x78 ) >> 3 ) );
result[pos--] = ( byte ) ( ( oidBytes[1] << 3 ) | ( ( oidBytes[2] & 0x70 ) >> 4 ) );
result[pos--] = ( byte ) ( ( oidBytes[0] << 2 ) | ( ( oidBytes[1] & 0x60 ) >> 5 ) );
result[pos] = ( byte ) ( ( oidBytes[0] & 0x40 ) >> 6 );
break;
case 6 :
result[pos--] = ( byte ) ( ( oidBytes[4] << 7 ) | ( oidBytes[5] & 0x7F ) );
result[pos--] = ( byte ) ( ( oidBytes[3] << 6 ) | ( ( oidBytes[4] & 0x7E ) >> 1 ) );
result[pos--] = ( byte ) ( ( oidBytes[2] << 5 ) | ( ( oidBytes[3] & 0x7C ) >> 2 ) );
result[pos--] = ( byte ) ( ( oidBytes[1] << 4 ) | ( ( oidBytes[2] & 0x78 ) >> 3 ) );
result[pos--] = ( byte ) ( ( oidBytes[0] << 3 ) | ( ( oidBytes[1] & 0x70 ) >> 4 ) );
result[pos] = ( byte ) ( ( oidBytes[0] & 0x60 ) >> 5 );
break;
case 5 :
result[pos--] = ( byte ) ( ( oidBytes[3] << 7 ) | ( oidBytes[4] & 0x7F ) );
result[pos--] = ( byte ) ( ( oidBytes[2] << 6 ) | ( ( oidBytes[3] & 0x7E ) >> 1 ) );
result[pos--] = ( byte ) ( ( oidBytes[1] << 5 ) | ( ( oidBytes[2] & 0x7C ) >> 2 ) );
result[pos--] = ( byte ) ( ( oidBytes[0] << 4 ) | ( ( oidBytes[1] & 0x78 ) >> 3 ) );
result[pos] = ( byte ) ( ( oidBytes[0] & 0x70 ) >> 4 );
break;
case 4 :
result[pos--] = ( byte ) ( ( oidBytes[2] << 7 ) | ( oidBytes[3] & 0x7F ) );
result[pos--] = ( byte ) ( ( oidBytes[1] << 6 ) | ( ( oidBytes[2] & 0x7E ) >> 1 ) );
result[pos--] = ( byte ) ( ( oidBytes[0] << 5 ) | ( ( oidBytes[1] & 0x7C ) >> 2 ) );
result[pos] = ( byte ) ( ( oidBytes[0] & 0x78 ) >> 3 );
break;
case 3 :
result[pos--] = ( byte ) ( ( oidBytes[1] << 7 ) | ( oidBytes[2] & 0x7F ) );
result[pos--] = ( byte ) ( ( oidBytes[0] << 6 ) | ( ( oidBytes[1] & 0x7E ) >> 1 ) );
result[pos] = ( byte ) ( ( oidBytes[0] & 0x7C ) >> 2 );
break;
case 2 :
result[pos--] = ( byte ) ( ( oidBytes[0] << 7 ) | ( oidBytes[1] & 0x7F ) );
result[pos] = ( byte ) ( ( oidBytes[0] & 0x7E ) >> 1 );
break;
case 1 :
result[pos] = ( byte ) ( oidBytes[0] & 0x7F );
break;
default :
// Exist to please checkstyle...
break;
}
BigInteger bigInteger;
if ( ( result[0] & 0x80 ) == 0x80 )
{
byte[] newResult = new byte[result.length + 1];
System.arraycopy( result, 0, newResult, 1, result.length );
result = newResult;
}
bigInteger = new BigInteger( result );
if ( firstArc )
{
// This is a joint-iso-itu-t(2) arc
bigInteger = bigInteger.subtract( JOINT_ISO_ITU_T );
builder.append( '2' );
}
builder.append( '.' ).append( bigInteger.toString() );
}
else
{
// value completed
if ( firstArc )
{
// first value special processing
if ( value >= 80 )
{
// starts with 2
builder.append( '2' );
value = value - 80;
}
else
{
// starts with 0 or 1
long one = value / 40;
long two = value % 40;
if ( ( one < 0 ) || ( one > 2 ) || ( two < 0 ) || ( ( one < 2 ) && ( two > 39 ) ) )
{
throw new DecoderException( I18n.err( I18n.ERR_00003_INVALID_OID,
Arrays.toString( oidBytes ) ) );
}
if ( one < 2 )
{
builder.append( one );
value = two;
}
}
firstArc = false;
}
// normal processing
builder.append( '.' ).append( value );
}
valStart = i;
valLength = 0;
value = 0;
}
}
return new Oid( builder.toString(), oidBytes );
}