mirror of
https://github.com/boostorg/beast.git
synced 2025-07-30 04:47:29 +02:00
@ -2,6 +2,7 @@ Version 76:
|
||||
|
||||
* Always go through write_some
|
||||
* 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`.
|
||||
|
||||
* `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`.
|
||||
|
||||
* `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
|
||||
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
|
||||
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_)));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<bool isRequest, class Body,
|
||||
class Fields, class ChunkDecorator>
|
||||
serializer<isRequest, Body, Fields, ChunkDecorator>::
|
||||
serializer(message<isRequest, Body, Fields> const& m,
|
||||
ChunkDecorator const& d)
|
||||
serializer(value_type& m)
|
||||
: 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)
|
||||
, d_(d)
|
||||
{
|
||||
|
@ -127,12 +127,34 @@ template<
|
||||
class ChunkDecorator = no_chunk_decorator>
|
||||
class serializer
|
||||
{
|
||||
public:
|
||||
static_assert(is_body<Body>::value,
|
||||
"Body requirements not met");
|
||||
|
||||
|
||||
static_assert(is_body_reader<Body>::value,
|
||||
"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
|
||||
{
|
||||
do_construct = 0,
|
||||
@ -225,7 +247,7 @@ class serializer
|
||||
boost::asio::const_buffers_1>>; // crlf
|
||||
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<reader> rd_;
|
||||
boost::variant<boost::blank,
|
||||
@ -258,14 +280,34 @@ public:
|
||||
@ref next. This allows the message to be lazily created.
|
||||
For example, if the header is filled in before serialization.
|
||||
|
||||
@param msg The message to serialize, which must remain valid
|
||||
for the lifetime of the serializer.
|
||||
@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 An optional decorator to use.
|
||||
@note This function participates in overload resolution only if
|
||||
Body::reader is constructible from a `const` message reference.
|
||||
*/
|
||||
explicit
|
||||
serializer(message<isRequest, Body, Fields> const& msg,
|
||||
ChunkDecorator const& decorator = ChunkDecorator{});
|
||||
serializer(value_type& msg);
|
||||
|
||||
/** 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
|
||||
std::size_t
|
||||
|
@ -87,10 +87,10 @@ struct is_body_reader<T, beast::detail::void_t<
|
||||
is_const_buffer_sequence<
|
||||
typename T::reader::const_buffers_type>::value &&
|
||||
std::is_constructible<typename T::reader,
|
||||
message<true, T, detail::fields_model> const&,
|
||||
message<true, T, detail::fields_model>&,
|
||||
error_code&>::value &&
|
||||
std::is_constructible<typename T::reader,
|
||||
message<false, T, detail::fields_model> const&,
|
||||
message<false, T, detail::fields_model>&,
|
||||
error_code&>::value
|
||||
> {};
|
||||
#endif
|
||||
|
@ -17,6 +17,63 @@ namespace http {
|
||||
class serializer_test : public beast::unit_test::suite
|
||||
{
|
||||
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
|
||||
{
|
||||
std::size_t size;
|
||||
|
Reference in New Issue
Block a user