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
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 51 : while(curr_ != capy::end(cbs_))
72 : {
73 : // triggers conversion operator
74 48 : const_buffer buf = *curr_++;
75 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 108 : for(auto it = curr_; it != capy::end(cbs_); ++it)
86 : {
87 : // triggers conversion operator
88 98 : const_buffer buf = *it;
89 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 6 : for(auto it = curr_; it != capy::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 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
|