]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/beast/http/buffer_body.hpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / boost / beast / http / buffer_body.hpp
1 //
2 // Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
3 //
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)
6 //
7 // Official repository: https://github.com/boostorg/beast
8 //
9
10 #ifndef BOOST_BEAST_HTTP_BUFFER_BODY_HPP
11 #define BOOST_BEAST_HTTP_BUFFER_BODY_HPP
12
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>
19 #include <utility>
20
21 namespace boost {
22 namespace beast {
23 namespace http {
24
25 /** A @b Body using a caller provided buffer
26
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.
31 */
32 struct buffer_body
33 {
34 /// The type of the body member when used in a message.
35 struct value_type
36 {
37 /** A pointer to a contiguous area of memory of @ref size octets, else `nullptr`.
38
39 @par When Serializing
40
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.
46
47 @par When Parsing
48
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
57 pointed to by `data`.
58 */
59 void* data = nullptr;
60
61 /** The number of octets in the buffer pointed to by @ref data.
62
63 @par When Serializing
64
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`.
68
69 @par When Parsing
70
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.
77 */
78 std::size_t size = 0;
79
80 /** `true` if this is not the last buffer.
81
82 @par When Serializing
83
84 If this is `true` and `data` is `nullptr`, the error
85 @ref error::need_buffer will be returned from @ref serializer::get
86
87 @par When Parsing
88
89 This field is not used during parsing.
90 */
91 bool more = true;
92 };
93
94 /** The algorithm for parsing the body
95
96 Meets the requirements of @b BodyReader.
97 */
98 #if BOOST_BEAST_DOXYGEN
99 using reader = implementation_defined;
100 #else
101 class reader
102 {
103 value_type& body_;
104
105 public:
106 template<bool isRequest, class Fields>
107 explicit
108 reader(header<isRequest, Fields>&, value_type& b)
109 : body_(b)
110 {
111 }
112
113 void
114 init(boost::optional<std::uint64_t> const&, error_code& ec)
115 {
116 ec.assign(0, ec.category());
117 }
118
119 template<class ConstBufferSequence>
120 std::size_t
121 put(ConstBufferSequence const& buffers,
122 error_code& ec)
123 {
124 using boost::asio::buffer_size;
125 using boost::asio::buffer_copy;
126 if(! body_.data)
127 {
128 ec = error::need_buffer;
129 return 0;
130 }
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());
139 else
140 ec = error::need_buffer;
141 return bytes_transferred;
142 }
143
144 void
145 finish(error_code& ec)
146 {
147 ec.assign(0, ec.category());
148 }
149 };
150 #endif
151
152 /** The algorithm for serializing the body
153
154 Meets the requirements of @b BodyWriter.
155 */
156 #if BOOST_BEAST_DOXYGEN
157 using writer = implementation_defined;
158 #else
159 class writer
160 {
161 bool toggle_ = false;
162 value_type const& body_;
163
164 public:
165 using const_buffers_type =
166 boost::asio::const_buffer;
167
168 template<bool isRequest, class Fields>
169 explicit
170 writer(header<isRequest, Fields> const&, value_type const& b)
171 : body_(b)
172 {
173 }
174
175 void
176 init(error_code& ec)
177 {
178 ec.assign(0, ec.category());
179 }
180
181 boost::optional<
182 std::pair<const_buffers_type, bool>>
183 get(error_code& ec)
184 {
185 if(toggle_)
186 {
187 if(body_.more)
188 {
189 toggle_ = false;
190 ec = error::need_buffer;
191 }
192 else
193 {
194 ec.assign(0, ec.category());
195 }
196 return boost::none;
197 }
198 if(body_.data)
199 {
200 ec.assign(0, ec.category());
201 toggle_ = true;
202 return {{const_buffers_type{
203 body_.data, body_.size}, body_.more}};
204 }
205 if(body_.more)
206 ec = error::need_buffer;
207 else
208 ec.assign(0, ec.category());
209 return boost::none;
210 }
211 };
212 #endif
213 };
214
215 #if ! BOOST_BEAST_DOXYGEN
216 // operator<< is not supported for buffer_body
217 template<bool isRequest, class Fields>
218 std::ostream&
219 operator<<(std::ostream& os, message<isRequest,
220 buffer_body, Fields> const& msg) = delete;
221 #endif
222
223 } // http
224 } // beast
225 } // boost
226
227 #endif