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();
185 DBG(cerr <<
"xsgetn... num: " << num << endl);
188 if (num <= (egptr() - gptr())) {
189 memcpy(s, gptr(), num);
192 return traits_type::not_eof(num);
196 uint32_t bytes_left_to_read = num;
199 if (gptr() < egptr()) {
200 int bytes_to_transfer = egptr() - gptr();
201 memcpy(s, gptr(), bytes_to_transfer);
202 gbump(bytes_to_transfer);
203 s += bytes_to_transfer;
204 bytes_left_to_read -= bytes_to_transfer;
220 d_is.read((
char *) &header, 4);
221 #if !BYTE_ORDER_PREFIX 229 if (d_is.eof())
return traits_type::eof();
230 #if BYTE_ORDER_PREFIX 231 if (d_twiddle_bytes) header = bswap_32(header);
234 if (!d_set_twiddle) {
236 d_set_twiddle =
true;
240 uint32_t chunk_size = header & CHUNK_SIZE_MASK;
241 DBG(cerr <<
"xsgetn: chunk size from header: " << chunk_size << endl);
242 DBG(cerr <<
"xsgetn: chunk type from header: " << hex << (header & CHUNK_TYPE_MASK) << endl);
243 DBG(cerr <<
"xsgetn: chunk byte order from header: " << hex << (header & CHUNK_BIG_ENDIAN) << endl);
246 if ((header & CHUNK_TYPE_MASK) == CHUNK_ERR) {
251 std::vector<char> message(chunk_size);
252 d_is.read(&message[0], chunk_size);
253 d_error_message = string(&message[0], chunk_size);
255 setg(d_buffer, d_buffer, d_buffer);
258 else if (chunk_size == 0 && (header & CHUNK_TYPE_MASK) == CHUNK_END) {
259 return traits_type::not_eof(num-bytes_left_to_read);
263 else if (chunk_size > bytes_left_to_read) {
264 d_is.read(s, bytes_left_to_read);
265 if (d_is.bad())
return traits_type::eof();
268 uint32_t bytes_leftover = chunk_size - bytes_left_to_read;
270 if (bytes_leftover > d_buf_size) {
271 d_buf_size = chunk_size;
275 d_is.read(d_buffer, bytes_leftover);
276 if (d_is.bad())
return traits_type::eof();
280 d_buffer + bytes_leftover );
282 bytes_left_to_read = 0 ;
286 if (chunk_size > d_buf_size) {
287 d_buf_size = chunk_size;
292 if (chunk_size > 0) {
293 d_is.read(s, chunk_size);
294 if (d_is.bad())
return traits_type::eof();
295 bytes_left_to_read -= chunk_size ;
300 switch (header & CHUNK_TYPE_MASK) {
302 DBG(cerr <<
"Found end chunk" << endl);
310 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);
398 return traits_type::not_eof(chunk_size);
404 d_error_message = string(d_buffer, chunk_size);
405 return traits_type::eof();
409 d_error_message =
"Failed to read known chunk header type.";
410 return traits_type::eof();
int_type read_next_chunk()
Read a chunk Normally the chunked nature of a chunked_istream/chunked_inbuf is hidden from the caller...
top level DAP object to house generic methods
virtual int_type underflow()
Insert new characters into the buffer This specialization of underflow is called when the gptr() is a...
virtual std::streamsize xsgetn(char *s, std::streamsize num)
Read a block of data This specialization of xsgetn() reads num bytes and puts them in s first reading...
bool is_host_big_endian()
Does this host use big-endian byte order?