KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > socket > io > WrappedOutputStream


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.DataOutputStream JavaDoc;
20 import java.io.FilterOutputStream JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.OutputStream JavaDoc;
23
24 /**
25  * This output stream works in conjunction with the WrappedInputStream
26  * to introduce a protocol for sending arbitrary length data in a
27  * uniform way. This output stream allows variable length data to be
28  * inserted into an existing output stream so that it can be read by
29  * an input stream without reading too many bytes (in case of buffering
30  * by the input stream).
31  * <p>
32  * This output stream is used like any normal output stream. The protocol
33  * is introduced by the WrappedOutputStream and does not need to be known
34  * by the user of this class. However, for those that are interested, the
35  * method is described below.
36  * <p>
37  * The output stream writes the requested bytes as packets of binary
38  * information. The packet consists of a header and payload. The header
39  * is two bytes of a single unsigned short (written in network order)
40  * that specifies the length of bytes in the payload. A header value of
41  * 0 indicates that the stream is "closed".
42  * <p>
43  * <strong>Note:</strong> For this wrapped output stream to be used,
44  * the application <strong>must</strong> call <code>close()</code>
45  * to end the output.
46  *
47  * @see WrappedInputStream
48  *
49  * @author Andy Clark, IBM
50  *
51  * @version $Id: WrappedOutputStream.java,v 1.5 2004/02/24 23:41:06 mrglavas Exp $
52  */

53 public class WrappedOutputStream
54     extends FilterOutputStream JavaDoc {
55
56     //
57
// Constants
58
//
59

60     /** Default buffer size (1024). */
61     public static final int DEFAULT_BUFFER_SIZE = 1024;
62
63     //
64
// Data
65
//
66

67     /** Buffer. */
68     protected byte[] fBuffer;
69
70     /** Buffer position. */
71     protected int fPosition;
72
73     /**
74      * Data output stream. This stream is used to output the block sizes
75      * into the data stream that are read by the WrappedInputStream.
76      * <p>
77      * <strong>Note:</strong> The data output stream is only used for
78      * writing the byte count for performance reasons. We avoid the
79      * method indirection for writing the byte data.
80      */

81     protected DataOutputStream JavaDoc fDataOutputStream;
82
83     //
84
// Constructors
85
//
86

87     /** Constructs a wrapper for the given output stream. */
88     public WrappedOutputStream(OutputStream JavaDoc stream) {
89         this(stream, DEFAULT_BUFFER_SIZE);
90     } // <init>(OutputStream)
91

92     /**
93      * Constructs a wrapper for the given output stream with the
94      * given buffer size.
95      */

96     public WrappedOutputStream(OutputStream JavaDoc stream, int bufferSize) {
97         super(stream);
98         fBuffer = new byte[bufferSize];
99         fDataOutputStream = new DataOutputStream JavaDoc(stream);
100     } // <init>(OutputStream)
101

102     //
103
// OutputStream methods
104
//
105

106     /**
107      * Writes a single byte to the output.
108      * <p>
109      * <strong>Note:</strong> Single bytes written to the output stream
110      * will be buffered
111      */

112     public void write(int b) throws IOException JavaDoc {
113         fBuffer[fPosition++] = (byte)b;
114         if (fPosition == fBuffer.length) {
115             fPosition = 0;
116             fDataOutputStream.writeInt(fBuffer.length);
117             super.out.write(fBuffer, 0, fBuffer.length);
118         }
119     } // write(int)
120

121     /** Writes an array of bytes to the output. */
122     public void write(byte[] b, int offset, int length)
123         throws IOException JavaDoc {
124
125         // flush existing buffer
126
if (fPosition > 0) {
127             flush0();
128         }
129
130         // write header followed by actual bytes
131
fDataOutputStream.writeInt(length);
132         super.out.write(b, offset, length);
133
134     } // write(byte[])
135

136     /**
137      * Flushes the output buffer, writing all bytes currently in
138      * the buffer to the output.
139      */

140     public void flush() throws IOException JavaDoc {
141         flush0();
142         super.out.flush();
143     } // flush()
144

145     /**
146      * Closes the output stream. This method <strong>must</strong> be
147      * called when done writing all data to the output stream.
148      * <p>
149      * <strong>Note:</strong> This method does <em>not</em> close the
150      * actual output stream, only makes the input stream see the stream
151      * closed. Do not write bytes after closing the output stream.
152      */

153     public void close() throws IOException JavaDoc {
154         flush0();
155         fDataOutputStream.writeInt(0);
156         super.out.flush();
157     } // close()
158

159     //
160
// Protected methods
161
//
162

163     /**
164      * Flushes the output buffer, writing all bytes currently in
165      * the buffer to the output. This method does not call the
166      * flush() method of the output stream; it merely writes the
167      * remaining bytes in the buffer.
168      */

169     public void flush0() throws IOException JavaDoc {
170         int length = fPosition;
171         fPosition = 0;
172         if (length > 0) {
173             fDataOutputStream.writeInt(length);
174             super.out.write(fBuffer, 0, length);
175         }
176     } // flush0()
177

178 } // class WrappedOutputStream
179
Popular Tags