libs/http/include/boost/http/impl/serializer.hpp

100.0% Lines (30/30) 86.7% Functions (13/15) 83.3% Branches (10/12)
libs/http/include/boost/http/impl/serializer.hpp
Line Branch Hits Source Code
1 //
2 // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2025 Mohammad Nejati
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/cppalliance/http
9 //
10
11 #ifndef BOOST_HTTP_IMPL_SERIALIZER_HPP
12 #define BOOST_HTTP_IMPL_SERIALIZER_HPP
13
14 #include <boost/http/detail/except.hpp>
15
16 namespace boost {
17 namespace http {
18
19 class serializer::cbs_gen
20 {
21 public:
22 struct stats_t
23 {
24 std::size_t size = 0;
25 std::size_t count = 0;
26 };
27
28 // Return the next non-empty buffer or an
29 // empty buffer if none remain.
30 virtual
31 capy::const_buffer
32 next() = 0;
33
34 // Return the total size and count of
35 // remaining non-empty buffers.
36 virtual
37 stats_t
38 stats() const = 0;
39
40 // Return true if there are no remaining
41 // non-empty buffers.
42 virtual
43 bool
44 is_empty() const = 0;
45 };
46
47 template<class ConstBufferSequence>
48 class serializer::cbs_gen_impl
49 : public cbs_gen
50 {
51 using it_t = decltype(capy::begin(
52 std::declval<ConstBufferSequence>()));
53
54 ConstBufferSequence cbs_;
55 it_t curr_;
56
57 public:
58 using const_buffer =
59 capy::const_buffer;
60
61 explicit
62 10 cbs_gen_impl(ConstBufferSequence cbs)
63 20 : cbs_(std::move(cbs))
64 10 , curr_(capy::begin(cbs_))
65 {
66 10 }
67
68 const_buffer
69 51 next() override
70 {
71
2/2
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 3 times.
51 while(curr_ != capy::end(cbs_))
72 {
73 // triggers conversion operator
74 48 const_buffer buf = *curr_++;
75
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 if(buf.size() != 0)
76 48 return buf;
77 }
78 3 return {};
79 }
80
81 stats_t
82 10 stats() const override
83 {
84 10 stats_t r;
85
2/2
✓ Branch 1 taken 98 times.
✓ Branch 2 taken 10 times.
108 for(auto it = curr_; it != capy::end(cbs_); ++it)
86 {
87 // triggers conversion operator
88 98 const_buffer buf = *it;
89
2/2
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 50 times.
98 if(buf.size() != 0)
90 {
91 48 r.size += buf.size();
92 48 r.count += 1;
93 }
94 }
95 10 return r;
96 }
97
98 bool
99 6 is_empty() const override
100 {
101
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4 times.
6 for(auto it = curr_; it != capy::end(cbs_); ++it)
102 {
103 // triggers conversion operator
104 2 const_buffer buf = *it;
105
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if(buf.size() != 0)
106 2 return false;
107 }
108 4 return true;
109 }
110 };
111
112 //---------------------------------------------------------
113
114 template<
115 class ConstBufferSequence,
116 class>
117 void
118 10 serializer::
119 start(
120 message_base const& m,
121 ConstBufferSequence&& cbs)
122 {
123 static_assert(
124 capy::ConstBufferSequence<ConstBufferSequence>,
125 "ConstBufferSequence type requirements not met");
126
127 10 start_init(m);
128 10 start_buffers(
129 m,
130 10 ws().emplace<cbs_gen_impl<typename
131 10 std::decay<ConstBufferSequence>::type>>(
132 std::forward<ConstBufferSequence>(cbs)));
133 10 }
134
135 } // http
136 } // boost
137
138 #endif
139