1 |
/* |
/* |
2 |
* $Id$ |
* ChunkedInputStream.java |
3 |
* Copyright (C) 2004 The Free Software Foundation |
* Copyright (C) 2004 The Free Software Foundation |
4 |
* |
* |
5 |
* This file is part of GNU inetlib, a library. |
* This file is part of GNU inetlib, a library. |
49 |
* @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> |
* @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> |
50 |
*/ |
*/ |
51 |
public class ChunkedInputStream |
public class ChunkedInputStream |
52 |
extends FilterInputStream |
extends FilterInputStream |
53 |
{ |
{ |
54 |
|
|
55 |
private static final byte CR = 0x0d; |
private static final byte CR = 0x0d; |
66 |
* @param in the response socket input stream |
* @param in the response socket input stream |
67 |
* @param headers the headers to receive additional header lines |
* @param headers the headers to receive additional header lines |
68 |
*/ |
*/ |
69 |
public ChunkedInputStream (InputStream in, Headers headers) |
public ChunkedInputStream(InputStream in, Headers headers) |
70 |
{ |
{ |
71 |
super (in); |
super(in); |
72 |
this.headers = headers; |
this.headers = headers; |
73 |
size = -1; |
size = -1; |
74 |
count = 0; |
count = 0; |
75 |
meta = true; |
meta = true; |
76 |
} |
} |
77 |
|
|
78 |
public int read () |
public int read() |
79 |
throws IOException |
throws IOException |
80 |
{ |
{ |
81 |
byte[] buf = new byte[1]; |
byte[] buf = new byte[1]; |
82 |
int len = read (buf, 0, 1); |
int len = read(buf, 0, 1); |
83 |
if (len == -1) |
if (len == -1) |
84 |
{ |
{ |
85 |
return -1; |
return -1; |
92 |
return ret; |
return ret; |
93 |
} |
} |
94 |
|
|
95 |
public int read (byte[] buffer) |
public int read(byte[] buffer) |
96 |
throws IOException |
throws IOException |
97 |
{ |
{ |
98 |
return read (buffer, 0, buffer.length); |
return read(buffer, 0, buffer.length); |
99 |
} |
} |
100 |
|
|
101 |
public int read (byte[] buffer, int offset, int length) |
public int read(byte[] buffer, int offset, int length) |
102 |
throws IOException |
throws IOException |
103 |
{ |
{ |
104 |
if (eof) |
if (eof) |
110 |
// Read chunk header |
// Read chunk header |
111 |
int c, last = 0; |
int c, last = 0; |
112 |
boolean seenSemi = false; |
boolean seenSemi = false; |
113 |
StringBuffer buf = new StringBuffer (); |
StringBuffer buf = new StringBuffer(); |
114 |
do |
do |
115 |
{ |
{ |
116 |
c = in.read (); |
c = in.read(); |
117 |
if (c == 0x3b) // ; |
if (c == 0x3b) // ; |
118 |
{ |
{ |
119 |
seenSemi = true; |
seenSemi = true; |
120 |
} |
} |
121 |
else if (c == 0x0a && last == 0x0d) // CRLF |
else if (c == 0x0a && last == 0x0d) // CRLF |
122 |
{ |
{ |
123 |
size = Integer.parseInt (buf.toString (), 16); |
size = Integer.parseInt(buf.toString(), 16); |
124 |
break; |
break; |
125 |
} |
} |
126 |
else if (!seenSemi && c >= 0x30) |
else if (!seenSemi && c >= 0x30) |
129 |
} |
} |
130 |
last = c; |
last = c; |
131 |
} |
} |
132 |
while (c != -1); |
while(c != -1); |
133 |
count = 0; |
count = 0; |
134 |
meta = false; |
meta = false; |
135 |
} |
} |
136 |
if (size == 0) |
if (size == 0) |
137 |
{ |
{ |
138 |
// Read trailer |
// Read trailer |
139 |
headers.parse (in); |
headers.parse(in); |
140 |
eof = true; |
eof = true; |
141 |
return -1; |
return -1; |
142 |
} |
} |
145 |
int diff = length - offset; |
int diff = length - offset; |
146 |
int max = size - count; |
int max = size - count; |
147 |
max = (diff < max) ? diff : max; |
max = (diff < max) ? diff : max; |
148 |
int len = (max > 0) ? in.read (buffer, offset, max) : 0; |
int len = (max > 0) ? in.read(buffer, offset, max) : 0; |
149 |
count += len; |
count += len; |
150 |
if (count == size) |
if (count == size) |
151 |
{ |
{ |
152 |
// Read CRLF |
// Read CRLF |
153 |
int c1 = in.read (); |
int c1 = in.read(); |
154 |
int c2 = in.read (); |
int c2 = in.read(); |
155 |
if (c1 == -1 && c2 == -1) |
if (c1 == -1 && c2 == -1) |
156 |
{ |
{ |
157 |
// EOF before CRLF: bad, but ignore |
// EOF before CRLF: bad, but ignore |
160 |
} |
} |
161 |
if (c1 != 0x0d || c2 != 0x0a) |
if (c1 != 0x0d || c2 != 0x0a) |
162 |
{ |
{ |
163 |
throw new ProtocolException ("expecting CRLF: " + c1 + "," + c2); |
throw new ProtocolException("expecting CRLF: " + c1 + "," + c2); |
164 |
} |
} |
165 |
meta = true; |
meta = true; |
166 |
} |
} |
169 |
} |
} |
170 |
|
|
171 |
} |
} |
172 |
|
|