/*
* Sun Public License
*
* The contents of this file are subject to the Sun Public License Version
* 1.0 (the "License"). You may not use this file except in compliance with
* the License. A copy of the License is available at http://www.sun.com/
*
* The Original Code is the SLAMD Distributed Load Generation Engine.
* The Initial Developer of the Original Code is Neil A. Wilson.
* Portions created by Neil A. Wilson are Copyright (C) 2004-2010.
* Some preexisting portions Copyright (C) 2002-2006 Sun Microsystems, Inc.
* All Rights Reserved.
*
* Contributor(s): Neil A. Wilson
*/
package com.slamd.asn1;
/**
* This class defines a generic ASN.1 element and a set of core methods for
* dealing with them. Subclasses may deal with more specific kinds of ASN.1
* elements.
*
*
* @author Neil A. Wilson
*/
public class ASN1Element
{
/**
* The standard ASN.1 type for boolean values.
*/
public static final byte ASN1_BOOLEAN_TYPE = 0x01;
/**
* The standard ASN.1 type for integer values.
*/
public static final byte ASN1_INTEGER_TYPE = 0x02;
/**
* The standard ASN.1 type for octet string values.
*/
public static final byte ASN1_OCTET_STRING_TYPE = 0x04;
/**
* The standard ASN.1 type for null values.
*/
public static final byte ASN1_NULL_TYPE = 0x05;
/**
* The standard ASN.1 type for enumerated values.
*/
public static final byte ASN1_ENUMERATED_TYPE = 0x0A;
/**
* The standard ASN.1 type for sequence values.
*/
public static final byte ASN1_SEQUENCE_TYPE = 0x30;
/**
* The standard ASN.1 type for set values.
*/
public static final byte ASN1_SET_TYPE = 0x31;
/**
* An empty byte array, used to prevent multiple allocations for empty arrays.
*/
public static final byte[] EMPTY_BYTES = new byte[0];
// The type of this ASN.1 element. This implementation only supports
// single-byte type values (up through "APPLICATION 31").
byte type;
// The encoded form of this ASN.1 element.
byte[] encodedElement;
// The encoded value for this ASN.1 element.
byte[] value;
// The end of line character(s) for this platform.
static String eol = System.getProperty("line.separator");
/**
* Creates a new ASN.1 element with the specified type and no value.
*
* @param type The type of this ASN.1 element.
*/
public ASN1Element(byte type)
{
this(type, EMPTY_BYTES);
}
/**
* Creates a new ASN.1 element with the specified type and value.
*
* @param type The type of this ASN.1 element.
* @param value The encoded value for this ASN.1 element.
*/
public ASN1Element(byte type, byte[] value)
{
this.type = type;
if (value == null)
{
value = EMPTY_BYTES;
}
this.value = value;
byte[] encodedLength = encodeLength(value.length);
encodedElement = new byte[1 + encodedLength.length + value.length];
encodedElement[0] = type;
System.arraycopy(encodedLength, 0, encodedElement, 1, encodedLength.length);
System.arraycopy(value, 0, encodedElement, 1+encodedLength.length,
value.length);
}
/**
* Creates a new ASN.1 element with the specified information.
*
* @param type The type of this ASN.1 element.
* @param value The value for this ASN.1 element.
* @param encodedElement The ASN.1 element encoded as a byte array.
*/
public ASN1Element(byte type, byte[] value, byte[] encodedElement)
{
this.type = type;
this.value = value;
this.encodedElement = encodedElement;
}
/**
* Gets the type of this ASN.1 element.
*
* @return The type of this ASN.1 element.
*/
public byte getType()
{
return type;
}
/**
* Gets the type of this ASN.1 element without either of the class bits or the
* primitive/constructed bit set (i.e., the least significant five bits).
*
* @return The type of this ASN.1 element without any of the flag bits set.
*/
public byte getTypeWithoutFlags()
{
return (byte) (type & 0x1F);
}
/**
* Specifies the type for this ASN.1 element.
*
* @param type The type for this ASN.1 element.
*/
public void setType(byte type)
{
this.type = type;
}
/**
* Gets the encoded value for this ASN.1 element.
*
* @return The encoded value for this ASN.1 element.
*/
public byte[] getValue()
{
return value;
}
/**
* Specifies the value for this ASN.1 element.
*
* @param value The value for this ASN.1 element.
*/
public void setValue(byte[] value)
{
if (value == null)
{
value = EMPTY_BYTES;
}
this.value = value;
byte[] encodedLength = encodeLength(value.length);
encodedElement = new byte[1 + encodedLength.length + value.length];
encodedElement[0] = type;
System.arraycopy(encodedLength, 0, encodedElement, 1,
encodedLength.length);
System.arraycopy(value, 0, encodedElement, 1+encodedLength.length,
value.length);
}
/**
* Encodes the specified length as a byte array as it should appear in an
* ASN.1 element.
*
* @param length The length value to be encoded.
*
* @return The encoded length as a byte array.
*/
protected static byte[] encodeLength(int length)
{
// First, see if the int value is within the first 128 values. If so, then
// just return the pre-encoded version.
switch (length)
{
case 0: return ASN1Integer.INT_VALUE_0;
case 1: return ASN1Integer.INT_VALUE_1;
case 2: return ASN1Integer.INT_VALUE_2;
case 3: return ASN1Integer.INT_VALUE_3;
case 4: return ASN1Integer.INT_VALUE_4;
case 5: return ASN1Integer.INT_VALUE_5;
case 6: return ASN1Integer.INT_VALUE_6;
case 7: return ASN1Integer.INT_VALUE_7;
case 8: return ASN1Integer.INT_VALUE_8;
case 9: return ASN1Integer.INT_VALUE_9;
case 10: return ASN1Integer.INT_VALUE_10;
case 11: return ASN1Integer.INT_VALUE_11;
case 12: return ASN1Integer.INT_VALUE_12;
case 13: return ASN1Integer.INT_VALUE_13;
case 14: return ASN1Integer.INT_VALUE_14;
case 15: return ASN1Integer.INT_VALUE_15;
case 16: return ASN1Integer.INT_VALUE_16;
case 17: return ASN1Integer.INT_VALUE_17;
case 18: return ASN1Integer.INT_VALUE_18;
case 19: return ASN1Integer.INT_VALUE_19;
case 20: return ASN1Integer.INT_VALUE_20;
case 21: return ASN1Integer.INT_VALUE_21;
case 22: return ASN1Integer.INT_VALUE_22;
case 23: return ASN1Integer.INT_VALUE_23;
case 24: return ASN1Integer.INT_VALUE_24;
case 25: return ASN1Integer.INT_VALUE_25;
case 26: return ASN1Integer.INT_VALUE_26;
case 27: return ASN1Integer.INT_VALUE_27;
case 28: return ASN1Integer.INT_VALUE_28;
case 29: return ASN1Integer.INT_VALUE_29;
case 30: return ASN1Integer.INT_VALUE_30;
case 31: return ASN1Integer.INT_VALUE_31;
case 32: return ASN1Integer.INT_VALUE_32;
case 33: return ASN1Integer.INT_VALUE_33;
case 34: return ASN1Integer.INT_VALUE_34;
case 35: return ASN1Integer.INT_VALUE_35;
case 36: return ASN1Integer.INT_VALUE_36;
case 37: return ASN1Integer.INT_VALUE_37;
case 38: return ASN1Integer.INT_VALUE_38;
case 39: return ASN1Integer.INT_VALUE_39;
case 40: return ASN1Integer.INT_VALUE_40;
case 41: return ASN1Integer.INT_VALUE_41;
case 42: return ASN1Integer.INT_VALUE_42;
case 43: return ASN1Integer.INT_VALUE_43;
case 44: return ASN1Integer.INT_VALUE_44;
case 45: return ASN1Integer.INT_VALUE_45;
case 46: return ASN1Integer.INT_VALUE_46;
case 47: return ASN1Integer.INT_VALUE_47;
case 48: return ASN1Integer.INT_VALUE_48;
case 49: return ASN1Integer.INT_VALUE_49;
case 50: return ASN1Integer.INT_VALUE_50;
case 51: return ASN1Integer.INT_VALUE_51;
case 52: return ASN1Integer.INT_VALUE_52;
case 53: return ASN1Integer.INT_VALUE_53;
case 54: return ASN1Integer.INT_VALUE_54;
case 55: return ASN1Integer.INT_VALUE_55;
case 56: return ASN1Integer.INT_VALUE_56;
case 57: return ASN1Integer.INT_VALUE_57;
case 58: return ASN1Integer.INT_VALUE_58;
case 59: return ASN1Integer.INT_VALUE_59;
case 60: return ASN1Integer.INT_VALUE_60;
case 61: return ASN1Integer.INT_VALUE_61;
case 62: return ASN1Integer.INT_VALUE_62;
case 63: return ASN1Integer.INT_VALUE_63;
case 64: return ASN1Integer.INT_VALUE_64;
case 65: return ASN1Integer.INT_VALUE_65;
case 66: return ASN1Integer.INT_VALUE_66;
case 67: return ASN1Integer.INT_VALUE_67;
case 68: return ASN1Integer.INT_VALUE_68;
case 69: return ASN1Integer.INT_VALUE_69;
case 70: return ASN1Integer.INT_VALUE_70;
case 71: return ASN1Integer.INT_VALUE_71;
case 72: return ASN1Integer.INT_VALUE_72;
case 73: return ASN1Integer.INT_VALUE_73;
case 74: return ASN1Integer.INT_VALUE_74;
case 75: return ASN1Integer.INT_VALUE_75;
case 76: return ASN1Integer.INT_VALUE_76;
case 77: return ASN1Integer.INT_VALUE_77;
case 78: return ASN1Integer.INT_VALUE_78;
case 79: return ASN1Integer.INT_VALUE_79;
case 80: return ASN1Integer.INT_VALUE_80;
case 81: return ASN1Integer.INT_VALUE_81;
case 82: return ASN1Integer.INT_VALUE_82;
case 83: return ASN1Integer.INT_VALUE_83;
case 84: return ASN1Integer.INT_VALUE_84;
case 85: return ASN1Integer.INT_VALUE_85;
case 86: return ASN1Integer.INT_VALUE_86;
case 87: return ASN1Integer.INT_VALUE_87;
case 88: return ASN1Integer.INT_VALUE_88;
case 89: return ASN1Integer.INT_VALUE_89;
case 90: return ASN1Integer.INT_VALUE_90;
case 91: return ASN1Integer.INT_VALUE_91;
case 92: return ASN1Integer.INT_VALUE_92;
case 93: return ASN1Integer.INT_VALUE_93;
case 94: return ASN1Integer.INT_VALUE_94;
case 95: return ASN1Integer.INT_VALUE_95;
case 96: return ASN1Integer.INT_VALUE_96;
case 97: return ASN1Integer.INT_VALUE_97;
case 98: return ASN1Integer.INT_VALUE_98;
case 99: return ASN1Integer.INT_VALUE_99;
case 100: return ASN1Integer.INT_VALUE_100;
case 101: return ASN1Integer.INT_VALUE_101;
case 102: return ASN1Integer.INT_VALUE_102;
case 103: return ASN1Integer.INT_VALUE_103;
case 104: return ASN1Integer.INT_VALUE_104;
case 105: return ASN1Integer.INT_VALUE_105;
case 106: return ASN1Integer.INT_VALUE_106;
case 107: return ASN1Integer.INT_VALUE_107;
case 108: return ASN1Integer.INT_VALUE_108;
case 109: return ASN1Integer.INT_VALUE_109;
case 110: return ASN1Integer.INT_VALUE_110;
case 111: return ASN1Integer.INT_VALUE_111;
case 112: return ASN1Integer.INT_VALUE_112;
case 113: return ASN1Integer.INT_VALUE_113;
case 114: return ASN1Integer.INT_VALUE_114;
case 115: return ASN1Integer.INT_VALUE_115;
case 116: return ASN1Integer.INT_VALUE_116;
case 117: return ASN1Integer.INT_VALUE_117;
case 118: return ASN1Integer.INT_VALUE_118;
case 119: return ASN1Integer.INT_VALUE_119;
case 120: return ASN1Integer.INT_VALUE_120;
case 121: return ASN1Integer.INT_VALUE_121;
case 122: return ASN1Integer.INT_VALUE_122;
case 123: return ASN1Integer.INT_VALUE_123;
case 124: return ASN1Integer.INT_VALUE_124;
case 125: return ASN1Integer.INT_VALUE_125;
case 126: return ASN1Integer.INT_VALUE_126;
case 127: return ASN1Integer.INT_VALUE_127;
}
// It was not less than or equal to 128, so do it the "long" way.
if ((length & 0xFF000000) != 0)
{
byte[] returnArray = new byte[5];
returnArray[0] = (byte) 0x84;
returnArray[1] = (byte) ((length & 0xFF000000) >>> 24);
returnArray[2] = (byte) ((length & 0x00FF0000) >>> 16);
returnArray[3] = (byte) ((length & 0x0000FF00) >>> 8);
returnArray[4] = (byte) (length & 0x000000FF);
return returnArray;
}
else if ((length & 0x00FF0000) != 0)
{
byte[] returnArray = new byte[4];
returnArray[0] = (byte) 0x83;
returnArray[1] = (byte) ((length & 0x00FF0000) >>> 16);
returnArray[2] = (byte) ((length & 0x0000FF00) >>> 8);
returnArray[3] = (byte) (length & 0x000000FF);
return returnArray;
}
else if ((length & 0x0000FF00) != 0)
{
byte[] returnArray = new byte[3];
returnArray[0] = (byte) 0x82;
returnArray[1] = (byte) ((length & 0x0000FF00) >>> 8);
returnArray[2] = (byte) (length & 0x000000FF);
return returnArray;
}
else
{
byte[] returnArray = new byte[2];
returnArray[0] = (byte) 0x81;
returnArray[1] = (byte) (length & 0x000000FF);
return returnArray;
}
}
/**
* Decodes the provided byte array as a length.
*
* @param encodedLength The encoded value to decode as a length.
*
* @return The length decoded from the provided byte array.
*
* @throws ASN1Exception If the provided byte array cannot be decoded as an
* ASN.1 length.
*/
public static int decodeLength(byte[] encodedLength)
throws ASN1Exception
{
// First, make sure that an encoded value was actually provided.
if ((encodedLength == null) || (encodedLength.length == 0))
{
throw new ASN1Exception("No length provided to decode");
}
if (encodedLength.length == 1)
{
if ((encodedLength[0] & 0x7F) == encodedLength[0])
{
// There is only a single byte and its value is less than 128, so just
// return it as is.
return encodedLength[0];
}
else if ((encodedLength[0] & 0x7F) == 0)
{
// There is only a single byte and its value is 0x80, so just return
// 128.
return 128;
}
else
{
// There is only a single byte, but the 0x80 bit is set, which requires
// that multiple bytes actually be provided, so throw an exception
throw new ASN1Exception("Only one byte in length, but it is an " +
"invalid value");
}
}
else
{
if ((encodedLength[0] & 0x7F) != encodedLength[0])
{
// There are multiple bytes in this length and the first byte appears to
// be set properly. Put together the appropriate value if it can be
// encoded as a Java integer, or throw an exception if it cannot.
int numLengthBytes = (encodedLength[0] & 0x7F);
if (numLengthBytes == (encodedLength.length - 1))
{
if (numLengthBytes <= 4)
{
byte[] byteArray = new byte[numLengthBytes];
System.arraycopy(encodedLength, 1, byteArray, 0, byteArray.length);
return byteArrayToInt(byteArray);
}
throw new ASN1Exception("Unable to represent length " +
"as a Java int");
}
else
{
// The length of the array does not equal the expected length.
throw new ASN1Exception("Encoded length indicates " + numLengthBytes +
" bytes in length, but " +
(encodedLength.length - 1) +
" bytes were provided");
}
}
else
{
// There are multiple bytes in the value, but the first byte does not
// have the 0x80 bit set to specify the number of bytes in the length.
throw new ASN1Exception("Multiple bytes in length, but first byte " +
"does not have 0x80 bit set");
}
}
}
/**
* Encodes this ASN.1 element into a byte array.
*
* @return This ASN.1 element encoded as a byte array.
*/
public byte[] encode()
{
return encodedElement;
}
/**
* Encodes this ASN.1 element into the provided byte array at the indicated
* position.
*
* @param byteArray The byte array into which the value is to be encoded.
* @param startPos The position in the byte array at which to start writing
* the encoded value.
*
* @return The number of bytes written into the array, or -1 if the array was
* not big enough to hold the encoded value.
*/
public int encode(byte[] byteArray, int startPos)
{
// First, make sure there is enough space in the provided byte array.
int length = encodedElement.length;
if (startPos + length > byteArray.length)
{
return -1;
}
// Encode the value into the array.
System.arraycopy(encodedElement, 0, byteArray, startPos,
encodedElement.length);
return length;
}
/**
* Decodes the provided byte array as a generic ASN.1 element.
*
* @param encodedValue The encoded ASN.1 element.
*
* @return The decoded ASN.1 element.
*
* @throws ASN1Exception If the provided byte array cannot be decoded as an
* ASN.1 element.
*/
public static ASN1Element decode(byte[] encodedValue)
throws ASN1Exception
{
// First make sure that there actually was a value provided
if ((encodedValue == null) || (encodedValue.length == 0))
{
throw new ASN1Exception("No data to decode");
}
// Make sure that the encoded value is at least two bytes. Otherwise, there
// can't be both a type and a length
if (encodedValue.length < 2)
{
throw new ASN1Exception("Not enough data to make a valid ASN.1 element");
}
// First, see if the type is supposed to be a single byte or multiple bytes.
if ((encodedValue[0] & 0x1F) == 0x1F)
{
// This indicates that the type is supposed to consist of multiple bytes,
// which we do not support, so throw an exception
throw new ASN1Exception("Multibyte type detected (not supported in " +
"this package)");
}
byte type = encodedValue[0];
// Next, look at the second byte to see if there is a single byte or
// multibyte length.
int length = 0;
int valueStartPos = 2;
if ((encodedValue[1] & 0x7F) != encodedValue[1])
{
if ((encodedValue[1] & 0x7F) == 0x00)
{
length = 128;
}
else
{
int numLengthBytes = (encodedValue[1] & 0x7F);
if (encodedValue.length < (numLengthBytes + 2))
{
throw new ASN1Exception ("Determined the length is encoded in " +
numLengthBytes + " bytes, but only " +
encodedValue.length +
"bytes exist in the encoded value");
}
else
{
byte[] lengthArray = new byte[numLengthBytes+1];
lengthArray[0] = encodedValue[1];
System.arraycopy(encodedValue, 2, lengthArray, 1, numLengthBytes);
length = decodeLength(lengthArray);
valueStartPos += numLengthBytes;
}
}
}
else
{
length = encodedValue[1];
}
// Make sure that there are the correct number of bytes in the value. If
// not, then throw an exception.
if ((encodedValue.length - valueStartPos) != length)
{
throw new ASN1Exception("Expected a value of " + length + " bytes, but " +
(encodedValue.length - valueStartPos) +
" bytes exist");
}
byte[] value = new byte[length];
System.arraycopy(encodedValue, valueStartPos, value, 0, length);
return new ASN1Element(type, value, encodedValue);
}
/**
* Decodes the provided byte array as a generic ASN.1 element. The provided
* array may contain a partial element, exactly a complete element, or
* a complete element plus some additional data. The beginning of the data
* in the array must be the beginning of an ASN.1 element.
*
* @param encodedValue The encoded ASN.1 element.
*
* @return The result of attempting to decode the element.
*
* @throws ASN1Exception If the provided byte array cannot be decoded as an
* ASN.1 element.
*/
public static ASN1DecodeResult decodePartial(byte[] encodedValue)
throws ASN1Exception
{
// First make sure that there actually was a value provided and that there
// are enough bytes to contain a valid element.
if ((encodedValue == null) || (encodedValue.length < 2))
{
return new ASN1DecodeResult(null, null);
}
// First, see if the type is supposed to be a single byte or multiple bytes.
if ((encodedValue[0] & 0x1F) == 0x1F)
{
// This indicates that the type is supposed to consist of multiple bytes,
// which we do not support, so throw an exception
throw new ASN1Exception("Multibyte type detected (not supported in " +
"this package)");
}
byte type = encodedValue[0];
// Next, look at the second byte to see if there is a single byte or
// multibyte length.
int length = 0;
int valueStartPos = 2;
if ((encodedValue[1] & 0x7F) != encodedValue[1])
{
if ((encodedValue[1] & 0x7F) == 0x00)
{
length = 128;
}
else
{
int numLengthBytes = (encodedValue[1] & 0x7F);
if (encodedValue.length < (numLengthBytes + 2))
{
return new ASN1DecodeResult(null, null);
}
else
{
byte[] lengthArray = new byte[numLengthBytes+1];
lengthArray[0] = encodedValue[1];
System.arraycopy(encodedValue, 2, lengthArray, 1, numLengthBytes);
length = decodeLength(lengthArray);
valueStartPos += numLengthBytes;
}
}
}
else
{
length = encodedValue[1];
}
// Make sure that there are the correct number of bytes in the value. If
// not, then throw an exception.
int numExtraBytes = (encodedValue.length - valueStartPos) - length;
if (numExtraBytes < 0)
{
return new ASN1DecodeResult(null, null);
}
byte[] value = new byte[length];
System.arraycopy(encodedValue, valueStartPos, value, 0, length);
ASN1Element element = new ASN1Element(type, value, encodedValue);
byte[] remainingData;
if (numExtraBytes > 0)
{
remainingData = new byte[numExtraBytes];
System.arraycopy(encodedValue, valueStartPos+length, remainingData, 0,
numExtraBytes);
}
else
{
remainingData = null;
}
return new ASN1DecodeResult(element, remainingData);
}
/**
* Decodes this element as an ASN.1 Boolean element.
*
* @return The decoded ASN.1 Boolean element.
*
* @throws ASN1Exception If this element cannot be decoded as an ASN.1
* Boolean element.
*/
public ASN1Boolean decodeAsBoolean()
throws ASN1Exception
{
return ASN1Boolean.decodeAsBoolean(encode());
}
/**
* Decodes the provided byte array as an ASN.1 Boolean element.
*
* @param encodedValue The encoded ASN.1 element.
*
* @return The decoded ASN.1 Boolean element.
*
* @throws ASN1Exception If the provided byte array cannot be decoded as an
* ASN.1 Boolean element.
*/
public static ASN1Boolean decodeAsBoolean(byte[] encodedValue)
throws ASN1Exception
{
return ASN1Boolean.decodeAsBoolean(encodedValue);
}
/**
* Decodes this element as an ASN.1 integer element.
*
* @return The decoded ASN.1 integer element.
*
* @throws ASN1Exception If this element cannot be decoded as an ASN.1
* integer element.
*/
public ASN1Integer decodeAsInteger()
throws ASN1Exception
{
return ASN1Integer.decodeAsInteger(encodedElement);
}
/**
* Decodes the provided byte array as an ASN.1 integer element.
*
* @param encodedValue The encoded ASN.1 element.
*
* @return The decoded ASN.1 integer element.
*
* @throws ASN1Exception If the provided byte array cannot be decoded as an
* ASN.1 integer element.
*/
public static ASN1Integer decodeAsInteger(byte[] encodedValue)
throws ASN1Exception
{
return ASN1Integer.decodeAsInteger(encodedValue);
}
/**
* Decodes this element as an ASN.1 octet string element.
*
* @return The decoded ASN.1 octet string element.
*
* @throws ASN1Exception If this element cannot be decoded as an ASN.1
* octet string element.
*/
public ASN1OctetString decodeAsOctetString()
throws ASN1Exception
{
return ASN1OctetString.decodeAsOctetString(encodedElement);
}
/**
* Decodes the provided byte array as an ASN.1 octet string element.
*
* @param encodedValue The encoded ASN.1 element.
*
* @return The decoded ASN.1 octet string element.
*
* @throws ASN1Exception If the provided byte array cannot be decoded as an
* ASN.1 octet string element.
*/
public static ASN1OctetString decodeAsOctetString(byte[] encodedValue)
throws ASN1Exception
{
return ASN1OctetString.decodeAsOctetString(encodedValue);
}
/**
* Decodes this element as an ASN.1 null element.
*
* @return The decoded ASN.1 null element.
*
* @throws ASN1Exception If this element cannot be decoded as an ASN.1 null
* element.
*/
public ASN1Null decodeAsNull()
throws ASN1Exception
{
return ASN1Null.decodeAsNull(encodedElement);
}
/**
* Decodes the provided byte array as an ASN.1 null element.
*
* @param encodedValue The encoded ASN.1 element.
*
* @return The decoded ASN.1 null element.
*
* @throws ASN1Exception If the provided byte array cannot be decoded as an
* ASN.1 null element.
*/
public static ASN1Null decodeAsNull(byte[] encodedValue)
throws ASN1Exception
{
return ASN1Null.decodeAsNull(encodedValue);
}
/**
* Decodes this element as an ASN.1 enumerated element.
*
* @return The decoded ASN.1 enumerated element.
*
* @throws ASN1Exception If this element cannot be decoded as an ASN.1
* enumerated element.
*/
public ASN1Enumerated decodeAsEnumerated()
throws ASN1Exception
{
return ASN1Enumerated.decodeAsEnumerated(encodedElement);
}
/**
* Decodes the provided byte array as an ASN.1 enumerated element.
*
* @param encodedValue The encoded ASN.1 element.
*
* @return The decoded ASN.1 enumerated element.
*
* @throws ASN1Exception If the provided byte array cannot be decoded as an
* ASN.1 enumerated element.
*/
public static ASN1Enumerated decodeAsEnumerated(byte[] encodedValue)
throws ASN1Exception
{
return ASN1Enumerated.decodeAsEnumerated(encodedValue);
}
/**
* Decodes this element as an ASN.1 sequence element.
*
* @return The decoded ASN.1 sequence element.
*
* @throws ASN1Exception If this element cannot be decoded as an ASN.1
* sequence element.
*/
public ASN1Sequence decodeAsSequence()
throws ASN1Exception
{
return ASN1Sequence.decodeAsSequence(encodedElement);
}
/**
* Decodes the provided byte array as an ASN.1 sequence element.
*
* @param encodedValue The encoded ASN.1 element.
*
* @return The decoded ASN.1 sequence element.
*
* @throws ASN1Exception If the provided byte array cannot be decoded as an
* ASN.1 sequence element.
*/
public static ASN1Sequence decodeAsSequence(byte[] encodedValue)
throws ASN1Exception
{
return ASN1Sequence.decodeAsSequence(encodedValue);
}
/**
* Decodes this element as an ASN.1 set element.
*
* @return The decoded ASN.1 set element.
*
* @throws ASN1Exception If this element cannot be decoded as an ASN.1 set
* element.
*/
public ASN1Set decodeAsSet()
throws ASN1Exception
{
return ASN1Set.decodeAsSet(encodedElement);
}
/**
* Decodes the provided byte array as an ASN.1 set element.
*
* @param encodedValue The encoded ASN.1 element.
*
* @return The decoded ASN.1 set element.
*
* @throws ASN1Exception If the provided byte array cannot be decoded as an
* ASN.1 set element.
*/
public static ASN1Set decodeAsSet(byte[] encodedValue)
throws ASN1Exception
{
return ASN1Set.decodeAsSet(encodedValue);
}
/**
* Converts the provided byte array into a Java int value. Note that this
* method assumes that the provided array contains no more than four bytes.
*
* @param byteArray The byte array containing the encoded integer value.
*
* @return The Java int value decoded from the byte array.
*/
protected static int byteArrayToInt(byte[] byteArray)
{
int value = 0x00000000;
switch (byteArray.length)
{
case 1: value |= (0x000000FF & byteArray[0]);
break;
case 2: value |= ((0x000000FF & byteArray[0]) << 8) |
(0x000000FF & byteArray[1]);
break;
case 3: value |= ((0x000000FF & byteArray[0]) << 16) |
((0x000000FF & byteArray[1]) << 8) |
(0x000000FF & byteArray[2]);
break;
case 4: value |= ((0x000000FF & byteArray[0]) << 24) |
((0x000000FF & byteArray[1]) << 16) |
((0x000000FF & byteArray[2]) << 8) |
(0x000000FF & byteArray[3]);
break;
}
return value;
}
/**
* Retrieves a string representation of this ASN.1 element.
*
* @return A string representation of this ASN.1 element.
*/
@Override()
public String toString()
{
return toString(0);
}
/**
* Retrieves a string representation of this ASN.1 element. The information
* will be indented the specified number of spaces.
*
* @param indent The number of spaces to indent each line of the output.
*
* @return A string representation of this ASN.1 element.
*/
public String toString(int indent)
{
String indentStr = "";
for (int i=0; i < indent; i++)
{
indentStr += " ";
}
return indentStr + "Type: " + type + eol +
byteArrayToString(new byte[] { type }, 2+indent) + eol +
indentStr + "Length: " + value.length + eol +
byteArrayToString(encodeLength(value.length), 2+indent) + eol +
indentStr + "Value: " + new String(value) + eol +
byteArrayToString(value, 2+indent) + eol;
}
/**
* Retrieves a string containing the hexadecimal digits contained in the
* provided byte array.
*
* @param byteArray The byte array containing the information to be output.
*
* @return A string containing the hexadecimal digits contained in the
* provided byte array.
*/
public static String byteArrayToString(byte[] byteArray)
{
return byteArrayToString(byteArray, 0);
}
/**
* Retrieves a string containing the hexadecimal digits contained in the
* provided byte array. Each line will be indented the specified number of
* spaces.
*
* @param byteArray The byte array containing the information to be output.
* @param indent The number of spaces to indent each line of the output.
*
* @return A string containing the hexadecimal digits contained in the
* provided byte array.
*/
public static String byteArrayToString(byte[] byteArray, int indent)
{
String indentStr = "";
for (int i=0; i < indent; i++)
{
indentStr += " ";
}
String returnStr = indentStr;
for (int i=0; i < byteArray.length; i++)
{
String hexStr = Integer.toHexString((0x000000FF & byteArray[i]));
if (hexStr.length() == 1)
{
returnStr += "0";
}
returnStr += hexStr;
if ((i+1) % 16 == 0)
{
returnStr += eol + indentStr;
}
else
{
returnStr += " ";
}
}
if (byteArray.length % 16 != 0)
{
returnStr += eol;
}
return returnStr;
}
/**
* Retrieves a string representation of the provided byte array (including the
* ASCII equivalent).
*
* @param byteArray The byte array to be displayed as a string.
*
* @return A string representation of the provided byte array with the ASCII
* equivalent.
*/
public static String byteArrayToStringWithASCII(byte[] byteArray)
{
return byteArrayToStringWithASCII(byteArray, 0);
}
/**
* Retrieves a string representation of the provided byte array (including the
* ASCII equivalent) using the specified indent.
*
* @param byteArray The byte array to be displayed as a string.
* @param indent The number of spaces to indent the output.
*
* @return A string representation of the provided byte array with the ASCII
* equivalent.
*/
public static String byteArrayToStringWithASCII(byte[] byteArray, int indent)
{
String EOL = System.getProperty("line.separator");
StringBuilder indentBuf = new StringBuilder(indent);
for (int i=0; i < indent; i++)
{
indentBuf.append(' ');
}
StringBuilder buffer = new StringBuilder();
StringBuilder hexBuf = new StringBuilder();
StringBuilder asciiBuf = new StringBuilder();
for (int i=0; i < byteArray.length; i++)
{
switch (byteArray[i])
{
case 0x00:
hexBuf.append("00 ");
asciiBuf.append('.');
break;
case 0x01:
hexBuf.append("01 ");
asciiBuf.append('.');
break;
case 0x02:
hexBuf.append("02 ");
asciiBuf.append('.');
break;
case 0x03:
hexBuf.append("03 ");
asciiBuf.append('.');
break;
case 0x04:
hexBuf.append("04 ");
asciiBuf.append('.');
break;
case 0x05:
hexBuf.append("05 ");
asciiBuf.append('.');
break;
case 0x06:
hexBuf.append("06 ");
asciiBuf.append('.');
break;
case 0x07:
hexBuf.append("07 ");
asciiBuf.append('.');
break;
case 0x08:
hexBuf.append("08 ");
asciiBuf.append('.');
break;
case 0x09:
hexBuf.append("09 ");
asciiBuf.append('.');
break;
case 0x0A:
hexBuf.append("0A ");
asciiBuf.append('.');
break;
case 0x0B:
hexBuf.append("0B ");
asciiBuf.append('.');
break;
case 0x0C:
hexBuf.append("0C ");
asciiBuf.append('.');
break;
case 0x0D:
hexBuf.append("0D ");
asciiBuf.append('.');
break;
case 0x0E:
hexBuf.append("0E ");
asciiBuf.append('.');
break;
case 0x0F:
hexBuf.append("0F ");
asciiBuf.append('.');
break;
case 0x10:
hexBuf.append("10 ");
asciiBuf.append('.');
break;
case 0x11:
hexBuf.append("11 ");
asciiBuf.append('.');
break;
case 0x12:
hexBuf.append("12 ");
asciiBuf.append('.');
break;
case 0x13:
hexBuf.append("13 ");
asciiBuf.append('.');
break;
case 0x14:
hexBuf.append("14 ");
asciiBuf.append('.');
break;
case 0x15:
hexBuf.append("15 ");
asciiBuf.append('.');
break;
case 0x16:
hexBuf.append("16 ");
asciiBuf.append('.');
break;
case 0x17:
hexBuf.append("17 ");
asciiBuf.append('.');
break;
case 0x18:
hexBuf.append("18 ");
asciiBuf.append('.');
break;
case 0x19:
hexBuf.append("19 ");
asciiBuf.append('.');
break;
case 0x1A:
hexBuf.append("1A ");
asciiBuf.append('.');
break;
case 0x1B:
hexBuf.append("1B ");
asciiBuf.append('.');
break;
case 0x1C:
hexBuf.append("1C ");
asciiBuf.append('.');
break;
case 0x1D:
hexBuf.append("1D ");
asciiBuf.append('.');
break;
case 0x1E:
hexBuf.append("1E ");
asciiBuf.append('.');
break;
case 0x1F:
hexBuf.append("1F ");
asciiBuf.append('.');
break;
case 0x20:
hexBuf.append("20 ");
asciiBuf.append(' ');
break;
case 0x21:
hexBuf.append("21 ");
asciiBuf.append('!');
break;
case 0x22:
hexBuf.append("22 ");
asciiBuf.append('"');
break;
case 0x23:
hexBuf.append("23 ");
asciiBuf.append('#');
break;
case 0x24:
hexBuf.append("24 ");
asciiBuf.append('$');
break;
case 0x25:
hexBuf.append("25 ");
asciiBuf.append('%');
break;
case 0x26:
hexBuf.append("26 ");
asciiBuf.append('&');
break;
case 0x27:
hexBuf.append("27");
asciiBuf.append('\'');
break;
case 0x28:
hexBuf.append("28 ");
asciiBuf.append('(');
break;
case 0x29:
hexBuf.append("29 ");
asciiBuf.append(')');
break;
case 0x2A:
hexBuf.append("2A ");
asciiBuf.append('*');
break;
case 0x2B:
hexBuf.append("2B ");
asciiBuf.append('+');
break;
case 0x2C:
hexBuf.append("2C ");
asciiBuf.append(',');
break;
case 0x2D:
hexBuf.append("2D ");
asciiBuf.append('-');
break;
case 0x2E:
hexBuf.append("2E ");
asciiBuf.append('.');
break;
case 0x2F:
hexBuf.append("2F ");
asciiBuf.append('/');
break;
case 0x30:
hexBuf.append("30 ");
asciiBuf.append('0');
break;
case 0x31:
hexBuf.append("31 ");
asciiBuf.append('1');
break;
case 0x32:
hexBuf.append("32 ");
asciiBuf.append('2');
break;
case 0x33:
hexBuf.append("33 ");
asciiBuf.append('3');
break;
case 0x34:
hexBuf.append("34 ");
asciiBuf.append('4');
break;
case 0x35:
hexBuf.append("35 ");
asciiBuf.append('5');
break;
case 0x36:
hexBuf.append("36 ");
asciiBuf.append('6');
break;
case 0x37:
hexBuf.append("37 ");
asciiBuf.append('7');
break;
case 0x38:
hexBuf.append("38 ");
asciiBuf.append('8');
break;
case 0x39:
hexBuf.append("39 ");
asciiBuf.append('9');
break;
case 0x3A:
hexBuf.append("3A ");
asciiBuf.append(':');
break;
case 0x3B:
hexBuf.append("3B ");
asciiBuf.append(';');
break;
case 0x3C:
hexBuf.append("3C ");
asciiBuf.append('<');
break;
case 0x3D:
hexBuf.append("3D ");
asciiBuf.append('=');
break;
case 0x3E:
hexBuf.append("3E ");
asciiBuf.append('>');
break;
case 0x3F:
hexBuf.append("3F ");
asciiBuf.append('?');
break;
case 0x40:
hexBuf.append("40 ");
asciiBuf.append('@');
break;
case 0x41:
hexBuf.append("41 ");
asciiBuf.append('A');
break;
case 0x42:
hexBuf.append("42 ");
asciiBuf.append('B');
break;
case 0x43:
hexBuf.append("43 ");
asciiBuf.append('C');
break;
case 0x44:
hexBuf.append("44 ");
asciiBuf.append('D');
break;
case 0x45:
hexBuf.append("45 ");
asciiBuf.append('E');
break;
case 0x46:
hexBuf.append("46 ");
asciiBuf.append('F');
break;
case 0x47:
hexBuf.append("47 ");
asciiBuf.append('G');
break;
case 0x48:
hexBuf.append("48 ");
asciiBuf.append('H');
break;
case 0x49:
hexBuf.append("49 ");
asciiBuf.append('I');
break;
case 0x4A:
hexBuf.append("4A ");
asciiBuf.append('J');
break;
case 0x4B:
hexBuf.append("4B ");
asciiBuf.append('K');
break;
case 0x4C:
hexBuf.append("4C ");
asciiBuf.append('L');
break;
case 0x4D:
hexBuf.append("4D ");
asciiBuf.append('M');
break;
case 0x4E:
hexBuf.append("4E ");
asciiBuf.append('N');
break;
case 0x4F:
hexBuf.append("4F ");
asciiBuf.append('O');
break;
case 0x50:
hexBuf.append("50 ");
asciiBuf.append('P');
break;
case 0x51:
hexBuf.append("51 ");
asciiBuf.append('Q');
break;
case 0x52:
hexBuf.append("52 ");
asciiBuf.append('R');
break;
case 0x53:
hexBuf.append("53 ");
asciiBuf.append('S');
break;
case 0x54:
hexBuf.append("54 ");
asciiBuf.append('T');
break;
case 0x55:
hexBuf.append("55 ");
asciiBuf.append('U');
break;
case 0x56:
hexBuf.append("56 ");
asciiBuf.append('V');
break;
case 0x57:
hexBuf.append("57 ");
asciiBuf.append('W');
break;
case 0x58:
hexBuf.append("58 ");
asciiBuf.append('X');
break;
case 0x59:
hexBuf.append("59 ");
asciiBuf.append('Y');
break;
case 0x5A:
hexBuf.append("5A ");
asciiBuf.append('Z');
break;
case 0x5B:
hexBuf.append("5B ");
asciiBuf.append('[');
break;
case 0x5C:
hexBuf.append("5C ");
asciiBuf.append('\\');
break;
case 0x5D:
hexBuf.append("5D ");
asciiBuf.append(']');
break;
case 0x5E:
hexBuf.append("5E ");
asciiBuf.append('^');
break;
case 0x5F:
hexBuf.append("5F ");
asciiBuf.append('_');
break;
case 0x60:
hexBuf.append("60 ");
asciiBuf.append('`');
break;
case 0x61:
hexBuf.append("61 ");
asciiBuf.append('a');
break;
case 0x62:
hexBuf.append("62 ");
asciiBuf.append('b');
break;
case 0x63:
hexBuf.append("63 ");
asciiBuf.append('c');
break;
case 0x64:
hexBuf.append("64 ");
asciiBuf.append('d');
break;
case 0x65:
hexBuf.append("65 ");
asciiBuf.append('e');
break;
case 0x66:
hexBuf.append("66 ");
asciiBuf.append('f');
break;
case 0x67:
hexBuf.append("67 ");
asciiBuf.append('g');
break;
case 0x68:
hexBuf.append("68 ");
asciiBuf.append('h');
break;
case 0x69:
hexBuf.append("69 ");
asciiBuf.append('i');
break;
case 0x6A:
hexBuf.append("6A ");
asciiBuf.append('j');
break;
case 0x6B:
hexBuf.append("6B ");
asciiBuf.append('k');
break;
case 0x6C:
hexBuf.append("6C ");
asciiBuf.append('l');
break;
case 0x6D:
hexBuf.append("6D ");
asciiBuf.append('m');
break;
case 0x6E:
hexBuf.append("6E ");
asciiBuf.append('n');
break;
case 0x6F:
hexBuf.append("6F ");
asciiBuf.append('o');
break;
case 0x70:
hexBuf.append("70 ");
asciiBuf.append('p');
break;
case 0x71:
hexBuf.append("71 ");
asciiBuf.append('q');
break;
case 0x72:
hexBuf.append("72 ");
asciiBuf.append('r');
break;
case 0x73:
hexBuf.append("73 ");
asciiBuf.append('s');
break;
case 0x74:
hexBuf.append("74 ");
asciiBuf.append('t');
break;
case 0x75:
hexBuf.append("75 ");
asciiBuf.append('u');
break;
case 0x76:
hexBuf.append("76 ");
asciiBuf.append('v');
break;
case 0x77:
hexBuf.append("77 ");
asciiBuf.append('w');
break;
case 0x78:
hexBuf.append("78 ");
asciiBuf.append('x');
break;
case 0x79:
hexBuf.append("79 ");
asciiBuf.append('y');
break;
case 0x7A:
hexBuf.append("7A ");
asciiBuf.append('z');
break;
case 0x7B:
hexBuf.append("7B ");
asciiBuf.append('{');
break;
case 0x7C:
hexBuf.append("7C ");
asciiBuf.append('|');
break;
case 0x7D:
hexBuf.append("7D ");
asciiBuf.append('}');
break;
case 0x7E:
hexBuf.append("7E ");
asciiBuf.append('~');
break;
case 0x7F:
hexBuf.append("7F ");
asciiBuf.append('.');
break;
case (byte) 0x80:
hexBuf.append("80 ");
asciiBuf.append('.');
break;
case (byte) 0x81:
hexBuf.append("81 ");
asciiBuf.append('.');
break;
case (byte) 0x82:
hexBuf.append("82 ");
asciiBuf.append('.');
break;
case (byte) 0x83:
hexBuf.append("83 ");
asciiBuf.append('.');
break;
case (byte) 0x84:
hexBuf.append("84 ");
asciiBuf.append('.');
break;
case (byte) 0x85:
hexBuf.append("85 ");
asciiBuf.append('.');
break;
case (byte) 0x86:
hexBuf.append("86 ");
asciiBuf.append('.');
break;
case (byte) 0x87:
hexBuf.append("87 ");
asciiBuf.append('.');
break;
case (byte) 0x88:
hexBuf.append("88 ");
asciiBuf.append('.');
break;
case (byte) 0x89:
hexBuf.append("89 ");
asciiBuf.append('.');
break;
case (byte) 0x8A:
hexBuf.append("8A ");
asciiBuf.append('.');
break;
case (byte) 0x8B:
hexBuf.append("8B ");
asciiBuf.append('.');
break;
case (byte) 0x8C:
hexBuf.append("8C ");
asciiBuf.append('.');
break;
case (byte) 0x8D:
hexBuf.append("8D ");
asciiBuf.append('.');
break;
case (byte) 0x8E:
hexBuf.append("8E ");
asciiBuf.append('.');
break;
case (byte) 0x8F:
hexBuf.append("8F ");
asciiBuf.append('.');
break;
case (byte) 0x90:
hexBuf.append("90 ");
asciiBuf.append('.');
break;
case (byte) 0x91:
hexBuf.append("91 ");
asciiBuf.append('.');
break;
case (byte) 0x92:
hexBuf.append("92 ");
asciiBuf.append('.');
break;
case (byte) 0x93:
hexBuf.append("93 ");
asciiBuf.append('.');
break;
case (byte) 0x94:
hexBuf.append("94 ");
asciiBuf.append('.');
break;
case (byte) 0x95:
hexBuf.append("95 ");
asciiBuf.append('.');
break;
case (byte) 0x96:
hexBuf.append("96 ");
asciiBuf.append('.');
break;
case (byte) 0x97:
hexBuf.append("97 ");
asciiBuf.append('.');
break;
case (byte) 0x98:
hexBuf.append("98 ");
asciiBuf.append('.');
break;
case (byte) 0x99:
hexBuf.append("99 ");
asciiBuf.append('.');
break;
case (byte) 0x9A:
hexBuf.append("9A ");
asciiBuf.append('.');
break;
case (byte) 0x9B:
hexBuf.append("9B ");
asciiBuf.append('.');
break;
case (byte) 0x9C:
hexBuf.append("9C ");
asciiBuf.append('.');
break;
case (byte) 0x9D:
hexBuf.append("9D ");
asciiBuf.append('.');
break;
case (byte) 0x9E:
hexBuf.append("9E ");
asciiBuf.append('.');
break;
case (byte) 0x9F:
hexBuf.append("9F ");
asciiBuf.append('.');
break;
case (byte) 0xA0:
hexBuf.append("A0 ");
asciiBuf.append('.');
break;
case (byte) 0xA1:
hexBuf.append("A1 ");
asciiBuf.append('.');
break;
case (byte) 0xA2:
hexBuf.append("A2 ");
asciiBuf.append('.');
break;
case (byte) 0xA3:
hexBuf.append("A3 ");
asciiBuf.append('.');
break;
case (byte) 0xA4:
hexBuf.append("A4 ");
asciiBuf.append('.');
break;
case (byte) 0xA5:
hexBuf.append("A5 ");
asciiBuf.append('.');
break;
case (byte) 0xA6:
hexBuf.append("A6 ");
asciiBuf.append('.');
break;
case (byte) 0xA7:
hexBuf.append("A7 ");
asciiBuf.append('.');
break;
case (byte) 0xA8:
hexBuf.append("A8 ");
asciiBuf.append('.');
break;
case (byte) 0xA9:
hexBuf.append("A9 ");
asciiBuf.append('.');
break;
case (byte) 0xAA:
hexBuf.append("AA ");
asciiBuf.append('.');
break;
case (byte) 0xAB:
hexBuf.append("AB ");
asciiBuf.append('.');
break;
case (byte) 0xAC:
hexBuf.append("AC ");
asciiBuf.append('.');
break;
case (byte) 0xAD:
hexBuf.append("AD ");
asciiBuf.append('.');
break;
case (byte) 0xAE:
hexBuf.append("AE ");
asciiBuf.append('.');
break;
case (byte) 0xAF:
hexBuf.append("AF ");
asciiBuf.append('.');
break;
case (byte) 0xB0:
hexBuf.append("B0 ");
asciiBuf.append('.');
break;
case (byte) 0xB1:
hexBuf.append("B1 ");
asciiBuf.append('.');
break;
case (byte) 0xB2:
hexBuf.append("B2 ");
asciiBuf.append('.');
break;
case (byte) 0xB3:
hexBuf.append("B3 ");
asciiBuf.append('.');
break;
case (byte) 0xB4:
hexBuf.append("B4 ");
asciiBuf.append('.');
break;
case (byte) 0xB5:
hexBuf.append("B5 ");
asciiBuf.append('.');
break;
case (byte) 0xB6:
hexBuf.append("B6 ");
asciiBuf.append('.');
break;
case (byte) 0xB7:
hexBuf.append("B7 ");
asciiBuf.append('.');
break;
case (byte) 0xB8:
hexBuf.append("B8 ");
asciiBuf.append('.');
break;
case (byte) 0xB9:
hexBuf.append("B9 ");
asciiBuf.append('.');
break;
case (byte) 0xBA:
hexBuf.append("BA ");
asciiBuf.append('.');
break;
case (byte) 0xBB:
hexBuf.append("BB ");
asciiBuf.append('.');
break;
case (byte) 0xBC:
hexBuf.append("BC ");
asciiBuf.append('.');
break;
case (byte) 0xBD:
hexBuf.append("BD ");
asciiBuf.append('.');
break;
case (byte) 0xBE:
hexBuf.append("BE ");
asciiBuf.append('.');
break;
case (byte) 0xBF:
hexBuf.append("BF ");
asciiBuf.append('.');
break;
case (byte) 0xC0:
hexBuf.append("C0 ");
asciiBuf.append('.');
break;
case (byte) 0xC1:
hexBuf.append("C1 ");
asciiBuf.append('.');
break;
case (byte) 0xC2:
hexBuf.append("C2 ");
asciiBuf.append('.');
break;
case (byte) 0xC3:
hexBuf.append("C3 ");
asciiBuf.append('.');
break;
case (byte) 0xC4:
hexBuf.append("C4 ");
asciiBuf.append('.');
break;
case (byte) 0xC5:
hexBuf.append("C5 ");
asciiBuf.append('.');
break;
case (byte) 0xC6:
hexBuf.append("C6 ");
asciiBuf.append('.');
break;
case (byte) 0xC7:
hexBuf.append("C7 ");
asciiBuf.append('.');
break;
case (byte) 0xC8:
hexBuf.append("C8 ");
asciiBuf.append('.');
break;
case (byte) 0xC9:
hexBuf.append("C9 ");
asciiBuf.append('.');
break;
case (byte) 0xCA:
hexBuf.append("CA ");
asciiBuf.append('.');
break;
case (byte) 0xCB:
hexBuf.append("CB ");
asciiBuf.append('.');
break;
case (byte) 0xCC:
hexBuf.append("CC ");
asciiBuf.append('.');
break;
case (byte) 0xCD:
hexBuf.append("CD ");
asciiBuf.append('.');
break;
case (byte) 0xCE:
hexBuf.append("CE ");
asciiBuf.append('.');
break;
case (byte) 0xCF:
hexBuf.append("CF ");
asciiBuf.append('.');
break;
case (byte) 0xD0:
hexBuf.append("D0 ");
asciiBuf.append('.');
break;
case (byte) 0xD1:
hexBuf.append("D1 ");
asciiBuf.append('.');
break;
case (byte) 0xD2:
hexBuf.append("D2 ");
asciiBuf.append('.');
break;
case (byte) 0xD3:
hexBuf.append("D3 ");
asciiBuf.append('.');
break;
case (byte) 0xD4:
hexBuf.append("D4 ");
asciiBuf.append('.');
break;
case (byte) 0xD5:
hexBuf.append("D5 ");
asciiBuf.append('.');
break;
case (byte) 0xD6:
hexBuf.append("D6 ");
asciiBuf.append('.');
break;
case (byte) 0xD7:
hexBuf.append("D7 ");
asciiBuf.append('.');
break;
case (byte) 0xD8:
hexBuf.append("D8 ");
asciiBuf.append('.');
break;
case (byte) 0xD9:
hexBuf.append("D9 ");
asciiBuf.append('.');
break;
case (byte) 0xDA:
hexBuf.append("DA ");
asciiBuf.append('.');
break;
case (byte) 0xDB:
hexBuf.append("DB ");
asciiBuf.append('.');
break;
case (byte) 0xDC:
hexBuf.append("DC ");
asciiBuf.append('.');
break;
case (byte) 0xDD:
hexBuf.append("DD ");
asciiBuf.append('.');
break;
case (byte) 0xDE:
hexBuf.append("DE ");
asciiBuf.append('.');
break;
case (byte) 0xDF:
hexBuf.append("DF ");
asciiBuf.append('.');
break;
case (byte) 0xE0:
hexBuf.append("E0 ");
asciiBuf.append('.');
break;
case (byte) 0xE1:
hexBuf.append("E1 ");
asciiBuf.append('.');
break;
case (byte) 0xE2:
hexBuf.append("E2 ");
asciiBuf.append('.');
break;
case (byte) 0xE3:
hexBuf.append("E3 ");
asciiBuf.append('.');
break;
case (byte) 0xE4:
hexBuf.append("E4 ");
asciiBuf.append('.');
break;
case (byte) 0xE5:
hexBuf.append("E5 ");
asciiBuf.append('.');
break;
case (byte) 0xE6:
hexBuf.append("E6 ");
asciiBuf.append('.');
break;
case (byte) 0xE7:
hexBuf.append("E7 ");
asciiBuf.append('.');
break;
case (byte) 0xE8:
hexBuf.append("E8 ");
asciiBuf.append('.');
break;
case (byte) 0xE9:
hexBuf.append("E9 ");
asciiBuf.append('.');
break;
case (byte) 0xEA:
hexBuf.append("EA ");
asciiBuf.append('.');
break;
case (byte) 0xEB:
hexBuf.append("EB ");
asciiBuf.append('.');
break;
case (byte) 0xEC:
hexBuf.append("EC ");
asciiBuf.append('.');
break;
case (byte) 0xED:
hexBuf.append("ED ");
asciiBuf.append('.');
break;
case (byte) 0xEE:
hexBuf.append("EE ");
asciiBuf.append('.');
break;
case (byte) 0xEF:
hexBuf.append("EF ");
asciiBuf.append('.');
break;
case (byte) 0xF0:
hexBuf.append("F0 ");
asciiBuf.append('.');
break;
case (byte) 0xF1:
hexBuf.append("F1 ");
asciiBuf.append('.');
break;
case (byte) 0xF2:
hexBuf.append("F2 ");
asciiBuf.append('.');
break;
case (byte) 0xF3:
hexBuf.append("F3 ");
asciiBuf.append('.');
break;
case (byte) 0xF4:
hexBuf.append("F4 ");
asciiBuf.append('.');
break;
case (byte) 0xF5:
hexBuf.append("F5 ");
asciiBuf.append('.');
break;
case (byte) 0xF6:
hexBuf.append("F6 ");
asciiBuf.append('.');
break;
case (byte) 0xF7:
hexBuf.append("F7 ");
asciiBuf.append('.');
break;
case (byte) 0xF8:
hexBuf.append("F8 ");
asciiBuf.append('.');
break;
case (byte) 0xF9:
hexBuf.append("F9 ");
asciiBuf.append('.');
break;
case (byte) 0xFA:
hexBuf.append("FA ");
asciiBuf.append('.');
break;
case (byte) 0xFB:
hexBuf.append("FB ");
asciiBuf.append('.');
break;
case (byte) 0xFC:
hexBuf.append("FC ");
asciiBuf.append('.');
break;
case (byte) 0xFD:
hexBuf.append("FD ");
asciiBuf.append('.');
break;
case (byte) 0xFE:
hexBuf.append("FE ");
asciiBuf.append('.');
break;
case (byte) 0xFF:
hexBuf.append("FF ");
asciiBuf.append('.');
break;
}
if ((i % 16) == 15)
{
buffer.append(indentBuf).append(hexBuf).append(' ').append(asciiBuf).
append(EOL);
hexBuf = new StringBuilder();
asciiBuf = new StringBuilder();
}
else if ((i % 8) == 7)
{
hexBuf.append(' ');
asciiBuf.append(' ');
}
}
int charsLeft = 16 - (byteArray.length % 16);
if (charsLeft < 16)
{
for (int i=0; i < charsLeft; i++)
{
hexBuf.append(" ");
}
if (charsLeft > 8)
{
hexBuf.append(' ');
}
}
buffer.append(indentBuf).append(hexBuf).append(' ').append(asciiBuf).
append(EOL);
return buffer.toString();
}
/**
* Retrieves a byte array containing the binary representation of the
* provided string. If the provided string is 7-bit clean, then this method
* is about 5 times faster than the standard Java
* <CODE>String.getBytes()</CODE> method.
*
* @param stringValue The string for which to retrieve the binary
* representation.
*
* @return A byte array containing the binary representation of the provided
* string.
*/
public static byte[] getBytes(String stringValue)
{
if (stringValue == null)
{
return new byte[0];
}
byte b;
char c;
byte[] returnArray = new byte[stringValue.length()];
for (int i=0; i < returnArray.length; i++)
{
c = stringValue.charAt(i);
b = (byte) (c & 0x0000007F);
if (b == c)
{
returnArray[i] = b;
}
else
{
return stringValue.getBytes();
}
}
return returnArray;
}
}