KickJava   Java API By Example, From Geeks To Geeks.

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


1 // ========================================================================
2
// $Id: ChunkingOutputStream.java,v 1.6 2004/10/19 00:27:23 gregwilkins Exp $
3
// Copyright 1996-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
18 import java.io.IOException JavaDoc;
19 import java.io.OutputStream JavaDoc;
20
21 /* ---------------------------------------------------------------- */
22 /** HTTP Chunking OutputStream.
23  * @version $Id: ChunkingOutputStream.java,v 1.6 2004/10/19 00:27:23 gregwilkins Exp $
24  * @author Greg Wilkins
25 */

26 public class ChunkingOutputStream
27     extends BufferedOutputStream
28     implements HttpMessage.HeaderWriter
29 {
30     /* ------------------------------------------------------------ */
31     final static byte[]
32         __CRLF = {(byte)'\015',(byte)'\012'};
33     final static byte[]
34         __CHUNK_EOF ={(byte)'0',(byte)'\015',(byte)'\012',(byte)'\015',(byte)'\012'};
35
36     final static int __CHUNK_RESERVE=8;
37     final static int __EOF_RESERVE=8;
38     
39     /* ------------------------------------------------------------ */
40     private boolean _chunking;
41     private boolean _complete;
42     private boolean _completed;
43
44     /* ------------------------------------------------------------ */
45     /** Constructor.
46      * @param outputStream The outputStream to buffer or chunk to.
47      */

48     public ChunkingOutputStream(OutputStream JavaDoc outputStream,
49                                 int bufferSize,
50                                 int headerReserve)
51     {
52         this(outputStream,bufferSize,headerReserve,true);
53     }
54     /* ------------------------------------------------------------ */
55     /** Constructor.
56      * @param outputStream The outputStream to buffer or chunk to.
57      */

58     public ChunkingOutputStream(OutputStream JavaDoc outputStream,
59                                 int bufferSize,
60                                 int headerReserve,
61                                 boolean chunking)
62     {
63         super(outputStream,
64               bufferSize,
65               headerReserve,
66               __CHUNK_RESERVE,
67               __EOF_RESERVE);
68         _chunking=chunking;
69         setBypassBuffer(true);
70         setFixed(true);
71     }
72
73     /* ------------------------------------------------------------ */
74     public boolean isChunking()
75     {
76         return _chunking;
77     }
78
79     /* ------------------------------------------------------------ */
80     public void setChunking(boolean chunking)
81     {
82         _chunking=chunking;
83     }
84     
85     /* ------------------------------------------------------------ */
86     public void close()
87         throws IOException JavaDoc
88     {
89         _complete=true;
90         flush();
91     }
92
93     /* ------------------------------------------------------------ */
94     public void resetStream()
95     {
96         _complete=false;
97         _completed=false;
98         _chunking=true;
99         super.resetStream();
100     }
101     
102     /* ------------------------------------------------------------ */
103     protected void wrapBuffer()
104         throws IOException JavaDoc
105     {
106         // Handle chunking
107
int size=size();
108         if (_chunking && size()>0)
109         {
110             prewrite(__CRLF,0,__CRLF.length);
111             while (size>0)
112             {
113                 int d=size%16;
114                 if (d<=9)
115                     prewrite('0'+d);
116                 else
117                     prewrite('a'-10+d);
118                 size=size/16;
119             }
120             postwrite(__CRLF,0,__CRLF.length);
121         }
122         
123         // Complete it if we must.
124
if (_complete && !_completed)
125         {
126             _completed=true;
127             if (_chunking)
128                 postwrite(__CHUNK_EOF,0,__CHUNK_EOF.length);
129         }
130     }
131     
132     /* ------------------------------------------------------------ */
133     protected void bypassWrite(byte[] b, int offset, int length)
134         throws IOException JavaDoc
135     {
136         int i=9;
137         int chunk=length;
138         _buf[10]=(byte)'\012';
139         _buf[9]=(byte)'\015';
140         while (chunk>0)
141         {
142             int d=chunk%16;
143             if (d<=9)
144                 _buf[--i]=(byte)('0'+d);
145             else
146                 _buf[--i]=(byte)('a'-10+d);
147             chunk=chunk/16;
148         }
149         if (_chunking)
150             _out.write(_buf,i,10-i+1);
151         _out.write(b,offset,length);
152         if (_chunking)
153             _out.write(__CRLF,0,__CRLF.length);
154         _out.flush();
155     }
156     
157 }
158
159     
160
Popular Tags