GCC Code Coverage Report


Directory: libs/http_proto/include/boost/http_proto/
File: boost/http_proto/serializer.hpp
Date: 2023-02-02 18:17:22
Exec Total Coverage
Lines: 5 6 83.3%
Functions: 2 3 66.7%
Branches: 0 4 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/error_types.hpp>
15 #include <boost/http_proto/source.hpp>
16 #include <boost/http_proto/string_view.hpp>
17 #include <boost/http_proto/detail/circular_buffer.hpp>
18 #include <boost/http_proto/detail/array_of_buffers.hpp>
19 #include <boost/http_proto/detail/header.hpp>
20 #include <boost/http_proto/detail/workspace.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 struct brotli_decoder_t;
35 struct brotli_encoder_t;
36 struct deflate_decoder_t;
37 struct deflate_encoder_t;
38 struct gzip_decoder_t;
39 struct gzip_encoder_t;
40 namespace detail {
41 struct codec;
42 } // detail
43 #endif
44
45 /** A serializer for HTTP/1 messages
46
47 This is used to serialize one or more complete
48 HTTP/1 messages. Each message consists of a
49 required header followed by an optional body.
50 */
51 class BOOST_SYMBOL_VISIBLE
52 serializer
53 {
54 public:
55 /** A ConstBuffers representing the output
56 */
57 class const_buffers_type;
58
59 /** Destructor
60 */
61 BOOST_HTTP_PROTO_DECL
62 ~serializer();
63
64 /** Constructor
65 */
66 BOOST_HTTP_PROTO_DECL
67 serializer();
68
69 /** Constructor
70 */
71 BOOST_HTTP_PROTO_DECL
72 serializer(
73 serializer&&) noexcept;
74
75 /** Constructor
76 */
77 BOOST_HTTP_PROTO_DECL
78 explicit
79 serializer(
80 std::size_t buffer_size);
81
82 /** Constructor
83 */
84 template<class P0, class... Pn>
85 serializer(
86 std::size_t buffer_size,
87 P0&& p0,
88 Pn&&... pn);
89
90 //--------------------------------------------
91
92 /** Prepare the serializer for a new stream
93 */
94 BOOST_HTTP_PROTO_DECL
95 void
96 reset() noexcept;
97
98 /** Prepare the serializer for a new message
99
100 The message will not contain a body.
101 Changing the contents of the message
102 after calling this function and before
103 @ref is_done returns `true` results in
104 undefined behavior.
105 */
106 void
107 4 start(
108 message_view_base const& m)
109 {
110 4 start_empty(m);
111 4 }
112
113 /** Prepare the serializer for a new message
114
115 Changing the contents of the message
116 after calling this function and before
117 @ref is_done returns `true` results in
118 undefined behavior.
119
120 @par Constraints
121 @code
122 is_const_buffers< ConstBuffers >::value == true
123 @endcode
124 */
125 template<
126 class ConstBuffers
127 #ifndef BOOST_HTTP_PROTO_DOCS
128 ,class = typename
129 std::enable_if<
130 is_const_buffers<
131 ConstBuffers>::value
132 >::type
133 #endif
134 >
135 void
136 start(
137 message_view_base const& m,
138 ConstBuffers&& body);
139
140 /** Prepare the serializer for a new message
141
142 Changing the contents of the message
143 after calling this function and before
144 @ref is_done returns `true` results in
145 undefined behavior.
146 */
147 template<
148 class Source
149 #ifndef BOOST_HTTP_PROTO_DOCS
150 ,class = typename
151 std::enable_if<
152 is_source<Source
153 >::value>::type
154 #endif
155 >
156 auto
157 start(
158 message_view_base const& m,
159 Source&& body) ->
160 typename std::decay<
161 Source>::type&;
162
163 //--------------------------------------------
164
165 struct stream
166 {
167 stream() = default;
168 stream(stream const&) = default;
169 stream& operator=
170 (stream const&) = default;
171
172 using buffers_type =
173 mutable_buffers_pair;
174
175 BOOST_HTTP_PROTO_DECL
176 std::size_t
177 capacity() const;
178
179 BOOST_HTTP_PROTO_DECL
180 std::size_t
181 size() const;
182
183 BOOST_HTTP_PROTO_DECL
184 buffers_type
185 prepare(std::size_t n) const;
186
187 BOOST_HTTP_PROTO_DECL
188 void
189 commit(std::size_t n) const;
190
191 BOOST_HTTP_PROTO_DECL
192 void
193 close() const;
194
195 private:
196 friend class serializer;
197
198 explicit
199 stream(
200 serializer& sr) noexcept
201 : sr_(&sr)
202 {
203 }
204
205 serializer* sr_ = nullptr;
206 };
207
208 struct reserve_nothing
209 {
210 void
211 operator()(
212 std::size_t,
213 source::reserve_fn const&) noexcept
214 {
215 }
216 };
217
218 template<
219 class MaybeReserve = reserve_nothing>
220 stream
221 start_stream(
222 message_view_base const& m,
223 MaybeReserve&& maybe_reserve = {});
224
225 //--------------------------------------------
226
227 /** Return true if serialization is complete.
228 */
229 bool
230 21 is_done() const noexcept
231 {
232 21 return is_done_;
233 }
234
235 /** Return the output area.
236
237 This function will serialize some or
238 all of the content and return the
239 corresponding output buffers.
240
241 @par Preconditions
242 @code
243 this->is_done() == false
244 @endcode
245 */
246 BOOST_HTTP_PROTO_DECL
247 auto
248 prepare() ->
249 result<const_buffers_type>;
250
251 /** Consume bytes from the output area.
252 */
253 BOOST_HTTP_PROTO_DECL
254 void
255 consume(std::size_t n);
256
257 private:
258 static void copy(
259 const_buffer*,
260 const_buffer const*,
261 std::size_t n) noexcept;
262 auto
263 make_array(std::size_t n) ->
264 detail::array_of_const_buffers;
265 void apply_param(...) = delete;
266 void apply_params() noexcept;
267 template<class P0, class... Pn> void apply_params(P0&&, Pn&&...);
268
269 // in detail/impl/brotli_codec.ipp
270 BOOST_HTTP_PROTO_EXT_DECL void apply_param(brotli_decoder_t const&);
271 BOOST_HTTP_PROTO_EXT_DECL void apply_param(brotli_encoder_t const&);
272
273 // in detail/impl/zlib_codec.ipp
274 BOOST_HTTP_PROTO_ZLIB_DECL void apply_param(deflate_decoder_t const&);
275 BOOST_HTTP_PROTO_ZLIB_DECL void apply_param(deflate_encoder_t const&);
276 BOOST_HTTP_PROTO_ZLIB_DECL void apply_param(gzip_decoder_t const&);
277 BOOST_HTTP_PROTO_ZLIB_DECL void apply_param(gzip_encoder_t const&);
278
279 BOOST_HTTP_PROTO_DECL void do_maybe_reserve(source&, std::size_t);
280 BOOST_HTTP_PROTO_DECL void start_init(message_view_base const&);
281 BOOST_HTTP_PROTO_DECL void start_empty(message_view_base const&);
282 BOOST_HTTP_PROTO_DECL void start_buffers(message_view_base const&);
283 BOOST_HTTP_PROTO_DECL void start_source(message_view_base const&, source*);
284 BOOST_HTTP_PROTO_DECL void start_stream(message_view_base const&, source&);
285
286 enum class style
287 {
288 empty,
289 buffers,
290 source,
291 stream
292 };
293
294 enum
295 {
296 br_codec = 0,
297 deflate_codec = 1,
298 gzip_codec = 2
299 };
300
301 static
302 constexpr
303 std::size_t
304 chunked_overhead_ =
305 16 + // size
306 2 + // CRLF
307 2 + // CRLF
308 1 + // "0"
309 2 + // CRLF
310 2; // CRLF
311
312 class reserve;
313
314 detail::workspace ws_;
315 std::unique_ptr<
316 detail::codec> dec_[3];
317 std::unique_ptr<
318 detail::codec> enc_[3];
319
320 source* src_;
321 detail::array_of_const_buffers buf_;
322
323 detail::circular_buffer tmp0_;
324 detail::circular_buffer tmp1_;
325 detail::array_of_const_buffers out_;
326
327 const_buffer* hp_; // header
328 detail::codec* cod_;
329
330 style st_;
331 bool more_;
332 bool is_done_;
333 bool is_chunked_;
334 bool is_expect_continue_;
335 bool is_reserving_ = false;
336 };
337
338 //------------------------------------------------
339
340 } // http_proto
341 } // boost
342
343 #include <boost/http_proto/impl/serializer.hpp>
344
345 #endif
346