30 #include <arpa/inet.h>
41 #include "chunked_stream.h"
42 #include "chunked_ostream.h"
53 std::streambuf::int_type
56 DBG(cerr <<
"In chunked_outbuf::data_chunk" << endl);
58 int32_t num = pptr() - pbase();
76 uint32_t header = num;
77 #if !BYTE_ORDER_PREFIX
79 if (!d_big_endian) header |= CHUNK_LITTLE_ENDIAN;
80 #if HEADER_IN_NETWORK_BYTE_ORDER
82 header = htonl(header);
86 d_os.write((
const char *)&header,
sizeof(int32_t));
90 d_os.write(d_buffer, num);
91 if (d_os.eof() || d_os.bad())
92 return traits_type::eof();
109 std::streambuf::int_type
112 DBG(cerr <<
"In chunked_outbuf::end_chunk" << endl);
114 int32_t num = pptr() - pbase();
120 uint32_t header = (uint32_t)num | CHUNK_END;
122 #if !BYTE_ORDER_PREFIX
124 if (!d_big_endian) header |= CHUNK_LITTLE_ENDIAN;
125 #if HEADER_IN_NETWORK_BYTE_ORDER
134 d_os.write((
const char *)&header,
sizeof(uint32_t));
138 d_os.write(d_buffer, num);
139 if (d_os.eof() || d_os.bad())
140 return traits_type::eof();
153 std::streambuf::int_type
156 DBG(cerr <<
"In chunked_outbuf::err_chunk" << endl);
161 int32_t num = pptr() - pbase();
166 if (msg.length() > 0x00FFFFFF)
167 msg =
"Error message too long";
169 uint32_t header = (uint32_t)msg.length() | CHUNK_ERR;
171 #if !BYTE_ORDER_PREFIX
173 if (!d_big_endian) header |= CHUNK_LITTLE_ENDIAN;
174 #if HEADER_IN_NETWORK_BYTE_ORDER
176 header = htonl(header);
183 d_os.write((
const char *)&header,
sizeof(uint32_t));
187 d_os.write(msg.data(), msg.length());
188 if (d_os.eof() || d_os.bad())
189 return traits_type::eof();
210 std::streambuf::int_type
213 DBG(cerr <<
"In chunked_outbuf::overflow" << endl);
218 if (!traits_type::eq_int_type(c, traits_type::eof())) {
219 *pptr() = traits_type::not_eof(c);
225 return traits_type::eof();
228 return traits_type::not_eof(c);
255 DBG(cerr <<
"In chunked_outbuf::xsputn: num: " << num << endl);
265 int32_t bytes_in_buffer = pptr() - pbase();
270 if (bytes_in_buffer + num < d_buf_size) {
271 DBG2(cerr <<
":xsputn: buffering num: " << num << endl);
272 memcpy(pptr(), s, num);
274 return traits_type::not_eof(num);
279 uint32_t header = d_buf_size;
280 #if !BYTE_ORDER_PREFIX
282 if (!d_big_endian) header |= CHUNK_LITTLE_ENDIAN;
283 #if HEADER_IN_NETWORK_BYTE_ORDER
285 header = htonl(header);
288 d_os.write((
const char *)&header,
sizeof(int32_t));
293 setp(d_buffer, d_buffer + (d_buf_size - 1));
295 d_os.write(d_buffer, bytes_in_buffer);
296 if (d_os.eof() || d_os.bad())
297 return traits_type::not_eof(0);
299 int bytes_to_fill_out_buffer = d_buf_size - bytes_in_buffer;
300 d_os.write(s, bytes_to_fill_out_buffer);
301 if (d_os.eof() || d_os.bad())
302 return traits_type::not_eof(0);
303 s += bytes_to_fill_out_buffer;
304 uint32_t bytes_still_to_send = num - bytes_to_fill_out_buffer;
308 while (bytes_still_to_send >= d_buf_size) {
310 d_os.write((
const char *) &header,
sizeof(int32_t));
311 d_os.write(s, d_buf_size);
312 if (d_os.eof() || d_os.bad())
return traits_type::not_eof(0);
314 bytes_still_to_send -= d_buf_size;
317 if (bytes_still_to_send > 0) {
321 memcpy(d_buffer, s, bytes_still_to_send);
322 pbump(bytes_still_to_send);
327 return traits_type::not_eof(num);
335 std::streambuf::int_type
338 DBG(cerr <<
"In chunked_outbuf::sync" << endl);
342 return traits_type::not_eof(-1);
344 return traits_type::not_eof(0);
virtual int_type overflow(int c)
Virtual method called when the internal buffer would overflow. When the internal buffer fills...
virtual std::streamsize xsputn(const char *s, std::streamsize num)
Write bytes to the chunked stream Write the bytes in s to the chunked stream.
int_type end_chunk()
Send an end chunk.
int_type err_chunk(const std::string &msg)
Send an error chunk While building up the next chunk, send an error chunk, ignoring the data currentl...
virtual int_type sync()
Synchronize the stream with its data sink.
int_type data_chunk()
Write out the contents of the buffer as a chunk.