KickJava   Java API By Example, From Geeks To Geeks.

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


1 // ========================================================================
2
// $Id: ChunkingInputStream.java,v 1.7 2005/08/13 00:01:24 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.InputStream JavaDoc;
20
21 import org.apache.commons.logging.Log;
22 import org.mortbay.log.LogFactory;
23 import org.mortbay.util.LineInput;
24 import org.mortbay.util.LogSupport;
25
26
27 /* ------------------------------------------------------------ */
28 /** Dechunk input.
29  * Or limit content length.
30  */

31 public class ChunkingInputStream extends InputStream JavaDoc
32 {
33     private static Log log = LogFactory.getLog(ChunkingInputStream.class);
34     private static final String JavaDoc __UNEXPECTED_EOF="Unexpected EOF while chunking";
35
36     /* ------------------------------------------------------------ */
37     int _chunkSize=0;
38     HttpFields _trailer=null;
39     LineInput _in;
40     
41     /* ------------------------------------------------------------ */
42     /** Constructor.
43      */

44     public ChunkingInputStream(LineInput in)
45     {
46         _in=in;
47     }
48     
49     /* ------------------------------------------------------------ */
50     public void resetStream()
51     {
52         _chunkSize=0;
53         _trailer=null;
54     }
55     
56     /* ------------------------------------------------------------ */
57     public int read()
58         throws IOException JavaDoc
59     {
60         int b=-1;
61         if (_chunkSize<=0 && getChunkSize()<=0)
62             return -1;
63         b=_in.read();
64         if (b<0)
65         {
66             _chunkSize=-1;
67             throw new IOException JavaDoc(__UNEXPECTED_EOF);
68         }
69         _chunkSize--;
70         return b;
71     }
72     
73     /* ------------------------------------------------------------ */
74     public int read(byte b[]) throws IOException JavaDoc
75     {
76         int len = b.length;
77         if (_chunkSize<=0 && getChunkSize()<=0)
78             return -1;
79         if (len > _chunkSize)
80             len=_chunkSize;
81         len=_in.read(b,0,len);
82         if (len<0)
83         {
84             _chunkSize=-1;
85             throw new IOException JavaDoc(__UNEXPECTED_EOF);
86         }
87         _chunkSize=_chunkSize-len;
88         return len;
89     }
90     
91     /* ------------------------------------------------------------ */
92     public int read(byte b[], int off, int len) throws IOException JavaDoc
93     {
94         if (_chunkSize<=0 && getChunkSize()<=0)
95             return -1;
96         if (len > _chunkSize)
97             len=_chunkSize;
98         len=_in.read(b,off,len);
99         if (len<0)
100         {
101             _chunkSize=-1;
102             throw new IOException JavaDoc(__UNEXPECTED_EOF);
103         }
104         _chunkSize=_chunkSize-len;
105         return len;
106     }
107     
108     /* ------------------------------------------------------------ */
109     public long skip(long len) throws IOException JavaDoc
110     {
111         if (_chunkSize<=0 && getChunkSize()<=0)
112                 return -1;
113         if (len > _chunkSize)
114             len=_chunkSize;
115         len=_in.skip(len);
116         if (len<0)
117         {
118             _chunkSize=-1;
119             throw new IOException JavaDoc(__UNEXPECTED_EOF);
120         }
121         _chunkSize=_chunkSize-(int)len;
122         return len;
123     }
124     
125     /* ------------------------------------------------------------ */
126     public int available()
127         throws IOException JavaDoc
128     {
129         int len = _in.available();
130         if (len<=_chunkSize || _chunkSize==0)
131             return len;
132         return _chunkSize;
133     }
134     
135     /* ------------------------------------------------------------ */
136     public void close()
137         throws IOException JavaDoc
138     {
139         _chunkSize=-1;
140     }
141     
142     /* ------------------------------------------------------------ */
143     /** Mark is not supported.
144      * @return false
145      */

146     public boolean markSupported()
147     {
148         return false;
149     }
150     
151     /* ------------------------------------------------------------ */
152     /** Not Implemented.
153      */

154     public void reset()
155     {
156         log.warn(LogSupport.NOT_IMPLEMENTED);
157     }
158     
159     /* ------------------------------------------------------------ */
160     /** Not Implemented.
161      * @param readlimit
162      */

163     public void mark(int readlimit)
164     {
165         log.warn(LogSupport.NOT_IMPLEMENTED);
166     }
167     
168     /* ------------------------------------------------------------ */
169     /* Get the size of the next chunk.
170      * @return size of the next chunk or -1 for EOF.
171      * @exception IOException
172      */

173     private int getChunkSize()
174         throws IOException JavaDoc
175     {
176         if (_chunkSize<0)
177             return -1;
178         
179         _trailer=null;
180         _chunkSize=-1;
181         
182         // Get next non blank line
183
org.mortbay.util.LineInput.LineBuffer line_buffer
184             =_in.readLineBuffer();
185         while(line_buffer!=null && line_buffer.size==0)
186             line_buffer=_in.readLineBuffer();
187         
188         // Handle early EOF or error in format
189
if (line_buffer==null)
190             throw new IOException JavaDoc("Unexpected EOF");
191         
192         String JavaDoc line= new String JavaDoc(line_buffer.buffer,0,line_buffer.size);
193         
194         
195         // Get chunksize
196
int i=line.indexOf(';');
197         if (i>0)
198             line=line.substring(0,i).trim();
199         try
200         {
201             _chunkSize = Integer.parseInt(line,16);
202         }
203         catch (NumberFormatException JavaDoc e)
204         {
205             _chunkSize=-1;
206             log.warn("Bad Chunk:"+line);
207             log.debug(LogSupport.EXCEPTION,e);
208             throw new IOException JavaDoc("Bad chunk size");
209         }
210                  
211         // check for EOF
212
if (_chunkSize==0)
213         {
214             _chunkSize=-1;
215             // Look for trailers
216
_trailer = new HttpFields();
217             _trailer.read(_in);
218         }
219         
220         return _chunkSize;
221     }
222 }
223
Popular Tags