From 263d085885df024dca9250cc03c807912b0a7662 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Tue, 24 Apr 2012 22:33:21 +0000
Subject: [PATCH] Reformat to comply with new Checkstyle rules.

---
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/asn1/ASN1ByteSequenceReader.java |  839 +++++++++++++++++++++++++----------------------------------
 1 files changed, 362 insertions(+), 477 deletions(-)

diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/asn1/ASN1ByteSequenceReader.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/asn1/ASN1ByteSequenceReader.java
index b02393c..6eeb6bd 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/asn1/ASN1ByteSequenceReader.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/asn1/ASN1ByteSequenceReader.java
@@ -6,17 +6,16 @@
  * (the "License").  You may not use this file except in compliance
  * with the License.
  *
- * You can obtain a copy of the license at
- * trunk/opendj3/legal-notices/CDDLv1_0.txt
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
  * or http://forgerock.org/license/CDDLv1.0.html.
  * See the License for the specific language governing permissions
  * and limitations under the License.
  *
  * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
  *      Portions Copyright [yyyy] [name of copyright owner]
  *
  * CDDL HEADER END
@@ -28,8 +27,6 @@
 
 package org.forgerock.opendj.asn1;
 
-
-
 import static org.forgerock.opendj.asn1.ASN1Constants.ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE;
 import static org.forgerock.opendj.asn1.ASN1Constants.ELEMENT_READ_STATE_NEED_TYPE;
 import static org.forgerock.opendj.asn1.ASN1Constants.ELEMENT_READ_STATE_NEED_VALUE_BYTES;
@@ -47,521 +44,409 @@
 
 import com.forgerock.opendj.util.StaticUtils;
 
-
-
 /**
  * An ASN.1 reader that reads from a {@link ByteSequenceReader}.
  */
-final class ASN1ByteSequenceReader extends AbstractASN1Reader implements
-    ASN1Reader
-{
+final class ASN1ByteSequenceReader extends AbstractASN1Reader implements ASN1Reader {
 
-  private int state = ELEMENT_READ_STATE_NEED_TYPE;
+    private int state = ELEMENT_READ_STATE_NEED_TYPE;
 
-  private byte peekType = 0;
+    private byte peekType = 0;
 
-  private int peekLength = -1;
+    private int peekLength = -1;
 
-  private final int maxElementSize;
+    private final int maxElementSize;
 
-  private ByteSequenceReader reader;
+    private ByteSequenceReader reader;
 
-  private final LinkedList<ByteSequenceReader> readerStack;
+    private final LinkedList<ByteSequenceReader> readerStack;
 
-
-
-  /**
-   * Creates a new ASN1 reader whose source is the provided byte sequence reader
-   * and having a user defined maximum BER element size.
-   *
-   * @param reader
-   *          The byte sequence reader to be read.
-   * @param maxElementSize
-   *          The maximum BER element size, or <code>0</code> to indicate that
-   *          there is no limit.
-   */
-  ASN1ByteSequenceReader(final ByteSequenceReader reader,
-      final int maxElementSize)
-  {
-    this.reader = reader;
-    this.readerStack = new LinkedList<ByteSequenceReader>();
-    this.maxElementSize = maxElementSize;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public void close() throws IOException
-  {
-    readerStack.clear();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public boolean elementAvailable() throws IOException
-  {
-    if ((state == ELEMENT_READ_STATE_NEED_TYPE) && !needTypeState(false))
-    {
-      return false;
-    }
-    if ((state == ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE)
-        && !needFirstLengthByteState(false))
-    {
-      return false;
+    /**
+     * Creates a new ASN1 reader whose source is the provided byte sequence
+     * reader and having a user defined maximum BER element size.
+     *
+     * @param reader
+     *            The byte sequence reader to be read.
+     * @param maxElementSize
+     *            The maximum BER element size, or <code>0</code> to indicate
+     *            that there is no limit.
+     */
+    ASN1ByteSequenceReader(final ByteSequenceReader reader, final int maxElementSize) {
+        this.reader = reader;
+        this.readerStack = new LinkedList<ByteSequenceReader>();
+        this.maxElementSize = maxElementSize;
     }
 
-    return peekLength <= reader.remaining();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public boolean hasNextElement() throws IOException
-  {
-    return (state != ELEMENT_READ_STATE_NEED_TYPE) || needTypeState(false);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public int peekLength() throws IOException
-  {
-    peekType();
-
-    if (state == ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE)
-    {
-      needFirstLengthByteState(true);
+    /**
+     * {@inheritDoc}
+     */
+    public void close() throws IOException {
+        readerStack.clear();
     }
 
-    return peekLength;
-  }
+    /**
+     * {@inheritDoc}
+     */
+    public boolean elementAvailable() throws IOException {
+        if ((state == ELEMENT_READ_STATE_NEED_TYPE) && !needTypeState(false)) {
+            return false;
+        }
+        if ((state == ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE)
+                && !needFirstLengthByteState(false)) {
+            return false;
+        }
 
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public byte peekType() throws IOException
-  {
-    if (state == ELEMENT_READ_STATE_NEED_TYPE)
-    {
-      // Read just the type.
-      if (reader.remaining() <= 0)
-      {
-        final LocalizableMessage message = ERR_ASN1_TRUCATED_TYPE_BYTE.get();
-        throw DecodeException.fatalError(message);
-      }
-      final int type = reader.get();
-
-      peekType = (byte) type;
-      state = ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE;
+        return peekLength <= reader.remaining();
     }
 
-    return peekType;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public boolean readBoolean() throws IOException
-  {
-    // Read the header if haven't done so already
-    peekLength();
-
-    if (peekLength != 1)
-    {
-      final LocalizableMessage message = ERR_ASN1_BOOLEAN_INVALID_LENGTH
-          .get(peekLength);
-      throw DecodeException.fatalError(message);
+    /**
+     * {@inheritDoc}
+     */
+    public boolean hasNextElement() throws IOException {
+        return (state != ELEMENT_READ_STATE_NEED_TYPE) || needTypeState(false);
     }
 
-    if (reader.remaining() < peekLength)
-    {
-      final LocalizableMessage message = ERR_ASN1_BOOLEAN_TRUNCATED_VALUE
-          .get(peekLength);
-      throw DecodeException.fatalError(message);
-    }
-    final int readByte = reader.get();
+    /**
+     * {@inheritDoc}
+     */
+    public int peekLength() throws IOException {
+        peekType();
 
-    state = ELEMENT_READ_STATE_NEED_TYPE;
-    return readByte != 0x00;
-  }
+        if (state == ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE) {
+            needFirstLengthByteState(true);
+        }
 
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public void readEndSequence() throws IOException
-  {
-    if (readerStack.isEmpty())
-    {
-      final LocalizableMessage message = ERR_ASN1_SEQUENCE_READ_NOT_STARTED
-          .get();
-      throw new IllegalStateException(message.toString());
+        return peekLength;
     }
 
-    if ((reader.remaining() > 0)
-        && StaticUtils.DEBUG_LOG.isLoggable(Level.FINE))
-    {
-      StaticUtils.DEBUG_LOG.fine("Ignoring " + reader.remaining()
-          + " unused trailing bytes in " + "ASN.1 SEQUENCE");
+    /**
+     * {@inheritDoc}
+     */
+    public byte peekType() throws IOException {
+        if (state == ELEMENT_READ_STATE_NEED_TYPE) {
+            // Read just the type.
+            if (reader.remaining() <= 0) {
+                final LocalizableMessage message = ERR_ASN1_TRUCATED_TYPE_BYTE.get();
+                throw DecodeException.fatalError(message);
+            }
+            final int type = reader.get();
+
+            peekType = (byte) type;
+            state = ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE;
+        }
+
+        return peekType;
     }
 
-    reader = readerStack.removeFirst();
+    /**
+     * {@inheritDoc}
+     */
+    public boolean readBoolean() throws IOException {
+        // Read the header if haven't done so already
+        peekLength();
 
-    // Reset the state
-    state = ELEMENT_READ_STATE_NEED_TYPE;
-  }
+        if (peekLength != 1) {
+            final LocalizableMessage message = ERR_ASN1_BOOLEAN_INVALID_LENGTH.get(peekLength);
+            throw DecodeException.fatalError(message);
+        }
 
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public void readEndSet() throws IOException
-  {
-    // From an implementation point of view, a set is equivalent to a
-    // sequence.
-    readEndSequence();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public int readEnumerated() throws IOException
-  {
-    // Read the header if haven't done so already
-    peekLength();
-
-    if ((peekLength < 1) || (peekLength > 4))
-    {
-      final LocalizableMessage message = ERR_ASN1_INTEGER_INVALID_LENGTH
-          .get(peekLength);
-      throw DecodeException.fatalError(message);
-    }
-
-    // From an implementation point of view, an enumerated value is
-    // equivalent to an integer.
-    return (int) readInteger();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public long readInteger() throws IOException
-  {
-    // Read the header if haven't done so already
-    peekLength();
-
-    if ((peekLength < 1) || (peekLength > 8))
-    {
-      final LocalizableMessage message = ERR_ASN1_INTEGER_INVALID_LENGTH
-          .get(peekLength);
-      throw DecodeException.fatalError(message);
-    }
-
-    if (reader.remaining() < peekLength)
-    {
-      final LocalizableMessage message = ERR_ASN1_INTEGER_TRUNCATED_VALUE
-          .get(peekLength);
-      throw DecodeException.fatalError(message);
-    }
-    if (peekLength > 4)
-    {
-      long longValue = 0;
-      for (int i = 0; i < peekLength; i++)
-      {
+        if (reader.remaining() < peekLength) {
+            final LocalizableMessage message = ERR_ASN1_BOOLEAN_TRUNCATED_VALUE.get(peekLength);
+            throw DecodeException.fatalError(message);
+        }
         final int readByte = reader.get();
-        if ((i == 0) && (readByte < 0))
-        {
-          longValue = 0xFFFFFFFFFFFFFFFFL;
+
+        state = ELEMENT_READ_STATE_NEED_TYPE;
+        return readByte != 0x00;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void readEndSequence() throws IOException {
+        if (readerStack.isEmpty()) {
+            final LocalizableMessage message = ERR_ASN1_SEQUENCE_READ_NOT_STARTED.get();
+            throw new IllegalStateException(message.toString());
         }
-        longValue = (longValue << 8) | (readByte & 0xFF);
-      }
 
-      state = ELEMENT_READ_STATE_NEED_TYPE;
-      return longValue;
-    }
-    else
-    {
-      int intValue = 0;
-      for (int i = 0; i < peekLength; i++)
-      {
-        final int readByte = reader.get();
-        if ((i == 0) && (readByte < 0))
-        {
-          intValue = 0xFFFFFFFF;
+        if ((reader.remaining() > 0) && StaticUtils.DEBUG_LOG.isLoggable(Level.FINE)) {
+            StaticUtils.DEBUG_LOG.fine("Ignoring " + reader.remaining()
+                    + " unused trailing bytes in " + "ASN.1 SEQUENCE");
         }
-        intValue = (intValue << 8) | (readByte & 0xFF);
-      }
 
-      state = ELEMENT_READ_STATE_NEED_TYPE;
-      return intValue;
-    }
-  }
+        reader = readerStack.removeFirst();
 
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public void readNull() throws IOException
-  {
-    // Read the header if haven't done so already
-    peekLength();
-
-    // Make sure that the decoded length is exactly zero byte.
-    if (peekLength != 0)
-    {
-      final LocalizableMessage message = ERR_ASN1_NULL_INVALID_LENGTH
-          .get(peekLength);
-      throw DecodeException.fatalError(message);
+        // Reset the state
+        state = ELEMENT_READ_STATE_NEED_TYPE;
     }
 
-    state = ELEMENT_READ_STATE_NEED_TYPE;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public ByteString readOctetString() throws IOException
-  {
-    // Read the header if haven't done so already
-    peekLength();
-
-    if (reader.remaining() < peekLength)
-    {
-      final LocalizableMessage message = ERR_ASN1_OCTET_STRING_TRUNCATED_VALUE
-          .get(peekLength);
-      throw DecodeException.fatalError(message);
+    /**
+     * {@inheritDoc}
+     */
+    public void readEndSet() throws IOException {
+        // From an implementation point of view, a set is equivalent to a
+        // sequence.
+        readEndSequence();
     }
 
-    state = ELEMENT_READ_STATE_NEED_TYPE;
-    return reader.getByteString(peekLength);
-  }
+    /**
+     * {@inheritDoc}
+     */
+    public int readEnumerated() throws IOException {
+        // Read the header if haven't done so already
+        peekLength();
 
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public ByteStringBuilder readOctetString(final ByteStringBuilder builder)
-      throws IOException
-  {
-    // Read the header if haven't done so already
-    peekLength();
-
-    // Copy the value.
-    if (reader.remaining() < peekLength)
-    {
-      final LocalizableMessage message = ERR_ASN1_OCTET_STRING_TRUNCATED_VALUE
-          .get(peekLength);
-      throw DecodeException.fatalError(message);
-    }
-    builder.append(reader, peekLength);
-
-    state = ELEMENT_READ_STATE_NEED_TYPE;
-    return builder;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public String readOctetStringAsString() throws IOException
-  {
-    // Read the header if haven't done so already
-    peekLength();
-
-    if (reader.remaining() < peekLength)
-    {
-      final LocalizableMessage message = ERR_ASN1_OCTET_STRING_TRUNCATED_VALUE
-          .get(peekLength);
-      throw DecodeException.fatalError(message);
-    }
-
-    state = ELEMENT_READ_STATE_NEED_TYPE;
-    return reader.getString(peekLength);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public void readStartSequence() throws IOException
-  {
-    // Read the header if haven't done so already
-    peekLength();
-
-    if (reader.remaining() < peekLength)
-    {
-      final LocalizableMessage message = ERR_ASN1_SEQUENCE_SET_TRUNCATED_VALUE
-          .get(peekLength);
-      throw DecodeException.fatalError(message);
-    }
-
-    final ByteSequenceReader subByteString = reader.getByteSequence(peekLength)
-        .asReader();
-    readerStack.addFirst(reader);
-    reader = subByteString;
-
-    // Reset the state
-    state = ELEMENT_READ_STATE_NEED_TYPE;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public void readStartSet() throws IOException
-  {
-    // From an implementation point of view, a set is equivalent to a
-    // sequence.
-    readStartSequence();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public ASN1Reader skipElement() throws IOException
-  {
-    // Read the header if haven't done so already
-    peekLength();
-
-    if (reader.remaining() < peekLength)
-    {
-      final LocalizableMessage message = ERR_ASN1_SKIP_TRUNCATED_VALUE
-          .get(peekLength);
-      throw DecodeException.fatalError(message);
-    }
-
-    state = ELEMENT_READ_STATE_NEED_TYPE;
-    reader.skip(peekLength);
-    return this;
-  }
-
-
-
-  /**
-   * Internal helper method reading the first length bytes and transition to the
-   * next state if successful.
-   *
-   * @param throwEofException
-   *          <code>true</code> to throw an exception when the end of the
-   *          sequence is encountered.
-   * @return <code>true</code> if the length bytes was successfully read
-   * @throws IOException
-   *           If an error occurs while trying to decode an ASN1 element.
-   */
-  private boolean needFirstLengthByteState(final boolean throwEofException)
-      throws IOException
-  {
-    if (reader.remaining() <= 0)
-    {
-      if (throwEofException)
-      {
-        final LocalizableMessage message = ERR_ASN1_TRUNCATED_LENGTH_BYTE.get();
-        throw DecodeException.fatalError(message);
-      }
-      return false;
-    }
-    int readByte = reader.get();
-    peekLength = (readByte & 0x7F);
-    if (peekLength != readByte)
-    {
-      int lengthBytesNeeded = peekLength;
-      if (lengthBytesNeeded > 4)
-      {
-        final LocalizableMessage message = ERR_ASN1_INVALID_NUM_LENGTH_BYTES
-            .get(lengthBytesNeeded);
-        throw DecodeException.fatalError(message);
-      }
-
-      peekLength = 0x00;
-      if (reader.remaining() < lengthBytesNeeded)
-      {
-        if (throwEofException)
-        {
-          final LocalizableMessage message = ERR_ASN1_TRUNCATED_LENGTH_BYTES
-              .get(lengthBytesNeeded);
-          throw DecodeException.fatalError(message);
+        if ((peekLength < 1) || (peekLength > 4)) {
+            final LocalizableMessage message = ERR_ASN1_INTEGER_INVALID_LENGTH.get(peekLength);
+            throw DecodeException.fatalError(message);
         }
-        return false;
-      }
 
-      while (lengthBytesNeeded > 0)
-      {
-        readByte = reader.get();
-        peekLength = (peekLength << 8) | (readByte & 0xFF);
-        lengthBytesNeeded--;
-      }
+        // From an implementation point of view, an enumerated value is
+        // equivalent to an integer.
+        return (int) readInteger();
     }
 
-    // Make sure that the element is not larger than the maximum allowed
-    // message size.
-    if ((maxElementSize > 0) && (peekLength > maxElementSize))
-    {
-      final LocalizableMessage message = ERR_LDAP_CLIENT_DECODE_MAX_REQUEST_SIZE_EXCEEDED
-          .get(peekLength, maxElementSize);
-      throw DecodeException.fatalError(message);
+    /**
+     * {@inheritDoc}
+     */
+    public long readInteger() throws IOException {
+        // Read the header if haven't done so already
+        peekLength();
+
+        if ((peekLength < 1) || (peekLength > 8)) {
+            final LocalizableMessage message = ERR_ASN1_INTEGER_INVALID_LENGTH.get(peekLength);
+            throw DecodeException.fatalError(message);
+        }
+
+        if (reader.remaining() < peekLength) {
+            final LocalizableMessage message = ERR_ASN1_INTEGER_TRUNCATED_VALUE.get(peekLength);
+            throw DecodeException.fatalError(message);
+        }
+        if (peekLength > 4) {
+            long longValue = 0;
+            for (int i = 0; i < peekLength; i++) {
+                final int readByte = reader.get();
+                if ((i == 0) && (readByte < 0)) {
+                    longValue = 0xFFFFFFFFFFFFFFFFL;
+                }
+                longValue = (longValue << 8) | (readByte & 0xFF);
+            }
+
+            state = ELEMENT_READ_STATE_NEED_TYPE;
+            return longValue;
+        } else {
+            int intValue = 0;
+            for (int i = 0; i < peekLength; i++) {
+                final int readByte = reader.get();
+                if ((i == 0) && (readByte < 0)) {
+                    intValue = 0xFFFFFFFF;
+                }
+                intValue = (intValue << 8) | (readByte & 0xFF);
+            }
+
+            state = ELEMENT_READ_STATE_NEED_TYPE;
+            return intValue;
+        }
     }
-    state = ELEMENT_READ_STATE_NEED_VALUE_BYTES;
-    return true;
-  }
 
+    /**
+     * {@inheritDoc}
+     */
+    public void readNull() throws IOException {
+        // Read the header if haven't done so already
+        peekLength();
 
+        // Make sure that the decoded length is exactly zero byte.
+        if (peekLength != 0) {
+            final LocalizableMessage message = ERR_ASN1_NULL_INVALID_LENGTH.get(peekLength);
+            throw DecodeException.fatalError(message);
+        }
 
-  /**
-   * Internal helper method reading the ASN.1 type byte and transition to the
-   * next state if successful.
-   *
-   * @param throwEofException
-   *          <code>true</code> to throw an exception when the end of the
-   *          sequence is encountered.
-   * @return <code>true</code> if the type byte was successfully read
-   * @throws IOException
-   *           If an error occurs while trying to decode an ASN1 element.
-   */
-  private boolean needTypeState(final boolean throwEofException)
-      throws IOException
-  {
-    // Read just the type.
-    if (reader.remaining() <= 0)
-    {
-      if (throwEofException)
-      {
-        final LocalizableMessage message = ERR_ASN1_TRUCATED_TYPE_BYTE.get();
-        throw DecodeException.fatalError(message);
-      }
-      return false;
+        state = ELEMENT_READ_STATE_NEED_TYPE;
     }
-    final int type = reader.get();
 
-    peekType = (byte) type;
-    state = ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE;
-    return true;
-  }
+    /**
+     * {@inheritDoc}
+     */
+    public ByteString readOctetString() throws IOException {
+        // Read the header if haven't done so already
+        peekLength();
+
+        if (reader.remaining() < peekLength) {
+            final LocalizableMessage message =
+                    ERR_ASN1_OCTET_STRING_TRUNCATED_VALUE.get(peekLength);
+            throw DecodeException.fatalError(message);
+        }
+
+        state = ELEMENT_READ_STATE_NEED_TYPE;
+        return reader.getByteString(peekLength);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ByteStringBuilder readOctetString(final ByteStringBuilder builder) throws IOException {
+        // Read the header if haven't done so already
+        peekLength();
+
+        // Copy the value.
+        if (reader.remaining() < peekLength) {
+            final LocalizableMessage message =
+                    ERR_ASN1_OCTET_STRING_TRUNCATED_VALUE.get(peekLength);
+            throw DecodeException.fatalError(message);
+        }
+        builder.append(reader, peekLength);
+
+        state = ELEMENT_READ_STATE_NEED_TYPE;
+        return builder;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String readOctetStringAsString() throws IOException {
+        // Read the header if haven't done so already
+        peekLength();
+
+        if (reader.remaining() < peekLength) {
+            final LocalizableMessage message =
+                    ERR_ASN1_OCTET_STRING_TRUNCATED_VALUE.get(peekLength);
+            throw DecodeException.fatalError(message);
+        }
+
+        state = ELEMENT_READ_STATE_NEED_TYPE;
+        return reader.getString(peekLength);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void readStartSequence() throws IOException {
+        // Read the header if haven't done so already
+        peekLength();
+
+        if (reader.remaining() < peekLength) {
+            final LocalizableMessage message =
+                    ERR_ASN1_SEQUENCE_SET_TRUNCATED_VALUE.get(peekLength);
+            throw DecodeException.fatalError(message);
+        }
+
+        final ByteSequenceReader subByteString = reader.getByteSequence(peekLength).asReader();
+        readerStack.addFirst(reader);
+        reader = subByteString;
+
+        // Reset the state
+        state = ELEMENT_READ_STATE_NEED_TYPE;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void readStartSet() throws IOException {
+        // From an implementation point of view, a set is equivalent to a
+        // sequence.
+        readStartSequence();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ASN1Reader skipElement() throws IOException {
+        // Read the header if haven't done so already
+        peekLength();
+
+        if (reader.remaining() < peekLength) {
+            final LocalizableMessage message = ERR_ASN1_SKIP_TRUNCATED_VALUE.get(peekLength);
+            throw DecodeException.fatalError(message);
+        }
+
+        state = ELEMENT_READ_STATE_NEED_TYPE;
+        reader.skip(peekLength);
+        return this;
+    }
+
+    /**
+     * Internal helper method reading the first length bytes and transition to
+     * the next state if successful.
+     *
+     * @param throwEofException
+     *            <code>true</code> to throw an exception when the end of the
+     *            sequence is encountered.
+     * @return <code>true</code> if the length bytes was successfully read
+     * @throws IOException
+     *             If an error occurs while trying to decode an ASN1 element.
+     */
+    private boolean needFirstLengthByteState(final boolean throwEofException) throws IOException {
+        if (reader.remaining() <= 0) {
+            if (throwEofException) {
+                final LocalizableMessage message = ERR_ASN1_TRUNCATED_LENGTH_BYTE.get();
+                throw DecodeException.fatalError(message);
+            }
+            return false;
+        }
+        int readByte = reader.get();
+        peekLength = (readByte & 0x7F);
+        if (peekLength != readByte) {
+            int lengthBytesNeeded = peekLength;
+            if (lengthBytesNeeded > 4) {
+                final LocalizableMessage message =
+                        ERR_ASN1_INVALID_NUM_LENGTH_BYTES.get(lengthBytesNeeded);
+                throw DecodeException.fatalError(message);
+            }
+
+            peekLength = 0x00;
+            if (reader.remaining() < lengthBytesNeeded) {
+                if (throwEofException) {
+                    final LocalizableMessage message =
+                            ERR_ASN1_TRUNCATED_LENGTH_BYTES.get(lengthBytesNeeded);
+                    throw DecodeException.fatalError(message);
+                }
+                return false;
+            }
+
+            while (lengthBytesNeeded > 0) {
+                readByte = reader.get();
+                peekLength = (peekLength << 8) | (readByte & 0xFF);
+                lengthBytesNeeded--;
+            }
+        }
+
+        // Make sure that the element is not larger than the maximum allowed
+        // message size.
+        if ((maxElementSize > 0) && (peekLength > maxElementSize)) {
+            final LocalizableMessage message =
+                    ERR_LDAP_CLIENT_DECODE_MAX_REQUEST_SIZE_EXCEEDED
+                            .get(peekLength, maxElementSize);
+            throw DecodeException.fatalError(message);
+        }
+        state = ELEMENT_READ_STATE_NEED_VALUE_BYTES;
+        return true;
+    }
+
+    /**
+     * Internal helper method reading the ASN.1 type byte and transition to the
+     * next state if successful.
+     *
+     * @param throwEofException
+     *            <code>true</code> to throw an exception when the end of the
+     *            sequence is encountered.
+     * @return <code>true</code> if the type byte was successfully read
+     * @throws IOException
+     *             If an error occurs while trying to decode an ASN1 element.
+     */
+    private boolean needTypeState(final boolean throwEofException) throws IOException {
+        // Read just the type.
+        if (reader.remaining() <= 0) {
+            if (throwEofException) {
+                final LocalizableMessage message = ERR_ASN1_TRUCATED_TYPE_BYTE.get();
+                throw DecodeException.fatalError(message);
+            }
+            return false;
+        }
+        final int type = reader.get();
+
+        peekType = (byte) type;
+        state = ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE;
+        return true;
+    }
 }

--
Gitblit v1.10.0