From f2160f4bd1c8ac67e5a86a6710d431e8932877f9 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Fri, 28 May 2010 11:47:51 +0000
Subject: [PATCH] Synchronize SDK on java.net with internal repository.

---
 sdk/src/com/sun/opends/sdk/ldap/ASN1BufferReader.java |  278 ++++++++++++++++++++++++++-----------------------------
 1 files changed, 131 insertions(+), 147 deletions(-)

diff --git a/sdk/src/com/sun/opends/sdk/ldap/ASN1StreamReader.java b/sdk/src/com/sun/opends/sdk/ldap/ASN1BufferReader.java
similarity index 71%
rename from sdk/src/com/sun/opends/sdk/ldap/ASN1StreamReader.java
rename to sdk/src/com/sun/opends/sdk/ldap/ASN1BufferReader.java
index d6ab025..156c288 100644
--- a/sdk/src/com/sun/opends/sdk/ldap/ASN1StreamReader.java
+++ b/sdk/src/com/sun/opends/sdk/ldap/ASN1BufferReader.java
@@ -22,17 +22,20 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2009 Sun Microsystems, Inc.
+ *      Copyright 2010 Sun Microsystems, Inc.
  */
+
 package com.sun.opends.sdk.ldap;
 
 
 
+import static com.sun.opends.sdk.ldap.LDAPConstants.ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES;
+import static com.sun.opends.sdk.ldap.LDAPConstants.ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE;
+import static com.sun.opends.sdk.ldap.LDAPConstants.ELEMENT_READ_STATE_NEED_TYPE;
+import static com.sun.opends.sdk.ldap.LDAPConstants.ELEMENT_READ_STATE_NEED_VALUE_BYTES;
 import static com.sun.opends.sdk.messages.Messages.*;
-import static com.sun.opends.sdk.ldap.LDAPConstants.*;
 
 import java.io.IOException;
-import java.nio.BufferUnderflowException;
 import java.util.logging.Level;
 
 import org.opends.sdk.ByteString;
@@ -42,8 +45,9 @@
 import org.opends.sdk.asn1.ASN1Reader;
 import org.opends.sdk.asn1.AbstractASN1Reader;
 
-import com.sun.grizzly.streams.StreamReader;
-import com.sun.grizzly.utils.PoolableObject;
+import com.sun.grizzly.Buffer;
+import com.sun.grizzly.memory.ByteBuffersBuffer;
+import com.sun.grizzly.memory.CompositeBuffer;
 import com.sun.opends.sdk.util.StaticUtils;
 
 
@@ -51,10 +55,9 @@
 /**
  * Grizzly ASN1 reader implementation.
  */
-public final class ASN1StreamReader extends AbstractASN1Reader implements
-    PoolableObject, ASN1Reader
+final class ASN1BufferReader extends AbstractASN1Reader implements ASN1Reader
 {
-  class ChildSequenceLimiter implements SequenceLimiter
+  private final class ChildSequenceLimiter implements SequenceLimiter
   {
     private SequenceLimiter parent;
 
@@ -66,12 +69,12 @@
 
 
 
-    public void checkLimit(int readSize) throws IOException,
-        BufferUnderflowException
+    public void checkLimit(final int readSize) throws IOException
     {
       if ((readLimit > 0) && (bytesRead + readSize > readLimit))
       {
-        throw new BufferUnderflowException();
+        final LocalizableMessage message = ERR_ASN1_TRUNCATED_LENGTH_BYTE.get();
+        throw DecodeException.fatalError(message);
       }
 
       parent.checkLimit(readSize);
@@ -85,17 +88,17 @@
     {
       parent.checkLimit(remaining());
 
-      if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINE)
-          && remaining() > 0)
+      if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINE) && remaining() > 0)
       {
-        StaticUtils.DEBUG_LOG.fine(String.format(
-            "Ignoring %d unused trailing bytes in ASN.1 SEQUENCE",
-            remaining()));
+        StaticUtils.DEBUG_LOG
+            .fine(String.format(
+                "Ignoring %d unused trailing bytes in ASN.1 SEQUENCE",
+                remaining()));
       }
 
       for (int i = 0; i < remaining(); i++)
       {
-        streamReader.readByte();
+        buffer.get();
       }
 
       return parent;
@@ -110,7 +113,7 @@
 
 
 
-    public ChildSequenceLimiter startSequence(int readLimit)
+    public ChildSequenceLimiter startSequence(final int readLimit)
     {
       if (child == null)
       {
@@ -127,21 +130,27 @@
 
 
 
-  class RootSequenceLimiter implements SequenceLimiter
+  private final class RootSequenceLimiter implements SequenceLimiter
   {
     private ChildSequenceLimiter child;
 
 
 
-    public void checkLimit(int readSize)
+    public void checkLimit(final int readSize) throws IOException
     {
+      if (buffer.remaining() < readSize)
+      {
+        final LocalizableMessage message = ERR_ASN1_TRUNCATED_LENGTH_BYTE.get();
+        throw DecodeException.fatalError(message);
+      }
     }
 
 
 
     public ChildSequenceLimiter endSequence() throws DecodeException
     {
-      LocalizableMessage message = ERR_ASN1_SEQUENCE_READ_NOT_STARTED.get();
+      final LocalizableMessage message = ERR_ASN1_SEQUENCE_READ_NOT_STARTED
+          .get();
       throw new IllegalStateException(message.toString());
     }
 
@@ -149,12 +158,12 @@
 
     public int remaining()
     {
-      return streamReader.availableDataSize();
+      return buffer.remaining();
     }
 
 
 
-    public ChildSequenceLimiter startSequence(int readLimit)
+    public ChildSequenceLimiter startSequence(final int readLimit)
     {
       if (child == null)
       {
@@ -173,8 +182,7 @@
 
   private interface SequenceLimiter
   {
-    public void checkLimit(int readSize) throws IOException,
-        BufferUnderflowException;
+    public void checkLimit(int readSize) throws IOException;
 
 
 
@@ -203,29 +211,28 @@
 
   private final int maxElementSize;
 
-  private StreamReader streamReader;
-
-  private final RootSequenceLimiter rootLimiter;
+  private final CompositeBuffer buffer;
 
   private SequenceLimiter readLimiter;
 
-  private final byte[] buffer;
+  private final byte[] stringBuffer;
 
 
 
   /**
-   * Creates a new ASN1 reader whose source is the provided input stream
-   * and having a user defined maximum BER element size.
+   * Creates a new ASN1 reader whose source is the provided input stream and
+   * having a user defined maximum BER element size.
    *
    * @param maxElementSize
-   *          The maximum BER element size, or <code>0</code> to
-   *          indicate that there is no limit.
+   *          The maximum BER element size, or <code>0</code> to indicate that
+   *          there is no limit.
    */
-  public ASN1StreamReader(int maxElementSize)
+  ASN1BufferReader(final int maxElementSize)
   {
-    this.readLimiter = this.rootLimiter = new RootSequenceLimiter();
-    this.buffer = new byte[MAX_STRING_BUFFER_SIZE];
+    this.readLimiter = new RootSequenceLimiter();
+    this.stringBuffer = new byte[MAX_STRING_BUFFER_SIZE];
     this.maxElementSize = maxElementSize;
+    this.buffer = ByteBuffersBuffer.create();
   }
 
 
@@ -238,55 +245,45 @@
    */
   public void close() throws IOException
   {
-    // close the stream reader.
-    streamReader.close();
+    buffer.dispose();
   }
 
 
 
   /**
-   * Determines if a complete ASN.1 element is ready to be read from the
-   * stream reader.
+   * Determines if a complete ASN.1 element is ready to be read from the stream
+   * reader.
    *
-   * @return <code>true</code> if another complete element is available
-   *         or <code>false</code> otherwise.
+   * @return <code>true</code> if another complete element is available or
+   *         <code>false</code> otherwise.
    * @throws IOException
-   *           If an error occurs while trying to decode an ASN1
-   *           element.
+   *           If an error occurs while trying to decode an ASN1 element.
    */
   public boolean elementAvailable() throws IOException
   {
-    if ((state == ELEMENT_READ_STATE_NEED_TYPE) && !needTypeState(true))
-    {
-      return false;
-    }
-    if ((state == ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE)
-        && !needFirstLengthByteState(true))
-    {
-      return false;
-    }
-    return !((state == ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES)
-        && !needAdditionalLengthBytesState(true)) &&
-        peekLength <= readLimiter.remaining();
+    return !((state == ELEMENT_READ_STATE_NEED_TYPE) && !needTypeState(true))
+        && !((state == ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE)
+            && !needFirstLengthByteState(true))
+        && !((state == ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES)
+            && !needAdditionalLengthBytesState(true))
+        && peekLength <= readLimiter.remaining();
 
   }
 
 
 
   /**
-   * Determines if the input stream contains at least one ASN.1 element
-   * to be read.
+   * Determines if the input stream contains at least one ASN.1 element to be
+   * read.
    *
    * @return <code>true</code> if another element is available or
    *         <code>false</code> otherwise.
    * @throws IOException
-   *           If an error occurs while trying to decode an ASN1
-   *           element.
+   *           If an error occurs while trying to decode an ASN1 element.
    */
   public boolean hasNextElement() throws IOException
   {
-    return (state != ELEMENT_READ_STATE_NEED_TYPE)
-        || needTypeState(true);
+    return (state != ELEMENT_READ_STATE_NEED_TYPE) || needTypeState(true);
   }
 
 
@@ -328,13 +325,6 @@
 
 
 
-  public void prepare()
-  {
-    // Nothing to do
-  }
-
-
-
   /**
    * {@inheritDoc}
    */
@@ -345,18 +335,19 @@
 
     if (peekLength != 1)
     {
-      LocalizableMessage message = ERR_ASN1_BOOLEAN_INVALID_LENGTH.get(peekLength);
+      final LocalizableMessage message = ERR_ASN1_BOOLEAN_INVALID_LENGTH
+          .get(peekLength);
       throw DecodeException.fatalError(message);
     }
 
     readLimiter.checkLimit(peekLength);
-    byte readByte = streamReader.readByte();
+    final byte readByte = buffer.get();
 
     if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
     {
       StaticUtils.DEBUG_LOG.finest(String.format(
-          "READ ASN.1 BOOLEAN(type=0x%x, length=%d, value=%s)",
-          peekType, peekLength, String.valueOf(readByte != 0x00)));
+          "READ ASN.1 BOOLEAN(type=0x%x, length=%d, value=%s)", peekType,
+          peekLength, String.valueOf(readByte != 0x00)));
     }
 
     state = ELEMENT_READ_STATE_NEED_TYPE;
@@ -368,15 +359,13 @@
   /**
    * {@inheritDoc}
    */
-  public void readEndSequence() throws IOException,
-      IllegalStateException
+  public void readEndSequence() throws IOException, IllegalStateException
   {
     readLimiter = readLimiter.endSequence();
 
     if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
     {
-      StaticUtils.DEBUG_LOG.finest(String
-          .format("READ ASN.1 END SEQUENCE"));
+      StaticUtils.DEBUG_LOG.finest(String.format("READ ASN.1 END SEQUENCE"));
     }
 
     // Reset the state
@@ -407,7 +396,8 @@
 
     if ((peekLength < 1) || (peekLength > 4))
     {
-      LocalizableMessage message = ERR_ASN1_INTEGER_INVALID_LENGTH.get(peekLength);
+      final LocalizableMessage message = ERR_ASN1_INTEGER_INVALID_LENGTH
+          .get(peekLength);
       throw DecodeException.fatalError(message);
     }
 
@@ -428,7 +418,8 @@
 
     if ((peekLength < 1) || (peekLength > 8))
     {
-      LocalizableMessage message = ERR_ASN1_INTEGER_INVALID_LENGTH.get(peekLength);
+      final LocalizableMessage message = ERR_ASN1_INTEGER_INVALID_LENGTH
+          .get(peekLength);
       throw DecodeException.fatalError(message);
     }
 
@@ -438,7 +429,7 @@
       long longValue = 0;
       for (int i = 0; i < peekLength; i++)
       {
-        int readByte = streamReader.readByte();
+        final int readByte = buffer.get();
         if ((i == 0) && (((byte) readByte) < 0))
         {
           longValue = 0xFFFFFFFFFFFFFFFFL;
@@ -454,7 +445,7 @@
       int intValue = 0;
       for (int i = 0; i < peekLength; i++)
       {
-        int readByte = streamReader.readByte();
+        final int readByte = buffer.get();
         if ((i == 0) && (((byte) readByte) < 0))
         {
           intValue = 0xFFFFFFFF;
@@ -465,8 +456,8 @@
       if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
       {
         StaticUtils.DEBUG_LOG.finest(String.format(
-            "READ ASN.1 INTEGER(type=0x%x, length=%d, value=%d)",
-            peekType, peekLength, intValue));
+            "READ ASN.1 INTEGER(type=0x%x, length=%d, value=%d)", peekType,
+            peekLength, intValue));
       }
 
       state = ELEMENT_READ_STATE_NEED_TYPE;
@@ -487,15 +478,15 @@
     // Make sure that the decoded length is exactly zero byte.
     if (peekLength != 0)
     {
-      LocalizableMessage message = ERR_ASN1_NULL_INVALID_LENGTH.get(peekLength);
+      final LocalizableMessage message = ERR_ASN1_NULL_INVALID_LENGTH
+          .get(peekLength);
       throw DecodeException.fatalError(message);
     }
 
     if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
     {
-      StaticUtils.DEBUG_LOG.finest(String
-          .format("READ ASN.1 NULL(type=0x%x, length=%d)", peekType,
-              peekLength));
+      StaticUtils.DEBUG_LOG.finest(String.format(
+          "READ ASN.1 NULL(type=0x%x, length=%d)", peekType, peekLength));
     }
 
     state = ELEMENT_READ_STATE_NEED_TYPE;
@@ -519,14 +510,14 @@
 
     readLimiter.checkLimit(peekLength);
     // Copy the value and construct the element to return.
-    byte[] value = new byte[peekLength];
-    streamReader.readByteArray(value);
+    final byte[] value = new byte[peekLength];
+    buffer.get(value);
 
     if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
     {
-      StaticUtils.DEBUG_LOG.finest(String.format(
-          "READ ASN.1 OCTETSTRING(type=0x%x, length=%d)", peekType,
-          peekLength));
+      StaticUtils.DEBUG_LOG
+          .finest(String.format("READ ASN.1 OCTETSTRING(type=0x%x, length=%d)",
+              peekType, peekLength));
     }
 
     state = ELEMENT_READ_STATE_NEED_TYPE;
@@ -538,7 +529,7 @@
   /**
    * {@inheritDoc}
    */
-  public ByteStringBuilder readOctetString(ByteStringBuilder builder)
+  public ByteStringBuilder readOctetString(final ByteStringBuilder builder)
       throws IOException
   {
     // Read the header if haven't done so already
@@ -555,14 +546,14 @@
     // TODO: Is there a more efficient way to do this?
     for (int i = 0; i < peekLength; i++)
     {
-      builder.append(streamReader.readByte());
+      builder.append(buffer.get());
     }
 
     if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
     {
-      StaticUtils.DEBUG_LOG.finest(String.format(
-          "READ ASN.1 OCTETSTRING(type=0x%x, length=%d)", peekType,
-          peekLength));
+      StaticUtils.DEBUG_LOG
+          .finest(String.format("READ ASN.1 OCTETSTRING(type=0x%x, length=%d)",
+              peekType, peekLength));
     }
 
     state = ELEMENT_READ_STATE_NEED_TYPE;
@@ -586,9 +577,9 @@
     }
 
     byte[] readBuffer;
-    if (peekLength <= buffer.length)
+    if (peekLength <= stringBuffer.length)
     {
-      readBuffer = buffer;
+      readBuffer = stringBuffer;
     }
     else
     {
@@ -596,7 +587,7 @@
     }
 
     readLimiter.checkLimit(peekLength);
-    streamReader.readByteArray(readBuffer, 0, peekLength);
+    buffer.get(readBuffer, 0, peekLength);
 
     state = ELEMENT_READ_STATE_NEED_TYPE;
 
@@ -605,7 +596,7 @@
     {
       str = new String(readBuffer, 0, peekLength, "UTF-8");
     }
-    catch (Exception e)
+    catch (final Exception e)
     {
       if (StaticUtils.DEBUG_LOG.isLoggable(Level.WARNING))
       {
@@ -614,14 +605,14 @@
                 + e.toString());
       }
 
-      str = new String(buffer, 0, peekLength);
+      str = new String(stringBuffer, 0, peekLength);
     }
 
     if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
     {
       StaticUtils.DEBUG_LOG.finest(String.format(
-          "READ ASN.1 OCTETSTRING(type=0x%x, length=%d, value=%s)",
-          peekType, peekLength, str));
+          "READ ASN.1 OCTETSTRING(type=0x%x, length=%d, value=%s)", peekType,
+          peekLength, str));
     }
 
     return str;
@@ -664,24 +655,6 @@
 
 
 
-  public void release()
-  {
-    streamReader = null;
-    peekLength = -1;
-    peekType = 0;
-    readLimiter = rootLimiter;
-    state = ELEMENT_READ_STATE_NEED_TYPE;
-  }
-
-
-
-  public void setStreamReader(StreamReader streamReader)
-  {
-    this.streamReader = streamReader;
-  }
-
-
-
   /**
    * {@inheritDoc}
    */
@@ -693,7 +666,7 @@
     readLimiter.checkLimit(peekLength);
     for (int i = 0; i < peekLength; i++)
     {
-      streamReader.readByte();
+      buffer.get();
     }
     state = ELEMENT_READ_STATE_NEED_TYPE;
     return this;
@@ -701,18 +674,31 @@
 
 
 
+  void appendBytesRead(final Buffer buffer)
+  {
+    this.buffer.append(buffer);
+  }
+
+
+
+  void disposeBytesRead()
+  {
+    this.buffer.disposeUnused();
+  }
+
+
+
   /**
-   * Internal helper method reading the additional ASN.1 length bytes
-   * and transition to the next state if successful.
+   * Internal helper method reading the additional ASN.1 length bytes and
+   * transition to the next state if successful.
    *
    * @param ensureRead
    *          <code>true</code> to check for availability first.
-   * @return <code>true</code> if the length bytes was successfully
-   *         read.
+   * @return <code>true</code> if the length bytes was successfully read.
    * @throws IOException
    *           If an error occurs while reading from the stream.
    */
-  private boolean needAdditionalLengthBytesState(boolean ensureRead)
+  private boolean needAdditionalLengthBytesState(final boolean ensureRead)
       throws IOException
   {
     if (ensureRead && (readLimiter.remaining() < lengthBytesNeeded))
@@ -724,7 +710,7 @@
     readLimiter.checkLimit(lengthBytesNeeded);
     while (lengthBytesNeeded > 0)
     {
-      readByte = streamReader.readByte();
+      readByte = buffer.get();
       peekLength = (peekLength << 8) | (readByte & 0xFF);
       lengthBytesNeeded--;
     }
@@ -733,8 +719,8 @@
     // message size.
     if ((maxElementSize > 0) && (peekLength > maxElementSize))
     {
-      LocalizableMessage m = ERR_LDAP_CLIENT_DECODE_MAX_REQUEST_SIZE_EXCEEDED.get(
-          peekLength, maxElementSize);
+      final LocalizableMessage m = ERR_LDAP_CLIENT_DECODE_MAX_REQUEST_SIZE_EXCEEDED
+          .get(peekLength, maxElementSize);
       throw DecodeException.fatalError(m);
     }
     state = ELEMENT_READ_STATE_NEED_VALUE_BYTES;
@@ -744,17 +730,16 @@
 
 
   /**
-   * Internal helper method reading the first length bytes and
-   * transition to the next state if successful.
+   * Internal helper method reading the first length bytes and transition to the
+   * next state if successful.
    *
    * @param ensureRead
    *          <code>true</code> to check for availability first.
    * @return <code>true</code> if the length bytes was successfully read
    * @throws IOException
-   *           If an error occurs while trying to decode an ASN1
-   *           element.
+   *           If an error occurs while trying to decode an ASN1 element.
    */
-  private boolean needFirstLengthByteState(boolean ensureRead)
+  private boolean needFirstLengthByteState(final boolean ensureRead)
       throws IOException
   {
     if (ensureRead && (readLimiter.remaining() <= 0))
@@ -763,14 +748,14 @@
     }
 
     readLimiter.checkLimit(1);
-    byte readByte = streamReader.readByte();
+    byte readByte = buffer.get();
     peekLength = (readByte & 0x7F);
     if (peekLength != readByte)
     {
       lengthBytesNeeded = peekLength;
       if (lengthBytesNeeded > 4)
       {
-        LocalizableMessage message = ERR_ASN1_INVALID_NUM_LENGTH_BYTES
+        final LocalizableMessage message = ERR_ASN1_INVALID_NUM_LENGTH_BYTES
             .get(lengthBytesNeeded);
         throw DecodeException.fatalError(message);
       }
@@ -785,7 +770,7 @@
       readLimiter.checkLimit(lengthBytesNeeded);
       while (lengthBytesNeeded > 0)
       {
-        readByte = streamReader.readByte();
+        readByte = buffer.get();
         peekLength = (peekLength << 8) | (readByte & 0xFF);
         lengthBytesNeeded--;
       }
@@ -795,8 +780,8 @@
     // message size.
     if ((maxElementSize > 0) && (peekLength > maxElementSize))
     {
-      LocalizableMessage m = ERR_LDAP_CLIENT_DECODE_MAX_REQUEST_SIZE_EXCEEDED.get(
-          peekLength, maxElementSize);
+      final LocalizableMessage m = ERR_LDAP_CLIENT_DECODE_MAX_REQUEST_SIZE_EXCEEDED
+          .get(peekLength, maxElementSize);
       throw DecodeException.fatalError(m);
     }
     state = ELEMENT_READ_STATE_NEED_VALUE_BYTES;
@@ -806,17 +791,16 @@
 
 
   /**
-   * Internal helper method reading the ASN.1 type byte and transition
-   * to the next state if successful.
+   * Internal helper method reading the ASN.1 type byte and transition to the
+   * next state if successful.
    *
    * @param ensureRead
    *          <code>true</code> to check for availability first.
    * @return <code>true</code> if the type byte was successfully read
    * @throws IOException
-   *           If an error occurs while trying to decode an ASN1
-   *           element.
+   *           If an error occurs while trying to decode an ASN1 element.
    */
-  private boolean needTypeState(boolean ensureRead) throws IOException
+  private boolean needTypeState(final boolean ensureRead) throws IOException
   {
     // Read just the type.
     if (ensureRead && (readLimiter.remaining() <= 0))
@@ -825,7 +809,7 @@
     }
 
     readLimiter.checkLimit(1);
-    peekType = streamReader.readByte();
+    peekType = buffer.get();
     state = ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE;
     return true;
   }

--
Gitblit v1.10.0