mirror of
https://github.com/boostorg/beast.git
synced 2025-07-30 21:07:26 +02:00
Don't use dynamic_buffer_ref
This commit is contained in:
@ -1,3 +1,9 @@
|
|||||||
|
Version 230:
|
||||||
|
|
||||||
|
* Don't use dynamic_buffer_ref
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
Version 229:
|
Version 229:
|
||||||
|
|
||||||
* Rename to buffer_bytes
|
* Rename to buffer_bytes
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <boost/beast/core/error.hpp>
|
#include <boost/beast/core/error.hpp>
|
||||||
#include <boost/asio/async_result.hpp>
|
#include <boost/asio/async_result.hpp>
|
||||||
#include <boost/asio/buffer.hpp>
|
#include <boost/asio/buffer.hpp>
|
||||||
|
#include <boost/logic/tribool.hpp>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
@ -60,12 +61,12 @@ namespace http {
|
|||||||
template<class NextLayer>
|
template<class NextLayer>
|
||||||
class icy_stream
|
class icy_stream
|
||||||
{
|
{
|
||||||
struct ops;
|
|
||||||
|
|
||||||
NextLayer stream_;
|
NextLayer stream_;
|
||||||
bool detect_ = true;
|
|
||||||
unsigned char copy_ = 0;
|
|
||||||
char buf_[8];
|
char buf_[8];
|
||||||
|
unsigned char n_ = 0;
|
||||||
|
bool detect_ = true;
|
||||||
|
|
||||||
|
struct ops;
|
||||||
|
|
||||||
static
|
static
|
||||||
net::const_buffer
|
net::const_buffer
|
||||||
|
@ -11,22 +11,13 @@
|
|||||||
#define BOOST_BEAST_CORE_IMPL_ICY_STREAM_HPP
|
#define BOOST_BEAST_CORE_IMPL_ICY_STREAM_HPP
|
||||||
|
|
||||||
#include <boost/beast/core/async_base.hpp>
|
#include <boost/beast/core/async_base.hpp>
|
||||||
#include <boost/beast/core/bind_handler.hpp>
|
|
||||||
#include <boost/beast/core/buffer_traits.hpp>
|
#include <boost/beast/core/buffer_traits.hpp>
|
||||||
#include <boost/beast/core/buffers_adaptor.hpp>
|
#include <boost/beast/core/error.hpp>
|
||||||
#include <boost/beast/core/buffers_prefix.hpp>
|
|
||||||
#include <boost/beast/core/buffers_suffix.hpp>
|
|
||||||
#include <boost/beast/core/dynamic_buffer_ref.hpp>
|
|
||||||
#include <boost/beast/core/stream_traits.hpp>
|
#include <boost/beast/core/stream_traits.hpp>
|
||||||
#include <boost/beast/core/detail/buffers_ref.hpp>
|
#include <boost/beast/core/detail/is_invocable.hpp>
|
||||||
#include <boost/asio/buffers_iterator.hpp>
|
|
||||||
#include <boost/asio/coroutine.hpp>
|
#include <boost/asio/coroutine.hpp>
|
||||||
#include <boost/asio/post.hpp>
|
|
||||||
#include <boost/asio/read.hpp>
|
|
||||||
#include <boost/asio/read_until.hpp>
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/throw_exception.hpp>
|
#include <boost/throw_exception.hpp>
|
||||||
#include <algorithm>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -37,84 +28,25 @@ namespace http {
|
|||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<class MutableBuffers, class ConstBuffers>
|
template<class ConstBufferSequence>
|
||||||
void
|
boost::tribool
|
||||||
buffer_shift(MutableBuffers const& out, ConstBuffers const& in)
|
is_icy(ConstBufferSequence const& buffers)
|
||||||
{
|
{
|
||||||
auto in_pos = net::buffer_sequence_end(in);
|
char buf[3];
|
||||||
auto out_pos = net::buffer_sequence_end(out);
|
auto const n = net::buffer_copy(
|
||||||
auto const in_begin = net::buffer_sequence_begin(in);
|
net::mutable_buffer(buf, 3),
|
||||||
auto const out_begin = net::buffer_sequence_begin(out);
|
buffers);
|
||||||
BOOST_ASSERT(buffer_bytes(in) == buffer_bytes(out));
|
if(n >= 1 && buf[0] != 'I')
|
||||||
if(in_pos == in_begin || out_pos == out_begin)
|
return false;
|
||||||
return;
|
if(n >= 2 && buf[1] != 'C')
|
||||||
net::const_buffer cb{*--in_pos};
|
return false;
|
||||||
net::mutable_buffer mb{*--out_pos};
|
if(n >= 3 && buf[2] != 'Y')
|
||||||
for(;;)
|
return false;
|
||||||
{
|
if(n < 3)
|
||||||
if(mb.size() >= cb.size())
|
return boost::indeterminate;
|
||||||
{
|
return true;
|
||||||
std::memmove(
|
|
||||||
static_cast<char*>(
|
|
||||||
mb.data()) + mb.size() - cb.size(),
|
|
||||||
cb.data(),
|
|
||||||
cb.size());
|
|
||||||
mb = net::mutable_buffer{
|
|
||||||
mb.data(), mb.size() - cb.size()};
|
|
||||||
if(in_pos == in_begin)
|
|
||||||
break;
|
|
||||||
cb = *--in_pos;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::memmove(
|
|
||||||
mb.data(),
|
|
||||||
static_cast<char const*>(
|
|
||||||
cb.data()) + cb.size() - mb.size(),
|
|
||||||
mb.size());
|
|
||||||
cb = net::const_buffer{
|
|
||||||
cb.data(), cb.size() - mb.size()};
|
|
||||||
if(out_pos == out_begin)
|
|
||||||
break;
|
|
||||||
mb = *--out_pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class FwdIt>
|
|
||||||
class match_icy
|
|
||||||
{
|
|
||||||
bool& match_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
using result_type = std::pair<FwdIt, bool>;
|
|
||||||
explicit
|
|
||||||
match_icy(bool& b)
|
|
||||||
: match_(b)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
result_type
|
|
||||||
operator()(FwdIt first, FwdIt last) const
|
|
||||||
{
|
|
||||||
auto it = first;
|
|
||||||
if(it == last)
|
|
||||||
return {first, false};
|
|
||||||
if(*it != 'I')
|
|
||||||
return {last, true};
|
|
||||||
if(++it == last)
|
|
||||||
return {first, false};
|
|
||||||
if(*it != 'C')
|
|
||||||
return {last, true};
|
|
||||||
if(++it == last)
|
|
||||||
return {first, false};
|
|
||||||
if(*it != 'Y')
|
|
||||||
return {last, true};
|
|
||||||
match_ = true;
|
|
||||||
return {last, true};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
} // detail
|
} // detail
|
||||||
|
|
||||||
template<class NextLayer>
|
template<class NextLayer>
|
||||||
@ -123,35 +55,15 @@ struct icy_stream<NextLayer>::ops
|
|||||||
|
|
||||||
template<class Buffers, class Handler>
|
template<class Buffers, class Handler>
|
||||||
class read_op
|
class read_op
|
||||||
: public beast::stable_async_base<Handler,
|
: public beast::async_base<Handler,
|
||||||
beast::executor_type<icy_stream>>
|
beast::executor_type<icy_stream>>
|
||||||
, public net::coroutine
|
, public net::coroutine
|
||||||
{
|
{
|
||||||
// VFALCO We need a stable reference to `b`
|
icy_stream& s_;
|
||||||
// to pass to asio's read functions.
|
Buffers b_;
|
||||||
//
|
std::size_t n_ = 0;
|
||||||
// VFALCO Why did I do all this rigamarole?
|
error_code ec_;
|
||||||
// we only need 6 or 8 bytes at most,
|
bool match_ = false;
|
||||||
// this should all just be tucked
|
|
||||||
// away into the icy_stream. We can
|
|
||||||
// simulate a dynamic buffer adaptor
|
|
||||||
// with one or two simple ints.
|
|
||||||
struct data
|
|
||||||
{
|
|
||||||
icy_stream& s;
|
|
||||||
buffers_adaptor<Buffers> b;
|
|
||||||
bool match = false;
|
|
||||||
|
|
||||||
data(
|
|
||||||
icy_stream& s_,
|
|
||||||
Buffers const& b_)
|
|
||||||
: s(s_)
|
|
||||||
, b(b_)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
data& d_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<class Handler_>
|
template<class Handler_>
|
||||||
@ -159,140 +71,77 @@ public:
|
|||||||
Handler_&& h,
|
Handler_&& h,
|
||||||
icy_stream& s,
|
icy_stream& s,
|
||||||
Buffers const& b)
|
Buffers const& b)
|
||||||
: stable_async_base<Handler,
|
: async_base<Handler,
|
||||||
beast::executor_type<icy_stream>>(
|
beast::executor_type<icy_stream>>(
|
||||||
std::forward<Handler_>(h), s.get_executor())
|
std::forward<Handler_>(h), s.get_executor())
|
||||||
, d_(beast::allocate_stable<data>(*this, s, b))
|
, s_(s)
|
||||||
|
, b_(b)
|
||||||
{
|
{
|
||||||
(*this)({}, 0);
|
(*this)({}, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
operator()(
|
operator()(
|
||||||
boost::system::error_code ec,
|
error_code ec,
|
||||||
std::size_t bytes_transferred)
|
std::size_t bytes_transferred,
|
||||||
|
bool cont = true)
|
||||||
{
|
{
|
||||||
using iterator = net::buffers_iterator<
|
|
||||||
typename beast::dynamic_buffer_ref_wrapper<
|
|
||||||
buffers_adaptor<Buffers>>::const_buffers_type>;
|
|
||||||
BOOST_ASIO_CORO_REENTER(*this)
|
BOOST_ASIO_CORO_REENTER(*this)
|
||||||
{
|
{
|
||||||
if(d_.b.max_size() == 0)
|
if(s_.detect_)
|
||||||
{
|
{
|
||||||
BOOST_ASIO_CORO_YIELD
|
BOOST_ASSERT(s_.n_ == 0);
|
||||||
net::post(d_.s.get_executor(),
|
for(;;)
|
||||||
beast::bind_handler(std::move(*this), ec, 0));
|
|
||||||
goto upcall;
|
|
||||||
}
|
|
||||||
if(! d_.s.detect_)
|
|
||||||
{
|
|
||||||
if(d_.s.copy_ > 0)
|
|
||||||
{
|
|
||||||
auto const n = net::buffer_copy(
|
|
||||||
d_.b.prepare(std::min<std::size_t>(
|
|
||||||
d_.s.copy_, d_.b.max_size())),
|
|
||||||
net::buffer(d_.s.buf_));
|
|
||||||
d_.b.commit(n);
|
|
||||||
d_.s.copy_ = static_cast<unsigned char>(
|
|
||||||
d_.s.copy_ - n);
|
|
||||||
if(d_.s.copy_ > 0)
|
|
||||||
std::memmove(
|
|
||||||
d_.s.buf_,
|
|
||||||
&d_.s.buf_[n],
|
|
||||||
d_.s.copy_);
|
|
||||||
}
|
|
||||||
if(d_.b.size() < d_.b.max_size())
|
|
||||||
{
|
{
|
||||||
|
// Try to read the first three characters
|
||||||
BOOST_ASIO_CORO_YIELD
|
BOOST_ASIO_CORO_YIELD
|
||||||
d_.s.next_layer().async_read_some(
|
s_.next_layer().async_read_some(
|
||||||
d_.b.prepare(d_.b.max_size() - d_.b.size()),
|
net::mutable_buffer(
|
||||||
|
s_.buf_ + s_.n_, 3 - s_.n_),
|
||||||
std::move(*this));
|
std::move(*this));
|
||||||
d_.b.commit(bytes_transferred);
|
s_.n_ += static_cast<char>(bytes_transferred);
|
||||||
|
if(ec)
|
||||||
|
goto upcall;
|
||||||
|
auto result = detail::is_icy(
|
||||||
|
net::const_buffer(s_.buf_, s_.n_));
|
||||||
|
if(boost::indeterminate(result))
|
||||||
|
continue;
|
||||||
|
if(result)
|
||||||
|
s_.n_ = static_cast<char>(net::buffer_copy(
|
||||||
|
net::buffer(s_.buf_, sizeof(s_.buf_)),
|
||||||
|
icy_stream::version()));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
bytes_transferred = d_.b.size();
|
s_.detect_ = false;
|
||||||
goto upcall;
|
|
||||||
}
|
}
|
||||||
|
if(s_.n_ > 0)
|
||||||
d_.s.detect_ = false;
|
{
|
||||||
if(d_.b.max_size() < 8)
|
bytes_transferred = net::buffer_copy(
|
||||||
|
b_, net::const_buffer(s_.buf_, s_.n_));
|
||||||
|
s_.n_ -= static_cast<char>(bytes_transferred);
|
||||||
|
std::memmove(
|
||||||
|
s_.buf_,
|
||||||
|
s_.buf_ + bytes_transferred,
|
||||||
|
sizeof(s_.buf_) - bytes_transferred);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
BOOST_ASIO_CORO_YIELD
|
BOOST_ASIO_CORO_YIELD
|
||||||
net::async_read(
|
s_.next_layer().async_read_some(
|
||||||
d_.s.next_layer(),
|
b_, std::move(*this));
|
||||||
net::buffer(d_.s.buf_, 3),
|
|
||||||
std::move(*this));
|
|
||||||
if(ec)
|
|
||||||
goto upcall;
|
|
||||||
auto n = bytes_transferred;
|
|
||||||
BOOST_ASSERT(n == 3);
|
|
||||||
if(
|
|
||||||
d_.s.buf_[0] != 'I' ||
|
|
||||||
d_.s.buf_[1] != 'C' ||
|
|
||||||
d_.s.buf_[2] != 'Y')
|
|
||||||
{
|
|
||||||
net::buffer_copy(
|
|
||||||
d_.b.value(),
|
|
||||||
net::buffer(d_.s.buf_, n));
|
|
||||||
if(d_.b.max_size() < 3)
|
|
||||||
{
|
|
||||||
d_.s.copy_ = static_cast<unsigned char>(
|
|
||||||
3 - d_.b.max_size());
|
|
||||||
std::memmove(
|
|
||||||
d_.s.buf_,
|
|
||||||
&d_.s.buf_[d_.b.max_size()],
|
|
||||||
d_.s.copy_);
|
|
||||||
|
|
||||||
}
|
|
||||||
bytes_transferred = (std::min)(
|
|
||||||
n, d_.b.max_size());
|
|
||||||
goto upcall;
|
|
||||||
}
|
|
||||||
d_.s.copy_ = static_cast<unsigned char>(
|
|
||||||
net::buffer_copy(
|
|
||||||
net::buffer(d_.s.buf_),
|
|
||||||
icy_stream::version() + d_.b.max_size()));
|
|
||||||
bytes_transferred = net::buffer_copy(
|
|
||||||
d_.b.value(), icy_stream::version());
|
|
||||||
goto upcall;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_ASIO_CORO_YIELD
|
|
||||||
net::async_read_until(
|
|
||||||
d_.s.next_layer(),
|
|
||||||
beast::dynamic_buffer_ref(d_.b),
|
|
||||||
detail::match_icy<iterator>(d_.match),
|
|
||||||
std::move(*this));
|
|
||||||
if(ec)
|
|
||||||
goto upcall;
|
|
||||||
{
|
|
||||||
auto n = bytes_transferred;
|
|
||||||
BOOST_ASSERT(n == d_.b.size());
|
|
||||||
if(! d_.match)
|
|
||||||
goto upcall;
|
|
||||||
if(d_.b.size() + 5 > d_.b.max_size())
|
|
||||||
{
|
|
||||||
d_.s.copy_ = static_cast<unsigned char>(
|
|
||||||
n + 5 - d_.b.max_size());
|
|
||||||
std::copy(
|
|
||||||
net::buffers_begin(d_.b.value()) + n - d_.s.copy_,
|
|
||||||
net::buffers_begin(d_.b.value()) + n,
|
|
||||||
d_.s.buf_);
|
|
||||||
n = d_.b.max_size() - 5;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
buffers_suffix<beast::detail::buffers_ref<
|
|
||||||
Buffers>> dest(
|
|
||||||
boost::in_place_init, d_.b.value());
|
|
||||||
dest.consume(5);
|
|
||||||
detail::buffer_shift(
|
|
||||||
beast::buffers_prefix(n, dest),
|
|
||||||
beast::buffers_prefix(n, d_.b.value()));
|
|
||||||
net::buffer_copy(d_.b.value(), icy_stream::version());
|
|
||||||
n += 5;
|
|
||||||
bytes_transferred = n;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
upcall:
|
upcall:
|
||||||
|
if(! cont)
|
||||||
|
{
|
||||||
|
ec_ = ec;
|
||||||
|
n_ = bytes_transferred;
|
||||||
|
BOOST_ASIO_CORO_YIELD
|
||||||
|
s_.next_layer().async_read_some(
|
||||||
|
net::mutable_buffer{},
|
||||||
|
std::move(*this));
|
||||||
|
ec = ec_;
|
||||||
|
bytes_transferred = n_;
|
||||||
|
}
|
||||||
this->complete_now(ec, bytes_transferred);
|
this->complete_now(ec, bytes_transferred);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -333,6 +182,7 @@ icy_stream<NextLayer>::
|
|||||||
icy_stream(Args&&... args)
|
icy_stream(Args&&... args)
|
||||||
: stream_(std::forward<Args>(args)...)
|
: stream_(std::forward<Args>(args)...)
|
||||||
{
|
{
|
||||||
|
std::memset(buf_, 0, sizeof(buf_));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class NextLayer>
|
template<class NextLayer>
|
||||||
@ -364,109 +214,46 @@ read_some(MutableBufferSequence const& buffers, error_code& ec)
|
|||||||
static_assert(net::is_mutable_buffer_sequence<
|
static_assert(net::is_mutable_buffer_sequence<
|
||||||
MutableBufferSequence>::value,
|
MutableBufferSequence>::value,
|
||||||
"MutableBufferSequence type requirements not met");
|
"MutableBufferSequence type requirements not met");
|
||||||
using iterator = net::buffers_iterator<
|
std::size_t bytes_transferred;
|
||||||
typename beast::dynamic_buffer_ref_wrapper<
|
if(detect_)
|
||||||
buffers_adaptor<MutableBufferSequence>>::const_buffers_type>;
|
|
||||||
buffers_adaptor<MutableBufferSequence> b(buffers);
|
|
||||||
if(b.max_size() == 0)
|
|
||||||
{
|
{
|
||||||
ec = {};
|
BOOST_ASSERT(n_ == 0);
|
||||||
return 0;
|
for(;;)
|
||||||
}
|
|
||||||
if(! detect_)
|
|
||||||
{
|
|
||||||
if(copy_ > 0)
|
|
||||||
{
|
{
|
||||||
auto const n = net::buffer_copy(
|
// Try to read the first three characters
|
||||||
b.prepare(std::min<std::size_t>(
|
bytes_transferred = next_layer().read_some(
|
||||||
copy_, b.max_size())),
|
net::mutable_buffer(buf_ + n_, 3 - n_), ec);
|
||||||
net::buffer(buf_));
|
n_ += static_cast<char>(bytes_transferred);
|
||||||
b.commit(n);
|
if(ec)
|
||||||
copy_ = static_cast<unsigned char>(
|
return 0;
|
||||||
copy_ - n);
|
auto result = detail::is_icy(
|
||||||
if(copy_ > 0)
|
net::const_buffer(buf_, n_));
|
||||||
std::memmove(
|
if(boost::indeterminate(result))
|
||||||
buf_,
|
continue;
|
||||||
&buf_[n],
|
if(result)
|
||||||
copy_);
|
n_ = static_cast<char>(net::buffer_copy(
|
||||||
|
net::buffer(buf_, sizeof(buf_)),
|
||||||
|
icy_stream::version()));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if(b.size() < b.max_size())
|
detect_ = false;
|
||||||
b.commit(stream_.read_some(
|
|
||||||
b.prepare(b.max_size() - b.size()), ec));
|
|
||||||
return b.size();
|
|
||||||
}
|
}
|
||||||
|
if(n_ > 0)
|
||||||
detect_ = false;
|
|
||||||
if(b.max_size() < 8)
|
|
||||||
{
|
{
|
||||||
auto n = net::read(
|
bytes_transferred = net::buffer_copy(
|
||||||
stream_,
|
buffers, net::const_buffer(buf_, n_));
|
||||||
net::buffer(buf_, 3),
|
n_ -= static_cast<char>(bytes_transferred);
|
||||||
ec);
|
std::memmove(
|
||||||
if(ec)
|
buf_,
|
||||||
return 0;
|
buf_ + bytes_transferred,
|
||||||
BOOST_ASSERT(n == 3);
|
sizeof(buf_) - bytes_transferred);
|
||||||
if(
|
|
||||||
buf_[0] != 'I' ||
|
|
||||||
buf_[1] != 'C' ||
|
|
||||||
buf_[2] != 'Y')
|
|
||||||
{
|
|
||||||
net::buffer_copy(
|
|
||||||
buffers,
|
|
||||||
net::buffer(buf_, n));
|
|
||||||
if(b.max_size() < 3)
|
|
||||||
{
|
|
||||||
copy_ = static_cast<unsigned char>(
|
|
||||||
3 - b.max_size());
|
|
||||||
std::memmove(
|
|
||||||
buf_,
|
|
||||||
&buf_[b.max_size()],
|
|
||||||
copy_);
|
|
||||||
|
|
||||||
}
|
|
||||||
return std::min<std::size_t>(
|
|
||||||
n, b.max_size());
|
|
||||||
}
|
|
||||||
copy_ = static_cast<unsigned char>(
|
|
||||||
net::buffer_copy(
|
|
||||||
net::buffer(buf_),
|
|
||||||
version() + b.max_size()));
|
|
||||||
return net::buffer_copy(
|
|
||||||
buffers,
|
|
||||||
version());
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
bool match = false;
|
|
||||||
auto n = net::read_until(
|
|
||||||
stream_,
|
|
||||||
beast::dynamic_buffer_ref(b),
|
|
||||||
detail::match_icy<iterator>(match),
|
|
||||||
ec);
|
|
||||||
if(ec)
|
|
||||||
return n;
|
|
||||||
BOOST_ASSERT(n == b.size());
|
|
||||||
if(! match)
|
|
||||||
return n;
|
|
||||||
if(b.size() + 5 > b.max_size())
|
|
||||||
{
|
{
|
||||||
copy_ = static_cast<unsigned char>(
|
bytes_transferred =
|
||||||
n + 5 - b.max_size());
|
next_layer().read_some(buffers, ec);
|
||||||
std::copy(
|
|
||||||
net::buffers_begin(buffers) + n - copy_,
|
|
||||||
net::buffers_begin(buffers) + n,
|
|
||||||
buf_);
|
|
||||||
n = b.max_size() - 5;
|
|
||||||
}
|
}
|
||||||
buffers_suffix<beast::detail::buffers_ref<
|
return bytes_transferred;
|
||||||
MutableBufferSequence>> dest(
|
|
||||||
boost::in_place_init, buffers);
|
|
||||||
dest.consume(5);
|
|
||||||
detail::buffer_shift(
|
|
||||||
buffers_prefix(n, dest),
|
|
||||||
buffers_prefix(n, buffers));
|
|
||||||
net::buffer_copy(buffers, version());
|
|
||||||
n += 5;
|
|
||||||
return n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class NextLayer>
|
template<class NextLayer>
|
||||||
|
Reference in New Issue
Block a user