2 // Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 // Official repository: https://github.com/boostorg/beast
10 #ifndef BOOST_BEAST_HTTP_BUFFER_BODY_HPP
11 #define BOOST_BEAST_HTTP_BUFFER_BODY_HPP
13 #include <boost/beast/core/detail/config.hpp>
14 #include <boost/beast/http/error.hpp>
15 #include <boost/beast/http/message.hpp>
16 #include <boost/beast/http/type_traits.hpp>
17 #include <boost/optional.hpp>
18 #include <type_traits>
25 /** A @b Body using a caller provided buffer
27 Messages using this body type may be serialized and parsed.
28 To use this class, the caller must initialize the members
29 of @ref buffer_body::value_type to appropriate values before
30 each call to read or write during a stream operation.
34 /// The type of the body member when used in a message.
37 /** A pointer to a contiguous area of memory of @ref size octets, else `nullptr`.
41 If this is `nullptr` and `more` is `true`, the error
42 @ref error::need_buffer will be returned from @ref serializer::get
43 Otherwise, the serializer will use the memory pointed to
44 by `data` having `size` octets of valid storage as the
45 next buffer representing the body.
49 If this is `nullptr`, the error @ref error::need_buffer
50 will be returned from @ref parser::put. Otherwise, the
51 parser will store body octets into the memory pointed to
52 by `data` having `size` octets of valid storage. After
53 octets are stored, the `data` and `size` members are
54 adjusted: `data` is incremented to point to the next
55 octet after the data written, while `size` is decremented
56 to reflect the remaining space at the memory location
61 /** The number of octets in the buffer pointed to by @ref data.
65 If `data` is `nullptr` during serialization, this value
66 is ignored. Otherwise, it represents the number of valid
67 body octets pointed to by `data`.
71 The value of this field will be decremented during parsing
72 to indicate the number of remaining free octets in the
73 buffer pointed to by `data`. When it reaches zero, the
74 parser will return @ref error::need_buffer, indicating to
75 the caller that the values of `data` and `size` should be
76 updated to point to a new memory buffer.
80 /** `true` if this is not the last buffer.
84 If this is `true` and `data` is `nullptr`, the error
85 @ref error::need_buffer will be returned from @ref serializer::get
89 This field is not used during parsing.
94 /** The algorithm for parsing the body
96 Meets the requirements of @b BodyReader.
98 #if BOOST_BEAST_DOXYGEN
99 using reader = implementation_defined;
106 template<bool isRequest, class Fields>
108 reader(header<isRequest, Fields>&, value_type& b)
114 init(boost::optional<std::uint64_t> const&, error_code& ec)
116 ec.assign(0, ec.category());
119 template<class ConstBufferSequence>
121 put(ConstBufferSequence const& buffers,
124 using boost::asio::buffer_size;
125 using boost::asio::buffer_copy;
128 ec = error::need_buffer;
131 auto const bytes_transferred =
132 buffer_copy(boost::asio::buffer(
133 body_.data, body_.size), buffers);
134 body_.data = reinterpret_cast<char*>(
135 body_.data) + bytes_transferred;
136 body_.size -= bytes_transferred;
137 if(bytes_transferred == buffer_size(buffers))
138 ec.assign(0, ec.category());
140 ec = error::need_buffer;
141 return bytes_transferred;
145 finish(error_code& ec)
147 ec.assign(0, ec.category());
152 /** The algorithm for serializing the body
154 Meets the requirements of @b BodyWriter.
156 #if BOOST_BEAST_DOXYGEN
157 using writer = implementation_defined;
161 bool toggle_ = false;
162 value_type const& body_;
165 using const_buffers_type =
166 boost::asio::const_buffer;
168 template<bool isRequest, class Fields>
170 writer(header<isRequest, Fields> const&, value_type const& b)
178 ec.assign(0, ec.category());
182 std::pair<const_buffers_type, bool>>
190 ec = error::need_buffer;
194 ec.assign(0, ec.category());
200 ec.assign(0, ec.category());
202 return {{const_buffers_type{
203 body_.data, body_.size}, body_.more}};
206 ec = error::need_buffer;
208 ec.assign(0, ec.category());
215 #if ! BOOST_BEAST_DOXYGEN
216 // operator<< is not supported for buffer_body
217 template<bool isRequest, class Fields>
219 operator<<(std::ostream& os, message<isRequest,
220 buffer_body, Fields> const& msg) = delete;