1//
2// Copyright (c) 2016-2019 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/core/buffer_traits.hpp>
15#include <boost/beast/http/error.hpp>
16#include <boost/beast/http/message.hpp>
17#include <boost/beast/core/buffers_range.hpp>
18#include <boost/beast/core/detail/clamp.hpp>
19#include <boost/asio/buffer.hpp>
20#include <boost/optional.hpp>
21#include <cstdint>
22#include <limits>
23#include <memory>
24#include <stdexcept>
25#include <string>
26#include <utility>
27
28namespace boost {
29namespace beast {
30namespace http {
31
32/** A <em>Body</em> using `std::basic_string`
33
34 This body uses `std::basic_string` as a memory-based container
35 for holding message payloads. Messages using this body type
36 may be serialized and parsed.
37*/
38template<
39 class CharT,
40 class Traits = std::char_traits<CharT>,
41 class Allocator = std::allocator<CharT>>
42struct basic_string_body
43{
44private:
45 static_assert(
46 std::is_integral<CharT>::value &&
47 sizeof(CharT) == 1,
48 "CharT requirements not met");
49
50public:
51 /** The type of container used for the body
52
53 This determines the type of @ref message::body
54 when this body type is used with a message container.
55 */
56 using value_type =
57 std::basic_string<CharT, Traits, Allocator>;
58
59 /** Returns the payload size of the body
60
61 When this body is used with @ref message::prepare_payload,
62 the Content-Length will be set to the payload size, and
63 any chunked Transfer-Encoding will be removed.
64 */
65 static
66 std::uint64_t
67 size(value_type const& body)
68 {
69 return body.size();
70 }
71
72 /** The algorithm for parsing the body
73
74 Meets the requirements of <em>BodyReader</em>.
75 */
76#if BOOST_BEAST_DOXYGEN
77 using reader = __implementation_defined__;
78#else
79 class reader
80 {
81 value_type& body_;
82
83 public:
84 template<bool isRequest, class Fields>
85 explicit
86 reader(header<isRequest, Fields>&, value_type& b)
87 : body_(b)
88 {
89 }
90
91 void
92 init(boost::optional<
93 std::uint64_t> const& length, error_code& ec)
94 {
95 if(length)
96 {
97 if(*length > body_.max_size())
98 {
99 BOOST_BEAST_ASSIGN_EC(ec, error::buffer_overflow);
100 return;
101 }
102 body_.reserve(beast::detail::clamp(x: *length));
103 }
104 ec = {};
105 }
106
107 template<class ConstBufferSequence>
108 std::size_t
109 put(ConstBufferSequence const& buffers,
110 error_code& ec)
111 {
112 auto const extra = buffer_bytes(buffers);
113 auto const size = body_.size();
114 if (extra > body_.max_size() - size)
115 {
116 BOOST_BEAST_ASSIGN_EC(ec, error::buffer_overflow);
117 return 0;
118 }
119
120 body_.resize(size + extra);
121 ec = {};
122 CharT* dest = &body_[size];
123 for(auto b : beast::buffers_range_ref(buffers))
124 {
125 Traits::copy(dest, static_cast<
126 CharT const*>(b.data()), b.size());
127 dest += b.size();
128 }
129 return extra;
130 }
131
132 void
133 finish(error_code& ec)
134 {
135 ec = {};
136 }
137 };
138#endif
139
140 /** The algorithm for serializing the body
141
142 Meets the requirements of <em>BodyWriter</em>.
143 */
144#if BOOST_BEAST_DOXYGEN
145 using writer = __implementation_defined__;
146#else
147 class writer
148 {
149 value_type const& body_;
150
151 public:
152 using const_buffers_type =
153 net::const_buffer;
154
155 template<bool isRequest, class Fields>
156 explicit
157 writer(header<isRequest, Fields> const&, value_type const& b)
158 : body_(b)
159 {
160 }
161
162 void
163 init(error_code& ec)
164 {
165 ec = {};
166 }
167
168 boost::optional<std::pair<const_buffers_type, bool>>
169 get(error_code& ec)
170 {
171 ec = {};
172 return {{const_buffers_type{
173 body_.data(), body_.size()}, false}};
174 }
175 };
176#endif
177};
178
179/// A <em>Body</em> using `std::string`
180using string_body = basic_string_body<char>;
181
182} // http
183} // beast
184} // boost
185
186#endif
187

source code of boost/libs/beast/include/boost/beast/http/string_body.hpp