KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mortbay > http > BufferedOutputStream


1 // ========================================================================
2
// $Id: BufferedOutputStream.java,v 1.8 2006/06/29 12:41:11 gregwilkins Exp $
3
// Copyright 2001-2004 Mort Bay Consulting Pty. Ltd.
4
// ------------------------------------------------------------------------
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
// ========================================================================
15

16 package org.mortbay.http;
17 import java.io.IOException JavaDoc;
18 import java.io.OutputStream JavaDoc;
19 import java.net.SocketException JavaDoc;
20
21 import org.mortbay.util.ByteArrayISO8859Writer;
22 import org.mortbay.util.ByteBufferOutputStream;
23 import org.mortbay.util.OutputObserver;
24
25 /* ------------------------------------------------------------ */
26 /** Buffered Output Stream.
27  * Uses ByteBufferOutputStream to allow pre and post writes.
28  * @version $Revision: 1.8 $
29  * @author Greg Wilkins (gregw)
30  */

31 public class BufferedOutputStream
32     extends ByteBufferOutputStream
33     implements HttpMessage.HeaderWriter
34 {
35     protected OutputStream JavaDoc _out;
36     protected ByteArrayISO8859Writer _httpMessageWriter;
37     private OutputObserver _commitObserver;
38     private boolean _commited ;
39     private int _preReserve;
40     private boolean _bypassBuffer ;
41
42     /* ------------------------------------------------------------ */
43     /** Constructor.
44      * @param out the OutputStream to buffer to.
45      * @param capacity Buffer capacity.
46      * @param headerReserve The reserve of bytes for prepending to be used
47      * for the first buffer after reset
48      * @param preReserve The reserve of bytes for prepending
49      * @param postReserve The reserve of bytes for appending
50      */

51     public BufferedOutputStream(OutputStream JavaDoc out,
52                                 int capacity,
53                                 int headerReserve,
54                                 int preReserve,
55                                 int postReserve)
56     {
57         super(capacity,headerReserve,postReserve);
58         _out=out;
59         _preReserve=preReserve;
60         _httpMessageWriter = new ByteArrayISO8859Writer(headerReserve);
61     }
62     
63     /* ------------------------------------------------------------ */
64     public OutputStream JavaDoc getOutputStream()
65     {
66         return _out;
67     }
68     
69     /* ------------------------------------------------------------ */
70     /**
71      * @return OutputObserver to receives commit events from this stream.
72      */

73     public OutputObserver getCommitObserver()
74     {
75         return _commitObserver;
76     }
77     
78     /* ------------------------------------------------------------ */
79     /**
80      * @param commitObserver OutputObserver to receives commit events from this stream.
81      */

82     public void setCommitObserver(OutputObserver commitObserver)
83     {
84         _commitObserver = commitObserver;
85     }
86     
87     /* ------------------------------------------------------------ */
88     public boolean isCommitted()
89     {
90         return _commited;
91     }
92     
93     /* ------------------------------------------------------------ */
94     /**
95      * @return If true, the buffer is bypassed for large writes
96      * to a committed stream.
97      */

98     public boolean getBypassBuffer()
99     {
100         return _bypassBuffer;
101     }
102     
103     /* ------------------------------------------------------------ */
104     /**
105      * @param bypassBuffer If true, the buffer is bypassed for large writes
106      * to a committed stream.
107      */

108     public void setBypassBuffer(boolean bypassBuffer)
109     {
110         _bypassBuffer = bypassBuffer;
111     }
112     
113     /* ------------------------------------------------------------ */
114     public void writeHeader(HttpMessage httpMessage)
115         throws IOException JavaDoc
116     {
117         httpMessage.writeHeader(_httpMessageWriter);
118         if (_httpMessageWriter.size()>capacity())
119             throw new IllegalStateException JavaDoc("Header too large");
120     }
121     
122     /* ------------------------------------------------------------ */
123     public void write(byte[] b)
124         throws IOException JavaDoc
125     {
126         write(b,0,b.length);
127     }
128     
129     /* ------------------------------------------------------------ */
130     public void write(byte[] b, int offset, int length)
131         throws IOException JavaDoc
132     {
133         int o=offset;
134         int l=length;
135         while (l>0)
136         {
137             int c=capacity();
138             
139             if (_bypassBuffer && isCommitted() && size()==0 && l>c)
140             {
141                 // Bypass buffer
142
bypassWrite(b,o,l);
143                 break;
144             }
145
146             if (l<c || !isFixed())
147             {
148                 // Write all
149
super.write(b,o,l);
150                 break;
151             }
152             else
153             {
154                 // Write a block
155
super.write(b,o,c);
156                 flush();
157                 l-=c;
158                 o+=c;
159             }
160         }
161     }
162
163     /* ------------------------------------------------------------ */
164     protected void bypassWrite(byte[] b, int offset, int length)
165         throws IOException JavaDoc
166     {
167         try
168         {
169             _out.write(b,offset,length);
170             _out.flush();
171         }
172         catch (IOException JavaDoc e)
173         {
174             throw new EOFException(e);
175         }
176     }
177     
178     /* ------------------------------------------------------------ */
179     /**
180      * This implementation calls the commitObserver on the first flush since
181      * construction or reset.
182      */

183     public void flush()
184         throws IOException JavaDoc
185     {
186         try
187         {
188             if (!_commited)
189             {
190                 _commited=true;
191                 if (_commitObserver!=null)
192                     _commitObserver.outputNotify(this,OutputObserver.__COMMITING,null);
193             }
194             
195             wrapBuffer();
196             
197             // Add headers
198
if (_httpMessageWriter.size()>0)
199             {
200                 prewrite(_httpMessageWriter.getBuf(),0,_httpMessageWriter.size());
201                 _httpMessageWriter.resetWriter();
202             }
203             
204             if (size()>0)
205                 writeTo(_out);
206         }
207         catch (IOException JavaDoc e)
208         {
209             throw new EOFException(e);
210         }
211         finally
212         {
213             reset(_preReserve);
214         }
215     }
216     
217     
218     /* ------------------------------------------------------------ */
219     /** Wrap Buffer.
220      * Called by flush() to allow the data in the buffer to be pre and post
221      * written for any protocol wrapping. The default implementation does
222      * nothing.
223      * @exception IOException
224      */

225     protected void wrapBuffer()
226         throws IOException JavaDoc
227     {
228     }
229     
230     /* ------------------------------------------------------------ */
231     public void close()
232         throws IOException JavaDoc
233     {
234         flush();
235         _out.close();
236     }
237     
238     /* ------------------------------------------------------------ */
239     public void resetStream()
240     {
241         super.reset(_httpMessageWriter.capacity());
242         _commited=false;
243     }
244     
245     /* ------------------------------------------------------------ */
246     public void destroy()
247     {
248         super.destroy();
249         if (_httpMessageWriter!=null)
250             _httpMessageWriter.destroy();
251         _httpMessageWriter=null;
252         _out=null;
253     }
254     
255 }
256
Popular Tags