001: /*
002: * @(#)ChunkedInputStream.java 0.3-2 18/06/1999
003: *
004: * This file is part of the HTTPClient package
005: * Copyright (C) 1996-1999 Ronald Tschalär
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free
019: * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
020: * MA 02111-1307, USA
021: *
022: * For questions, suggestions, bug-reports, enhancement-requests etc.
023: * I may be contacted at:
024: *
025: * ronald@innovation.ch
026: *
027: */
028:
029: package HTTPClient;
030:
031: import java.io.IOException;
032: import java.io.EOFException;
033: import java.io.InputStream;
034: import java.io.FilterInputStream;
035:
036: /**
037: * This class de-chunks an input stream.
038: *
039: * @version 0.3-2 18/06/1999
040: * @author Ronald Tschalär
041: */
042: class ChunkedInputStream extends FilterInputStream {
043: /**
044: * @param is the input stream to dechunk
045: */
046: ChunkedInputStream(InputStream is) {
047: super (is);
048: }
049:
050: byte[] one = new byte[1];
051:
052: public synchronized int read() throws IOException {
053: int b = read(one, 0, 1);
054: if (b == 1)
055: return (one[0] & 0xff);
056: else
057: return -1;
058: }
059:
060: private int chunk_len = -1;
061: private boolean eof = false;
062:
063: public synchronized int read(byte[] buf, int off, int len)
064: throws IOException {
065: if (eof)
066: return -1;
067:
068: if (chunk_len == -1) // it's a new chunk
069: {
070: try {
071: chunk_len = Codecs.getChunkLength(in);
072: } catch (ParseException pe) {
073: throw new IOException(pe.toString());
074: }
075: }
076:
077: if (chunk_len > 0) // it's data
078: {
079: if (len > chunk_len)
080: len = chunk_len;
081: int rcvd = in.read(buf, off, len);
082: if (rcvd == -1)
083: throw new EOFException("Premature EOF encountered");
084:
085: chunk_len -= rcvd;
086: if (chunk_len == 0) // got the whole chunk
087: {
088: in.read(); // CR
089: in.read(); // LF
090: chunk_len = -1;
091: }
092:
093: return rcvd;
094: } else // the footers (trailers)
095: {
096: // discard
097: Request dummy = new Request(null, null, null, null, null,
098: null, false);
099: new Response(dummy, null).readTrailers(in);
100:
101: eof = true;
102: return -1;
103: }
104: }
105:
106: public synchronized long skip(long num) throws IOException {
107: byte[] tmp = new byte[(int) num];
108: int got = read(tmp, 0, (int) num);
109:
110: if (got > 0)
111: return (long) got;
112: else
113: return 0L;
114: }
115:
116: public synchronized int available() throws IOException {
117: if (eof)
118: return 0;
119:
120: if (chunk_len != -1)
121: return chunk_len + in.available();
122: else
123: return in.available();
124: }
125: }
|