/*
 * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */


package com.sun.jmx.snmp;


/**
 * The <CODE>BerEncoder</CODE> class is used for encoding data using BER.
 *
 * A <CODE>BerEncoder</CODE> needs to be set up with a byte buffer. The encoded
 * data are stored in this byte buffer.
 * <P>
 * NOTE : the buffer is filled from end to start. This means the caller
 * needs to encode its data in the reverse order.
 *
 *
 * <p><b>This API is a Sun Microsystems internal API  and is subject
 * to change without notice.</b></p>
 *
 * @since 1.5
 */

public class BerEncoder {

  /**
  * Constructs a new encoder and attaches it to the specified byte string.
  *
  * @param b The byte string containing the encoded data.
  */

  public BerEncoder(byte b[]) {
    bytes = b ;
    start = b.length ;
    stackTop = 0 ;
  }


  /**
  * 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 <CODE>trim</CODE> method.
  *
  * After a call to the <CODE>trim</CODE> method, the encoder is reinitialized and <CODE>putXXX</CODE>
  * overwrite any existing encoded data.
  *
  * @return The length of the encoded data.
  */

  public int trim() {
    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 ;
  }

  /**
  * Put an integer.
  *
  * @param v The integer to encode.
  */

  public void putInteger(int v) {
    putInteger(v, IntegerTag) ;
  }


  /**
  * Put an integer with the specified tag.
  *
  * @param v The integer to encode.
  * @param tag The tag to encode.
  */

  public void putInteger(int v, int tag) {
    putIntegerValue(v) ;
    putTag(tag) ;
  }



  /**
  * Put an integer expressed as a long.
  *
  * @param v The long to encode.
  */

  public void putInteger(long v) {
    putInteger(v, IntegerTag) ;
  }


  /**
  * Put an integer expressed as a long with the specified tag.
  *
  * @param v The long to encode
  * @param tag The tag to encode.
  */

  public void putInteger(long v, int tag) {
    putIntegerValue(v) ;
    putTag(tag) ;
  }



  /**
  * Put an octet string.
  *
  * @param s The bytes to encode
  */

  public void putOctetString(byte[] s) {
    putOctetString(s, OctetStringTag) ;
  }


  /**
  * Put an octet string with a specified tag.
  *
  * @param s The bytes to encode
  * @param tag The tag to encode.
  */

  public void putOctetString(byte[] s, int tag) {
    putStringValue(s) ;
    putTag(tag) ;
  }


  /**
  * Put an object identifier.
  *
  * @param s The oid to encode.
  */

  public void putOid(long[] s) {
    putOid(s, OidTag) ;
  }


  /**
  * Put an object identifier with a specified tag.
  *
  * @param s The integer to encode.
  * @param tag The tag to encode.
  */

  public void putOid(long[] s, int tag) {
    putOidValue(s) ;
    putTag(tag) ;
  }


  /**
  * Put a <CODE>NULL</CODE> value.
  */

  public void putNull() {
    putNull(NullTag) ;
  }


  /**
  * Put a <CODE>NULL</CODE> value with a specified tag.
  *
  * @param tag The tag to encode.
  */

  public void putNull(int tag) {
    putLength(0) ;
    putTag(tag) ;
  }



  /**
  * Put an <CODE>ANY</CODE> value. In fact, this method does not encode anything.
  * It simply copies the specified bytes into the encoding.
  *
  * @param s The encoding of the <CODE>ANY</CODE> value.
  */

  public void putAny(byte[] s) {
        putAny(s, s.length) ;
  }


  /**
  * Put an <CODE>ANY</CODE> value. Only the first <CODE>byteCount</CODE> are considered.
  *
  * @param s The encoding of the <CODE>ANY</CODE> value.
  * @param byteCount The number of bytes of the encoding.
  */

  public void putAny(byte[] s, int byteCount) {
      java.lang.System.arraycopy(s,0,bytes,start-byteCount,byteCount);
      start -= byteCount;
      //    for (int i = byteCount - 1 ; i >= 0 ; i--) {
      //      bytes[--start] = s[i] ;
      //    }
  }


  /**
  * Open a sequence.
  * The encoder push the current position on its stack.
  */

  public void openSequence() {
    stackBuf[stackTop++] = start ;
  }


  /**
  * Close a sequence.
  * The decode pull the stack to know the end of the current sequence.
  */

  public void closeSequence() {
    closeSequence(SequenceTag) ;
  }


  /**
  * Close a sequence with the specified tag.
  */

  public void closeSequence(int tag) {
    final int end = stackBuf[--stackTop] ;
    putLength(end - start) ;
    putTag(tag) ;
  }


  //
  // Some standard tags
  //
  public final static int BooleanTag      = 1 ;
  public final static int IntegerTag      = 2 ;
  public final static int OctetStringTag  = 4 ;
  public final static int NullTag          = 5 ;
  public final static int OidTag          = 6 ;
  public final static int SequenceTag      = 0x30 ;




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



  /**
  * Put a tag and move the current position backward.
  *
  * @param tag The tag to encode.
  */

  protected final void putTag(int tag) {
    if (tag < 256) {
      bytes[--start] = (byte)tag ;
    }
    else {
      while (tag != 0) {
        bytes[--start] = (byte)(tag & 127) ;
        tag = tag << 7 ;
      }
    }
  }


  /**
  * Put a length and move the current position backward.
  *
  * @param length The length to encode.
  */

  protected final void putLength(final int length) {
    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 ;
    }
  }


  /**
  * Put an integer value and move the current position backward.
  *
  * @param v The integer to encode.
  */

  protected final void putIntegerValue(int v) {
    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) ;
  }


  /**
  * Put an integer value expressed as a long.
  *
  * @param v The integer to encode.
  */

  protected final void putIntegerValue(long v) {
    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) ;
  }


  /**
  * Put a byte string and move the current position backward.
  *
  * @param s The byte string to encode.
  */

  protected final void putStringValue(byte[] s) {
      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) ;
  }



  /**
  * Put an oid and move the current position backward.
  *
  * @param s The oid to encode.
  */

  protected final void putOidValue(final long[] s) {
      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) ;
  }


  //
  // This is the byte array containing the encoding.
  //
  protected final byte bytes[];

  //
  // This is the index of the first byte of the encoding.
  // It is initialized to <CODE>bytes.length</CODE> and decrease each time
  // an value is put in the encoder.
  //
  protected int start = -1 ;

  //
  // This is the stack where end of sequences are kept.
  // A value is computed and pushed in it each time the <CODE>openSequence</CODE> method
  // is invoked.
  // A value is pulled and checked each time the <CODE>closeSequence</CODE> method is called.
  //
  protected final int stackBuf[] = new int[200] ;
  protected int stackTop = 0 ;

}
