KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis2 > transport > http > ChunkedInputStream


1 /*
2  * Copyright 2001-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 package org.apache.axis2.transport.http;
17
18
19 import java.io.IOException JavaDoc;
20 import java.io.InputStream JavaDoc;
21
22
23 /**
24  *
25  * @author Rick Rineholt
26  */

27
28 public class ChunkedInputStream extends java.io.FilterInputStream JavaDoc {
29     protected long chunkSize = 0l;
30     protected volatile boolean closed = false;
31     private static final int maxCharLong = (Long.toHexString(Long.MAX_VALUE))
32       .toString().length();
33     private ChunkedInputStream () {
34         super(null);
35     }
36
37     public ChunkedInputStream (InputStream JavaDoc is) {
38         super(is);
39     }
40
41     public int read()
42         throws IOException JavaDoc {
43         byte[] d = new byte[1];
44         int rc = read(d, 0, 1);
45
46         return rc > 0 ? (d[0] & 0xFF) : rc;
47     }
48
49     public int read(byte[] b)
50         throws IOException JavaDoc {
51         return read(b, 0, b.length);
52     }
53
54     public synchronized int read(byte[] b,
55         int off,
56         int len)
57         throws IOException JavaDoc {
58         if (closed) return -1;
59         int cs = (int) Math.min(Integer.MAX_VALUE, chunkSize);
60         int totalread = 0;
61         int bytesread = 0;
62
63         try {
64             do {
65                 if (chunkSize < 1L) {
66                     if (0l == getChunked()) {
67                         if (totalread == 0) return -1;
68                         else return totalread;
69                     }
70                 }
71                 bytesread = in.read(b, off + totalread, Math.min(len - totalread,
72                                 (int) Math.min(chunkSize, Integer.MAX_VALUE)));
73                 if (bytesread > 0) {
74                     totalread += bytesread;
75                     chunkSize -= bytesread;
76                 }
77             }
78             while (len - totalread > 0 && bytesread > -1);
79         } catch (IOException JavaDoc e) {
80             closed = true;
81             throw e;
82         }
83         return totalread;
84     }
85
86     public long skip(final long n)
87         throws IOException JavaDoc {
88         if (closed) return 0;
89         long skipped = 0l;
90         byte[] b = new byte[1024];
91         int bread = -1;
92
93         do {
94             bread = read(b, 0, b.length);
95             if (bread > 0) skipped += bread;
96         }
97         while (bread != -1 && skipped < n);
98         return skipped;
99     }
100
101     public int available()
102         throws IOException JavaDoc {
103         if (closed) return 0;
104         int rc = (int) Math.min(chunkSize, Integer.MAX_VALUE);
105
106         return Math.min(rc, in.available());
107     }
108               
109     protected long getChunked()throws IOException JavaDoc {
110         //StringBuffer buf= new StringBuffer(1024);
111
byte[]buf = new byte[maxCharLong + 2];
112         int bufsz = 0;
113  
114         chunkSize = -1L;
115         int c = -1;
116
117         do {
118             c = in.read();
119             if (c > -1) {
120                 if (c != '\r' && c != '\n' && c != ' ' && c != '\t') {
121                     buf[bufsz++] = ((byte) c);
122                 }
123             }
124         }
125         while (c > -1 && (c != '\n' || bufsz == 0) && bufsz < buf.length);
126         if (c < 0) {
127             closed = true;
128         }
129         String JavaDoc sbuf = new String JavaDoc(buf, 0, bufsz);
130
131         if (bufsz > maxCharLong) {
132             closed = true;
133             throw new IOException JavaDoc("Chunked input stream failed to receive valid chunk size:" + sbuf);
134         }
135         try {
136             chunkSize = Long.parseLong(sbuf, 16);
137         } catch (NumberFormatException JavaDoc ne) {
138             closed = true;
139             throw new IOException JavaDoc("'" + sbuf + "' " + ne.getMessage());
140         }
141         if (chunkSize < 1L) closed = true;
142         if (chunkSize != 0L && c < 0) {
143             //If chunk size is zero try and be tolerant that there maybe no cr or lf at the end.
144
throw new IOException JavaDoc("HTTP Chunked stream closed in middle of chunk.");
145         }
146         if (chunkSize < 0L) throw new IOException JavaDoc("HTTP Chunk size received " +
147             chunkSize + " is less than zero.");
148         return chunkSize;
149     }
150
151     public void close() throws IOException JavaDoc {
152    
153         synchronized (this) {
154             if (closed) return;
155             closed = true;
156         }
157
158         byte[] b = new byte[1024];
159         int bread = -1;
160
161         do {
162             bread = read(b, 0, b.length);
163         }
164         while (bread != -1);
165     }
166
167     /*
168      public void mark(int readlimit)
169      {
170      
171      }
172      */

173
174     public void reset()
175         throws IOException JavaDoc {
176         throw new IOException JavaDoc("Don't support marked streams");
177     }
178
179     public boolean markSupported() {
180         return false;
181     }
182
183 }
184
Popular Tags