Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:31

0001 //
0002 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/beast
0008 //
0009 
0010 #ifndef BOOST_BEAST_HTTP_BUFFER_BODY_HPP
0011 #define BOOST_BEAST_HTTP_BUFFER_BODY_HPP
0012 
0013 #include <boost/beast/core/detail/config.hpp>
0014 #include <boost/beast/core/buffer_traits.hpp>
0015 #include <boost/beast/http/error.hpp>
0016 #include <boost/beast/http/message.hpp>
0017 #include <boost/beast/http/type_traits.hpp>
0018 #include <boost/optional.hpp>
0019 
0020 #include <cstdint>
0021 #include <type_traits>
0022 #include <utility>
0023 
0024 namespace boost {
0025 namespace beast {
0026 namespace http {
0027 
0028 /** A <em>Body</em> using a caller provided buffer
0029 
0030     Messages using this body type may be serialized and parsed.
0031     To use this class, the caller must initialize the members
0032     of @ref buffer_body::value_type to appropriate values before
0033     each call to read or write during a stream operation.
0034 */
0035 struct buffer_body
0036 {
0037     /// The type of the body member when used in a message.
0038     struct value_type
0039     {
0040         /** A pointer to a contiguous area of memory of @ref size octets, else `nullptr`.
0041 
0042             @par When Serializing
0043 
0044             If this is `nullptr` and `more` is `true`, the error
0045             @ref error::need_buffer will be returned from @ref serializer::get
0046             Otherwise, the serializer will use the memory pointed to
0047             by `data` having `size` octets of valid storage as the
0048             next buffer representing the body.
0049 
0050             @par When Parsing
0051 
0052             If this is `nullptr`, the error @ref error::need_buffer
0053             will be returned from @ref parser::put. Otherwise, the
0054             parser will store body octets into the memory pointed to
0055             by `data` having `size` octets of valid storage. After
0056             octets are stored, the `data` and `size` members are
0057             adjusted: `data` is incremented to point to the next
0058             octet after the data written, while `size` is decremented
0059             to reflect the remaining space at the memory location
0060             pointed to by `data`.
0061         */
0062         void* data = nullptr;
0063 
0064         /** The number of octets in the buffer pointed to by @ref data.
0065 
0066             @par When Serializing
0067 
0068             If `data` is `nullptr` during serialization, this value
0069             is ignored. Otherwise, it represents the number of valid
0070             body octets pointed to by `data`.
0071 
0072             @par When Parsing
0073 
0074             The value of this field will be decremented during parsing
0075             to indicate the number of remaining free octets in the
0076             buffer pointed to by `data`. When it reaches zero, the
0077             parser will return @ref error::need_buffer, indicating to
0078             the caller that the values of `data` and `size` should be
0079             updated to point to a new memory buffer.
0080         */
0081         std::size_t size = 0;
0082 
0083         /** `true` if this is not the last buffer.
0084 
0085             @par When Serializing
0086             
0087             If this is `true` and `data` is `nullptr`, the error
0088             @ref error::need_buffer will be returned from @ref serializer::get
0089 
0090             @par When Parsing
0091 
0092             This field is not used during parsing.
0093         */
0094         bool more = true;
0095     };
0096 
0097     /** The algorithm for parsing the body
0098 
0099         Meets the requirements of <em>BodyReader</em>.
0100     */
0101 #if BOOST_BEAST_DOXYGEN
0102     using reader = __implementation_defined__;
0103 #else
0104     class reader
0105     {
0106         value_type& body_;
0107 
0108     public:
0109         template<bool isRequest, class Fields>
0110         explicit
0111         reader(header<isRequest, Fields>&, value_type& b)
0112             : body_(b)
0113         {
0114         }
0115 
0116         void
0117         init(boost::optional<std::uint64_t> const&, error_code& ec)
0118         {
0119             ec = {};
0120         }
0121 
0122         template<class ConstBufferSequence>
0123         std::size_t
0124         put(ConstBufferSequence const& buffers,
0125             error_code& ec)
0126         {
0127             if(! body_.data)
0128             {
0129                 BOOST_BEAST_ASSIGN_EC(ec, error::need_buffer);
0130                 return 0;
0131             }
0132             auto const bytes_transferred =
0133                 net::buffer_copy(net::buffer(
0134                     body_.data, body_.size), buffers);
0135             body_.data = static_cast<char*>(
0136                 body_.data) + bytes_transferred;
0137             body_.size -= bytes_transferred;
0138             if(bytes_transferred == buffer_bytes(buffers))
0139                 ec = {};
0140             else
0141             {
0142                 BOOST_BEAST_ASSIGN_EC(ec, error::need_buffer);
0143             }
0144             return bytes_transferred;
0145         }
0146 
0147         void
0148         finish(error_code& ec)
0149         {
0150             ec = {};
0151         }
0152     };
0153 #endif
0154 
0155     /** The algorithm for serializing the body
0156 
0157         Meets the requirements of <em>BodyWriter</em>.
0158     */
0159 #if BOOST_BEAST_DOXYGEN
0160     using writer = __implementation_defined__;
0161 #else
0162     class writer
0163     {
0164         bool toggle_ = false;
0165         value_type const& body_;
0166 
0167     public:
0168         using const_buffers_type =
0169             net::const_buffer;
0170 
0171         template<bool isRequest, class Fields>
0172         explicit
0173         writer(header<isRequest, Fields> const&, value_type const& b)
0174             : body_(b)
0175         {
0176         }
0177 
0178         void
0179         init(error_code& ec)
0180         {
0181             ec = {};
0182         }
0183 
0184         boost::optional<
0185             std::pair<const_buffers_type, bool>>
0186         get(error_code& ec)
0187         {
0188             if(toggle_)
0189             {
0190                 if(body_.more)
0191                 {
0192                     toggle_ = false;
0193                     BOOST_BEAST_ASSIGN_EC(ec, error::need_buffer);
0194                 }
0195                 else
0196                 {
0197                     ec = {};
0198                 }
0199                 return boost::none;
0200             }
0201             if(body_.data)
0202             {
0203                 ec = {};
0204                 toggle_ = true;
0205                 return {{const_buffers_type{
0206                     body_.data, body_.size}, body_.more}};
0207             }
0208             if(body_.more)
0209             {
0210                 BOOST_BEAST_ASSIGN_EC(ec, error::need_buffer);
0211             }
0212             else
0213                 ec = {};
0214             return boost::none;
0215         }
0216     };
0217 #endif
0218 };
0219 
0220 #if ! BOOST_BEAST_DOXYGEN
0221 // operator<< is not supported for buffer_body
0222 template<bool isRequest, class Fields>
0223 std::ostream&
0224 operator<<(std::ostream& os, message<isRequest,
0225     buffer_body, Fields> const& msg) = delete;
0226 #endif
0227 
0228 } // http
0229 } // beast
0230 } // boost
0231 
0232 #endif