KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > axis > transport > http > ChunkedInputStream


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Axis" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation. For more
52  * information on the Apache Software Foundation, please see
53  * <http://www.apache.org/>.
54  */

55 package org.jboss.axis.transport.http;
56
57
58 import java.io.IOException JavaDoc;
59 import java.io.InputStream JavaDoc;
60
61
62 /**
63  * @author Rick Rineholt
64  */

65
66 public class ChunkedInputStream extends java.io.FilterInputStream JavaDoc
67 {
68    protected long chunkSize = 0l;
69    protected volatile boolean closed = false;
70    private static final int maxCharLong = (Long.toHexString(Long.MAX_VALUE))
71            .toString().length();
72
73    private ChunkedInputStream()
74    {
75       super(null);
76    }
77
78    public ChunkedInputStream(InputStream JavaDoc is)
79    {
80       super(is);
81    }
82
83    public int read()
84            throws IOException JavaDoc
85    {
86       byte[] d = new byte[1];
87       int rc = read(d, 0, 1);
88
89       return rc > 0 ? (d[0] & 0xFF) : rc;
90    }
91
92    public int read(byte[] b)
93            throws IOException JavaDoc
94    {
95       return read(b, 0, b.length);
96    }
97
98    public synchronized int read(byte[] b,
99                                 int off,
100                                 int len)
101            throws IOException JavaDoc
102    {
103       if (closed) return -1;
104       int cs = (int)Math.min(Integer.MAX_VALUE, chunkSize);
105       int totalread = 0;
106       int bytesread = 0;
107
108       try
109       {
110          do
111          {
112             if (chunkSize < 1L)
113             {
114                if (0l == getChunked())
115                {
116                   if (totalread == 0)
117                      return -1;
118                   else
119                      return totalread;
120                }
121             }
122             bytesread = in.read(b, off + totalread, Math.min(len - totalread,
123                     (int)Math.min(chunkSize, Integer.MAX_VALUE)));
124             if (bytesread > 0)
125             {
126                totalread += bytesread;
127                chunkSize -= bytesread;
128             }
129          }
130          while (len - totalread > 0 && bytesread > -1);
131       }
132       catch (IOException JavaDoc e)
133       {
134          closed = true;
135          throw e;
136       }
137       return totalread;
138    }
139
140    public long skip(final long n)
141            throws IOException JavaDoc
142    {
143       if (closed) return 0;
144       long skipped = 0l;
145       byte[] b = new byte[1024];
146       int bread = -1;
147
148       do
149       {
150          bread = read(b, 0, b.length);
151          if (bread > 0) skipped += bread;
152       }
153       while (bread != -1 && skipped < n);
154       return skipped;
155    }
156
157    public int available()
158            throws IOException JavaDoc
159    {
160       if (closed) return 0;
161       int rc = (int)Math.min(chunkSize, Integer.MAX_VALUE);
162
163       return Math.min(rc, in.available());
164    }
165
166    protected long getChunked() throws IOException JavaDoc
167    {
168       //StringBuffer buf= new StringBuffer(1024);
169
byte[] buf = new byte[maxCharLong + 2];
170       int bufsz = 0;
171
172       chunkSize = -1L;
173       int c = -1;
174
175       do
176       {
177          c = in.read();
178          if (c > -1)
179          {
180             if (c != '\r' && c != '\n' && c != ' ' && c != '\t')
181             {
182                buf[bufsz++] = ((byte)c);
183             }
184          }
185       }
186       while (c > -1 && (c != '\n' || bufsz == 0) && bufsz < buf.length);
187       if (c < 0)
188       {
189          closed = true;
190       }
191       String JavaDoc sbuf = new String JavaDoc(buf, 0, bufsz);
192
193       if (bufsz > maxCharLong)
194       {
195          closed = true;
196          throw new IOException JavaDoc("Chunked input stream failed to receive valid chunk size:" + sbuf);
197       }
198       try
199       {
200          chunkSize = Long.parseLong(sbuf, 16);
201       }
202       catch (NumberFormatException JavaDoc ne)
203       {
204          closed = true;
205          throw new IOException JavaDoc("'" + sbuf + "' " + ne.getMessage());
206       }
207       if (chunkSize < 1L) closed = true;
208       if (chunkSize != 0L && c < 0)
209       {
210          //If chunk size is zero try and be tolerant that there maybe no cr or lf at the end.
211
throw new IOException JavaDoc("HTTP Chunked stream closed in middle of chunk.");
212       }
213       if (chunkSize < 0L)
214          throw new IOException JavaDoc("HTTP Chunk size received " +
215                  chunkSize + " is less than zero.");
216       return chunkSize;
217    }
218
219    public void close() throws IOException JavaDoc
220    {
221
222       synchronized (this)
223       {
224          if (closed) return;
225          closed = true;
226       }
227
228       byte[] b = new byte[1024];
229       int bread = -1;
230
231       do
232       {
233          bread = read(b, 0, b.length);
234       }
235       while (bread != -1);
236    }
237
238    /*
239     public void mark(int readlimit)
240     {
241
242     }
243     */

244
245    public void reset()
246            throws IOException JavaDoc
247    {
248       throw new IOException JavaDoc("Don't support marked streams");
249    }
250
251    public boolean markSupported()
252    {
253       return false;
254    }
255
256 }
257
Popular Tags