GCC Code Coverage Report


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