mirror of
https://github.com/boostorg/beast.git
synced 2025-08-02 14:24:31 +02:00
Add dynamic_buffer_ref
This commit is contained in:
@@ -4,6 +4,7 @@ Version 209:
|
|||||||
* async_echo supports move-only handlers
|
* async_echo supports move-only handlers
|
||||||
* test::stream maintains a handler work guard
|
* test::stream maintains a handler work guard
|
||||||
* Qualify buffer_copy, don't qualify buffer_size
|
* Qualify buffer_copy, don't qualify buffer_size
|
||||||
|
* Add dynamic_buffer_ref
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@@ -125,6 +125,15 @@ set of additional implementations of the dynamic buffer concept:
|
|||||||
The basic container is an
|
The basic container is an
|
||||||
[@https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer [*AllocatorAwareContainer]].
|
[@https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer [*AllocatorAwareContainer]].
|
||||||
]]
|
]]
|
||||||
|
[[
|
||||||
|
[link beast.ref.boost__beast__dynamic_buffer_ref `dynamic_buffer_ref`]
|
||||||
|
[link beast.ref.boost__beast__dynamic_buffer_ref_wrapper `dynamic_buffer_ref_wrapper`]
|
||||||
|
][
|
||||||
|
This function returns a wrapper containing a reference to the passed
|
||||||
|
dynamic buffer, permitting a Beast dynamic buffer type (which acts
|
||||||
|
like a true container type) to be used with Networking algorithms
|
||||||
|
which want to take ownership of the dynamic buffer in their interface.
|
||||||
|
]]
|
||||||
[[
|
[[
|
||||||
[link beast.ref.boost__beast__flat_static_buffer `flat_static_buffer`]
|
[link beast.ref.boost__beast__flat_static_buffer `flat_static_buffer`]
|
||||||
[link beast.ref.boost__beast__flat_static_buffer_base `flat_static_buffer_base`]
|
[link beast.ref.boost__beast__flat_static_buffer_base `flat_static_buffer_base`]
|
||||||
|
@@ -186,6 +186,7 @@
|
|||||||
<member><link linkend="beast.ref.boost__beast__buffers_cat_view">buffers_cat_view</link></member>
|
<member><link linkend="beast.ref.boost__beast__buffers_cat_view">buffers_cat_view</link></member>
|
||||||
<member><link linkend="beast.ref.boost__beast__buffers_prefix_view">buffers_prefix_view</link></member>
|
<member><link linkend="beast.ref.boost__beast__buffers_prefix_view">buffers_prefix_view</link></member>
|
||||||
<member><link linkend="beast.ref.boost__beast__buffers_suffix">buffers_suffix</link></member>
|
<member><link linkend="beast.ref.boost__beast__buffers_suffix">buffers_suffix</link></member>
|
||||||
|
<member><link linkend="beast.ref.boost__beast__dynamic_buffer_ref_wrapper">dynamic_buffer_ref_wrapper</link></member>
|
||||||
<member><link linkend="beast.ref.boost__beast__file">file</link></member>
|
<member><link linkend="beast.ref.boost__beast__file">file</link></member>
|
||||||
<member><link linkend="beast.ref.boost__beast__file_mode">file_mode</link></member>
|
<member><link linkend="beast.ref.boost__beast__file_mode">file_mode</link></member>
|
||||||
<member><link linkend="beast.ref.boost__beast__file_posix">file_posix</link></member>
|
<member><link linkend="beast.ref.boost__beast__file_posix">file_posix</link></member>
|
||||||
@@ -236,6 +237,7 @@
|
|||||||
<member><link linkend="beast.ref.boost__beast__buffers_range_ref">buffers_range_ref</link></member>
|
<member><link linkend="beast.ref.boost__beast__buffers_range_ref">buffers_range_ref</link></member>
|
||||||
<member><link linkend="beast.ref.boost__beast__buffers_to_string">buffers_to_string</link></member>
|
<member><link linkend="beast.ref.boost__beast__buffers_to_string">buffers_to_string</link></member>
|
||||||
<member><link linkend="beast.ref.boost__beast__close_socket">close_socket</link></member>
|
<member><link linkend="beast.ref.boost__beast__close_socket">close_socket</link></member>
|
||||||
|
<member><link linkend="beast.ref.boost__beast__dynamic_buffer_ref">dynamic_buffer_ref</link></member>
|
||||||
<member><link linkend="beast.ref.boost__beast__generic_category">generic_category</link></member>
|
<member><link linkend="beast.ref.boost__beast__generic_category">generic_category</link></member>
|
||||||
<member><link linkend="beast.ref.boost__beast__get_lowest_layer">get_lowest_layer</link></member>
|
<member><link linkend="beast.ref.boost__beast__get_lowest_layer">get_lowest_layer</link></member>
|
||||||
<member><link linkend="beast.ref.boost__beast__iequals">iequals</link></member>
|
<member><link linkend="beast.ref.boost__beast__iequals">iequals</link></member>
|
||||||
|
@@ -1,99 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (c) 2018 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
||||||
//
|
|
||||||
// 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/boostorg/beast
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef BOOST_BEAST_CORE_DETAIL_DYNAMIC_BUFFER_REF_HPP
|
|
||||||
#define BOOST_BEAST_CORE_DETAIL_DYNAMIC_BUFFER_REF_HPP
|
|
||||||
|
|
||||||
#include <boost/asio/buffer.hpp>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace beast {
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<class DynamicBuffer>
|
|
||||||
class dynamic_buffer_ref
|
|
||||||
{
|
|
||||||
DynamicBuffer& b_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
using const_buffers_type = typename
|
|
||||||
DynamicBuffer::const_buffers_type;
|
|
||||||
|
|
||||||
using mutable_buffers_type = typename
|
|
||||||
DynamicBuffer::mutable_buffers_type;
|
|
||||||
|
|
||||||
dynamic_buffer_ref(
|
|
||||||
dynamic_buffer_ref&&) = default;
|
|
||||||
|
|
||||||
explicit
|
|
||||||
dynamic_buffer_ref(
|
|
||||||
DynamicBuffer& b) noexcept
|
|
||||||
: b_(b)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t
|
|
||||||
size() const noexcept
|
|
||||||
{
|
|
||||||
return b_.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t
|
|
||||||
max_size() const noexcept
|
|
||||||
{
|
|
||||||
return b_.max_size();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t
|
|
||||||
capacity() const noexcept
|
|
||||||
{
|
|
||||||
return b_.capacity();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_buffers_type
|
|
||||||
data() const noexcept
|
|
||||||
{
|
|
||||||
return b_.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
mutable_buffers_type
|
|
||||||
prepare(std::size_t n)
|
|
||||||
{
|
|
||||||
return b_.prepare(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
commit(std::size_t n)
|
|
||||||
{
|
|
||||||
b_.commit(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
consume(std::size_t n)
|
|
||||||
{
|
|
||||||
b_.consume(n);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class DynamicBuffer>
|
|
||||||
typename std::enable_if<
|
|
||||||
net::is_dynamic_buffer<DynamicBuffer>::value,
|
|
||||||
dynamic_buffer_ref<DynamicBuffer>>::type
|
|
||||||
ref(DynamicBuffer& b)
|
|
||||||
{
|
|
||||||
return dynamic_buffer_ref<DynamicBuffer>(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // detail
|
|
||||||
} // beast
|
|
||||||
} // boost
|
|
||||||
|
|
||||||
#endif
|
|
@@ -10,7 +10,7 @@
|
|||||||
#ifndef BOOST_BEAST_CORE_IMPL_ICY_STREAM_HPP
|
#ifndef BOOST_BEAST_CORE_IMPL_ICY_STREAM_HPP
|
||||||
#define BOOST_BEAST_CORE_IMPL_ICY_STREAM_HPP
|
#define BOOST_BEAST_CORE_IMPL_ICY_STREAM_HPP
|
||||||
|
|
||||||
#include <boost/beast/_experimental/core/detail/dynamic_buffer_ref.hpp>
|
#include <boost/beast/core/dynamic_buffer_ref.hpp>
|
||||||
#include <boost/beast/core/async_op_base.hpp>
|
#include <boost/beast/core/async_op_base.hpp>
|
||||||
#include <boost/beast/core/bind_handler.hpp>
|
#include <boost/beast/core/bind_handler.hpp>
|
||||||
#include <boost/beast/core/buffers_adaptor.hpp>
|
#include <boost/beast/core/buffers_adaptor.hpp>
|
||||||
@@ -164,7 +164,7 @@ public:
|
|||||||
std::size_t bytes_transferred)
|
std::size_t bytes_transferred)
|
||||||
{
|
{
|
||||||
using iterator = net::buffers_iterator<
|
using iterator = net::buffers_iterator<
|
||||||
typename beast::detail::dynamic_buffer_ref<
|
typename beast::dynamic_buffer_ref_wrapper<
|
||||||
buffers_adaptor<MutableBufferSequence>>::const_buffers_type>;
|
buffers_adaptor<MutableBufferSequence>>::const_buffers_type>;
|
||||||
BOOST_ASIO_CORO_REENTER(*this)
|
BOOST_ASIO_CORO_REENTER(*this)
|
||||||
{
|
{
|
||||||
@@ -250,7 +250,7 @@ public:
|
|||||||
BOOST_ASIO_CORO_YIELD
|
BOOST_ASIO_CORO_YIELD
|
||||||
net::async_read_until(
|
net::async_read_until(
|
||||||
d_.s.next_layer(),
|
d_.s.next_layer(),
|
||||||
beast::detail::ref(d_.b),
|
beast::dynamic_buffer_ref(d_.b),
|
||||||
detail::match_icy<iterator>(d_.match),
|
detail::match_icy<iterator>(d_.match),
|
||||||
std::move(*this));
|
std::move(*this));
|
||||||
if(ec)
|
if(ec)
|
||||||
@@ -329,7 +329,7 @@ read_some(MutableBufferSequence const& buffers, error_code& ec)
|
|||||||
MutableBufferSequence>::value,
|
MutableBufferSequence>::value,
|
||||||
"MutableBufferSequence requirements not met");
|
"MutableBufferSequence requirements not met");
|
||||||
using iterator = net::buffers_iterator<
|
using iterator = net::buffers_iterator<
|
||||||
typename beast::detail::dynamic_buffer_ref<
|
typename beast::dynamic_buffer_ref_wrapper<
|
||||||
buffers_adaptor<MutableBufferSequence>>::const_buffers_type>;
|
buffers_adaptor<MutableBufferSequence>>::const_buffers_type>;
|
||||||
buffers_adaptor<MutableBufferSequence> b(buffers);
|
buffers_adaptor<MutableBufferSequence> b(buffers);
|
||||||
if(b.max_size() == 0)
|
if(b.max_size() == 0)
|
||||||
@@ -403,7 +403,7 @@ read_some(MutableBufferSequence const& buffers, error_code& ec)
|
|||||||
bool match = false;
|
bool match = false;
|
||||||
auto n = net::read_until(
|
auto n = net::read_until(
|
||||||
stream_,
|
stream_,
|
||||||
beast::detail::ref(b),
|
beast::dynamic_buffer_ref(b),
|
||||||
detail::match_icy<iterator>(match),
|
detail::match_icy<iterator>(match),
|
||||||
ec);
|
ec);
|
||||||
if(ec)
|
if(ec)
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
#include <boost/beast/core/buffers_suffix.hpp>
|
#include <boost/beast/core/buffers_suffix.hpp>
|
||||||
#include <boost/beast/core/buffers_to_string.hpp>
|
#include <boost/beast/core/buffers_to_string.hpp>
|
||||||
#include <boost/beast/core/close_socket.hpp>
|
#include <boost/beast/core/close_socket.hpp>
|
||||||
|
#include <boost/beast/core/dynamic_buffer_ref.hpp>
|
||||||
#include <boost/beast/core/error.hpp>
|
#include <boost/beast/core/error.hpp>
|
||||||
#include <boost/beast/core/file.hpp>
|
#include <boost/beast/core/file.hpp>
|
||||||
#include <boost/beast/core/file_base.hpp>
|
#include <boost/beast/core/file_base.hpp>
|
||||||
|
140
include/boost/beast/core/dynamic_buffer_ref.hpp
Normal file
140
include/boost/beast/core/dynamic_buffer_ref.hpp
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2018 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||||
|
//
|
||||||
|
// 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/boostorg/beast
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef BOOST_BEAST_CORE_DYNAMIC_BUFFER_REF_HPP
|
||||||
|
#define BOOST_BEAST_CORE_DYNAMIC_BUFFER_REF_HPP
|
||||||
|
|
||||||
|
#include <boost/beast/core/detail/config.hpp>
|
||||||
|
#include <boost/asio/buffer.hpp>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace beast {
|
||||||
|
|
||||||
|
/** A lightweight reference to a dynamic buffer.
|
||||||
|
|
||||||
|
Objects of this type meet the requirements of <em>DynamicBuffer</em>.
|
||||||
|
This is the wrapper returned by the function @ref dynamic_buffer_ref.
|
||||||
|
|
||||||
|
@see dynamic_buffer_ref
|
||||||
|
*/
|
||||||
|
template<class DynamicBuffer>
|
||||||
|
class dynamic_buffer_ref_wrapper
|
||||||
|
#if ! BOOST_BEAST_DOXYGEN
|
||||||
|
{
|
||||||
|
static_assert(net::is_dynamic_buffer<DynamicBuffer>::value,
|
||||||
|
"DynamicBuffer requirements not met");
|
||||||
|
|
||||||
|
DynamicBuffer& b_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using const_buffers_type = typename
|
||||||
|
DynamicBuffer::const_buffers_type;
|
||||||
|
|
||||||
|
using mutable_buffers_type = typename
|
||||||
|
DynamicBuffer::mutable_buffers_type;
|
||||||
|
|
||||||
|
dynamic_buffer_ref_wrapper(
|
||||||
|
dynamic_buffer_ref_wrapper&&) = default;
|
||||||
|
|
||||||
|
explicit
|
||||||
|
dynamic_buffer_ref_wrapper(
|
||||||
|
DynamicBuffer& b) noexcept
|
||||||
|
: b_(b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t
|
||||||
|
size() const noexcept
|
||||||
|
{
|
||||||
|
return b_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t
|
||||||
|
max_size() const noexcept
|
||||||
|
{
|
||||||
|
return b_.max_size();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t
|
||||||
|
capacity() const noexcept
|
||||||
|
{
|
||||||
|
return b_.capacity();
|
||||||
|
}
|
||||||
|
|
||||||
|
const_buffers_type
|
||||||
|
data() const noexcept
|
||||||
|
{
|
||||||
|
return b_.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
mutable_buffers_type
|
||||||
|
prepare(std::size_t n)
|
||||||
|
{
|
||||||
|
return b_.prepare(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
commit(std::size_t n)
|
||||||
|
{
|
||||||
|
b_.commit(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
consume(std::size_t n)
|
||||||
|
{
|
||||||
|
b_.consume(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
|
/** Return a non-owning reference to a dynamic buffer.
|
||||||
|
|
||||||
|
This function returns a wrapper which holds a reference to the
|
||||||
|
passed dynamic buffer. The wrapper meets the requirements of
|
||||||
|
<em>DynamicBuffer</em>, allowing its use in Networking algorithms
|
||||||
|
which want to take ownership of the dynamic buffer. Since Beast
|
||||||
|
dynamic buffers are true storage types, they cannot be used directly
|
||||||
|
with functions that take ownership of the dynamic buffer.
|
||||||
|
|
||||||
|
@par Example
|
||||||
|
This function reads a line of text from a stream into a
|
||||||
|
@ref flat_buffer, using the net function `async_read_until`. The
|
||||||
|
@code
|
||||||
|
template <class SyncReadStream>
|
||||||
|
std::size_t read_line (SyncReadStream& stream, flat_buffer& buffer)
|
||||||
|
{
|
||||||
|
return net::read_until(stream, dynamic_buffer_ref(buffer), "\r\n");
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
@param buffer The dynamic buffer to wrap. Ownership of the buffer is
|
||||||
|
not transferred, the caller is still responsible for managing the
|
||||||
|
lifetime of the original object.
|
||||||
|
|
||||||
|
@return A wrapper meeting the requirements of <em>DynamicBuffer</em>
|
||||||
|
which references the original dynamic buffer.
|
||||||
|
|
||||||
|
@see dynamic_buffer_ref_wrapper
|
||||||
|
*/
|
||||||
|
template<class DynamicBuffer>
|
||||||
|
dynamic_buffer_ref_wrapper<DynamicBuffer>
|
||||||
|
dynamic_buffer_ref(DynamicBuffer& buffer) noexcept
|
||||||
|
{
|
||||||
|
static_assert(net::is_dynamic_buffer<DynamicBuffer>::value,
|
||||||
|
"DynamicBuffer requirements not met");
|
||||||
|
return dynamic_buffer_ref_wrapper<DynamicBuffer>(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // beast
|
||||||
|
} // boost
|
||||||
|
|
||||||
|
#endif
|
@@ -41,6 +41,7 @@ add_executable (tests-beast-core
|
|||||||
buffers_suffix.cpp
|
buffers_suffix.cpp
|
||||||
buffers_to_string.cpp
|
buffers_to_string.cpp
|
||||||
close_socket.cpp
|
close_socket.cpp
|
||||||
|
dynamic_buffer_ref.cpp
|
||||||
error.cpp
|
error.cpp
|
||||||
file.cpp
|
file.cpp
|
||||||
file_posix.cpp
|
file_posix.cpp
|
||||||
|
@@ -29,6 +29,7 @@ local SOURCES =
|
|||||||
buffers_suffix.cpp
|
buffers_suffix.cpp
|
||||||
buffers_to_string.cpp
|
buffers_to_string.cpp
|
||||||
close_socket.cpp
|
close_socket.cpp
|
||||||
|
dynamic_buffer_ref.cpp
|
||||||
error.cpp
|
error.cpp
|
||||||
file.cpp
|
file.cpp
|
||||||
file_posix.cpp
|
file_posix.cpp
|
||||||
|
51
test/beast/core/dynamic_buffer_ref.cpp
Normal file
51
test/beast/core/dynamic_buffer_ref.cpp
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2018 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||||
|
//
|
||||||
|
// 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/boostorg/beast
|
||||||
|
//
|
||||||
|
|
||||||
|
// Test that header file is self-contained.
|
||||||
|
#include <boost/beast/core/dynamic_buffer_ref.hpp>
|
||||||
|
|
||||||
|
#include <boost/beast/_experimental/unit_test/suite.hpp>
|
||||||
|
#include <boost/beast/_experimental/test/stream.hpp>
|
||||||
|
#include <boost/beast/core/flat_buffer.hpp>
|
||||||
|
#include <boost/asio/read_until.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace beast {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template <class SyncReadStream>
|
||||||
|
std::size_t read_line (SyncReadStream& stream, flat_buffer& buffer)
|
||||||
|
{
|
||||||
|
return net::read_until(stream, dynamic_buffer_ref(buffer), "\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // (anon)
|
||||||
|
|
||||||
|
class dynamic_buffer_ref_test : public beast::unit_test::suite
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void
|
||||||
|
testJavadocs()
|
||||||
|
{
|
||||||
|
BEAST_EXPECT(static_cast<
|
||||||
|
std::size_t(*)(test::stream&, flat_buffer&)>(
|
||||||
|
&read_line<test::stream>));
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() override
|
||||||
|
{
|
||||||
|
testJavadocs();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BEAST_DEFINE_TESTSUITE(beast,core,dynamic_buffer_ref);
|
||||||
|
|
||||||
|
} // beast
|
||||||
|
} // boost
|
Reference in New Issue
Block a user