Beast Logo

PrevUpHomeNext

BodyReader

A BodyReader provides an online algorithm to obtain a sequence of zero or more buffers from a body during serialization. The implementation creates an instance of this type when needed, and calls into it one or more times to retrieve buffers holding body octets. The interface of BodyReader is intended to obtain buffers for these scenarios:

Associated Types
Requirements

In this table:

Table 31. Valid expressions

Expression

Type

Semantics, Pre/Post-conditions

R::const_buffers_type

A type which meets the requirements of ConstBufferSequence. This is the type of buffer returned by R::get.

R(m);

Constructible from m. The lifetime of m is guaranteed to end no earlier than after the R is destroyed. The reader shall not access the contents of m before the first call to init, permitting lazy construction of the message.

The constructor may optionally require that m is const, which has these consequences:

* If R 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 R 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.

a.init(ec)

Called once to fully initialize the object before any calls to get. The message body becomes valid before entering this function, and remains valid until the reader is destroyed. The function will ensure that !ec is true if there was no error or set to the appropriate error code if there was one.

a.get(ec)

R<R::const_buffers_type>

Called one or more times after init succeeds. This function returns boost::none if all buffers representing the body have been returned in previous calls or if it sets ec to indicate an error. Otherwise, if there are buffers remaining the function should return a pair with the first element containing a non-zero length buffer sequence representing the next set of octets in the body, while the second element is a bool meaning true if there may be additional buffers returned on a subsequent call, or false if the buffer returned on this call is the last buffer representing the body. The function will ensure that !ec is true if there was no error or set to the appropriate error code if there was one.


Exemplar
struct BodyReader
{
public:
    /// The type of buffer returned by `get`.
    using const_buffers_type = boost::asio::const_buffers_1;

    /** Construct the reader.

        @param msg The message whose body is to be retrieved.

        @param ec Set to the error, if any occurred.
    */
    template<bool isRequest, class Body, class Fields>
    explicit
    BodyReader(message<isRequest, Body, Fields> const& msg);

    /** Initialize the reader

        This is called after construction and before the first
        call to `get`. The message is valid and complete upon
        entry.

        @param ec Set to the error, if any occurred.
    */
    void
    init(error_code& ec)
    {
        // The specification requires this to indicate "no error"
        ec.assign(0, ec.category());
    }

    /** Returns the next buffer in the body.

        @li If the return value is `boost::none` (unseated optional) and
            `ec` does not contain an error, this indicates the end of the
            body, no more buffers are present.

        @li If the optional contains a value, the first element of the
            pair represents a @b ConstBufferSequence containing one or
            more octets of the body data. The second element indicates
            whether or not there are additional octets of body data.
            A value of `true` means there is more data, and that the
            implementation will perform a subsequent call to `get`.
            A value of `false` means there is no more body data.

        @li If `ec` contains an error code, the return value is ignored.

        @param ec Set to the error, if any occurred.
    */
    boost::optional<std::pair<const_buffers_type, bool>>
    get(error_code& ec)
    {
        // The specification requires this to indicate "no error"
        ec.assign(0, ec.category());

        return boost::none; // for exposition only
    }
};
Models

PrevUpHomeNext