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>
317 template<
typename Const_buffer_sequence,
typename Const_it>
320 util::Blob* dest_buf, util::Blob::Iterator dest);
343 template<
typename Mutable_buffer_sequence,
typename Const_it>
346 const util::Blob& src_buf, util::Blob::Const_iterator src);
394template<
typename Const_buffer_sequence>
398 using boost::asio::buffer_sequence_begin;
399 using boost::asio::buffer_sequence_end;
400 using boost::asio::const_buffer;
401 using boost::asio::buffer_size;
413 for (
auto buf_data_ptr = buffer_sequence_begin(data),
414 buf_data_end_ptr = buffer_sequence_end(data);
415 buf_data_ptr != buf_data_end_ptr; ++buf_data_ptr)
417 const auto& buf_data = *buf_data_ptr;
425 const size_t to_copy = min(buf_data.size(),
434 const auto buf_start =
static_cast<Blob::value_type
const *
>(buf_data.data());
438 buf_copy->assign_copy(const_buffer(buf_start, to_copy));
439 m_q.push_back(buf_copy);
445 "buf_count [" <<
m_q.size() <<
"]; fed buffer "
446 "original/truncated size = [" << buf_data.size() <<
"/" << to_copy <<
"].");
474 size_t target_space_left = max_data_size -
m_data_size;
477 size_t src_size_left = buffer_size(data);
481 if (src_size_left == 0)
488 auto cur_buf_it = buffer_sequence_begin(data);
489 size_t pos_in_buf = 0;
509 Blob& target_buf = *
m_q.back();
516 const size_t to_copy = min(
m_block_size_hint - target_buf.size(), min(target_space_left, src_size_left));
519 assert(to_copy != 0);
526 target_buf.resize(target_buf.size() + to_copy);
527 copy_bytes_from_buf_seq<Const_buffer_sequence>(&cur_buf_it, &pos_in_buf, to_copy,
528 &target_buf, target_buf.end() - to_copy);
530 target_space_left -= to_copy;
531 src_size_left -= to_copy;
535 "buf_count [" <<
m_q.size() <<
"]; "
536 "fed/total buffer size = [" << to_copy <<
'/' << target_buf.size() <<
"].");
541 while ((src_size_left != 0) && (target_space_left != 0));
547template<
typename Mutable_buffer_sequence>
551 using boost::asio::buffer_sequence_begin;
552 using boost::asio::buffer_size;
553 using boost::asio::const_buffer;
565 size_t target_size_left = buffer_size(target_bufs);
567 if (target_size_left == 0)
575 Queue::iterator cur_src_it =
m_q.begin();
577 auto cur_buf_it = buffer_sequence_begin(target_bufs);
578 size_t pos_in_buf = 0;
581 Blob& src_bytes = **cur_src_it;
584 const size_t to_copy = min(src_bytes.size(), target_size_left);
589 copy_bytes_to_buf_seq<Mutable_buffer_sequence>
590 (&cur_buf_it, &pos_in_buf, to_copy, src_bytes, src_bytes.const_begin());
593 target_size_left -= to_copy;
596 "slow-consumed buffer of size/total [" << to_copy <<
'/' << src_bytes.size() <<
"].");
603 if (to_copy == src_bytes.size())
614 src_bytes.erase(src_bytes.begin(), src_bytes.begin() + to_copy);
617 while ((target_size_left != 0) && (
m_data_size != 0));
620 m_q.erase(
m_q.begin(), cur_src_it);
623 "buf_count [" <<
m_q.size() <<
"].");
628template<
typename Const_buffer_sequence,
typename Const_it>
630 size_t* pos_in_buf,
size_t to_copy,
632 util::Blob::Iterator dest)
635 using boost::asio::const_buffer;
651 while (*pos_in_buf == (cur_buf_size = (*cur_buf_it)->size()))
659 const size_t to_copy_in_buf = min(to_copy, cur_buf_size - *pos_in_buf);
662 dest = dest_buf->emplace_copy(dest,
663 const_buffer(
static_cast<Blob::Const_iterator
>((*cur_buf_it)->data()) + *pos_in_buf,
666 to_copy -= to_copy_in_buf;
667 *pos_in_buf += to_copy_in_buf;
672template<
typename Mutable_buffer_sequence,
typename Const_it>
674 size_t* pos_in_buf,
size_t to_copy,
676 util::Blob::Const_iterator src)
685 using boost::asio::mutable_buffer;
691 while (*pos_in_buf == (cur_buf_size = (*cur_buf_it)->size()))
697 const size_t to_copy_in_buf = min(to_copy, cur_buf_size - *pos_in_buf);
698 src = src_buf.sub_copy(src,
699 mutable_buffer(
static_cast<Blob::Iterator
>((*cur_buf_it)->data()) + *pos_in_buf,
702 to_copy -= to_copy_in_buf;
703 *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_to_buf_seq(Const_it *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...
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 ...
static void copy_bytes_from_buf_seq(Const_it *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...
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...
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...