diff --git a/CHANGELOG.md b/CHANGELOG.md index 97006584..4ec721f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ Version 187: * Add experimental timeout_socket * Fix warning in file tests * Fix uninitialized comparison in buffers iterator +* Partial support for BOOST_NO_EXCEPTIONS -------------------------------------------------------------------------------- diff --git a/doc/qbk/09_releases.qbk b/doc/qbk/09_releases.qbk index cd9989cf..c961ba05 100644 --- a/doc/qbk/09_releases.qbk +++ b/doc/qbk/09_releases.qbk @@ -35,6 +35,8 @@ * Workaround for http-server-fast and libstdc++ +* Partial support for `BOOST_NO_EXCEPTIONS` + [*Experimental] * Add [link beast.ref.boost__beast__timeout_socket `timeout_socket`] diff --git a/include/boost/beast/http/basic_dynamic_body.hpp b/include/boost/beast/http/basic_dynamic_body.hpp index 7d850d76..ba7208b7 100644 --- a/include/boost/beast/http/basic_dynamic_body.hpp +++ b/include/boost/beast/http/basic_dynamic_body.hpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -95,21 +96,15 @@ struct basic_dynamic_body ec = error::buffer_overflow; return 0; } - boost::optional b; - try - { - b.emplace(body_.prepare((std::min)(n, - body_.max_size() - body_.size()))); - } - catch(std::length_error const&) - { - ec = error::buffer_overflow; + auto const mb = + beast::detail::dynamic_buffer_prepare( + body_, (std::min)(n, + body_.max_size() - body_.size()), + ec, error::buffer_overflow); + if(ec) return 0; - } - ec.assign(0, ec.category()); auto const bytes_transferred = - buffer_copy(*b, buffers); + buffer_copy(*mb, buffers); body_.commit(bytes_transferred); return bytes_transferred; } diff --git a/include/boost/beast/http/impl/read.ipp b/include/boost/beast/http/impl/read.ipp index 2ff0c3b1..3d1a8508 100644 --- a/include/boost/beast/http/impl/read.ipp +++ b/include/boost/beast/http/impl/read.ipp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -121,8 +122,6 @@ operator()( bool cont) { cont_ = cont; - boost::optional mb; BOOST_ASIO_CORO_REENTER(*this) { if(b_.size() == 0) @@ -139,18 +138,22 @@ operator()( break; do_read: - try - { - mb.emplace(b_.prepare( - read_size_or_throw(b_, 65536))); - } - catch(std::length_error const&) - { - ec = error::buffer_overflow; - break; - } BOOST_ASIO_CORO_YIELD - s_.async_read_some(*mb, std::move(*this)); + { + // VFALCO This was read_size_or_throw + auto const size = read_size(b_, 65536); + if(size == 0) + { + ec = error::buffer_overflow; + goto upcall; + } + auto const mb = + beast::detail::dynamic_buffer_prepare( + b_, size, ec, error::buffer_overflow); + if(ec) + goto upcall; + s_.async_read_some(*mb, std::move(*this)); + } if(ec == boost::asio::error::eof) { BOOST_ASSERT(bytes_transferred == 0); @@ -513,19 +516,18 @@ read_some( break; } do_read: - boost::optional b; - try - { - b.emplace(buffer.prepare( - read_size_or_throw(buffer, 65536))); - } - catch(std::length_error const&) + auto const size = read_size(buffer, 65536); + if(size == 0) { ec = error::buffer_overflow; - return bytes_transferred; + break; } - auto const n = stream.read_some(*b, ec); + auto const mb = + beast::detail::dynamic_buffer_prepare( + buffer, size, ec, error::buffer_overflow); + if(ec) + break; + auto const n = stream.read_some(*mb, ec); if(ec == boost::asio::error::eof) { BOOST_ASSERT(n == 0); diff --git a/include/boost/beast/websocket/impl/accept.ipp b/include/boost/beast/websocket/impl/accept.ipp index c93e933b..5a322990 100644 --- a/include/boost/beast/websocket/impl/accept.ipp +++ b/include/boost/beast/websocket/impl/accept.ipp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -244,20 +245,12 @@ run(Buffers const& buffers) using boost::asio::buffer_size; auto& d = *d_; error_code ec; - boost::optional mb; - auto const len = buffer_size(buffers); - try - { - mb.emplace(d.ws.rd_buf_.prepare(len)); - } - catch(std::length_error const&) - { - ec = error::buffer_overflow; + auto const mb = beast::detail::dynamic_buffer_prepare( + d.ws.rd_buf_, buffer_size(buffers), ec, + error::buffer_overflow); + if(ec) return (*this)(ec); - } - d.ws.rd_buf_.commit( - buffer_copy(*mb, buffers)); + d.ws.rd_buf_.commit(buffer_copy(*mb, buffers)); (*this)(ec); } @@ -432,20 +425,12 @@ accept( using boost::asio::buffer_copy; using boost::asio::buffer_size; reset(); - boost::optional mb; - try - { - mb.emplace(rd_buf_.prepare( - buffer_size(buffers))); - } - catch(std::length_error const&) - { - ec = error::buffer_overflow; + auto const mb = beast::detail::dynamic_buffer_prepare( + rd_buf_, buffer_size(buffers), ec, + error::buffer_overflow); + if(ec) return; - } - rd_buf_.commit( - buffer_copy(*mb, buffers)); + rd_buf_.commit(buffer_copy(*mb, buffers)); do_accept(&default_decorate_res, ec); } @@ -472,18 +457,11 @@ accept_ex( using boost::asio::buffer_copy; using boost::asio::buffer_size; reset(); - boost::optional mb; - try - { - mb.emplace(rd_buf_.prepare( - buffer_size(buffers))); - } - catch(std::length_error const&) - { - ec = error::buffer_overflow; + auto const mb = beast::detail::dynamic_buffer_prepare( + rd_buf_, buffer_size(buffers), ec, + error::buffer_overflow); + if(ec) return; - } rd_buf_.commit(buffer_copy(*mb, buffers)); do_accept(decorator, ec); } diff --git a/include/boost/beast/websocket/impl/read.ipp b/include/boost/beast/websocket/impl/read.ipp index 9e8e0c47..3fb7f223 100644 --- a/include/boost/beast/websocket/impl/read.ipp +++ b/include/boost/beast/websocket/impl/read.ipp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -800,35 +801,27 @@ operator()( std::size_t bytes_transferred) { using beast::detail::clamp; - using buffers_type = typename - DynamicBuffer::mutable_buffers_type; - boost::optional mb; BOOST_ASIO_CORO_REENTER(*this) { do { - try - { - mb.emplace(b_.prepare(clamp( - ws_.read_size_hint(b_), limit_))); - } - catch(std::length_error const&) - { - ec = error::buffer_overflow; - } - if(ec) - { - BOOST_ASIO_CORO_YIELD - boost::asio::post( - ws_.get_executor(), - bind_handler(std::move(*this), - error::buffer_overflow, 0)); - break; - } BOOST_ASIO_CORO_YIELD - read_some_op{ - std::move(*this), ws_, *mb}( - {}, 0, false); + { + auto mb = beast::detail::dynamic_buffer_prepare(b_, + clamp(ws_.read_size_hint(b_), limit_), + ec, error::buffer_overflow); + if(ec) + boost::asio::post( + ws_.get_executor(), + bind_handler( + std::move(*this), ec, 0)); + else + read_some_op(std::move(*this), ws_, *mb)( + {}, 0, false); + return; + } if(ec) break; b_.commit(bytes_transferred); @@ -950,17 +943,10 @@ read_some( auto const size = clamp(read_size_hint(buffer), limit); BOOST_ASSERT(size > 0); - boost::optional mb; - try - { - mb.emplace(buffer.prepare(size)); - } - catch(std::length_error const&) - { - ec = error::buffer_overflow; + auto mb = beast::detail::dynamic_buffer_prepare( + buffer, size, ec, error::buffer_overflow); + if(ec) return 0; - } auto const bytes_written = read_some(*mb, ec); buffer.commit(bytes_written); return bytes_written;