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