/**************************************************************************
* Copyright (c) 2001 by Punch Telematix. All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* 1. Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* 3. Neither the name of Punch Telematix nor the names of *
* other contributors may be used to endorse or promote products *
* derived from this software without specific prior written permission.*
* *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED *
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. *
* IN NO EVENT SHALL PUNCH TELEMATIX OR OTHER CONTRIBUTORS BE LIABLE *
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF *
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR *
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, *
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE *
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN *
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
**************************************************************************/
package wonka.net.http;
import java.io.*;
public class ChunkedInputStream extends InputStream {
private InputStream in;
private int count;
private boolean eof;
ChunkedInputStream(InputStream in) throws IOException {
this.in = in;
nextChunk(false);
}
public void close() throws IOException {
count=0;
in.close();
}
public int read() throws IOException {
if(eof){
return -1;
}
if(count == 0 && nextChunk(true)){
return -1;
}
count--;
int rd = in.read();
if(rd == -1){
throw new IOException("unexpected EOF");
}
return rd;
}
public int read(byte[] bytes, int o, int l) throws IOException {
if(eof){
return -1;
}
if(count == 0 && nextChunk(true)){
return -1;
}
if(count < l){
l = count;
}
int rd = in.read(bytes,o,l);
if(rd == -1){
throw new IOException();
}
count -= rd;
return rd;
}
private boolean nextChunk(boolean skip) throws IOException {
try {
if(skip){
in.skip(2);
}
String line = readLine();
int idx = line.indexOf(';');
if(idx != -1){
line = line.substring(0,idx);
}
int size = Integer.parseInt(line.trim(),16);
if(size == 0){
BasicHttpURLConnection.debug("HTTP: end of chunked stream");
eof = true;
//read Trailer ...
while(!"".equals(readLine())){}
return true;
}
else {
BasicHttpURLConnection.debug("HTTP: Chunk size = " + size);
}
count = size;
return false;
}
catch(RuntimeException rt){
rt.printStackTrace();
throw new IOException("bad chunck -- 1");
}
}
private String readLine() throws IOException {
StringBuffer buf = new StringBuffer(64);
int ch = in.read();
while(ch != -1){
if(ch == '\r'){
ch = in.read();
if(ch == '\n'){
break;
}
throw new IOException("bad chunck -- 2");
}
buf.append((char)ch);
ch = in.read();
}
return buf.toString();
}
}