FileDocCategorySizeDatePackage
BerEncoder.javaAPI DocJava SE 5 API10043Fri Aug 26 14:55:02 BST 2005com.sun.jmx.snmp

BerEncoder

public class BerEncoder extends Object
The BerEncoder class is used for encoding data using BER. A BerEncoder needs to be set up with a byte buffer. The encoded data are stored in this byte buffer.

NOTE : the buffer is filled from end to start. This means the caller needs to encode its data in the reverse order.

This API is a Sun Microsystems internal API and is subject to change without notice.

version
4.16 12/19/03
author
Sun Microsystems, Inc
since
1.5

Fields Summary
public static final int
BooleanTag
public static final int
IntegerTag
public static final int
OctetStringTag
public static final int
NullTag
public static final int
OidTag
public static final int
SequenceTag
protected final byte[]
bytes
protected int
start
protected final int[]
stackBuf
protected int
stackTop
Constructors Summary
public BerEncoder(byte[] b)
Constructs a new encoder and attaches it to the specified byte string.

param
b The byte string containing the encoded data.

    bytes = b ;
    start = b.length ;
    stackTop = 0 ;
  
Methods Summary
public voidcloseSequence()
Close a sequence. The decode pull the stack to know the end of the current sequence.

    closeSequence(SequenceTag) ;
  
public voidcloseSequence(int tag)
Close a sequence with the specified tag.

    final int end = stackBuf[--stackTop] ;
    putLength(end - start) ;
    putTag(tag) ;
  
public voidopenSequence()
Open a sequence. The encoder push the current position on its stack.

    stackBuf[stackTop++] = start ;
  
public voidputAny(byte[] s)
Put an ANY value. In fact, this method does not encode anything. It simply copies the specified bytes into the encoding.

param
s The encoding of the ANY value.

  	putAny(s, s.length) ;
  
public voidputAny(byte[] s, int byteCount)
Put an ANY value. Only the first byteCount are considered.

param
s The encoding of the ANY value.
param
byteCount The number of bytes of the encoding.

      java.lang.System.arraycopy(s,0,bytes,start-byteCount,byteCount);
      start -= byteCount;
      //    for (int i = byteCount - 1 ; i >= 0 ; i--) {
      //      bytes[--start] = s[i] ;
      //    }
  
public voidputInteger(int v)
Put an integer.

param
v The integer to encode.

    putInteger(v, IntegerTag) ;
  
public voidputInteger(int v, int tag)
Put an integer with the specified tag.

param
v The integer to encode.
param
tag The tag to encode.

    putIntegerValue(v) ;
    putTag(tag) ;
  
public voidputInteger(long v)
Put an integer expressed as a long.

param
v The long to encode.

    putInteger(v, IntegerTag) ;
  
public voidputInteger(long v, int tag)
Put an integer expressed as a long with the specified tag.

param
v The long to encode
param
tag The tag to encode.

    putIntegerValue(v) ;
    putTag(tag) ;
  
protected final voidputIntegerValue(int v)
Put an integer value and move the current position backward.

param
v The integer to encode.

    final int end = start ;
    int mask = 0x7f800000 ;
    int byteNeeded = 4 ;
    if (v < 0) {
      while (((mask & v) == mask) && (byteNeeded > 1)) {
        mask = mask >> 8 ;
        byteNeeded-- ;
      }
    }
    else {
      while (((mask & v) == 0) && (byteNeeded > 1)) {
        mask = mask >> 8 ;
        byteNeeded-- ;
      }
    }
    for (int i = 0 ; i < byteNeeded ; i++) {
      bytes[--start] = (byte)v ;
      v =  v >> 8 ;
    }
    putLength(end - start) ;
  
protected final voidputIntegerValue(long v)
Put an integer value expressed as a long.

param
v The integer to encode.

    final int end = start ;
    long mask = 0x7f80000000000000L ;
    int byteNeeded = 8 ;
    if (v < 0) {
      while (((mask & v) == mask) && (byteNeeded > 1)) {
        mask = mask >> 8 ;
        byteNeeded-- ;
      }
    }
    else {
      while (((mask & v) == 0) && (byteNeeded > 1)) {
        mask = mask >> 8 ;
        byteNeeded-- ;
      }
    }
    for (int i = 0 ; i < byteNeeded ; i++) {
      bytes[--start] = (byte)v ;
      v =  v >> 8 ;
    }
    putLength(end - start) ;
  
protected final voidputLength(int length)
Put a length and move the current position backward.

param
length The length to encode.

    if (length < 0) {
      throw new IllegalArgumentException() ;
    }
    else if (length < 128) {
      bytes[--start] = (byte)length ;
    }
    else if (length < 256) {
      bytes[--start] = (byte)length ;
      bytes[--start] = (byte)0x81 ;
    }
    else if (length < 65536) {
      bytes[--start] = (byte)(length) ;
      bytes[--start] = (byte)(length >> 8) ;
      bytes[--start] = (byte)0x82 ;
    }
    else if (length < 16777126) {
      bytes[--start] = (byte)(length) ;
      bytes[--start] = (byte)(length >> 8) ;
      bytes[--start] = (byte)(length >> 16) ;
      bytes[--start] = (byte)0x83 ;
    }
    else {
      bytes[--start] = (byte)(length) ;
      bytes[--start] = (byte)(length >> 8) ;
      bytes[--start] = (byte)(length >> 16) ;
      bytes[--start] = (byte)(length >> 24) ;
      bytes[--start] = (byte)0x84 ;
    }
  
public voidputNull()
Put a NULL value.

    putNull(NullTag) ;
  
public voidputNull(int tag)
Put a NULL value with a specified tag.

param
tag The tag to encode.

    putLength(0) ;
    putTag(tag) ;
  
public voidputOctetString(byte[] s)
Put an octet string.

param
s The bytes to encode

    putOctetString(s, OctetStringTag) ;
  
public voidputOctetString(byte[] s, int tag)
Put an octet string with a specified tag.

param
s The bytes to encode
param
tag The tag to encode.

    putStringValue(s) ;
    putTag(tag) ;
  
public voidputOid(long[] s, int tag)
Put an object identifier with a specified tag.

param
s The integer to encode.
param
tag The tag to encode.

    putOidValue(s) ;
    putTag(tag) ;
  
public voidputOid(long[] s)
Put an object identifier.

param
s The oid to encode.

    putOid(s, OidTag) ;
  
protected final voidputOidValue(long[] s)
Put an oid and move the current position backward.

param
s The oid to encode.

      final int end = start ;
      final int slength = s.length;

      // bugId 4641746: 0, 1, and 2 are legal values.
      if ((slength < 2) || (s[0] > 2) || (s[1] >= 40)) {
	  throw new IllegalArgumentException() ;
      }
      for (int i = slength - 1 ; i >= 2 ; i--) {
	  long c = s[i] ;
	  if (c < 0) {
	      throw new IllegalArgumentException() ;
	  }
	  else if (c < 128) {
	      bytes[--start] = (byte)c ;
	  }
	  else {
	      bytes[--start] = (byte)(c & 127) ;
	      c = c >> 7 ;
	      while (c != 0) {
		  bytes[--start] = (byte)(c | 128) ;
		  c = c >> 7 ;
	      }
	  }
      }
      bytes[--start] = (byte)(s[0] * 40 + s[1]) ;
      putLength(end - start) ;
  
protected final voidputStringValue(byte[] s)
Put a byte string and move the current position backward.

param
s The byte string to encode.

      final int datalen = s.length;
      java.lang.System.arraycopy(s,0,bytes,start-datalen,datalen);
      start -= datalen;
      // for (int i = s.length - 1 ; i >= 0 ; i--) {
      //   bytes[--start] = s[i] ;
      // }
      putLength(datalen) ;
  
protected final voidputTag(int tag)
Put a tag and move the current position backward.

param
tag The tag to encode.





  ////////////////////////// PROTECTED ///////////////////////////////



                   

       
    if (tag < 256) {
      bytes[--start] = (byte)tag ;
    }
    else {
      while (tag != 0) {
        bytes[--start] = (byte)(tag & 127) ;
        tag = tag << 7 ;
      }
    }
  
public inttrim()
Trim the encoding data and returns the length of the encoding. The encoder does backward encoding : so the bytes buffer is filled from end to start. The encoded data must be shift before the buffer can be used. This is the purpose of the trim method. After a call to the trim method, the encoder is reinitialized and putXXX overwrite any existing encoded data.

return
The length of the encoded data.

    final int result = bytes.length - start ;

    // for (int i = start ; i < bytes.length ; i++) {
    //  bytes[i-start] = bytes[i] ;
    // }
    if (result > 0)  
	java.lang.System.arraycopy(bytes,start,bytes,0,result);

    start = bytes.length ;
    stackTop = 0 ;
    
    return result ;