25#include <boost/asio.hpp>
26#include <boost/shared_ptr.hpp>
97 private boost::noncopyable
164 template<
typename Const_buffer_sequence>
165 size_t feed_bufs_copy(
const Const_buffer_sequence& data,
size_t max_data_size);
212 template<
typename Mutable_buffer_sequence>
315 template<
typename Const_buffer_sequence>
316 static void copy_bytes_from_buf_seq(
typename Const_buffer_sequence::const_iterator* cur_buf_it,
size_t* pos_in_buf,
318 util::Blob* dest_buf, util::Blob::Iterator dest);
339 template<
typename Mutable_buffer_sequence>
340 static void copy_bytes_to_buf_seq(
typename Mutable_buffer_sequence::const_iterator* cur_buf_it,
size_t* pos_in_buf,
342 const util::Blob& src_buf, util::Blob::Const_iterator src);
390template<
typename Const_buffer_sequence>
394 using boost::asio::const_buffer;
395 using boost::asio::buffers_iterator;
396 using boost::asio::buffer_size;
408 for (
const auto& buf_data : data)
417 const const_buffer buf(buf_data);
420 const size_t to_copy = min(buf.size(),
429 const auto buf_start =
static_cast<Blob::value_type
const *
>(buf.data());
433 buf_copy->assign_copy(const_buffer(buf_start, to_copy));
434 m_q.push_back(buf_copy);
440 "buf_count [" <<
m_q.size() <<
"]; fed buffer "
441 "original/truncated size = [" << buf.size() <<
"/" << to_copy <<
"].");
469 size_t target_space_left = max_data_size -
m_data_size;
472 size_t src_size_left = buffer_size(data);
476 if (src_size_left == 0)
483 typename Const_buffer_sequence::const_iterator cur_buf_it = data.begin();
484 size_t pos_in_buf = 0;
504 Blob& target_buf = *
m_q.back();
511 const size_t to_copy = min(
m_block_size_hint - target_buf.size(), min(target_space_left, src_size_left));
514 assert(to_copy != 0);
521 target_buf.resize(target_buf.size() + to_copy);
522 copy_bytes_from_buf_seq<Const_buffer_sequence>(&cur_buf_it, &pos_in_buf, to_copy,
523 &target_buf, target_buf.end() - to_copy);
525 target_space_left -= to_copy;
526 src_size_left -= to_copy;
530 "buf_count [" <<
m_q.size() <<
"]; "
531 "fed/total buffer size = [" << to_copy <<
'/' << target_buf.size() <<
"].");
536 while ((src_size_left != 0) && (target_space_left != 0));
542template<
typename Mutable_buffer_sequence>
546 using boost::asio::buffer_size;
547 using boost::asio::buffers_iterator;
548 using boost::asio::const_buffer;
560 size_t target_size_left = buffer_size(target_bufs);
562 if (target_size_left == 0)
570 Queue::iterator cur_src_it =
m_q.begin();
572 typename Mutable_buffer_sequence::const_iterator cur_buf_it = target_bufs.begin();
573 size_t pos_in_buf = 0;
576 Blob& src_bytes = **cur_src_it;
579 const size_t to_copy = min(src_bytes.size(), target_size_left);
584 copy_bytes_to_buf_seq<Mutable_buffer_sequence>
585 (&cur_buf_it, &pos_in_buf, to_copy, src_bytes, src_bytes.const_begin());
588 target_size_left -= to_copy;
591 "slow-consumed buffer of size/total [" << to_copy <<
'/' << src_bytes.size() <<
"].");
598 if (to_copy == src_bytes.size())
609 src_bytes.erase(src_bytes.begin(), src_bytes.begin() + to_copy);
612 while ((target_size_left != 0) && (
m_data_size != 0));
615 m_q.erase(
m_q.begin(), cur_src_it);
618 "buf_count [" <<
m_q.size() <<
"].");
623template<
typename Const_buffer_sequence>
625 size_t* pos_in_buf,
size_t to_copy,
627 util::Blob::Iterator dest)
630 using boost::asio::const_buffer;
646 while (*pos_in_buf == (cur_buf_size = (*cur_buf_it)->size()))
654 const size_t to_copy_in_buf = min(to_copy, cur_buf_size - *pos_in_buf);
657 dest = dest_buf->emplace_copy(dest,
658 const_buffer(
static_cast<Blob::Const_iterator
>((*cur_buf_it)->data()) + *pos_in_buf,
661 to_copy -= to_copy_in_buf;
662 *pos_in_buf += to_copy_in_buf;
667template<
typename Mutable_buffer_sequence>
669 size_t* pos_in_buf,
size_t to_copy,
671 util::Blob::Const_iterator src)
680 using boost::asio::mutable_buffer;
686 while (*pos_in_buf == (cur_buf_size = (*cur_buf_it)->size()))
692 const size_t to_copy_in_buf = min(to_copy, cur_buf_size - *pos_in_buf);
693 src = src_buf.sub_copy(src,
694 mutable_buffer(
static_cast<Blob::Iterator
>((*cur_buf_it)->data()) + *pos_in_buf,
697 to_copy -= to_copy_in_buf;
698 *pos_in_buf += to_copy_in_buf;
Convenience class that simply stores a Logger and/or Component passed into a constructor; and returns...
Logger * get_logger() const
Returns the stored Logger pointer, particularly as many FLOW_LOG_*() macros expect.
Interface that the user should implement, passing the implementing Logger into logging classes (Flow'...
Internal net_flow class that implements a socket buffer, as used by Peer_socket for Send and Receive ...
size_t m_data_size
The total amount of data stored, in bytes, stored in this object.
boost::shared_ptr< const util::Blob > Blob_const_ptr
Short-hand for byte sequence on the heap. (Using ref-counted pointer purely for convenience....
std::deque< Blob_ptr > Queue
FIFO of byte sequences, together comprising an overall byte sequence.
void clear()
Destroys all stored data.
Socket_buffer(log::Logger *logger_ptr, size_t block_size_hint)
Initialize empty buffer.
static void copy_bytes_from_buf_seq(typename Const_buffer_sequence::const_iterator *cur_buf_it, size_t *pos_in_buf, size_t to_copy, util::Blob *dest_buf, util::Blob::Iterator dest)
Helper that copies, to a given raw memory buffer, a given number of bytes from a given Const_buffer_s...
size_t feed_buf_move(util::Blob *data, size_t max_data_size)
Feeds (adds to the back of the byte buffer) the byte sequence equal to the given byte sequence *data,...
size_t feed_bufs_copy(const Const_buffer_sequence &data, size_t max_data_size)
Feeds (adds to the back of the byte buffer) the contents of the byte stream composed of the bytes in ...
void consume_buf_move(util::Blob *target_buf, size_t max_data_size)
Consumes (removes from the front of the internal byte buffer and returns them to the caller) a byte s...
static void copy_bytes_to_buf_seq(typename Mutable_buffer_sequence::const_iterator *cur_buf_it, size_t *pos_in_buf, size_t to_copy, const util::Blob &src_buf, util::Blob::Const_iterator src)
Helper that copies, to a given raw memory buffer, a given number of bytes to a given Mutable_buffer_s...
Queue m_q
The data in the buffer.
bool empty() const
Returns true if and only if data_size() == 0.
const size_t m_block_size_hint
The max_data_size argument value that the user is predicting to use when calling consume_buf_move(); ...
boost::shared_ptr< util::Blob > Blob_ptr
Short-hand for byte sequence on the heap. (Using ref-counted pointer purely for convenience....
friend std::ostream & operator<<(std::ostream &os, const Socket_buffer &sock_buf)
Prints a printable representation of the data in sock_buf to the given standard ostream.
size_t data_size() const
The total number of bytes of application-layer data stored in this object.
size_t consume_bufs_copy(const Mutable_buffer_sequence &target_bufs)
Consumes (removes from the front of the internal byte buffer and returns them to the caller) a byte s...
#define FLOW_LOG_DATA(ARG_stream_fragment)
Logs a DATA message into flow::log::Logger *get_logger() with flow::log::Component get_log_component(...
#define FLOW_LOG_TRACE(ARG_stream_fragment)
Logs a TRACE message into flow::log::Logger *get_logger() with flow::log::Component get_log_component...
Flow module containing the API and implementation of the Flow network protocol, a TCP-inspired stream...
std::string buffers_dump_string(const Const_buffer_sequence &data, const std::string &indentation, size_t bytes_per_line)
Identical to buffers_to_ostream() but returns an std::string instead of writing to a given ostream.
Blob_with_log_context<> Blob
A concrete Blob_with_log_context that compile-time-disables Basic_blob::share() and the sharing API d...