31 #include <arpa/inet.h> 36 #include "chunked_stream.h" 37 #include "chunked_istream.h" 83 std::streambuf::int_type
86 DBG(cerr <<
"underflow..." << endl);
87 DBG2(cerr <<
"eback(): " << (
void*)eback() <<
", gptr(): " << (
void*)(gptr()-eback()) <<
", egptr(): " << (
void*)(egptr()-eback()) << endl);
91 return traits_type::to_int_type(*gptr());
97 d_is.read((
char *) &header, 4);
101 header = ntohl(header);
107 if (d_is.eof())
return traits_type::eof();
110 if (!d_set_twiddle) {
112 d_set_twiddle =
true;
115 uint32_t chunk_size = header & CHUNK_SIZE_MASK;
117 DBG(cerr <<
"underflow: chunk size from header: " << chunk_size << endl);
118 DBG(cerr <<
"underflow: chunk type from header: " << hex << (header & CHUNK_TYPE_MASK) << endl);
119 DBG(cerr <<
"underflow: chunk byte order from header: " << hex << (header & CHUNK_BIG_ENDIAN) << endl);
122 if (chunk_size > d_buf_size) {
123 d_buf_size = chunk_size;
128 if (chunk_size == 0 && (header & CHUNK_TYPE_MASK) == CHUNK_END)
return traits_type::eof();
131 d_is.read(d_buffer, chunk_size);
132 DBG2(cerr <<
"underflow: size read: " << d_is.gcount() <<
", eof: " << d_is.eof() <<
", bad: " << d_is.bad() << endl);
133 if (d_is.bad())
return traits_type::eof();
135 DBG2(cerr <<
"eback(): " << (
void*)eback() <<
", gptr(): " << (
void*)(gptr()-eback()) <<
", egptr(): " << (
void*)(egptr()-eback()) << endl);
138 d_buffer + chunk_size);
140 DBG2(cerr <<
"eback(): " << (
void*)eback() <<
", gptr(): " << (
void*)(gptr()-eback()) <<
", egptr(): " << (
void*)(egptr()-eback()) << endl);
142 switch (header & CHUNK_TYPE_MASK) {
144 DBG2(cerr <<
"Found end chunk" << endl);
145 return traits_type::to_int_type(*gptr());
147 return traits_type::to_int_type(*gptr());
153 d_error_message = string(d_buffer, chunk_size);
154 return traits_type::eof();
157 d_error_message =
"Failed to read known chunk header type.";
158 return traits_type::eof();
181 DBG(cerr <<
"xsgetn... num: " << num << endl);
184 if (num <= (egptr() - gptr())) {
185 memcpy(s, gptr(), num);
188 return traits_type::not_eof(num);
192 uint32_t bytes_left_to_read = num;
195 if (gptr() < egptr()) {
196 int bytes_to_transfer = egptr() - gptr();
197 memcpy(s, gptr(), bytes_to_transfer);
198 gbump(bytes_to_transfer);
199 s += bytes_to_transfer;
200 bytes_left_to_read -= bytes_to_transfer;
216 d_is.read((
char *) &header, 4);
218 header = ntohl(header);
224 if (d_is.eof())
return traits_type::eof();
227 if (!d_set_twiddle) {
229 d_set_twiddle =
true;
232 uint32_t chunk_size = header & CHUNK_SIZE_MASK;
233 DBG(cerr <<
"xsgetn: chunk size from header: " << chunk_size << endl);
234 DBG(cerr <<
"xsgetn: chunk type from header: " << hex << (header & CHUNK_TYPE_MASK) << endl);
235 DBG(cerr <<
"xsgetn: chunk byte order from header: " << hex << (header & CHUNK_BIG_ENDIAN) << endl);
238 if ((header & CHUNK_TYPE_MASK) == CHUNK_ERR) {
243 std::vector<char> message(chunk_size);
244 d_is.read(&message[0], chunk_size);
245 d_error_message = string(&message[0], chunk_size);
247 setg(d_buffer, d_buffer, d_buffer);
250 else if (chunk_size == 0 && (header & CHUNK_TYPE_MASK) == CHUNK_END) {
251 return traits_type::not_eof(num-bytes_left_to_read);
255 else if (chunk_size > bytes_left_to_read) {
256 d_is.read(s, bytes_left_to_read);
257 if (d_is.bad())
return traits_type::eof();
260 uint32_t bytes_leftover = chunk_size - bytes_left_to_read;
262 if (bytes_leftover > d_buf_size) {
263 d_buf_size = chunk_size;
267 d_is.read(d_buffer, bytes_leftover);
268 if (d_is.bad())
return traits_type::eof();
272 d_buffer + bytes_leftover );
274 bytes_left_to_read = 0 ;
278 if (chunk_size > d_buf_size) {
279 d_buf_size = chunk_size;
284 if (chunk_size > 0) {
285 d_is.read(s, chunk_size);
286 if (d_is.bad())
return traits_type::eof();
287 bytes_left_to_read -= chunk_size ;
292 switch (header & CHUNK_TYPE_MASK) {
294 DBG(cerr <<
"Found end chunk" << endl);
302 done = bytes_left_to_read == 0;
308 return traits_type::eof();
312 d_error_message =
"Failed to read known chunk header type.";
313 return traits_type::eof();
317 return traits_type::not_eof(num-bytes_left_to_read);
332 std::streambuf::int_type
337 d_is.read((
char *) &header, 4);
339 header = ntohl(header);
345 if (d_is.eof())
return traits_type::eof();
348 if (!d_set_twiddle) {
350 d_set_twiddle =
true;
353 uint32_t chunk_size = header & CHUNK_SIZE_MASK;
355 DBG(cerr <<
"read_next_chunk: chunk size from header: " << chunk_size << endl);
356 DBG(cerr <<
"read_next_chunk: chunk type from header: " << hex << (header & CHUNK_TYPE_MASK) << endl);
357 DBG(cerr <<
"read_next_chunk: chunk byte order from header: " << hex << (header & CHUNK_BIG_ENDIAN) << endl);
360 if (chunk_size > d_buf_size) {
361 d_buf_size = chunk_size;
366 if (chunk_size == 0 && (header & CHUNK_TYPE_MASK) == CHUNK_END)
return traits_type::eof();
369 d_is.read(d_buffer, chunk_size);
370 DBG2(cerr <<
"read_next_chunk: size read: " << d_is.gcount() <<
", eof: " << d_is.eof() <<
", bad: " << d_is.bad() << endl);
371 if (d_is.bad())
return traits_type::eof();
373 DBG2(cerr <<
"eback(): " << (
void*)eback() <<
", gptr(): " << (
void*)(gptr()-eback()) <<
", egptr(): " << (
void*)(egptr()-eback()) << endl);
376 d_buffer + chunk_size);
378 DBG2(cerr <<
"eback(): " << (
void*)eback() <<
", gptr(): " << (
void*)(gptr()-eback()) <<
", egptr(): " << (
void*)(egptr()-eback()) << endl);
380 switch (header & CHUNK_TYPE_MASK) {
382 DBG(cerr <<
"Found end chunk" << endl);
383 return traits_type::not_eof(chunk_size);
386 return traits_type::not_eof(chunk_size);
392 d_error_message = string(d_buffer, chunk_size);
393 return traits_type::eof();
397 d_error_message =
"Failed to read known chunk header type.";
398 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?