3 #include <boost/asio/streambuf.hpp>
29 static const size_t minimum_read_size = 1024;
33 :my( new detail::buffered_istream_impl(
std::move(is) ) )
35 FC_ASSERT( my->_istr !=
nullptr,
" this shouldn't be null" );
39 :my(
std::move(o.my) ){}
51 size_t bytes_from_rdbuf =
static_cast<size_t>(my->_rdbuf.sgetn(buf, len));
53 return bytes_from_rdbuf;
56 if( len > detail::minimum_read_size )
57 return my->_istr->readsome(buf,len);
59 char tmp[detail::minimum_read_size];
60 size_t bytes_read = my->_istr->readsome( tmp, detail::minimum_read_size );
62 size_t bytes_to_deliver_immediately = std::min<size_t>(bytes_read,len);
64 memcpy( buf, tmp, bytes_to_deliver_immediately );
67 if( bytes_read > len )
69 my->_rdbuf.sputn( tmp + len, bytes_read - len );
72 return bytes_to_deliver_immediately;
77 size_t bytes_from_rdbuf =
static_cast<size_t>(my->_rdbuf.sgetn(buf.get() + offset, len));
79 return bytes_from_rdbuf;
82 if( len > detail::minimum_read_size )
83 return my->_istr->readsome(buf.get() + offset, len);
89 struct check_buffer_in_use {
91 check_buffer_in_use(
bool& buffer_in_use) : _buffer_in_use(buffer_in_use) { assert(!_buffer_in_use); _buffer_in_use =
true; }
92 ~check_buffer_in_use() { assert(_buffer_in_use); _buffer_in_use =
false; }
93 } buffer_in_use_checker(my->_shared_read_buffer_in_use);
96 if (!my->_shared_read_buffer)
97 my->_shared_read_buffer.reset(
new char[detail::minimum_read_size], [](
char* p){
delete[] p; });
98 size_t bytes_read = my->_istr->readsome( my->_shared_read_buffer, detail::minimum_read_size, 0 );
100 size_t bytes_to_deliver_immediately = std::min<size_t>(bytes_read,len);
102 memcpy( buf.get() + offset, my->_shared_read_buffer.get(), bytes_to_deliver_immediately );
104 if( bytes_read > len )
106 my->_rdbuf.sputn( my->_shared_read_buffer.get() + len, bytes_read - len );
109 return bytes_to_deliver_immediately;
114 if( my->_rdbuf.size() )
116 return my->_rdbuf.sgetc();
119 char tmp[detail::minimum_read_size];
120 size_t bytes_read = my->_istr->readsome( tmp, detail::minimum_read_size );
121 my->_rdbuf.sputn( tmp, bytes_read );
123 if( my->_rdbuf.size() )
125 return my->_rdbuf.sgetc();
128 "at least one byte should be available, or eof should have been thrown" );
154 :my( new detail::buffered_ostream_impl(
std::move(os) ) )
159 :my(
std::move(o.my) ){}
163 my = std::move(i.my);
171 size_t written =
static_cast<size_t>(my->_rdbuf.sputn( buf, len ));
172 if( written < len ) {
flush(); }
173 return written +
static_cast<size_t>(my->_rdbuf.sputn( buf+written, len-written ));
178 return writesome(buf.get() + offset, len);
187 struct check_buffer_in_use {
188 bool& _buffer_in_use;
189 check_buffer_in_use(
bool& buffer_in_use) : _buffer_in_use(buffer_in_use) { assert(!_buffer_in_use); _buffer_in_use =
true; }
190 ~check_buffer_in_use() { assert(_buffer_in_use); _buffer_in_use =
false; }
191 } buffer_in_use_checker(my->_shared_write_buffer_in_use);
193 const size_t write_buffer_size = 2048;
194 if (!my->_shared_write_buffer)
195 my->_shared_write_buffer.reset(
new char[write_buffer_size], [](
char* p){
delete[] p; });
197 while(
size_t bytes_from_rdbuf =
static_cast<size_t>(my->_rdbuf.sgetn(my->_shared_write_buffer.get(), write_buffer_size)) )
198 my->_ostr->write( my->_shared_write_buffer, bytes_from_rdbuf );