]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/beast/http/impl/serializer.ipp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / beast / http / impl / serializer.ipp
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_IMPL_SERIALIZER_IPP
11 #define BOOST_BEAST_HTTP_IMPL_SERIALIZER_IPP
12
13 #include <boost/beast/core/detail/buffers_ref.hpp>
14 #include <boost/beast/http/error.hpp>
15 #include <boost/beast/http/status.hpp>
16 #include <boost/beast/core/detail/config.hpp>
17 #include <boost/assert.hpp>
18 #include <ostream>
19
20 namespace boost {
21 namespace beast {
22 namespace http {
23
24 template<
25 bool isRequest, class Body, class Fields>
26 void
27 serializer<isRequest, Body, Fields>::
28 frdinit(std::true_type)
29 {
30 frd_.emplace(m_, m_.version(), m_.method());
31 }
32
33 template<
34 bool isRequest, class Body, class Fields>
35 void
36 serializer<isRequest, Body, Fields>::
37 frdinit(std::false_type)
38 {
39 frd_.emplace(m_, m_.version(), m_.result_int());
40 }
41
42 template<
43 bool isRequest, class Body, class Fields>
44 template<std::size_t I, class Visit>
45 inline
46 void
47 serializer<isRequest, Body, Fields>::
48 do_visit(error_code& ec, Visit& visit)
49 {
50 pv_.template emplace<I>(limit_, v_.template get<I>());
51 visit(ec, beast::detail::make_buffers_ref(
52 pv_.template get<I>()));
53 }
54
55 //------------------------------------------------------------------------------
56
57 template<
58 bool isRequest, class Body, class Fields>
59 serializer<isRequest, Body, Fields>::
60 serializer(value_type& m)
61 : m_(m)
62 , rd_(m_)
63 {
64 }
65
66 template<
67 bool isRequest, class Body, class Fields>
68 template<class Visit>
69 void
70 serializer<isRequest, Body, Fields>::
71 next(error_code& ec, Visit&& visit)
72 {
73 using boost::asio::buffer_size;
74 switch(s_)
75 {
76 case do_construct:
77 {
78 frdinit(std::integral_constant<bool,
79 isRequest>{});
80 if(m_.chunked())
81 goto go_init_c;
82 s_ = do_init;
83 BOOST_BEAST_FALLTHROUGH;
84 }
85
86 case do_init:
87 {
88 rd_.init(ec);
89 if(ec)
90 return;
91 if(split_)
92 goto go_header_only;
93 auto result = rd_.get(ec);
94 if(ec == error::need_more)
95 goto go_header_only;
96 if(ec)
97 return;
98 if(! result)
99 goto go_header_only;
100 more_ = result->second;
101 v_.template emplace<2>(
102 boost::in_place_init,
103 frd_->get(),
104 result->first);
105 s_ = do_header;
106 BOOST_BEAST_FALLTHROUGH;
107 }
108
109 case do_header:
110 do_visit<2>(ec, visit);
111 break;
112
113 go_header_only:
114 v_.template emplace<1>(frd_->get());
115 s_ = do_header_only;
116 BOOST_BEAST_FALLTHROUGH;
117 case do_header_only:
118 do_visit<1>(ec, visit);
119 break;
120
121 case do_body:
122 s_ = do_body + 1;
123 BOOST_BEAST_FALLTHROUGH;
124
125 case do_body + 1:
126 {
127 auto result = rd_.get(ec);
128 if(ec)
129 return;
130 if(! result)
131 goto go_complete;
132 more_ = result->second;
133 v_.template emplace<3>(result->first);
134 s_ = do_body + 2;
135 BOOST_BEAST_FALLTHROUGH;
136 }
137
138 case do_body + 2:
139 do_visit<3>(ec, visit);
140 break;
141
142 //----------------------------------------------------------------------
143
144 go_init_c:
145 s_ = do_init_c;
146 BOOST_BEAST_FALLTHROUGH;
147 case do_init_c:
148 {
149 rd_.init(ec);
150 if(ec)
151 return;
152 if(split_)
153 goto go_header_only_c;
154 auto result = rd_.get(ec);
155 if(ec == error::need_more)
156 goto go_header_only_c;
157 if(ec)
158 return;
159 if(! result)
160 goto go_header_only_c;
161 more_ = result->second;
162 if(! more_)
163 {
164 // do it all in one buffer
165 v_.template emplace<7>(
166 boost::in_place_init,
167 frd_->get(),
168 buffer_size(result->first),
169 boost::asio::const_buffer{nullptr, 0},
170 chunk_crlf{},
171 result->first,
172 chunk_crlf{},
173 detail::chunk_last(),
174 boost::asio::const_buffer{nullptr, 0},
175 chunk_crlf{});
176 goto go_all_c;
177 }
178 v_.template emplace<4>(
179 boost::in_place_init,
180 frd_->get(),
181 buffer_size(result->first),
182 boost::asio::const_buffer{nullptr, 0},
183 chunk_crlf{},
184 result->first,
185 chunk_crlf{});
186 s_ = do_header_c;
187 BOOST_BEAST_FALLTHROUGH;
188 }
189
190 case do_header_c:
191 do_visit<4>(ec, visit);
192 break;
193
194 go_header_only_c:
195 v_.template emplace<1>(frd_->get());
196 s_ = do_header_only_c;
197 case do_header_only_c:
198 do_visit<1>(ec, visit);
199 break;
200
201 case do_body_c:
202 s_ = do_body_c + 1;
203 BOOST_BEAST_FALLTHROUGH;
204
205 case do_body_c + 1:
206 {
207 auto result = rd_.get(ec);
208 if(ec)
209 return;
210 if(! result)
211 goto go_final_c;
212 more_ = result->second;
213 if(! more_)
214 {
215 // do it all in one buffer
216 v_.template emplace<6>(
217 boost::in_place_init,
218 buffer_size(result->first),
219 boost::asio::const_buffer{nullptr, 0},
220 chunk_crlf{},
221 result->first,
222 chunk_crlf{},
223 detail::chunk_last(),
224 boost::asio::const_buffer{nullptr, 0},
225 chunk_crlf{});
226 goto go_body_final_c;
227 }
228 v_.template emplace<5>(
229 boost::in_place_init,
230 buffer_size(result->first),
231 boost::asio::const_buffer{nullptr, 0},
232 chunk_crlf{},
233 result->first,
234 chunk_crlf{});
235 s_ = do_body_c + 2;
236 BOOST_BEAST_FALLTHROUGH;
237 }
238
239 case do_body_c + 2:
240 do_visit<5>(ec, visit);
241 break;
242
243 go_body_final_c:
244 s_ = do_body_final_c;
245 BOOST_BEAST_FALLTHROUGH;
246 case do_body_final_c:
247 do_visit<6>(ec, visit);
248 break;
249
250 go_all_c:
251 s_ = do_all_c;
252 BOOST_BEAST_FALLTHROUGH;
253 case do_all_c:
254 do_visit<7>(ec, visit);
255 break;
256
257 go_final_c:
258 case do_final_c:
259 v_.template emplace<8>(
260 boost::in_place_init,
261 detail::chunk_last(),
262 boost::asio::const_buffer{nullptr, 0},
263 chunk_crlf{});
264 s_ = do_final_c + 1;
265 BOOST_BEAST_FALLTHROUGH;
266
267 case do_final_c + 1:
268 do_visit<8>(ec, visit);
269 break;
270
271 //----------------------------------------------------------------------
272
273 default:
274 case do_complete:
275 BOOST_ASSERT(false);
276 break;
277
278 go_complete:
279 s_ = do_complete;
280 break;
281 }
282 }
283
284 template<
285 bool isRequest, class Body, class Fields>
286 void
287 serializer<isRequest, Body, Fields>::
288 consume(std::size_t n)
289 {
290 using boost::asio::buffer_size;
291 switch(s_)
292 {
293 case do_header:
294 BOOST_ASSERT(
295 n <= buffer_size(v_.template get<2>()));
296 v_.template get<2>().consume(n);
297 if(buffer_size(v_.template get<2>()) > 0)
298 break;
299 header_done_ = true;
300 v_.reset();
301 if(! more_)
302 goto go_complete;
303 s_ = do_body + 1;
304 break;
305
306 case do_header_only:
307 BOOST_ASSERT(
308 n <= buffer_size(v_.template get<1>()));
309 v_.template get<1>().consume(n);
310 if(buffer_size(v_.template get<1>()) > 0)
311 break;
312 frd_ = boost::none;
313 header_done_ = true;
314 if(! split_)
315 goto go_complete;
316 s_ = do_body;
317 break;
318
319 case do_body + 2:
320 {
321 BOOST_ASSERT(
322 n <= buffer_size(v_.template get<3>()));
323 v_.template get<3>().consume(n);
324 if(buffer_size(v_.template get<3>()) > 0)
325 break;
326 v_.reset();
327 if(! more_)
328 goto go_complete;
329 s_ = do_body + 1;
330 break;
331 }
332
333 //----------------------------------------------------------------------
334
335 case do_header_c:
336 BOOST_ASSERT(
337 n <= buffer_size(v_.template get<4>()));
338 v_.template get<4>().consume(n);
339 if(buffer_size(v_.template get<4>()) > 0)
340 break;
341 header_done_ = true;
342 v_.reset();
343 if(more_)
344 s_ = do_body_c + 1;
345 else
346 s_ = do_final_c;
347 break;
348
349 case do_header_only_c:
350 {
351 BOOST_ASSERT(
352 n <= buffer_size(v_.template get<1>()));
353 v_.template get<1>().consume(n);
354 if(buffer_size(v_.template get<1>()) > 0)
355 break;
356 frd_ = boost::none;
357 header_done_ = true;
358 if(! split_)
359 {
360 s_ = do_final_c;
361 break;
362 }
363 s_ = do_body_c;
364 break;
365 }
366
367 case do_body_c + 2:
368 BOOST_ASSERT(
369 n <= buffer_size(v_.template get<5>()));
370 v_.template get<5>().consume(n);
371 if(buffer_size(v_.template get<5>()) > 0)
372 break;
373 v_.reset();
374 if(more_)
375 s_ = do_body_c + 1;
376 else
377 s_ = do_final_c;
378 break;
379
380 case do_body_final_c:
381 {
382 BOOST_ASSERT(
383 n <= buffer_size(v_.template get<6>()));
384 v_.template get<6>().consume(n);
385 if(buffer_size(v_.template get<6>()) > 0)
386 break;
387 v_.reset();
388 s_ = do_complete;
389 break;
390 }
391
392 case do_all_c:
393 {
394 BOOST_ASSERT(
395 n <= buffer_size(v_.template get<7>()));
396 v_.template get<7>().consume(n);
397 if(buffer_size(v_.template get<7>()) > 0)
398 break;
399 header_done_ = true;
400 v_.reset();
401 s_ = do_complete;
402 break;
403 }
404
405 case do_final_c + 1:
406 BOOST_ASSERT(buffer_size(v_.template get<8>()));
407 v_.template get<8>().consume(n);
408 if(buffer_size(v_.template get<8>()) > 0)
409 break;
410 v_.reset();
411 goto go_complete;
412
413 //----------------------------------------------------------------------
414
415 default:
416 BOOST_ASSERT(false);
417 case do_complete:
418 break;
419
420 go_complete:
421 s_ = do_complete;
422 break;
423 }
424 }
425
426 } // http
427 } // beast
428 } // boost
429
430 #endif