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_SPAN_BODY_HPP
11#define BOOST_BEAST_HTTP_SPAN_BODY_HPP
12
13#include <boost/beast/core/detail/config.hpp>
14#include <boost/beast/core/buffer_traits.hpp>
15#include <boost/beast/core/span.hpp>
16#include <boost/beast/http/error.hpp>
17#include <boost/beast/http/message.hpp>
18#include <boost/optional.hpp>
19
20namespace boost {
21namespace beast {
22namespace http {
23
24/** A <em>Body</em> using @ref span
25
26 This body uses @ref span as a memory-based container for
27 holding message payloads. The container represents a
28 non-owning reference to a contiguous area of memory.
29 Messages using this body type may be serialized and
30 parsed.
31
32 Unlike @ref buffer_body, only one buffer may be provided
33 during a parse or serialize operation.
34*/
35template<class T>
36struct span_body
37{
38private:
39 static_assert(
40 std::is_trivial<T>::value &&
41 std::is_standard_layout<T>::value,
42 "POD requirements not met");
43
44public:
45 /** The type of container used for the body
46
47 This determines the type of @ref message::body
48 when this body type is used with a message container.
49 */
50 using value_type = span<T>;
51
52 /** Returns the payload size of the body
53
54 When this body is used with @ref message::prepare_payload,
55 the Content-Length will be set to the payload size, and
56 any chunked Transfer-Encoding will be removed.
57 */
58 static
59 std::uint64_t
60 size(value_type const& body)
61 {
62 return body.size();
63 }
64
65 /** The algorithm for parsing the body
66
67 Meets the requirements of <em>BodyReader</em>.
68 */
69#if BOOST_BEAST_DOXYGEN
70 using reader = __implementation_defined__;
71#else
72 class reader
73 {
74 value_type& body_;
75
76 public:
77 template<bool isRequest, class Fields>
78 explicit
79 reader(header<isRequest, Fields>&, value_type& b)
80 : body_(b)
81 {
82 }
83
84 void
85 init(boost::optional<
86 std::uint64_t> const& length, error_code& ec)
87 {
88 if(length && *length > body_.size())
89 {
90 BOOST_BEAST_ASSIGN_EC(ec, error::buffer_overflow);
91 return;
92 }
93 ec = {};
94 }
95
96 template<class ConstBufferSequence>
97 std::size_t
98 put(ConstBufferSequence const& buffers,
99 error_code& ec)
100 {
101 auto const n = buffer_bytes(buffers);
102 auto const len = body_.size();
103 if(n > len)
104 {
105 BOOST_BEAST_ASSIGN_EC(ec, error::buffer_overflow);
106 return 0;
107 }
108 ec = {};
109 net::buffer_copy(net::buffer(
110 body_.data(), n), buffers);
111 body_ = value_type{
112 body_.data() + n, body_.size() - n};
113 return n;
114 }
115
116 void
117 finish(error_code& ec)
118 {
119 ec = {};
120 }
121 };
122#endif
123
124 /** The algorithm for serializing the body
125
126 Meets the requirements of <em>BodyWriter</em>.
127 */
128#if BOOST_BEAST_DOXYGEN
129 using writer = __implementation_defined__;
130#else
131 class writer
132 {
133 value_type const& body_;
134
135 public:
136 using const_buffers_type =
137 net::const_buffer;
138
139 template<bool isRequest, class Fields>
140 explicit
141 writer(header<isRequest, Fields> const&, value_type const& b)
142 : body_(b)
143 {
144 }
145
146 void
147 init(error_code& ec)
148 {
149 ec = {};
150 }
151
152 boost::optional<std::pair<const_buffers_type, bool>>
153 get(error_code& ec)
154 {
155 ec = {};
156 return {{
157 { body_.data(),
158 body_.size() * sizeof(typename
159 value_type::value_type)},
160 false}};
161 }
162 };
163#endif
164};
165
166} // http
167} // beast
168} // boost
169
170#endif
171

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