/*
 * 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>BerDecoder</CODE> class is used for decoding
 * BER-encoded data.
 *
 * A <CODE>BerDecoder</CODE> needs to be set up with the byte string containing
 * the encoding. It maintains a current position in the byte string.
 *
 * Methods allows to fetch integer, string, OID, etc., from the current
 * position. After a fetch the current position is moved forward.
 *
 * A fetch throws a <CODE>BerException</CODE> if the encoding is not of the
 * expected type.
 *
 * <p><b>This API is a Sun Microsystems internal API  and is subject
 * to change without notice.</b></p>
 *
 * @since 1.5
 */

public class BerDecoder {

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

  public BerDecoder(byte b[]) {
    bytes = b ;
    reset() ;
  }

  public void reset() {
    next = 0 ;
    stackTop = 0 ;
  }

  /**
  * Fetch an integer.
  *
  * @return The decoded integer.
  *
  * @exception BerException Current position does not point to an integer.
  */

  public int fetchInteger() throws BerException {
    return fetchInteger(IntegerTag) ;
  }


  /**
  * Fetch an integer with the specified tag.
  *
  * @param tag The expected tag.
  *
  * @return The decoded integer.
  *
  * @exception BerException Current position does not point to an integer
  *                         or the tag is not the expected one.
  */

  public int fetchInteger(int tag) throws BerException {
    int result = 0 ;
    final int backup = next ;
    try {
      if (fetchTag() != tag) {
        throw new BerException() ;
      }
      result = fetchIntegerValue() ;
    }
    catch(BerException e) {
      next = backup ;
      throw e ;
    }

    return result ;
  }



  /**
  * Fetch an integer and return a long value.
  *
  * @return The decoded integer.
  *
  * @exception BerException Current position does not point to an integer.
  */

  public long fetchIntegerAsLong() throws BerException {
    return fetchIntegerAsLong(IntegerTag) ;
  }


  /**
  * Fetch an integer with the specified tag and return a long value.
  *
  * @param tag The expected tag.
  *
  * @return The decoded integer.
  *
  * @exception BerException Current position does not point to an integer
  *                         or the tag is not the expected one.
  */

  public long fetchIntegerAsLong(int tag) throws BerException {
    long result = 0 ;
    final int backup = next ;
    try {
      if (fetchTag() != tag) {
        throw new BerException() ;
      }
      result = fetchIntegerValueAsLong() ;
    }
    catch(BerException e) {
      next = backup ;
      throw e ;
    }

    return result ;
  }



  /**
  * Fetch an octet string.
  *
  * @return The decoded string.
  *
  * @exception BerException Current position does not point to an octet string.
  */

  public byte[] fetchOctetString() throws BerException {
    return fetchOctetString(OctetStringTag) ;
  }


  /**
  * Fetch an octet string with a specified tag.
  *
  * @param tag The expected tag.
  *
  * @return The decoded string.
  *
  * @exception BerException Current position does not point to an octet string
  *                         or the tag is not the expected one.
  */

  public byte[] fetchOctetString(int tag) throws BerException {
    byte[] result = null ;
    final int backup = next ;
    try {
      if (fetchTag() != tag) {
        throw new BerException() ;
      }
      result = fetchStringValue() ;
    }
    catch(BerException e) {
      next = backup ;
      throw e ;
    }

    return result ;
  }


  /**
  * Fetch an object identifier.
  *
  * @return The decoded object identifier as an array of long.
  */

  public long[] fetchOid() throws BerException {
    return fetchOid(OidTag) ;
  }


  /**
  * Fetch an object identifier with a specified tag.
  *
  * @param tag The expected tag.
  *
  * @return The decoded object identifier as an array of long.
  *
  * @exception BerException Current position does not point to an oid
  *                         or the tag is not the expected one.
  */

  public long[] fetchOid(int tag) throws BerException {
    long[] result = null ;
    final int backup = next ;
    try {
      if (fetchTag() != tag) {
        throw new BerException() ;
      }
      result = fetchOidValue() ;
    }
    catch(BerException e) {
      next = backup ;
      throw e ;
    }

    return result ;
  }


  /**
  * Fetch a <CODE>NULL</CODE> value.
  *
  * @exception BerException Current position does not point to <CODE>NULL</CODE> value.
  */

  public void fetchNull() throws BerException {
    fetchNull(NullTag) ;
  }


  /**
  * Fetch a <CODE>NULL</CODE> value with a specified tag.
  *
  * @param tag The expected tag.
  *
  * @exception BerException Current position does not point to
  *            <CODE>NULL</CODE> value or the tag is not the expected one.
  */

  public void fetchNull(int tag) throws BerException {
    final int backup = next ;
    try {
      if (fetchTag() != tag) {
        throw new BerException() ;
      }
      final int length = fetchLength();
      if (length != 0) throw new BerException();
    }
    catch(BerException e) {
      next = backup ;
      throw e ;
    }
  }



  /**
  * Fetch an <CODE>ANY</CODE> value. In fact, this method does not decode anything
  * it simply returns the next TLV as an array of bytes.
  *
  * @return The TLV as a byte array.
  *
  * @exception BerException The next TLV is really badly encoded...
  */

  public byte[] fetchAny() throws BerException {
    byte[] result = null ;
    final int backup = next ;
    try {
      final int tag = fetchTag() ;
      final int contentLength = fetchLength() ;
      if (contentLength < 0) throw new BerException() ;
      final int tlvLength = next + contentLength - backup ;
      if (contentLength > (bytes.length - next))
          throw new IndexOutOfBoundsException("Decoded length exceeds buffer");
      final byte[] data = new byte[tlvLength] ;
      java.lang.System.arraycopy(bytes,backup,data,0,tlvLength);
      // for (int i = 0 ; i < tlvLength ; i++) {
      //  data[i] = bytes[backup + i] ;
      // }
      next = next + contentLength ;
      result = data;
    }
    catch(IndexOutOfBoundsException e) {
      next = backup ;
      throw new BerException() ;
    }
    // catch(Error e) {
    //    debug("fetchAny: Error decoding BER: " + e);
    //    throw e;
    // }

    return result ;
  }


  /**
  * Fetch an <CODE>ANY</CODE> value with a specific tag.
  *
  * @param tag The expected tag.
  *
  * @return The TLV as a byte array.
  *
  * @exception BerException The next TLV is really badly encoded...
  */

  public byte[] fetchAny(int tag) throws BerException {
    if (getTag() != tag) {
      throw new BerException() ;
    }
    return fetchAny() ;
  }



  /**
  * Fetch a sequence header.
  * The decoder computes the end position of the sequence and push it
  * on its stack.
  *
  * @exception BerException Current position does not point to a sequence header.
  */

  public void openSequence() throws BerException {
    openSequence(SequenceTag) ;
  }


  /**
  * Fetch a sequence header with a specific tag.
  *
  * @param tag The expected tag.
  *
  * @exception BerException Current position does not point to a sequence header
  *                         or the tag is not the expected one.
  */

  public void openSequence(int tag) throws BerException {
    final int backup = next ;
    try {
      if (fetchTag() != tag) {
        throw new BerException() ;
      }
      final int l = fetchLength() ;
      if (l < 0) throw new BerException();
      if (l > (bytes.length - next)) throw new BerException();
      stackBuf[stackTop++] = next + l ;
    }
    catch(BerException e) {
      next = backup ;
      throw e ;
    }
  }


  /**
  * Close a sequence.
  * The decode pull the stack and verifies that the current position
  * matches with the calculated end of the sequence. If not it throws
  * an exception.
  *
  * @exception BerException The sequence is not expected to finish here.
  */

  public void closeSequence() throws BerException {
    if (stackBuf[stackTop - 1] == next) {
      stackTop-- ;
    }
    else {
      throw new BerException() ;
    }
  }


  /**
  * Return <CODE>true</CODE> if the end of the current sequence is not reached.
  * When this method returns <CODE>false</CODE>, <CODE>closeSequence</CODE> can (and must) be
  * invoked.
  *
  * @return <CODE>true</CODE> if there is still some data in the sequence.
  */

  public boolean cannotCloseSequence() {
    return (next < stackBuf[stackTop - 1]) ;
  }


  /**
  * Get the tag of the data at the current position.
  * Current position is unchanged.
  *
  * @return The next tag.
  */

  public int getTag() throws BerException {
    int result = 0 ;
    final int backup = next ;
    try {
      result = fetchTag() ;
    }
    finally {
      next = backup ;
    }

    return result ;
  }



  public String toString() {
    final StringBuffer result = new StringBuffer(bytes.length * 2) ;
    for (int i = 0 ; i < bytes.length ; i++) {
      final int b = (bytes[i] > 0) ? bytes[i] : bytes[i] + 256 ;
      if (i == next) {
        result.append("(") ;
      }
      result.append(Character.forDigit(b / 16, 16)) ;
      result.append(Character.forDigit(b % 16, 16)) ;
      if (i == next) {
        result.append(")") ;
      }
    }
    if (bytes.length == next) {
      result.append("()") ;
    }

    return new String(result) ;
  }


  //
  // 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 ;




  ////////////////////////// PRIVATE ///////////////////////////////



  /**
  * Fetch a tag and move the current position forward.
  *
  * @return The tag
  */

  private final int fetchTag() throws BerException {
    int result = 0 ;
    final int backup = next ;

    try {
      final byte b0 = bytes[next++] ;
      result = (b0 >= 0) ? b0 : b0 + 256 ;
      if ((result & 31) == 31) {
        while ((bytes[next] & 128) != 0) {
          result = result << 7 ;
          result = result | (bytes[next++] & 127);
        }
      }
    }
    catch(IndexOutOfBoundsException e) {
      next = backup ;
      throw new BerException() ;
    }

    return result ;
  }


  /**
  * Fetch a length and move the current position forward.
  *
  * @return The length
  */

  private final int fetchLength() throws BerException {
    int result = 0 ;
    final int backup = next ;

    try {
      final byte b0 = bytes[next++] ;
      if (b0 >= 0) {
        result = b0 ;
      }
      else {
        for (int c = 128 + b0 ; c > 0 ; c--) {
          final byte bX = bytes[next++] ;
          result = result << 8 ;
          result = result | ((bX >= 0) ? bX : bX+256) ;
        }
      }
    }
    catch(IndexOutOfBoundsException e) {
      next = backup ;
      throw new BerException() ;
    }

    return result ;
  }


  /**
  * Fetch an integer value and move the current position forward.
  *
  * @return The integer
  */

  private int fetchIntegerValue() throws BerException {
    int result = 0 ;
    final int backup = next ;

    try {
      final int length = fetchLength() ;
      if (length <= 0) throw new BerException() ;
      if (length > (bytes.length - next)) throw
          new IndexOutOfBoundsException("Decoded length exceeds buffer");
      final int end = next + length ;
      result = bytes[next++] ;
      while (next < end) {
        final byte b = bytes[next++] ;
        if (b < 0) {
          result = (result << 8) | (256 + b) ;
        }
        else {
          result = (result << 8) | b ;
        }
      }
    }
    catch(BerException e) {
      next = backup ;
      throw e ;
    }
    catch(IndexOutOfBoundsException e) {
      next = backup ;
      throw new BerException() ;
    }
    catch(ArithmeticException e) {
      next = backup ;
      throw new BerException() ;
    }
    return result ;
  }


  /**
  * Fetch an integer value and return a long value.
  * FIX ME: someday we could have only on fetchIntegerValue() which always
  * returns a long value.
  *
  * @return The integer
  */

  private final long fetchIntegerValueAsLong() throws BerException {
    long result = 0 ;
    final int backup = next ;

    try {
      final int length = fetchLength() ;
      if (length <= 0) throw new BerException() ;
      if (length > (bytes.length - next)) throw
          new IndexOutOfBoundsException("Decoded length exceeds buffer");

      final int end = next + length ;
      result = bytes[next++] ;
      while (next < end) {
        final byte b = bytes[next++] ;
        if (b < 0) {
          result = (result << 8) | (256 + b) ;
        }
        else {
          result = (result << 8) | b ;
        }
      }
    }
    catch(BerException e) {
      next = backup ;
      throw e ;
    }
    catch(IndexOutOfBoundsException e) {
      next = backup ;
      throw new BerException() ;
    }
    catch(ArithmeticException e) {
      next = backup ;
      throw new BerException() ;
    }
    return result ;
  }


  /**
  * Fetch a byte string and move the current position forward.
  *
  * @return The byte string
  */

  private byte[] fetchStringValue() throws BerException {
    byte[] result = null ;
    final int backup = next ;

    try {
      final int length = fetchLength() ;
      if (length < 0) throw new BerException() ;
      if (length > (bytes.length - next))
          throw new IndexOutOfBoundsException("Decoded length exceeds buffer");
      final byte data[] = new byte[length] ;
      java.lang.System.arraycopy(bytes,next,data,0,length);
      next += length;
      //      int i = 0 ;
      //      while (i < length) {
      //          result[i++] = bytes[next++] ;
      //      }
      result = data;
    }
    catch(BerException e) {
        next = backup ;
      throw e ;
    }
    catch(IndexOutOfBoundsException e) {
      next = backup ;
      throw new BerException() ;
    }
    catch(ArithmeticException e) {
      next = backup ;
      throw new BerException() ;
    }
    // catch(Error e) {
    //  debug("fetchStringValue: Error decoding BER: " + e);
    //  throw e;
    // }

    return result ;
  }



  /**
  * Fetch an oid and move the current position forward.
  *
  * @return The oid
  */

  private final long[] fetchOidValue() throws BerException {
    long[] result = null ;
    final int backup = next ;

    try {
      final int length = fetchLength() ;
      if (length <= 0) throw new BerException() ;
      if (length > (bytes.length - next))
          throw new IndexOutOfBoundsException("Decoded length exceeds buffer");
      // Count how many bytes have their 8th bit to 0
      // -> this gives the number of components in the oid
      int subidCount = 2 ;
      for (int i = 1 ; i < length ; i++) {
        if ((bytes[next + i] & 0x80) == 0) {
          subidCount++ ;
        }
      }
      final int datalen = subidCount;
      final long[] data = new long[datalen];
      final byte b0 = bytes[next++] ;

      // bugId 4641746
      // The 8th bit of the first byte should always be set to 0
      if (b0 < 0) throw new BerException();

      // bugId 4641746
      // The first sub Id cannot be greater than 2
      final long lb0 =  b0 / 40 ;
      if (lb0 > 2) throw new BerException();

      final long lb1 = b0 % 40;
      data[0] = lb0 ;
      data[1] = lb1 ;
      int i = 2 ;
      while (i < datalen) {
        long subid = 0 ;
        byte b = bytes[next++] ;
        while ((b & 0x80) != 0) {
          subid = (subid << 7) | (b & 0x7f) ;
          // bugId 4654674
          if (subid < 0) throw new BerException();
          b = bytes[next++] ;
        }
        subid = (subid << 7) | b ;
        // bugId 4654674
        if (subid < 0) throw new BerException();
        data[i++] = subid ;
      }
      result = data;
    }
    catch(BerException e) {
      next = backup ;
      throw e ;
    }
    catch(IndexOutOfBoundsException e) {
      next = backup ;
      throw new BerException() ;
    }
    // catch(Error e) {
    //  debug("fetchOidValue: Error decoding BER: " + e);
    //  throw e;
    // }

    return result ;
  }

    // private static final void debug(String str) {
    //   System.out.println(str);
    // }

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

  //
  // This is the current location. It is the next byte
  // to be decoded. It's an index in bytes[].
  //
  private int next = 0 ;

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

}
