diff --git a/include/boost/http_proto/impl/sink.hpp b/include/boost/http_proto/impl/sink.hpp index dffa5fb5..aa064261 100644 --- a/include/boost/http_proto/impl/sink.hpp +++ b/include/boost/http_proto/impl/sink.hpp @@ -10,7 +10,7 @@ #ifndef BOOST_HTTP_PROTO_IMPL_SINK_HPP #define BOOST_HTTP_PROTO_IMPL_SINK_HPP -#include +#include #include #include #include @@ -59,10 +59,11 @@ write_impl( p != tmp_end && it != end_); rv += on_write( - buffers::const_buffer_span( - tmp, p - tmp), - it != end_ || - more); + true, + boost::span< + buffers::const_buffer const>( + tmp, p - tmp), + it != end_ || more); if(rv.ec.failed()) return rv; } diff --git a/include/boost/http_proto/impl/source.hpp b/include/boost/http_proto/impl/source.hpp index d7f569c1..dbfdf36d 100644 --- a/include/boost/http_proto/impl/source.hpp +++ b/include/boost/http_proto/impl/source.hpp @@ -11,8 +11,6 @@ #define BOOST_BUFFERS_IMPL_SOURCE_HPP #include -#include -#include #include namespace boost { @@ -61,8 +59,10 @@ read_impl( p != tmp_end && it != end_); rv += on_read( - buffers::mutable_buffer_span( - tmp, p - tmp)); + true, + boost::span< + buffers::mutable_buffer const>( + tmp, p - tmp)); if(rv.ec.failed()) return rv; if(rv.finished) diff --git a/include/boost/http_proto/parser.hpp b/include/boost/http_proto/parser.hpp index 3943c8d7..5a347eb8 100644 --- a/include/boost/http_proto/parser.hpp +++ b/include/boost/http_proto/parser.hpp @@ -18,10 +18,9 @@ #include #include -#include -#include -#include -#include +#include +#include +#include #include #include @@ -77,12 +76,12 @@ class parser /** The type of buffer returned from @ref prepare. */ using mutable_buffers_type = - buffers::mutable_buffer_span; + boost::span; /** The type of buffer returned from @ref pull_body. */ using const_buffers_type = - buffers::const_buffer_span; + boost::span; //-------------------------------------------- // diff --git a/include/boost/http_proto/serializer.hpp b/include/boost/http_proto/serializer.hpp index 8337b978..0d3fbfc0 100644 --- a/include/boost/http_proto/serializer.hpp +++ b/include/boost/http_proto/serializer.hpp @@ -15,9 +15,8 @@ #include #include -#include -#include -#include +#include +#include #include #include @@ -65,7 +64,7 @@ class serializer area. */ using const_buffers_type = - buffers::const_buffer_span; + boost::span; /** Constructor. diff --git a/include/boost/http_proto/sink.hpp b/include/boost/http_proto/sink.hpp index 01ba5bba..f49b9299 100644 --- a/include/boost/http_proto/sink.hpp +++ b/include/boost/http_proto/sink.hpp @@ -11,8 +11,8 @@ #define BOOST_HTTP_PROTO_SINK_HPP #include -#include -#include +#include +#include #include #include #include @@ -192,7 +192,8 @@ struct BOOST_SYMBOL_VISIBLE virtual results on_write( - buffers::const_buffer_span bs, + bool boost_span_issue_202_workaround, + boost::span bs, bool more); private: @@ -212,13 +213,13 @@ struct BOOST_SYMBOL_VISIBLE return on_write(b, more); } - results - write_impl( - buffers::const_buffer_span const& bs, - bool more) - { - return on_write(bs, more); - } + // results + // write_impl( + // boost::span const& bs, + // bool more) + // { + // return on_write(bs, more); + // } template results diff --git a/include/boost/http_proto/source.hpp b/include/boost/http_proto/source.hpp index 853ffebf..e8b9e5c1 100644 --- a/include/boost/http_proto/source.hpp +++ b/include/boost/http_proto/source.hpp @@ -11,8 +11,8 @@ #define BOOST_HTTP_PROTO_SOURCE_HPP #include -#include -#include +#include +#include #include #include #include @@ -195,7 +195,8 @@ struct BOOST_SYMBOL_VISIBLE virtual results on_read( - buffers::mutable_buffer_span bs); + bool boost_span_issue_202_workaround, + boost::span bs); private: results @@ -205,12 +206,12 @@ struct BOOST_SYMBOL_VISIBLE return on_read(b); } - results - read_impl( - buffers::mutable_buffer_span const& bs) - { - return on_read(bs); - } + // results + // read_impl( + // boost::span const& bs) + // { + // return on_read(bs); + // } template results diff --git a/include/boost/http_proto/string_body.hpp b/include/boost/http_proto/string_body.hpp index 6dac063e..6242bd79 100644 --- a/include/boost/http_proto/string_body.hpp +++ b/include/boost/http_proto/string_body.hpp @@ -11,7 +11,7 @@ #define BOOST_HTTP_PROTO_STRING_BODY_HPP #include -#include +#include #include #include diff --git a/src/detail/array_of_const_buffers.cpp b/src/detail/array_of_const_buffers.cpp index 91a51bc2..17e9f67c 100644 --- a/src/detail/array_of_const_buffers.cpp +++ b/src/detail/array_of_const_buffers.cpp @@ -12,7 +12,7 @@ #include -#include +#include namespace boost { namespace http_proto { @@ -38,7 +38,7 @@ consume(std::size_t n) auto* p = base_ + pos_; if(n < p->size()) { - *p = buffers::sans_prefix(*p, n); + buffers::trim_front(*p, n); return; } n -= p->size(); diff --git a/src/detail/array_of_const_buffers.hpp b/src/detail/array_of_const_buffers.hpp index 4bdece43..0db72cb9 100644 --- a/src/detail/array_of_const_buffers.hpp +++ b/src/detail/array_of_const_buffers.hpp @@ -11,7 +11,8 @@ #ifndef BOOST_HTTP_PROTO_DETAIL_ARRAY_OF_BUFFERS_HPP #define BOOST_HTTP_PROTO_DETAIL_ARRAY_OF_BUFFERS_HPP -#include +#include +#include #include diff --git a/src/detail/buffer_utils.hpp b/src/detail/buffer_utils.hpp new file mode 100644 index 00000000..64c6d6a6 --- /dev/null +++ b/src/detail/buffer_utils.hpp @@ -0,0 +1,44 @@ +// +// Copyright (c) 2025 Mohammad Nejati +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/cppalliance/http_proto +// + +#ifndef BOOST_HTTP_PROTO_DETAIL_BUFFER_UTILS_HPP +#define BOOST_HTTP_PROTO_DETAIL_BUFFER_UTILS_HPP + +#include +#include +#include + +namespace boost { +namespace http_proto { +namespace detail { + +template< + typename BufferSequence, + typename Buffer = typename BufferSequence::value_type> +boost::span +make_span(BufferSequence const& mbp) +{ + return { mbp.begin(), mbp.end() }; +} + +template +BufferSequence +prefix( + BufferSequence cbp, + std::size_t n) +{ + buffers::keep_front(cbp, n); + return cbp; +} + +} // detail +} // http_proto +} // boost + +#endif diff --git a/src/detail/filter.cpp b/src/detail/filter.cpp index 26ede36c..a6173862 100644 --- a/src/detail/filter.cpp +++ b/src/detail/filter.cpp @@ -11,8 +11,6 @@ #include "src/detail/filter.hpp" #include -#include -#include namespace boost { namespace http_proto { @@ -21,7 +19,8 @@ namespace detail { auto filter:: process( - buffers::mutable_buffer_subspan out, + buffers::slice_of< + boost::span> out, buffers::const_buffer_pair in, bool more) -> results { @@ -58,8 +57,8 @@ process( return rv; } - out = buffers::sans_prefix(out, rs.out_bytes); - in = buffers::sans_prefix(in, rs.in_bytes); + buffers::trim_front(out, rs.out_bytes); + buffers::trim_front(in, rs.in_bytes); if(buffers::size(out) == 0) return rv; diff --git a/src/detail/filter.hpp b/src/detail/filter.hpp index 20262647..373e0010 100644 --- a/src/detail/filter.hpp +++ b/src/detail/filter.hpp @@ -11,8 +11,9 @@ #ifndef BOOST_HTTP_PROTO_DETAIL_FILTER_HPP #define BOOST_HTTP_PROTO_DETAIL_FILTER_HPP -#include -#include +#include +#include +#include #include namespace boost { @@ -62,7 +63,8 @@ class filter results process( - buffers::mutable_buffer_subspan out, + buffers::slice_of< + boost::span> out, buffers::const_buffer_pair in, bool more); diff --git a/src/parser.cpp b/src/parser.cpp index 4df14db1..b82db336 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -13,6 +13,7 @@ #include #include "src/detail/brotli_filter_base.hpp" +#include "src/detail/buffer_utils.hpp" #include "src/detail/zlib_filter_base.hpp" #include @@ -20,9 +21,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -789,7 +787,7 @@ class parser::impl n = clamp(n, svc_.cfg.max_prepare); nprepare_ = n; mbp_ = cb0_.prepare(n); - return mutable_buffers_type(mbp_); + return detail::make_span(mbp_); } else { @@ -829,7 +827,7 @@ class parser::impl nprepare_ = n; mbp_ = cb0_.prepare(n); - return mutable_buffers_type(mbp_); + return detail::make_span(mbp_); } case style::elastic: { @@ -871,7 +869,7 @@ class parser::impl // we can detect overflow nprepare_ = 1; mbp_ = cb0_.prepare(1); - return mutable_buffers_type(mbp_); + return detail::make_span(mbp_); } } @@ -1319,7 +1317,7 @@ class parser::impl const std::size_t chunk_avail = clamp(chunk_remain_, cb0_.size()); const auto chunk = - buffers::prefix(cb0_.data(), chunk_avail); + detail::prefix(cb0_.data(), chunk_avail); if(body_limit_remain() < chunk_avail) { @@ -1461,9 +1459,7 @@ class parser::impl payload_remain_ -= payload_avail; body_total_ += payload_avail; auto sink_rs = sink_->write( - buffers::prefix( - cb0_.data(), - payload_avail), + detail::prefix(cb0_.data(), payload_avail), !is_complete); cb0_.consume(sink_rs.bytes); if(sink_rs.ec.failed()) @@ -1541,9 +1537,7 @@ class parser::impl case style::sink: { auto rs = sink_->write( - buffers::prefix( - body_buf.data(), - body_avail_), + detail::prefix(body_buf.data(), body_avail_), state_ == state::set_body); body_buf.consume(rs.bytes); body_avail_ -= rs.bytes; @@ -1600,10 +1594,10 @@ class parser::impl return {}; case state::body: case state::complete_in_place: - cbp_ = buffers::prefix( + cbp_ = detail::prefix( (is_plain() ? cb0_ : cb1_).data(), body_avail_); - return const_buffers_type(cbp_); + return detail::make_span(cbp_); default: detail::throw_logic_error(); } @@ -1736,9 +1730,7 @@ class parser::impl return filter_->process( eb_->prepare(n), - buffers::prefix( - cb0_.data(), - payload_avail), + detail::prefix(cb0_.data(), payload_avail), more); } else // in-place and sink @@ -1747,10 +1739,8 @@ class parser::impl n = clamp(n, cb1_.capacity()); return filter_->process( - buffers::mutable_buffer_span{ cb1_.prepare(n) }, - buffers::prefix( - cb0_.data(), - payload_avail), + detail::make_span(cb1_.prepare(n)), + detail::prefix(cb0_.data(), payload_avail), more); } }(); diff --git a/src/serializer.cpp b/src/serializer.cpp index 82813edf..d8e00a5e 100644 --- a/src/serializer.cpp +++ b/src/serializer.cpp @@ -16,14 +16,11 @@ #include "src/detail/array_of_const_buffers.hpp" #include "src/detail/brotli_filter_base.hpp" +#include "src/detail/buffer_utils.hpp" #include "src/detail/zlib_filter_base.hpp" #include #include -#include -#include -#include -#include #include #include #include @@ -396,9 +393,7 @@ class serializer::impl } } } - return const_buffers_type( - prepped_.begin(), - prepped_.size()); + return detail::make_span(prepped_); } case style::source: @@ -444,8 +439,7 @@ class serializer::impl break; const auto rs = filter_->process( - buffers::mutable_buffer_span( - out_prepare()), + detail::make_span(out_prepare()), {}, // empty input false); @@ -479,8 +473,7 @@ class serializer::impl } const auto rs = filter_->process( - buffers::mutable_buffer_span( - out_prepare()), + detail::make_span(out_prepare()), { tmp_, {} }, more_input_); @@ -491,8 +484,7 @@ class serializer::impl return rs.ec; } - tmp_ = buffers::sans_prefix( - tmp_, rs.in_bytes); + buffers::trim_front(tmp_, rs.in_bytes); out_commit(rs.out_bytes); if(rs.out_short) @@ -527,8 +519,7 @@ class serializer::impl } const auto rs = filter_->process( - buffers::mutable_buffer_span( - out_prepare()), + detail::make_span(out_prepare()), in_.data(), more_input_); @@ -560,8 +551,7 @@ class serializer::impl break; const auto rs = filter_->process( - buffers::mutable_buffer_span( - out_prepare()), + detail::make_span(out_prepare()), in_.data(), more_input_); @@ -590,15 +580,12 @@ class serializer::impl } prepped_.reset(!is_header_done()); - const auto cbp = out_.data(); - if(cbp[0].size() != 0) - prepped_.append(cbp[0]); - if(cbp[1].size() != 0) - prepped_.append(cbp[1]); - - return const_buffers_type( - prepped_.begin(), - prepped_.size()); + for(auto const& cb : out_.data()) + { + if(cb.size() != 0) + prepped_.append(cb); + } + return detail::make_span(prepped_); } void @@ -880,15 +867,15 @@ class serializer::impl buffers::mutable_buffer_pair out_prepare() noexcept { + auto mbp = out_.prepare(out_.capacity()); if(is_chunked_) { - return buffers::sans_suffix( - buffers::sans_prefix( - out_.prepare(out_.capacity()), - chunk_header_len_), - crlf_and_final_chunk.size()); + buffers::trim_front( + mbp, chunk_header_len_); + buffers::trim_back( + mbp, crlf_and_final_chunk.size()); } - return out_.prepare(out_.capacity()); + return mbp; } void diff --git a/src/sink.cpp b/src/sink.cpp index 1883ac79..6627791b 100644 --- a/src/sink.cpp +++ b/src/sink.cpp @@ -15,7 +15,8 @@ namespace http_proto { auto sink:: on_write( - buffers::const_buffer_span bs, + bool, + boost::span bs, bool more) -> results { @@ -27,9 +28,9 @@ on_write( do { buffers::const_buffer b(*it++); - rv += on_write(b, - it != end_ || - more); + rv += on_write( + b, + it != end_ || more); if(rv.ec.failed()) return rv; } diff --git a/src/source.cpp b/src/source.cpp index 7b535085..e160104d 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -16,7 +16,8 @@ namespace http_proto { auto source:: on_read( - buffers::mutable_buffer_span bs) -> + bool, + boost::span bs) -> results { results rv; diff --git a/test/unit/compression.cpp b/test/unit/compression.cpp index 643e8186..86ae0dc6 100644 --- a/test/unit/compression.cpp +++ b/test/unit/compression.cpp @@ -261,7 +261,7 @@ struct zlib_test results rs; auto n = buffers::copy(b, body_); - body_ = buffers::sans_prefix(body_, n); + buffers::trim_front(body_, n); rs.bytes = n; rs.finished = (body_.size() == 0); done_ = rs.finished; @@ -296,7 +296,7 @@ struct zlib_test { auto mbs = stream.prepare(); auto n = buffers::copy(mbs, body); - body = buffers::sans_prefix(body, n); + buffers::trim_front(body, n); stream.commit(n); if(body.size() == 0) stream.close(); @@ -333,8 +333,10 @@ struct zlib_test auto buf_size = std::min(body.size() / 23, body.size()); if(buf_size == 0) buf_size = 1; - buf_seq.push_back(buffers::prefix(body, buf_size)); - body = buffers::sans_prefix(body, buf_size); + buf_seq.emplace_back( + body.data(), + body.size() ? buf_size : 0); + buffers::trim_front(body, buf_size); } while(body.size() != 0); sr.start(res, buf_seq); @@ -481,8 +483,8 @@ struct zlib_test if(input.size() != 0) { auto n1 = buffers::copy(pr.prepare(), input); + buffers::trim_front(input, n1); pr.commit(n1); - input = buffers::sans_prefix(input, n1); } boost::system::error_code ec; @@ -519,9 +521,8 @@ struct zlib_test buffers::const_buffer input) { std::string rs; - std::size_t n1 = buffers::copy( - pr.prepare(), input); - input = buffers::sans_prefix(input, n1); + auto n1 = buffers::copy(pr.prepare(), input); + buffers::trim_front(input, n1); pr.commit(n1); system::error_code ec; pr.parse(ec); @@ -533,9 +534,8 @@ struct zlib_test while(ec == error::need_data) { - std::size_t n2 = buffers::copy( - pr.prepare(), input); - input = buffers::sans_prefix(input, n2); + auto n2 = buffers::copy(pr.prepare(), input); + buffers::trim_front(input, n2); pr.commit(n2); pr.parse(ec); if(n2 == 0) @@ -554,9 +554,8 @@ struct zlib_test response_parser& pr, buffers::const_buffer input) { - std::size_t n1 = buffers::copy( - pr.prepare(), input); - input = buffers::sans_prefix(input, n1); + auto n1 = buffers::copy(pr.prepare(), input); + buffers::trim_front(input, n1); pr.commit(n1); system::error_code ec; pr.parse(ec); @@ -596,9 +595,8 @@ struct zlib_test while(ec == error::need_data) { - std::size_t n2 = buffers::copy( - pr.prepare(), input); - input = buffers::sans_prefix(input, n2); + auto n2 = buffers::copy(pr.prepare(), input); + buffers::trim_front(input, n2); pr.commit(n2); pr.parse(ec); if(n2 == 0) diff --git a/test/unit/file_source.cpp b/test/unit/file_source.cpp index ee0b4259..aae19b10 100644 --- a/test/unit/file_source.cpp +++ b/test/unit/file_source.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include @@ -63,7 +62,7 @@ struct file_source_test file_source fsource(std::move(f)); char buf[16] = {}; auto rs = fsource.read( - buffers::mutable_buffer(buf, 16)); + buffers::make_buffer(buf)); BOOST_TEST_EQ(rs.bytes, 0); BOOST_TEST(rs.ec.failed()); BOOST_TEST(!rs.finished); @@ -86,8 +85,7 @@ struct file_source_test core::string_view { auto rs = fsource.read( - buffers::prefix( - buffers::make_buffer(buf), n)); + buffers::mutable_buffer{ buf, n }); BOOST_TEST_EQ(rs.finished, !more); BOOST_TEST(!rs.ec); return { buf, rs.bytes }; @@ -112,7 +110,8 @@ struct file_source_test { char buf[5] = {}; - auto rs = fsource.read(buffers::make_buffer(buf)); + auto rs = fsource.read( + buffers::make_buffer(buf)); BOOST_TEST_EQ(rs.bytes, 5); BOOST_TEST(!rs.ec); BOOST_TEST(!rs.finished); @@ -123,7 +122,8 @@ struct file_source_test { char buf[5] = {}; - auto rs = fsource.read(buffers::make_buffer(buf)); + auto rs = fsource.read( + buffers::make_buffer(buf)); BOOST_TEST_EQ(rs.bytes, 1); BOOST_TEST(!rs.ec); BOOST_TEST(rs.finished); diff --git a/test/unit/parser.cpp b/test/unit/parser.cpp index d1e446d7..55f8ee95 100644 --- a/test/unit/parser.cpp +++ b/test/unit/parser.cpp @@ -14,7 +14,6 @@ #include #include -#include #include #include #include diff --git a/test/unit/serializer.cpp b/test/unit/serializer.cpp index e7976f37..5c4ad838 100644 --- a/test/unit/serializer.cpp +++ b/test/unit/serializer.cpp @@ -12,12 +12,9 @@ #include #include -#include #include #include -#include -#include -#include +#include #include #include #include @@ -114,14 +111,17 @@ struct serializer_test std::string read_some(serializer& sr) { - auto cbs = sr.prepare().value(); + buffers::slice_of< + serializer::const_buffers_type> cbs + = sr.prepare().value(); BOOST_TEST(!sr.is_done()); // We limit buffer consumption to necessitate // multiple calls to serializer::prepare() and // serializer::consume(), allowing tests to cover // state management within these functions std::string s; - for( auto buf : buffers::prefix(cbs, 256) ) + buffers::keep_front(cbs, 256); + for( auto buf : cbs) { s.append( reinterpret_cast(buf.data()), @@ -326,9 +326,7 @@ struct serializer_test rts::context ctx; install_serializer_service(ctx, {}); serializer sr(ctx); - buffers::const_buffer_span cbs( - buf.data(), buf.size()); - sr.start(res, cbs); + sr.start(res, buf); std::string s = read(sr); core::string_view sv(s); @@ -412,17 +410,15 @@ struct serializer_test while( buf.size() > 0 ) { - auto num_copied = - buffers::copy(out_buf, buf); - - buf = buffers::sans_prefix(buf, num_copied); + auto n = buffers::copy(out_buf, buf); + buffers::trim_front(buf, n); s.insert( s.end(), storage.begin(), - storage.begin() + num_copied); + storage.begin() + n); - sr.consume(num_copied); + sr.consume(n); } }; diff --git a/test/unit/sink.cpp b/test/unit/sink.cpp index b0e21f63..44b90863 100644 --- a/test/unit/sink.cpp +++ b/test/unit/sink.cpp @@ -69,7 +69,7 @@ struct sink_test { &pat[0], 3 }, { &pat[3], 5 }, { &pat[8], 7 } }; - buffers::const_buffer_span bs(cb, 3); + boost::span bs(cb); auto rv = dest.write(bs, false); if(rv.ec.failed()) continue; @@ -107,8 +107,9 @@ struct sink_test // empty sequence { test_sink dest(99); - buffers::const_buffer_span bs; - auto rv = dest.write(bs, true); + auto rv = dest.write( + boost::span{}, + true); BOOST_TEST(! rv.ec.failed()); BOOST_TEST_EQ(rv.bytes, 0); } diff --git a/test/unit/source.cpp b/test/unit/source.cpp index 449ce7b6..6e781b9c 100644 --- a/test/unit/source.cpp +++ b/test/unit/source.cpp @@ -10,6 +10,9 @@ // Test that header file is self-contained. #include +#include +#include + #include "test_helpers.hpp" namespace boost { @@ -43,9 +46,8 @@ struct source_test boost::system::generic_category()); return rv; } - auto const n = - buffers::copy(b, cb_); - cb_ = buffers::sans_prefix(cb_, n); + auto n = buffers::copy(b, cb_); + buffers::trim_front(cb_, n); rv.bytes += n; rv.finished = cb_.size() == 0; return rv; @@ -67,7 +69,7 @@ struct source_test { &s[0], 3 }, { &s[3], 5 }, { &s[8], 7 } }; - buffers::mutable_buffer_span bs(mb, 3); + boost::span bs(mb); auto rv = src.read(bs); if(rv.ec.failed()) continue; @@ -101,8 +103,8 @@ struct source_test // empty sequence { test_source src(99); - buffers::mutable_buffer_span bs; - auto rv = src.read(bs); + auto rv = src.read( + boost::span{}); BOOST_TEST(! rv.ec.failed()); BOOST_TEST_EQ(rv.bytes, 0); } diff --git a/test/unit/test_helpers.hpp b/test/unit/test_helpers.hpp index c26b9ca5..f7a99618 100644 --- a/test/unit/test_helpers.hpp +++ b/test/unit/test_helpers.hpp @@ -14,10 +14,9 @@ #include #include #include -#include #include -#include #include +#include #include "test_suite.hpp"