GCC Code Coverage Report


Directory: libs/http_proto/
File: boost/http_proto/serializer.hpp
Date: 2024-03-22 16:56:24
Exec Total Coverage
Lines: 7 11 63.6%
Functions: 2 4 50.0%
Branches: 0 0 -%

Line Branch Exec Source
1 //
2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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/cppalliance/http_proto
8 //
9
10 #ifndef BOOST_HTTP_PROTO_SERIALIZER_HPP
11 #define BOOST_HTTP_PROTO_SERIALIZER_HPP
12
13 #include <boost/http_proto/detail/config.hpp>
14 #include <boost/http_proto/source.hpp>
15 #include <boost/http_proto/detail/array_of_buffers.hpp>
16 #include <boost/http_proto/detail/header.hpp>
17 #include <boost/http_proto/detail/workspace.hpp>
18 #include <boost/buffers/circular_buffer.hpp>
19 #include <boost/buffers/type_traits.hpp>
20 #include <boost/system/result.hpp>
21 #include <cstdint>
22 #include <memory>
23 #include <type_traits>
24
25 namespace boost {
26 namespace http_proto {
27
28 #ifndef BOOST_HTTP_PROTO_DOCS
29 class request;
30 class response;
31 class request_view;
32 class response_view;
33 class message_view_base;
34 #endif
35
36 /** A serializer for HTTP/1 messages
37
38 This is used to serialize one or more complete
39 HTTP/1 messages. Each message consists of a
40 required header followed by an optional body.
41 */
42 class BOOST_SYMBOL_VISIBLE
43 serializer
44 {
45 public:
46 /** A ConstBuffers representing the output
47 */
48 class const_buffers_type;
49
50 struct stream;
51
52 /** Destructor
53 */
54 BOOST_HTTP_PROTO_DECL
55 ~serializer();
56
57 /** Constructor
58 */
59 BOOST_HTTP_PROTO_DECL
60 serializer();
61
62 /** Constructor
63 */
64 BOOST_HTTP_PROTO_DECL
65 serializer(
66 serializer&&) noexcept;
67
68 /** Constructor
69 */
70 BOOST_HTTP_PROTO_DECL
71 explicit
72 serializer(
73 std::size_t buffer_size);
74
75 //--------------------------------------------
76
77 /** Prepare the serializer for a new stream
78 */
79 BOOST_HTTP_PROTO_DECL
80 void
81 reset() noexcept;
82
83 /** Prepare the serializer for a new message
84
85 The message will not contain a body.
86 Changing the contents of the message
87 after calling this function and before
88 @ref is_done returns `true` results in
89 undefined behavior.
90 */
91 void
92 4 start(
93 message_view_base const& m)
94 {
95 4 start_empty(m);
96 4 }
97
98 /** Prepare the serializer for a new message
99
100 Changing the contents of the message
101 after calling this function and before
102 @ref is_done returns `true` results in
103 undefined behavior.
104
105 @par Constraints
106 @code
107 is_const_buffers< ConstBuffers >::value == true
108 @endcode
109 */
110 template<
111 class ConstBufferSequence
112 #ifndef BOOST_HTTP_PROTO_DOCS
113 ,class = typename
114 std::enable_if<
115 buffers::is_const_buffer_sequence<
116 ConstBufferSequence>::value
117 >::type
118 #endif
119 >
120 void
121 start(
122 message_view_base const& m,
123 ConstBufferSequence&& body);
124
125 /** Prepare the serializer for a new message
126
127 Changing the contents of the message
128 after calling this function and before
129 @ref is_done returns `true` results in
130 undefined behavior.
131 */
132 template<
133 class Source,
134 class... Args
135 #ifndef BOOST_HTTP_PROTO_DOCS
136 ,class = typename std::enable_if<
137 is_source<Source>::value>::type
138 #endif
139 >
140 Source&
141 start(
142 message_view_base const& m,
143 Args&&... args);
144
145 //--------------------------------------------
146
147 BOOST_HTTP_PROTO_DECL
148 stream
149 start_stream(
150 message_view_base const& m);
151
152 //--------------------------------------------
153
154 /** Return true if serialization is complete.
155 */
156 bool
157 41 is_done() const noexcept
158 {
159 41 return is_done_;
160 }
161
162 /** Return the output area.
163
164 This function will serialize some or
165 all of the content and return the
166 corresponding output buffers.
167
168 @par Preconditions
169 @code
170 this->is_done() == false
171 @endcode
172 */
173 BOOST_HTTP_PROTO_DECL
174 auto
175 prepare() ->
176 system::result<
177 const_buffers_type>;
178
179 /** Consume bytes from the output area.
180 */
181 BOOST_HTTP_PROTO_DECL
182 void
183 consume(std::size_t n);
184
185 private:
186 static void copy(
187 buffers::const_buffer*,
188 buffers::const_buffer const*,
189 std::size_t n) noexcept;
190 auto
191 make_array(std::size_t n) ->
192 detail::array_of_const_buffers;
193
194 template<
195 class Source,
196 class... Args,
197 typename std::enable_if<
198 std::is_constructible<
199 Source,
200 Args...>::value>::type* = nullptr>
201 Source&
202 8 construct_source(Args&&... args)
203 {
204 return ws_.emplace<Source>(
205 8 std::forward<Args>(args)...);
206 }
207
208 template<
209 class Source,
210 class... Args,
211 typename std::enable_if<
212 std::is_constructible<
213 Source,
214 buffered_base::allocator&,
215 Args...>::value>::type* = nullptr>
216 Source&
217 construct_source(Args&&... args)
218 {
219 buffered_base::allocator a(
220 ws_.data(),
221 (ws_.size() - ws_.space_needed<Source>()) / 2,
222 false);
223 auto& src = ws_.emplace<Source>(
224 a, std::forward<Args>(args)...);
225 ws_.reserve_front(a.size_used());
226 return src;
227 }
228
229 BOOST_HTTP_PROTO_DECL void start_init(message_view_base const&);
230 BOOST_HTTP_PROTO_DECL void start_empty(message_view_base const&);
231 BOOST_HTTP_PROTO_DECL void start_buffers(message_view_base const&);
232 BOOST_HTTP_PROTO_DECL void start_source(message_view_base const&, source*);
233
234 enum class style
235 {
236 empty,
237 buffers,
238 source,
239 stream
240 };
241
242 static
243 constexpr
244 std::size_t
245 chunked_overhead_ =
246 16 + // size
247 2 + // CRLF
248 2 + // CRLF
249 1 + // "0"
250 2 + // CRLF
251 2; // CRLF
252
253 detail::workspace ws_;
254 detail::array_of_const_buffers buf_;
255 source* src_;
256
257 buffers::circular_buffer tmp0_;
258 buffers::circular_buffer tmp1_;
259 detail::array_of_const_buffers out_;
260
261 buffers::const_buffer* hp_; // header
262
263 style st_;
264 bool more_;
265 bool is_done_;
266 bool is_chunked_;
267 bool is_expect_continue_;
268 };
269
270 //------------------------------------------------
271
272 struct serializer::stream
273 {
274 /** Constructor.
275 */
276 stream() = default;
277
278 /** Constructor.
279 */
280 stream(stream const&) = default;
281
282 /** Constructor.
283 */
284 stream& operator=
285 (stream const&) = default;
286
287 using buffers_type =
288 buffers::mutable_buffer_pair;
289
290 BOOST_HTTP_PROTO_DECL
291 std::size_t
292 capacity() const;
293
294 BOOST_HTTP_PROTO_DECL
295 std::size_t
296 size() const;
297
298 BOOST_HTTP_PROTO_DECL
299 buffers_type
300 prepare(std::size_t n) const;
301
302 BOOST_HTTP_PROTO_DECL
303 void
304 commit(std::size_t n) const;
305
306 BOOST_HTTP_PROTO_DECL
307 void
308 close() const;
309
310 private:
311 friend class serializer;
312
313 explicit
314 stream(
315 serializer& sr) noexcept
316 : sr_(&sr)
317 {
318 }
319
320 serializer* sr_ = nullptr;
321 };
322
323 } // http_proto
324 } // boost
325
326 #include <boost/http_proto/impl/serializer.hpp>
327
328 #endif
329