Line data 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_proto
9 : //
10 :
11 : #ifndef BOOST_HTTP_PROTO_IMPL_SERIALIZER_HPP
12 : #define BOOST_HTTP_PROTO_IMPL_SERIALIZER_HPP
13 :
14 : #include <boost/http_proto/detail/except.hpp>
15 :
16 : namespace boost {
17 : namespace http_proto {
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 : buffers::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(buffers::begin(
52 : std::declval<ConstBufferSequence>()));
53 :
54 : ConstBufferSequence cbs_;
55 : it_t curr_;
56 :
57 : public:
58 : using const_buffer =
59 : buffers::const_buffer;
60 :
61 : explicit
62 24 : cbs_gen_impl(ConstBufferSequence cbs)
63 32 : : cbs_(std::move(cbs))
64 40 : , curr_(buffers::begin(cbs_))
65 : {
66 24 : }
67 :
68 : const_buffer
69 2056 : next() override
70 : {
71 2060 : while(curr_ != buffers::end(cbs_))
72 : {
73 : // triggers conversion operator
74 2042 : const_buffer buf = *curr_++;
75 2042 : if(buf.size() != 0)
76 2038 : return buf;
77 : }
78 18 : return {};
79 : }
80 :
81 : stats_t
82 8 : stats() const override
83 : {
84 8 : stats_t r;
85 104 : for(auto it = curr_; it != buffers::end(cbs_); ++it)
86 : {
87 : // triggers conversion operator
88 96 : const_buffer buf = *it;
89 96 : if(buf.size() != 0)
90 : {
91 46 : r.size += buf.size();
92 46 : r.count += 1;
93 : }
94 : }
95 8 : return r;
96 : }
97 :
98 : bool
99 4 : is_empty() const override
100 : {
101 4 : for(auto it = curr_; it != buffers::end(cbs_); ++it)
102 : {
103 : // triggers conversion operator
104 2 : const_buffer buf = *it;
105 2 : if(buf.size() != 0)
106 2 : return false;
107 : }
108 2 : return true;
109 : }
110 : };
111 :
112 : //---------------------------------------------------------
113 :
114 : template<
115 : class ConstBufferSequence,
116 : class>
117 : void
118 24 : serializer::
119 : start(
120 : message_view_base const& m,
121 : ConstBufferSequence&& cbs)
122 : {
123 : static_assert(buffers::is_const_buffer_sequence<
124 : ConstBufferSequence>::value,
125 : "ConstBufferSequence type requirements not met");
126 :
127 24 : start_init(m);
128 24 : start_buffers(
129 : m,
130 24 : ws().emplace<cbs_gen_impl<typename
131 24 : std::decay<ConstBufferSequence>::type>>(
132 : std::forward<ConstBufferSequence>(cbs)));
133 24 : }
134 :
135 : template<
136 : class Source,
137 : class... Args,
138 : class>
139 : Source&
140 25 : serializer::
141 : start(
142 : message_view_base const& m,
143 : Args&&... args)
144 : {
145 : static_assert(
146 : !std::is_abstract<Source>::value, "");
147 : static_assert(
148 : std::is_constructible<Source, Args...>::value ||
149 : std::is_constructible<Source, detail::workspace&, Args...>::value,
150 : "The Source cannot be constructed with the given arguments");
151 :
152 25 : start_init(m);
153 25 : auto& source = ws().emplace<Source>(
154 : std::forward<Args>(args)...);
155 25 : start_source(m, source);
156 25 : return source;
157 : }
158 :
159 : } // http_proto
160 : } // boost
161 :
162 : #endif
|