From 22094368c2865dcfb6daf8366425212b721a4657 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Thu, 05 Feb 2009 17:42:14 +0000
Subject: [PATCH] Merge ASN1 branch to trunk
---
opends/src/server/org/opends/server/protocols/asn1/ASN1Reader.java | 380 ++++++++++++++++++++---------------------------------
1 files changed, 145 insertions(+), 235 deletions(-)
diff --git a/opends/src/server/org/opends/server/protocols/asn1/ASN1Reader.java b/opends/src/server/org/opends/server/protocols/asn1/ASN1Reader.java
index 512dfd2..b67a5f5 100644
--- a/opends/src/server/org/opends/server/protocols/asn1/ASN1Reader.java
+++ b/opends/src/server/org/opends/server/protocols/asn1/ASN1Reader.java
@@ -25,299 +25,209 @@
* Copyright 2006-2008 Sun Microsystems, Inc.
*/
package org.opends.server.protocols.asn1;
-import org.opends.messages.Message;
-import java.io.InputStream;
+import java.io.Closeable;
import java.io.IOException;
-import java.net.Socket;
-import static org.opends.server.loggers.debug.DebugLogger.*;
-import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.types.DebugLogLevel;
-import static org.opends.messages.ProtocolMessages.*;
-
+import org.opends.server.types.ByteString;
+import org.opends.server.types.ByteStringBuilder;
/**
- * This class defines a utility that can be used to read ASN.1 elements from a
- * provided socket or input stream.
+ * An interface for decoding ASN.1 elements from a data source.
+ * <p>
+ * Methods for creating {@link ASN1Reader}s are provided in the
+ * {@link ASN1} class.
*/
-@org.opends.server.types.PublicAPI(
- stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
- mayInstantiate=true,
- mayExtend=false,
- mayInvoke=true)
-public final class ASN1Reader
+public interface ASN1Reader extends Closeable
{
+
/**
- * The tracer object for the debug logger.
+ * Closes this ASN.1 reader.
+ *
+ * @throws IOException if an I/O error occurs
*/
- private static final DebugTracer TRACER = getTracer();
-
-
-
-
- // The input stream from which to read the ASN.1 elements.
- private InputStream inputStream;
-
- // The largest element size (in bytes) that will be allowed.
- private int maxElementSize;
-
- // The socket with which the input stream is associated.
- private Socket socket;
+ void close() throws IOException;
/**
- * Creates a new ASN.1 reader that will read elements from the provided
- * socket.
+ * Determines if a complete ASN.1 element is waiting to be read.
*
- * @param socket The socket from which to read the ASN.1 elements.
- *
- * @throws IOException If a problem occurs while attempting to obtain the
- * input stream for the socket.
+ * @return <code>true</code> if another complete element is available or
+ * <code>false</code> otherwise.
+ * @throws ASN1Exception If an error occurs while trying to decode
+ * an ASN1 element.
*/
- public ASN1Reader(Socket socket)
- throws IOException
- {
- this.socket = socket;
- inputStream = socket.getInputStream();
-
- maxElementSize = -1;
- }
+ public boolean elementAvailable() throws ASN1Exception;
/**
- * Creates a new ASN.1 reader that will read elements from the provided input
- * stream.
+ * Determines if at least one ASN.1 element is waiting to be read.
*
- * @param inputStream The input stream from which to read the ASN.1
- * elements.
+ * @return <code>true</code> if another element is available or
+ * <code>false</code> if the EOF is reached.
+ * @throws ASN1Exception
+ * If an error occurs while trying to decode an ASN1
+ * element.
*/
- public ASN1Reader(InputStream inputStream)
- {
- this.inputStream = inputStream;
- socket = null;
- maxElementSize = -1;
- }
+ boolean hasNextElement() throws ASN1Exception;
/**
- * Retrieves the maximum size in bytes that will be allowed for elements read
- * using this reader. A negative value indicates that no limit should be
- * enforced.
+ * Gets the data length of the next element without actually reading
+ * the element and advancing the cursor.
*
- * @return The maximum size in bytes that will be allowed for elements.
+ * @return The data length of the next element or -1 if the EOF is
+ * encountered.
+ * @throws ASN1Exception
+ * If an error occurs while determining the length.
*/
- public int getMaxElementSize()
- {
- return maxElementSize;
- }
+ int peekLength() throws ASN1Exception;
/**
- * Specifies the maximum size in bytes that will be allowed for elements. A
- * negative value indicates that no limit should be enforced.
+ * Gets the BER type of the next element without actually reading
+ * the element and advancing the cursor.
*
- * @param maxElementSize The maximum size in bytes that will be allowed for
- * elements read using this reader.
+ * @return The BER type of the next element or -1 if the EOF is
+ * encountered.
+ * @throws ASN1Exception
+ * If an error occurs while determining the BER type.
*/
- public void setMaxElementSize(int maxElementSize)
- {
- this.maxElementSize = maxElementSize;
- }
+ byte peekType() throws ASN1Exception;
/**
- * Retrieves the maximum length of time in milliseconds that this reader will
- * be allowed to block while waiting to read data. This is only applicable
- * for readers created with sockets rather than input streams.
+ * Reads the next ASN.1 element as a boolean and advance the cursor.
*
- * @return The maximum length of time in milliseconds that this reader will
- * be allowed to block while waiting to read data, or 0 if there is
- * no limit, or -1 if this ASN.1 reader is not associated with a
- * socket and no timeout can be enforced.
- *
- * @throws IOException If a problem occurs while polling the socket to
- * determine the timeout.
+ * @return The decoded boolean value.
+ * @throws ASN1Exception
+ * If the element cannot be decoded as a boolean.
*/
- public int getIOTimeout()
- throws IOException
- {
- if (socket == null)
- {
- return -1;
- }
- else
- {
- return socket.getSoTimeout();
- }
- }
+ boolean readBoolean() throws ASN1Exception;
/**
- * Specifies the maximum length of time in milliseconds that this reader
- * should be allowed to block while waiting to read data. This will only be
- * applicable for readers created with sockets and will have no effect on
- * readers created with input streams.
+ * Finishes reading a sequence. Any elements not read in the
+ * sequence will be discarded.
*
- * @param ioTimeout The maximum length of time in milliseconds that this
- * reader should be allowed to block while waiting to read
- * data, or 0 if there should be no limit.
- *
- * @throws IOException If a problem occurs while setting the underlying
- * socket option.
+ * @throws ASN1Exception
+ * If an error occurs while advancing to the end of the
+ * sequence.
*/
- public void setIOTimeout(int ioTimeout)
- throws IOException
- {
- if (socket == null)
- {
- return;
- }
-
- socket.setSoTimeout(Math.max(0, ioTimeout));
- }
+ void readEndSequence() throws ASN1Exception;
/**
- * Reads an ASN.1 element from the associated input stream.
+ * Reads the next ASN.1 element as an integer and advances the
+ * cursor.
*
- * @return The ASN.1 element read from the associated input stream, or
- * <CODE>null</CODE> if the end of the stream has been reached.
- *
- * @throws IOException If a problem occurs while attempting to read from the
- * input stream.
- *
- * @throws ASN1Exception If a problem occurs while attempting to decode the
- * data read as an ASN.1 element.
+ * @return The decoded integer value.
+ * @throws ASN1Exception
+ * If the element cannot be decoded as a integer.
*/
- public ASN1Element readElement()
- throws IOException, ASN1Exception
- {
- // First, read the BER type, which should be the first byte.
- int typeValue = inputStream.read();
- if (typeValue < 0)
- {
- return null;
- }
-
- byte type = (byte) (typeValue & 0xFF);
-
-
-
- // Next, read the first byte of the length, and see if we need to read more.
- int length = inputStream.read();
- int numLengthBytes = (length & 0x7F);
- if (length != numLengthBytes)
- {
- // Make sure that there are an acceptable number of bytes in the length.
- if (numLengthBytes > 4)
- {
- Message message =
- ERR_ASN1_ELEMENT_SET_INVALID_NUM_LENGTH_BYTES.get(numLengthBytes);
- throw new ASN1Exception(message);
- }
-
-
- length = 0;
- for (int i=0; i < numLengthBytes; i++)
- {
- int lengthByte = inputStream.read();
- if (lengthByte < 0)
- {
- // We've reached the end of the stream in the middle of the value.
- // This is not good, so throw an exception.
- Message message =
- ERR_ASN1_ELEMENT_SET_TRUNCATED_LENGTH.get(numLengthBytes);
- throw new IOException(message.toString());
- }
-
- length = (length << 8) | lengthByte;
- }
- }
-
-
- // See how many bytes there are in the value. If there are none, then just
- // create an empty element with only a type. If the length is larger than
- // the maximum allowed, then fail.
- if (length == 0)
- {
- return new ASN1Element(type);
- }
- else if ((maxElementSize > 0) && (length > maxElementSize))
- {
- Message message =
- ERR_ASN1_READER_MAX_SIZE_EXCEEDED.get(length, maxElementSize);
- throw new ASN1Exception(message);
- }
-
-
- // There is a value for the element, so create an array to hold it and read
- // it from the stream.
- byte[] value = new byte[length];
- int readPos = 0;
- int bytesNeeded = length;
- while (bytesNeeded > 0)
- {
- int bytesRead = inputStream.read(value, readPos, bytesNeeded);
- if (bytesRead < 0)
- {
- Message message =
- ERR_ASN1_ELEMENT_SET_TRUNCATED_VALUE.get(length, bytesNeeded);
- throw new IOException(message.toString());
- }
-
- bytesNeeded -= bytesRead;
- readPos += bytesRead;
- }
-
-
- // Return the constructed element.
- return new ASN1Element(type, value);
- }
+ long readInteger() throws ASN1Exception;
/**
- * Closes this ASN.1 reader and the underlying input stream and/or socket.
+ * Reads the next ASN.1 element as a null element and advances the
+ * cursor.
+ *
+ * @throws ASN1Exception
+ * If the element cannot be decoded as an null element.
*/
- public void close()
- {
- try
- {
- inputStream.close();
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
- }
+ void readNull() throws ASN1Exception;
- if (socket != null)
- {
- try
- {
- socket.close();
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
- }
- }
- }
+
+
+ /**
+ * Reads the next ASN.1 element as an octet string and advances the
+ * cursor.
+ *
+ * @return The decoded octet string value represented using a
+ * {@link ByteString}.
+ * @throws ASN1Exception
+ * If the element cannot be decoded as an octet string.
+ */
+ ByteString readOctetString() throws ASN1Exception;
+
+
+
+ /**
+ * Reads the next ASN.1 element as an octet string and advances the
+ * cursor. The data will be appended to the provided
+ * {@link ByteStringBuilder}.
+ *
+ * @param buffer
+ * The {@link ByteStringBuilder} to append the data to.
+ * @throws ASN1Exception
+ * If the element cannot be decoded as an octet string.
+ */
+ void readOctetString(ByteStringBuilder buffer) throws ASN1Exception;
+
+
+
+ /**
+ * Reads the next ASN.1 element as an octet string and advances the
+ * cursor. The data will be decoded to a UTF-8 string. This method
+ * is equivalent to:
+ *
+ * <pre>
+ * readOctetStringAsString("UTF-8");
+ * </pre>
+ *
+ * @return The string representation of the octet string data.
+ * @throws ASN1Exception
+ * If the element cannot be decoded as an octet string.
+ */
+ String readOctetStringAsString() throws ASN1Exception;
+
+
+
+ /**
+ * Reads the next ASN.1 element as an octet string and advances the
+ * cursor. The data will be decoded to a string using the provided
+ * character set.
+ *
+ * @param charSet
+ * The character set to use in order to decode the data
+ * into a string.
+ * @return The string representation of the octet string data.
+ * @throws ASN1Exception
+ * If the element cannot be decoded as an octet string.
+ */
+ String readOctetStringAsString(String charSet) throws ASN1Exception;
+
+
+
+ /**
+ * Reads the next ASN.1 element as a sequence. All further reads
+ * will read the elements in the sequence until
+ * {@link #readEndSequence()} is called.
+ *
+ * @throws ASN1Exception
+ * If the next element is not a sequence.
+ */
+ void readStartSequence() throws ASN1Exception;
+
+
+
+ /**
+ * Advances this ASN.1 reader beyond the next ASN.1 element without
+ * decoding it.
+ *
+ * @throws ASN1Exception
+ * If the next ASN.1 element could not be skipped.
+ */
+ void skipElement() throws ASN1Exception;
}
-
--
Gitblit v1.10.0