mirror of
https://github.com/boostorg/beast.git
synced 2025-08-01 05:44:38 +02:00
Add dynamic_buffer_ref
This commit is contained in:
@@ -4,6 +4,7 @@ Version 209:
|
||||
* async_echo supports move-only handlers
|
||||
* test::stream maintains a handler work guard
|
||||
* 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
|
||||
[@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_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_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__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_mode">file_mode</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_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__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__get_lowest_layer">get_lowest_layer</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
|
||||
#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/bind_handler.hpp>
|
||||
#include <boost/beast/core/buffers_adaptor.hpp>
|
||||
@@ -164,7 +164,7 @@ public:
|
||||
std::size_t bytes_transferred)
|
||||
{
|
||||
using iterator = net::buffers_iterator<
|
||||
typename beast::detail::dynamic_buffer_ref<
|
||||
typename beast::dynamic_buffer_ref_wrapper<
|
||||
buffers_adaptor<MutableBufferSequence>>::const_buffers_type>;
|
||||
BOOST_ASIO_CORO_REENTER(*this)
|
||||
{
|
||||
@@ -250,7 +250,7 @@ public:
|
||||
BOOST_ASIO_CORO_YIELD
|
||||
net::async_read_until(
|
||||
d_.s.next_layer(),
|
||||
beast::detail::ref(d_.b),
|
||||
beast::dynamic_buffer_ref(d_.b),
|
||||
detail::match_icy<iterator>(d_.match),
|
||||
std::move(*this));
|
||||
if(ec)
|
||||
@@ -329,7 +329,7 @@ read_some(MutableBufferSequence const& buffers, error_code& ec)
|
||||
MutableBufferSequence>::value,
|
||||
"MutableBufferSequence requirements not met");
|
||||
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> b(buffers);
|
||||
if(b.max_size() == 0)
|
||||
@@ -403,7 +403,7 @@ read_some(MutableBufferSequence const& buffers, error_code& ec)
|
||||
bool match = false;
|
||||
auto n = net::read_until(
|
||||
stream_,
|
||||
beast::detail::ref(b),
|
||||
beast::dynamic_buffer_ref(b),
|
||||
detail::match_icy<iterator>(match),
|
||||
ec);
|
||||
if(ec)
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include <boost/beast/core/buffers_suffix.hpp>
|
||||
#include <boost/beast/core/buffers_to_string.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/file.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_to_string.cpp
|
||||
close_socket.cpp
|
||||
dynamic_buffer_ref.cpp
|
||||
error.cpp
|
||||
file.cpp
|
||||
file_posix.cpp
|
||||
|
@@ -29,6 +29,7 @@ local SOURCES =
|
||||
buffers_suffix.cpp
|
||||
buffers_to_string.cpp
|
||||
close_socket.cpp
|
||||
dynamic_buffer_ref.cpp
|
||||
error.cpp
|
||||
file.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