summaryrefslogtreecommitdiff
path: root/samples/socket/io/WrappedInputStream.java
diff options
Diffstat (limited to 'samples/socket/io/WrappedInputStream.java')
-rw-r--r--samples/socket/io/WrappedInputStream.java209
1 files changed, 209 insertions, 0 deletions
diff --git a/samples/socket/io/WrappedInputStream.java b/samples/socket/io/WrappedInputStream.java
new file mode 100644
index 0000000..f4dd7c0
--- /dev/null
+++ b/samples/socket/io/WrappedInputStream.java
@@ -0,0 +1,209 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2000 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Xerces" and "Apache Software Foundation" must
+ * not be used to endorse or promote products derived from this
+ * software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999, International
+ * Business Machines, Inc., http://www.apache.org. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package socket.io;
+
+import java.io.DataInputStream;
+import java.io.FilterInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * This input stream works in conjunction with the WrappedOutputStream
+ * to introduce a protocol for reading arbitrary length data in a
+ * uniform way.
+ * <p>
+ * <strong>Note:</strong> See the javadoc for WrappedOutputStream for
+ * more information.
+ *
+ * @see WrappedOutputStream
+ *
+ * @author Andy Clark, IBM
+ *
+ * @version $Id: WrappedInputStream.java,v 1.3 2002/04/23 10:36:57 andyc Exp $
+ */
+public class WrappedInputStream
+ extends FilterInputStream {
+
+ //
+ // Data
+ //
+
+ /** Bytes left on input stream for current packet. */
+ protected int fPacketCount;
+
+ /**
+ * Data input stream. This stream is used to input the block sizes
+ * from the data stream that are written by the WrappedOutputStream.
+ * <p>
+ * <strong>Note:</strong> The data input stream is only used for
+ * reading the byte count for performance reasons. We avoid the
+ * method indirection for reading the byte data.
+ */
+ protected DataInputStream fDataInputStream;
+
+ /** To mark that the stream is "closed". */
+ protected boolean fClosed;
+
+ //
+ // Constructors
+ //
+
+ /** Constructs a wrapper for the given an input stream. */
+ public WrappedInputStream(InputStream stream) {
+ super(stream);
+ fDataInputStream = new DataInputStream(stream);
+ } // <init>(InputStream)
+
+ //
+ // InputStream methods
+ //
+
+ /** Reads a single byte. */
+ public int read() throws IOException {
+
+ // ignore, if already closed
+ if (fClosed) {
+ return -1;
+ }
+
+ // read packet header
+ if (fPacketCount == 0) {
+ fPacketCount = fDataInputStream.readInt() & 0x7FFFFFFF;
+ if (fPacketCount == 0) {
+ fClosed = true;
+ return -1;
+ }
+ }
+
+ // read a byte from the packet
+ fPacketCount--;
+ return super.in.read();
+
+ } // read():int
+
+ /**
+ * Reads a block of bytes and returns the total number of bytes read.
+ */
+ public int read(byte[] b, int offset, int length) throws IOException {
+
+ // ignore, if already closed
+ if (fClosed) {
+ return -1;
+ }
+
+ // read packet header
+ if (fPacketCount == 0) {
+ fPacketCount = fDataInputStream.readInt() & 0x7FFFFFFF;
+ if (fPacketCount == 0) {
+ fClosed = true;
+ return -1;
+ }
+ }
+
+ // read bytes from packet
+ if (length > fPacketCount) {
+ length = fPacketCount;
+ }
+ int count = super.in.read(b, offset, length);
+ if (count == -1) {
+ // NOTE: This condition should not happen. The end of
+ // the stream should always be designated by a
+ // byte count header of 0. -Ac
+ fClosed = true;
+ return -1;
+ }
+ fPacketCount -= count;
+
+ // return total bytes read
+ return count;
+
+ } // read(byte[],int,int):int
+
+ /** Skips the specified number of bytes from the input stream. */
+ public long skip(long n) throws IOException {
+ if (!fClosed) {
+ // NOTE: This should be rewritten to be more efficient. -Ac
+ for (long i = 0; i < n; i++) {
+ int b = read();
+ if (b == -1) {
+ return i + 1;
+ }
+ }
+ return n;
+ }
+ return 0;
+ } // skip(long):long
+
+ /**
+ * Closes the input stream. This method will search for the end of
+ * the wrapped input, positioning the stream at after the end packet.
+ * <p>
+ * <strong>Note:</strong> This method does not close the underlying
+ * input stream.
+ */
+ public void close() throws IOException {
+ if (!fClosed) {
+ fClosed = true;
+ do {
+ super.in.skip(fPacketCount);
+ fPacketCount = fDataInputStream.readInt() & 0x7FFFFFFF;
+ } while (fPacketCount > 0);
+ }
+ } // close()
+
+} // class WrappedInputStream