mirror of
https://github.com/boostorg/beast.git
synced 2025-07-31 21:34:46 +02:00
@@ -2,6 +2,7 @@ Version 76:
|
|||||||
|
|
||||||
* Always go through write_some
|
* Always go through write_some
|
||||||
* Use Boost.Config
|
* Use Boost.Config
|
||||||
|
* BodyReader may construct from a non-const message
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@@ -29,7 +29,7 @@ In this table:
|
|||||||
|
|
||||||
* `a` denotes a value of type `X`.
|
* `a` denotes a value of type `X`.
|
||||||
|
|
||||||
* `m` denotes a value of type `message const&` where
|
* `m` denotes a possibly const value of type `message&` where
|
||||||
`std::is_same<decltype(m.body), Body::value_type>:value == true`.
|
`std::is_same<decltype(m.body), Body::value_type>:value == true`.
|
||||||
|
|
||||||
* `ec` is a value of type [link beast.ref.beast__error_code `error_code&`].
|
* `ec` is a value of type [link beast.ref.beast__error_code `error_code&`].
|
||||||
@@ -51,6 +51,17 @@ In this table:
|
|||||||
[
|
[
|
||||||
Constructible from `m`. The lifetime of `m` is guaranteed
|
Constructible from `m`. The lifetime of `m` is guaranteed
|
||||||
to end no earlier than after the `X` is destroyed.
|
to end no earlier than after the `X` is destroyed.
|
||||||
|
The constructor may optionally require that `m` is const, which
|
||||||
|
has these consequences:
|
||||||
|
|
||||||
|
* If `X` requires that `m` is a const reference, then serializers
|
||||||
|
constructed for messages with this body type will also require a
|
||||||
|
`const` reference to a message, otherwise:
|
||||||
|
|
||||||
|
* If `X` requires that `m` is a non-const reference, then serializers
|
||||||
|
constructed for messages with this body type will aso require
|
||||||
|
a non-const reference to a message.
|
||||||
|
|
||||||
The function will ensure that `!ec` is `true` if there was
|
The function will ensure that `!ec` is `true` if there was
|
||||||
no error or set to the appropriate error code if there was one.
|
no error or set to the appropriate error code if there was one.
|
||||||
]
|
]
|
||||||
|
@@ -52,11 +52,20 @@ do_visit(error_code& ec, Visit& visit)
|
|||||||
boost::get<T1>(pv_)));
|
boost::get<T1>(pv_)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
template<bool isRequest, class Body,
|
template<bool isRequest, class Body,
|
||||||
class Fields, class ChunkDecorator>
|
class Fields, class ChunkDecorator>
|
||||||
serializer<isRequest, Body, Fields, ChunkDecorator>::
|
serializer<isRequest, Body, Fields, ChunkDecorator>::
|
||||||
serializer(message<isRequest, Body, Fields> const& m,
|
serializer(value_type& m)
|
||||||
ChunkDecorator const& d)
|
: m_(m)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<bool isRequest, class Body,
|
||||||
|
class Fields, class ChunkDecorator>
|
||||||
|
serializer<isRequest, Body, Fields, ChunkDecorator>::
|
||||||
|
serializer(value_type& m, ChunkDecorator const& d)
|
||||||
: m_(m)
|
: m_(m)
|
||||||
, d_(d)
|
, d_(d)
|
||||||
{
|
{
|
||||||
|
@@ -127,12 +127,34 @@ template<
|
|||||||
class ChunkDecorator = no_chunk_decorator>
|
class ChunkDecorator = no_chunk_decorator>
|
||||||
class serializer
|
class serializer
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
static_assert(is_body<Body>::value,
|
static_assert(is_body<Body>::value,
|
||||||
"Body requirements not met");
|
"Body requirements not met");
|
||||||
|
|
||||||
static_assert(is_body_reader<Body>::value,
|
static_assert(is_body_reader<Body>::value,
|
||||||
"BodyReader requirements not met");
|
"BodyReader requirements not met");
|
||||||
|
|
||||||
|
/** The type of the message referenced by this object.
|
||||||
|
|
||||||
|
This may be const or non-const depending on the
|
||||||
|
implementation of the corresponding @b BodyReader.
|
||||||
|
*/
|
||||||
|
#if BEAST_DOXYGEN
|
||||||
|
using value_type = implementation_defined;
|
||||||
|
#else
|
||||||
|
using value_type =
|
||||||
|
typename std::conditional<
|
||||||
|
std::is_constructible<typename Body::reader,
|
||||||
|
message<isRequest, Body, Fields>&,
|
||||||
|
error_code&>::value &&
|
||||||
|
! std::is_constructible<typename Body::reader,
|
||||||
|
message<isRequest, Body, Fields> const&,
|
||||||
|
error_code&>::value,
|
||||||
|
message<isRequest, Body, Fields>,
|
||||||
|
message<isRequest, Body, Fields> const>::type;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
do_construct = 0,
|
do_construct = 0,
|
||||||
@@ -225,7 +247,7 @@ class serializer
|
|||||||
boost::asio::const_buffers_1>>; // crlf
|
boost::asio::const_buffers_1>>; // crlf
|
||||||
using pcb8_t = buffer_prefix_view<cb8_t const&>;
|
using pcb8_t = buffer_prefix_view<cb8_t const&>;
|
||||||
|
|
||||||
message<isRequest, Body, Fields> const& m_;
|
value_type& m_;
|
||||||
boost::optional<typename Fields::reader> frd_;
|
boost::optional<typename Fields::reader> frd_;
|
||||||
boost::optional<reader> rd_;
|
boost::optional<reader> rd_;
|
||||||
boost::variant<boost::blank,
|
boost::variant<boost::blank,
|
||||||
@@ -258,14 +280,34 @@ public:
|
|||||||
@ref next. This allows the message to be lazily created.
|
@ref next. This allows the message to be lazily created.
|
||||||
For example, if the header is filled in before serialization.
|
For example, if the header is filled in before serialization.
|
||||||
|
|
||||||
@param msg The message to serialize, which must remain valid
|
@param msg A reference to the message to serialize, which must
|
||||||
for the lifetime of the serializer.
|
remain valid for the lifetime of the serializer. Depending on
|
||||||
|
the type of Body used, this may or may not be a `const` reference.
|
||||||
|
|
||||||
@param decorator An optional decorator to use.
|
@note This function participates in overload resolution only if
|
||||||
|
Body::reader is constructible from a `const` message reference.
|
||||||
*/
|
*/
|
||||||
explicit
|
explicit
|
||||||
serializer(message<isRequest, Body, Fields> const& msg,
|
serializer(value_type& msg);
|
||||||
ChunkDecorator const& decorator = ChunkDecorator{});
|
|
||||||
|
/** Constructor
|
||||||
|
|
||||||
|
The implementation guarantees that the message passed on
|
||||||
|
construction will not be accessed until the first call to
|
||||||
|
@ref next. This allows the message to be lazily created.
|
||||||
|
For example, if the header is filled in before serialization.
|
||||||
|
|
||||||
|
@param msg A reference to the message to serialize, which must
|
||||||
|
remain valid for the lifetime of the serializer. Depending on
|
||||||
|
the type of Body used, this may or may not be a `const` reference.
|
||||||
|
|
||||||
|
@param decorator The decorator to use.
|
||||||
|
|
||||||
|
@note This function participates in overload resolution only if
|
||||||
|
Body::reader is constructible from a `const` message reference.
|
||||||
|
*/
|
||||||
|
explicit
|
||||||
|
serializer(value_type& msg, ChunkDecorator const& decorator);
|
||||||
|
|
||||||
/// Returns the serialized buffer size limit
|
/// Returns the serialized buffer size limit
|
||||||
std::size_t
|
std::size_t
|
||||||
|
@@ -87,10 +87,10 @@ struct is_body_reader<T, beast::detail::void_t<
|
|||||||
is_const_buffer_sequence<
|
is_const_buffer_sequence<
|
||||||
typename T::reader::const_buffers_type>::value &&
|
typename T::reader::const_buffers_type>::value &&
|
||||||
std::is_constructible<typename T::reader,
|
std::is_constructible<typename T::reader,
|
||||||
message<true, T, detail::fields_model> const&,
|
message<true, T, detail::fields_model>&,
|
||||||
error_code&>::value &&
|
error_code&>::value &&
|
||||||
std::is_constructible<typename T::reader,
|
std::is_constructible<typename T::reader,
|
||||||
message<false, T, detail::fields_model> const&,
|
message<false, T, detail::fields_model>&,
|
||||||
error_code&>::value
|
error_code&>::value
|
||||||
> {};
|
> {};
|
||||||
#endif
|
#endif
|
||||||
|
@@ -17,6 +17,63 @@ namespace http {
|
|||||||
class serializer_test : public beast::unit_test::suite
|
class serializer_test : public beast::unit_test::suite
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
struct const_body
|
||||||
|
{
|
||||||
|
struct value_type{};
|
||||||
|
|
||||||
|
struct reader
|
||||||
|
{
|
||||||
|
using const_buffers_type =
|
||||||
|
boost::asio::const_buffers_1;
|
||||||
|
|
||||||
|
template<bool isRequest, class Fields>
|
||||||
|
reader(message<isRequest, const_body, Fields> const&,
|
||||||
|
error_code&);
|
||||||
|
|
||||||
|
boost::optional<std::pair<const_buffers_type, bool>>
|
||||||
|
get(error_code&);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mutable_body
|
||||||
|
{
|
||||||
|
struct value_type{};
|
||||||
|
|
||||||
|
struct reader
|
||||||
|
{
|
||||||
|
using const_buffers_type =
|
||||||
|
boost::asio::const_buffers_1;
|
||||||
|
|
||||||
|
template<bool isRequest, class Fields>
|
||||||
|
reader(message<isRequest, mutable_body, Fields>&,
|
||||||
|
error_code&);
|
||||||
|
|
||||||
|
boost::optional<std::pair<const_buffers_type, bool>>
|
||||||
|
get(error_code&);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT(std::is_const< serializer<
|
||||||
|
true, const_body>::value_type>::value);
|
||||||
|
BOOST_STATIC_ASSERT(! std::is_const<serializer<
|
||||||
|
true, mutable_body>::value_type>::value);
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT(std::is_constructible<
|
||||||
|
serializer<true, const_body>,
|
||||||
|
message <true, const_body>&>::value);
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT(std::is_constructible<
|
||||||
|
serializer<true, const_body>,
|
||||||
|
message <true, const_body> const&>::value);
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT(std::is_constructible<
|
||||||
|
serializer<true, mutable_body>,
|
||||||
|
message <true, mutable_body>&>::value);
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT(! std::is_constructible<
|
||||||
|
serializer<true, mutable_body>,
|
||||||
|
message <true, mutable_body> const&>::value);
|
||||||
|
|
||||||
struct lambda
|
struct lambda
|
||||||
{
|
{
|
||||||
std::size_t size;
|
std::size_t size;
|
||||||
|
Reference in New Issue
Block a user