KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > socket > io > WrappedInputStream


1 /*
2  * Copyright 2000,2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package socket.io;
18
19 import java.io.DataInputStream JavaDoc;
20 import java.io.FilterInputStream JavaDoc;
21 import java.io.InputStream JavaDoc;
22 import java.io.IOException JavaDoc;
23
24 /**
25  * This input stream works in conjunction with the WrappedOutputStream
26  * to introduce a protocol for reading arbitrary length data in a
27  * uniform way.
28  * <p>
29  * <strong>Note:</strong> See the javadoc for WrappedOutputStream for
30  * more information.
31  *
32  * @see WrappedOutputStream
33  *
34  * @author Andy Clark, IBM
35  *
36  * @version $Id: WrappedInputStream.java,v 1.4 2004/02/24 23:41:06 mrglavas Exp $
37  */

38 public class WrappedInputStream
39     extends FilterInputStream JavaDoc {
40
41     //
42
// Data
43
//
44

45     /** Bytes left on input stream for current packet. */
46     protected int fPacketCount;
47
48     /**
49      * Data input stream. This stream is used to input the block sizes
50      * from the data stream that are written by the WrappedOutputStream.
51      * <p>
52      * <strong>Note:</strong> The data input stream is only used for
53      * reading the byte count for performance reasons. We avoid the
54      * method indirection for reading the byte data.
55      */

56     protected DataInputStream JavaDoc fDataInputStream;
57
58     /** To mark that the stream is "closed". */
59     protected boolean fClosed;
60
61     //
62
// Constructors
63
//
64

65     /** Constructs a wrapper for the given an input stream. */
66     public WrappedInputStream(InputStream JavaDoc stream) {
67         super(stream);
68         fDataInputStream = new DataInputStream JavaDoc(stream);
69     } // <init>(InputStream)
70

71     //
72
// InputStream methods
73
//
74

75     /** Reads a single byte. */
76     public int read() throws IOException JavaDoc {
77
78         // ignore, if already closed
79
if (fClosed) {
80             return -1;
81         }
82
83         // read packet header
84
if (fPacketCount == 0) {
85             fPacketCount = fDataInputStream.readInt() & 0x7FFFFFFF;
86             if (fPacketCount == 0) {
87                 fClosed = true;
88                 return -1;
89             }
90         }
91
92         // read a byte from the packet
93
fPacketCount--;
94         return super.in.read();
95
96     } // read():int
97

98     /**
99      * Reads a block of bytes and returns the total number of bytes read.
100      */

101     public int read(byte[] b, int offset, int length) throws IOException JavaDoc {
102
103         // ignore, if already closed
104
if (fClosed) {
105             return -1;
106         }
107
108         // read packet header
109
if (fPacketCount == 0) {
110             fPacketCount = fDataInputStream.readInt() & 0x7FFFFFFF;
111             if (fPacketCount == 0) {
112                 fClosed = true;
113                 return -1;
114             }
115         }
116
117         // read bytes from packet
118
if (length > fPacketCount) {
119             length = fPacketCount;
120         }
121         int count = super.in.read(b, offset, length);
122         if (count == -1) {
123             // NOTE: This condition should not happen. The end of
124
// the stream should always be designated by a
125
// byte count header of 0. -Ac
126
fClosed = true;
127             return -1;
128         }
129         fPacketCount -= count;
130
131         // return total bytes read
132
return count;
133
134     } // read(byte[],int,int):int
135

136     /** Skips the specified number of bytes from the input stream. */
137     public long skip(long n) throws IOException JavaDoc {
138         if (!fClosed) {
139             // NOTE: This should be rewritten to be more efficient. -Ac
140
for (long i = 0; i < n; i++) {
141                 int b = read();
142                 if (b == -1) {
143                     return i + 1;
144                 }
145             }
146             return n;
147         }
148         return 0;
149     } // skip(long):long
150

151     /**
152      * Closes the input stream. This method will search for the end of
153      * the wrapped input, positioning the stream at after the end packet.
154      * <p>
155      * <strong>Note:</strong> This method does not close the underlying
156      * input stream.
157      */

158     public void close() throws IOException JavaDoc {
159         if (!fClosed) {
160             fClosed = true;
161             do {
162                 super.in.skip(fPacketCount);
163                 fPacketCount = fDataInputStream.readInt() & 0x7FFFFFFF;
164             } while (fPacketCount > 0);
165         }
166     } // close()
167

168 } // class WrappedInputStream
169
Popular Tags