Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parser.consume #2913

Draft
wants to merge 3 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions include/boost/beast/core/buffers_cat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ class buffers_cat_view
/// Returns an iterator to one past the last buffer in the sequence
const_iterator
end() const;

/// Get an element in the buffer sequence tuple.
template<std::size_t I>
const detail::tuple_element<I, detail::tuple<Buffers...>> & get() const
{
return detail::get<I>(bn_);
}
};

/** Concatenate 1 or more buffer sequences.
Expand Down
9 changes: 9 additions & 0 deletions include/boost/beast/core/buffers_suffix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ class buffers_suffix
using value_type = buffers_type<BufferSequence>;
#endif

/// The type of the underlying buffer sequence
using sequence_type = BufferSequence;

#if BOOST_BEAST_DOXYGEN
/// A bidirectional iterator type that may be used to read elements.
using const_iterator = __implementation_defined__;
Expand Down Expand Up @@ -136,6 +139,12 @@ class buffers_suffix
*/
void
consume(std::size_t amount);

/// Get the underlying BufferSequence
const sequence_type & buffer_sequence() const {return bs_;}

/// Get the amount of data to skipped at the beginning of the sequence.
std::size_t skip() const {return skip_;}
};

} // beast
Expand Down
133 changes: 115 additions & 18 deletions include/boost/beast/http/impl/serializer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,26 +285,39 @@

template<
bool isRequest, class Body, class Fields>
void
std::size_t
serializer<isRequest, Body, Fields>::
consume(std::size_t n)
{
std::size_t consumed = 0u;
switch(s_)
{
case do_header:
{
BOOST_ASSERT(
n <= buffer_bytes(v_.template get<2>()));
v_.template get<2>().consume(n);
if(buffer_bytes(v_.template get<2>()) > 0)
cb2_t & cb = v_.template get<2>();

const std::size_t pre_size = buffer_bytes(cb.buffer_sequence().template get<0u>());
const std::size_t skip = (std::max)(cb.skip(), pre_size); // the start of the consumed data
cb.consume(n);
if (cb.skip() > skip)
consumed += cb.skip() - skip;

if (cb.skip() > pre_size)
header_done_ = true;

if(buffer_bytes(cb) > 0)
break;
header_done_ = true;

v_.reset();
if(! more_)
goto go_complete;
s_ = do_body + 1;
break;

}
case do_header_only:
{
BOOST_ASSERT(
n <= buffer_bytes(v_.template get<1>()));
v_.template get<1>().consume(n);
Expand All @@ -316,12 +329,13 @@
goto go_complete;
s_ = do_body;
break;

}
case do_body + 2:
{
BOOST_ASSERT(
n <= buffer_bytes(v_.template get<3>()));
v_.template get<3>().consume(n);
consumed = n;
if(buffer_bytes(v_.template get<3>()) > 0)
break;
v_.reset();
Expand All @@ -330,23 +344,43 @@
s_ = do_body + 1;
break;
}

//----------------------------------------------------------------------

case do_header_c:
{
BOOST_ASSERT(
n <= buffer_bytes(v_.template get<4>()));
v_.template get<4>().consume(n);
if(buffer_bytes(v_.template get<4>()) > 0)

cb4_t& cb = v_.template get<4>();
const typename cb4_t::sequence_type & bs = cb.buffer_sequence();

const std::size_t prefix = buffer_bytes(bs.template get<0>())
+ buffer_bytes(bs.template get<1>())
+ buffer_bytes(bs.template get<2>())
+ buffer_bytes(bs.template get<3>());

const std::size_t suffix = buffer_bytes(bs.template get<5>());
const std::size_t skip = (std::max)(cb.skip(), prefix);

cb.consume(n);

const std::size_t consume_end = (std::min)(buffer_bytes(bs) - suffix, cb.skip());

if (cb.skip() > skip)
consumed += consume_end - skip;

Check warning on line 370 in include/boost/beast/http/impl/serializer.hpp

View check run for this annotation

Codecov / codecov/patch

include/boost/beast/http/impl/serializer.hpp#L370

Added line #L370 was not covered by tests

if (cb.skip() >= buffer_bytes(bs.template get<0>()))
header_done_ = true;

Check warning on line 373 in include/boost/beast/http/impl/serializer.hpp

View check run for this annotation

Codecov / codecov/patch

include/boost/beast/http/impl/serializer.hpp#L373

Added line #L373 was not covered by tests

if(buffer_bytes(cb) > 0)
break;
header_done_ = true;
v_.reset();
if(more_)
s_ = do_body_c + 1;
else
s_ = do_final_c;
break;

}
case do_header_only_c:
{
BOOST_ASSERT(
Expand All @@ -366,10 +400,27 @@
}

case do_body_c + 2:
{
BOOST_ASSERT(
n <= buffer_bytes(v_.template get<5>()));
v_.template get<5>().consume(n);
if(buffer_bytes(v_.template get<5>()) > 0)

cb5_t& cb = v_.template get<5>();
const typename cb5_t::sequence_type & bs = cb.buffer_sequence();

const std::size_t prefix = buffer_bytes(bs.template get<0>())
+ buffer_bytes(bs.template get<1>())
+ buffer_bytes(bs.template get<2>());

const std::size_t suffix = buffer_bytes(bs.template get<4>());
const std::size_t skip = (std::max)(cb.skip(), prefix);

cb.consume(n);

const std::size_t consume_end = (std::min)({buffer_bytes(bs), suffix, cb.skip()});
if (cb.skip() > skip)
consumed += consume_end - skip;

if(buffer_bytes(cb) > 0)
break;
v_.reset();
if(more_)
Expand All @@ -378,12 +429,33 @@
s_ = do_final_c;
break;

}
case do_body_final_c:
{
BOOST_ASSERT(
n <= buffer_bytes(v_.template get<6>()));
v_.template get<6>().consume(n);
if(buffer_bytes(v_.template get<6>()) > 0)

cb6_t& cb = v_.template get<6>();
const typename cb6_t::sequence_type & bs = cb.buffer_sequence();

const std::size_t prefix = buffer_bytes(bs.template get<0>())
+ buffer_bytes(bs.template get<1>())
+ buffer_bytes(bs.template get<2>());

const std::size_t suffix = buffer_bytes(bs.template get<4>())
+ buffer_bytes(bs.template get<5>())
+ buffer_bytes(bs.template get<6>())
+ buffer_bytes(bs.template get<7>());

const std::size_t skip = (std::max)(cb.skip(), prefix);

cb.consume(n);

const std::size_t consume_end = (std::min)({buffer_bytes(bs), suffix, cb.skip()});
if (cb.skip() > skip)
consumed += consume_end - skip;

if(buffer_bytes(cb) > 0)
break;
v_.reset();
s_ = do_complete;
Expand All @@ -394,10 +466,34 @@
{
BOOST_ASSERT(
n <= buffer_bytes(v_.template get<7>()));
v_.template get<7>().consume(n);
if(buffer_bytes(v_.template get<7>()) > 0)

cb7_t& cb = v_.template get<7>();
const typename cb7_t::sequence_type & bs = cb.buffer_sequence();

const std::size_t prefix = buffer_bytes(bs.template get<0>())
+ buffer_bytes(bs.template get<1>())
+ buffer_bytes(bs.template get<2>())
+ buffer_bytes(bs.template get<3>());

const std::size_t suffix = buffer_bytes(bs.template get<5>())
+ buffer_bytes(bs.template get<6>())
+ buffer_bytes(bs.template get<7>())
+ buffer_bytes(bs.template get<8>());

const std::size_t skip = (std::max)(cb.skip(), prefix);

cb.consume(n);

const std::size_t consume_end = (std::min)({buffer_bytes(bs), suffix, cb.skip()});
if (cb.skip() > skip)
consumed += consume_end - skip;

if (cb.skip() >= buffer_bytes(bs.template get<0>()))
header_done_ = true;

if(buffer_bytes(cb) > 0)
break;
header_done_ = true;

v_.reset();
s_ = do_complete;
break;
Expand All @@ -422,6 +518,7 @@
s_ = do_complete;
break;
}
return consumed;
}

} // http
Expand Down
12 changes: 7 additions & 5 deletions include/boost/beast/http/impl/write.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,10 @@ class write_some_op
error_code ec,
std::size_t bytes_transferred)
{
std::size_t bytes_consumed = 0u;
if(! ec)
sr_.consume(bytes_transferred);
this->complete_now(ec, bytes_transferred);
bytes_consumed = sr_.consume(bytes_transferred);
this->complete_now(ec, bytes_consumed);
}
};

Expand Down Expand Up @@ -511,15 +512,16 @@ write_some_impl(
serializer<isRequest, Body, Fields>& sr,
error_code& ec)
{
std::size_t consumed = 0u;
if(! sr.is_done())
{
write_some_lambda<SyncWriteStream> f{stream};
sr.next(ec, f);
if(ec)
return f.bytes_transferred;
return consumed;
if(f.invoked)
sr.consume(f.bytes_transferred);
return f.bytes_transferred;
consumed = sr.consume(f.bytes_transferred);
return consumed;
}
ec = {};
return 0;
Expand Down
4 changes: 3 additions & 1 deletion include/boost/beast/http/serializer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,8 +356,10 @@ class serializer
@param n The number of octets to consume. This number must
be greater than zero and no greater than the number of
octets in the buffers provided in the prior call to @ref next.

@return The amount of octets that were consumed from the previous call of .get on the body.
*/
void
std::size_t
consume(std::size_t n);

/** Provides low-level access to the associated <em>BodyWriter</em>
Expand Down
Loading
Loading