32 #include <arpa/inet.h>
37 #include "chunked_stream.h"
38 #include "chunked_istream.h"
84 std::streambuf::int_type
87 DBG(cerr <<
"underflow..." << endl);
88 DBG2(cerr <<
"eback(): " << (
void*)eback() <<
", gptr(): " << (
void*)(gptr()-eback()) <<
", egptr(): " << (
void*)(egptr()-eback()) << endl);
92 return traits_type::to_int_type(*gptr());
98 d_is.read((
char *) &header, 4);
99 #if !BYTE_ORDER_PREFIX
109 if (d_is.eof())
return traits_type::eof();
110 #if BYTE_ORDER_PREFIX
111 if (d_twiddle_bytes) header = bswap_32(header);
114 if (!d_set_twiddle) {
116 d_set_twiddle =
true;
119 uint32_t chunk_size = header & CHUNK_SIZE_MASK;
121 DBG(cerr <<
"underflow: chunk size from header: " << chunk_size << endl);
122 DBG(cerr <<
"underflow: chunk type from header: " << hex << (header & CHUNK_TYPE_MASK) << endl);
123 DBG(cerr <<
"underflow: chunk byte order from header: " << hex << (header & CHUNK_BIG_ENDIAN) << endl);
126 if (chunk_size > d_buf_size) {
127 d_buf_size = chunk_size;
132 if (chunk_size == 0 && (header & CHUNK_TYPE_MASK) == CHUNK_END)
return traits_type::eof();
135 d_is.read(d_buffer, chunk_size);
136 DBG2(cerr <<
"underflow: size read: " << d_is.gcount() <<
", eof: " << d_is.eof() <<
", bad: " << d_is.bad() << endl);
137 if (d_is.bad())
return traits_type::eof();
139 DBG2(cerr <<
"eback(): " << (
void*)eback() <<
", gptr(): " << (
void*)(gptr()-eback()) <<
", egptr(): " << (
void*)(egptr()-eback()) << endl);
142 d_buffer + chunk_size);
144 DBG2(cerr <<
"eback(): " << (
void*)eback() <<
", gptr(): " << (
void*)(gptr()-eback()) <<
", egptr(): " << (
void*)(egptr()-eback()) << endl);
146 switch (header & CHUNK_TYPE_MASK) {
148 DBG2(cerr <<
"Found end chunk" << endl);
149 return traits_type::to_int_type(*gptr());
151 return traits_type::to_int_type(*gptr());
157 d_error_message = string(d_buffer, chunk_size);
158 return traits_type::eof();
161 d_error_message =
"Failed to read known chunk header type.";
162 return traits_type::eof();
165 return traits_type::eof();
187 DBG(cerr <<
"xsgetn... num: " << num << endl);
190 if (num <= (egptr() - gptr())) {
191 memcpy(s, gptr(), num);
194 return traits_type::not_eof(num);
198 uint32_t bytes_left_to_read = num;
201 if (gptr() < egptr()) {
202 int bytes_to_transfer = egptr() - gptr();
203 memcpy(s, gptr(), bytes_to_transfer);
204 gbump(bytes_to_transfer);
205 s += bytes_to_transfer;
206 bytes_left_to_read -= bytes_to_transfer;
222 d_is.read((
char *) &header, 4);
223 #if !BYTE_ORDER_PREFIX
231 if (d_is.eof())
return traits_type::eof();
232 #if BYTE_ORDER_PREFIX
233 if (d_twiddle_bytes) header = bswap_32(header);
236 if (!d_set_twiddle) {
238 d_set_twiddle =
true;
242 uint32_t chunk_size = header & CHUNK_SIZE_MASK;
243 DBG(cerr <<
"xsgetn: chunk size from header: " << chunk_size << endl);
244 DBG(cerr <<
"xsgetn: chunk type from header: " << hex << (header & CHUNK_TYPE_MASK) << endl);
245 DBG(cerr <<
"xsgetn: chunk byte order from header: " << hex << (header & CHUNK_BIG_ENDIAN) << endl);
248 if ((header & CHUNK_TYPE_MASK) == CHUNK_ERR) {
253 std::vector<char> message(chunk_size);
254 d_is.read(&message[0], chunk_size);
255 d_error_message = string(&message[0], chunk_size);
257 setg(d_buffer, d_buffer, d_buffer);
260 else if (chunk_size == 0 && (header & CHUNK_TYPE_MASK) == CHUNK_END) {
261 return traits_type::not_eof(num-bytes_left_to_read);
265 else if (chunk_size > bytes_left_to_read) {
266 d_is.read(s, bytes_left_to_read);
267 if (d_is.bad())
return traits_type::eof();
270 uint32_t bytes_leftover = chunk_size - bytes_left_to_read;
272 if (bytes_leftover > d_buf_size) {
273 d_buf_size = chunk_size;
277 d_is.read(d_buffer, bytes_leftover);
278 if (d_is.bad())
return traits_type::eof();
282 d_buffer + bytes_leftover );
284 bytes_left_to_read = 0 ;
288 if (chunk_size > d_buf_size) {
289 d_buf_size = chunk_size;
294 if (chunk_size > 0) {
295 d_is.read(s, chunk_size);
296 if (d_is.bad())
return traits_type::eof();
297 bytes_left_to_read -= chunk_size ;
302 switch (header & CHUNK_TYPE_MASK) {
304 DBG(cerr <<
"Found end chunk" << endl);
311 done = bytes_left_to_read == 0;
316 return traits_type::eof();
320 d_error_message =
"Failed to read known chunk header type.";
321 return traits_type::eof();
325 return traits_type::not_eof(num-bytes_left_to_read);
340 std::streambuf::int_type
345 d_is.read((
char *) &header, 4);
346 #if !BYTE_ORDER_PREFIX
354 if (d_is.eof())
return traits_type::eof();
355 #if BYTE_ORDER_PREFIX
356 if (d_twiddle_bytes) header = bswap_32(header);
359 if (!d_set_twiddle) {
361 d_set_twiddle =
true;
365 uint32_t chunk_size = header & CHUNK_SIZE_MASK;
367 DBG(cerr <<
"read_next_chunk: chunk size from header: " << chunk_size << endl);
368 DBG(cerr <<
"read_next_chunk: chunk type from header: " << hex << (header & CHUNK_TYPE_MASK) << endl);
369 DBG(cerr <<
"read_next_chunk: chunk byte order from header: " << hex << (header & CHUNK_BIG_ENDIAN) << endl);
372 if (chunk_size > d_buf_size) {
373 d_buf_size = chunk_size;
378 if (chunk_size == 0 && (header & CHUNK_TYPE_MASK) == CHUNK_END)
return traits_type::eof();
381 d_is.read(d_buffer, chunk_size);
382 DBG2(cerr <<
"read_next_chunk: size read: " << d_is.gcount() <<
", eof: " << d_is.eof() <<
", bad: " << d_is.bad() << endl);
383 if (d_is.bad())
return traits_type::eof();
385 DBG2(cerr <<
"eback(): " << (
void*)eback() <<
", gptr(): " << (
void*)(gptr()-eback()) <<
", egptr(): " << (
void*)(egptr()-eback()) << endl);
388 d_buffer + chunk_size);
390 DBG2(cerr <<
"eback(): " << (
void*)eback() <<
", gptr(): " << (
void*)(gptr()-eback()) <<
", egptr(): " << (
void*)(egptr()-eback()) << endl);
392 switch (header & CHUNK_TYPE_MASK) {
394 DBG(cerr <<
"Found end chunk" << endl);
395 return traits_type::not_eof(chunk_size);
397 return traits_type::not_eof(chunk_size);
403 d_error_message = string(d_buffer, chunk_size);
404 return traits_type::eof();
407 d_error_message =
"Failed to read known chunk header type.";
408 return traits_type::eof();
411 return traits_type::eof();