| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 | //// Copyright (c) 2016-2019 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_HTTP_SPAN_BODY_HPP#define BOOST_BEAST_HTTP_SPAN_BODY_HPP#include <boost/beast/core/detail/config.hpp>#include <boost/beast/core/buffer_traits.hpp>#include <boost/beast/core/span.hpp>#include <boost/beast/http/error.hpp>#include <boost/beast/http/message.hpp>#include <boost/optional.hpp>namespace boost {namespace beast {namespace http {/** A <em>Body</em> using @ref span    This body uses @ref span as a memory-based container for    holding message payloads. The container represents a    non-owning reference to a contiguous area of memory.    Messages using this body type may be serialized and    parsed.    Unlike @ref buffer_body, only one buffer may be provided    during a parse or serialize operation.*/template<class T>struct span_body{private:    static_assert(        std::is_trivial<T>::value &&        std::is_standard_layout<T>::value,            "POD requirements not met");public:    /** The type of container used for the body        This determines the type of @ref message::body        when this body type is used with a message container.    */    using value_type = span<T>;    /** Returns the payload size of the body        When this body is used with @ref message::prepare_payload,        the Content-Length will be set to the payload size, and        any chunked Transfer-Encoding will be removed.    */    static    std::uint64_t    size(value_type const& body)    {        return body.size();    }    /** The algorithm for parsing the body        Meets the requirements of <em>BodyReader</em>.    */#if BOOST_BEAST_DOXYGEN    using reader = __implementation_defined__;#else    class reader    {        value_type& body_;    public:        template<bool isRequest, class Fields>        explicit        reader(header<isRequest, Fields>&, value_type& b)            : body_(b)        {        }        void        init(boost::optional<            std::uint64_t> const& length, error_code& ec)        {            if(length && *length > body_.size())            {                ec = error::buffer_overflow;                return;            }            ec = {};        }        template<class ConstBufferSequence>        std::size_t        put(ConstBufferSequence const& buffers,            error_code& ec)        {            auto const n = buffer_bytes(buffers);            auto const len = body_.size();            if(n > len)            {                ec = error::buffer_overflow;                return 0;            }            ec = {};            net::buffer_copy(net::buffer(                body_.data(), n), buffers);            body_ = value_type{                body_.data() + n, body_.size() - n};            return n;        }        void        finish(error_code& ec)        {            ec = {};        }    };#endif    /** The algorithm for serializing the body        Meets the requirements of <em>BodyWriter</em>.    */#if BOOST_BEAST_DOXYGEN    using writer = __implementation_defined__;#else    class writer    {        value_type const& body_;    public:        using const_buffers_type =            net::const_buffer;        template<bool isRequest, class Fields>        explicit        writer(header<isRequest, Fields> const&, value_type const& b)            : body_(b)        {        }        void        init(error_code& ec)        {            ec = {};        }        boost::optional<std::pair<const_buffers_type, bool>>        get(error_code& ec)        {            ec = {};            return {{                { body_.data(),                  body_.size() * sizeof(typename                    value_type::value_type)},                false}};        }    };#endif};} // http} // beast} // boost#endif
 |