]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/beast/http/string_body.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / beast / http / string_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_STRING_BODY_HPP
11 #define BOOST_BEAST_HTTP_STRING_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/core/detail/type_traits.hpp>
17 #include <boost/asio/buffer.hpp>
18 #include <boost/optional.hpp>
19 #include <cstdint>
20 #include <limits>
21 #include <memory>
22 #include <stdexcept>
23 #include <string>
24 #include <utility>
25
26 namespace boost {
27 namespace beast {
28 namespace http {
29
30 /** A @b Body using `std::basic_string`
31
32 This body uses `std::basic_string` as a memory-based container
33 for holding message payloads. Messages using this body type
34 may be serialized and parsed.
35 */
36 template<
37 class CharT,
38 class Traits = std::char_traits<CharT>,
39 class Allocator = std::allocator<CharT>>
40 struct basic_string_body
41 {
42 private:
43 static_assert(
44 std::is_integral<CharT>::value &&
45 sizeof(CharT) == 1,
46 "CharT requirements not met");
47
48 public:
49 /** The type of container used for the body
50
51 This determines the type of @ref message::body
52 when this body type is used with a message container.
53 */
54 using value_type =
55 std::basic_string<CharT, Traits, Allocator>;
56
57 /** Returns the payload size of the body
58
59 When this body is used with @ref message::prepare_payload,
60 the Content-Length will be set to the payload size, and
61 any chunked Transfer-Encoding will be removed.
62 */
63 static
64 std::uint64_t
65 size(value_type const& body)
66 {
67 return body.size();
68 }
69
70 /** The algorithm for parsing the body
71
72 Meets the requirements of @b BodyReader.
73 */
74 #if BOOST_BEAST_DOXYGEN
75 using reader = implementation_defined;
76 #else
77 class reader
78 {
79 value_type& body_;
80
81 public:
82 template<bool isRequest, class Fields>
83 explicit
84 reader(message<isRequest,
85 basic_string_body, Fields>& m)
86 : body_(m.body())
87 {
88 }
89
90 void
91 init(boost::optional<
92 std::uint64_t> const& length, error_code& ec)
93 {
94 if(length)
95 {
96 if(static_cast<std::size_t>(*length) != *length)
97 {
98 ec = error::buffer_overflow;
99 return;
100 }
101 try
102 {
103 body_.reserve(
104 static_cast<std::size_t>(*length));
105 }
106 catch(std::exception const&)
107 {
108 ec = error::buffer_overflow;
109 return;
110 }
111 }
112 ec.assign(0, ec.category());
113 }
114
115 template<class ConstBufferSequence>
116 std::size_t
117 put(ConstBufferSequence const& buffers,
118 error_code& ec)
119 {
120 using boost::asio::buffer_size;
121 using boost::asio::buffer_copy;
122 auto const extra = buffer_size(buffers);
123 auto const size = body_.size();
124 try
125 {
126 body_.resize(size + extra);
127 }
128 catch(std::exception const&)
129 {
130 ec = error::buffer_overflow;
131 return 0;
132 }
133 ec.assign(0, ec.category());
134 CharT* dest = &body_[size];
135 for(auto b : beast::detail::buffers_range(buffers))
136 {
137 Traits::copy(dest, reinterpret_cast<
138 CharT const*>(b.data()), b.size());
139 dest += b.size();
140 }
141 return extra;
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 value_type const& body_;
162
163 public:
164 using const_buffers_type =
165 boost::asio::const_buffer;
166
167 template<bool isRequest, class Fields>
168 explicit
169 writer(message<isRequest,
170 basic_string_body, Fields> const& msg)
171 : body_(msg.body())
172 {
173 }
174
175 void
176 init(error_code& ec)
177 {
178 ec.assign(0, ec.category());
179 }
180
181 boost::optional<std::pair<const_buffers_type, bool>>
182 get(error_code& ec)
183 {
184 ec.assign(0, ec.category());
185 return {{const_buffers_type{
186 body_.data(), body_.size()}, false}};
187 }
188 };
189 #endif
190 };
191
192 /// A @b Body using `std::string`
193 using string_body = basic_string_body<char>;
194
195 } // http
196 } // beast
197 } // boost
198
199 #endif