GCC Code Coverage Report


Directory: libs/http_proto/include/boost/http_proto/
File: boost/http_proto/impl/serializer.ipp
Date: 2023-01-09 16:11:13
Exec Total Coverage
Lines: 0 77 0.0%
Functions: 0 6 0.0%
Branches: 0 50 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_IMPL_SERIALIZER_IPP
11 #define BOOST_HTTP_PROTO_IMPL_SERIALIZER_IPP
12
13 #include <boost/http_proto/serializer.hpp>
14 #include <boost/http_proto/detail/except.hpp>
15 #include <stddef.h>
16
17 namespace boost {
18 namespace http_proto {
19
20 //------------------------------------------------
21 /*
22
23 write algorithm:
24
25 get buffers from serializer
26 - can fail with ec
27 - can perform blocking I/O
28
29 write buffers to socket
30 - consume the written amount
31
32 serializer supply algorithm
33 - supply a const buffer sequence for everything
34 serializer sr;
35 sr.set_body( cb );
36 - supply a const buffer sequence iteratively
37 serializer sr;
38 sr.set_body_some( cb );
39 - write into serializer-provided buffers iteratively
40 sr.set_body( source( ... ) );
41 */
42 //------------------------------------------------
43
44 serializer::
45 ~serializer()
46 {
47 }
48
49 serializer::
50 serializer(
51 std::size_t buffer_size)
52 : ws_(buffer_size)
53 {
54 }
55
56 void
57 serializer::
58 reset(
59 message_view_base const& m) noexcept
60 {
61 ws_.clear();
62 h_ = m.ph_;
63 src_ = nullptr;
64 st_ = state::init;
65
66 cb_ = nullptr;
67 cbn_ = 0;
68 cbi_ = 0;
69 }
70
71 //------------------------------------------------
72
73 auto
74 serializer::
75 prepare() ->
76 result<buffers>
77 {
78 if(st_ == state::init)
79 init_impl();
80
81 //if(! expect:100 continue)
82
83 if(src_)
84 {
85 // source body
86 auto cb0 = cb_;
87 const_buffer* p;
88 if(hbuf_.size() > 0)
89 {
90 *cb0 = hbuf_;
91 p = cb0 + 1;
92 }
93 else
94 {
95 ++cb0;
96 p = cb0;
97 }
98 ++p;
99 auto dest = buf_.prepare();
100 auto rv = src_->read(
101 dest.first.data(),
102 dest.first.size());
103 if(rv.has_error())
104 return rv.error();
105 buf_.commit(rv->bytes);
106 if( rv->more &&
107 dest.second.size() > 0)
108 {
109 rv = src_->read(
110 dest.second.data(),
111 dest.second.size());
112 if(rv.has_error())
113 return rv.error();
114 buf_.commit(rv->bytes);
115 }
116 more_ = rv->more;
117 auto src = buf_.data();
118 *p++ = src.first;
119 if(src.second.size() > 0)
120 *p++ = src.second;
121 return buffers(cb0, p - cb0);
122 }
123
124 // buffers body
125 if(hbuf_.size() > 0)
126 {
127 BOOST_ASSERT(cbi_ == 0);
128 cb_[0] = hbuf_;
129 return buffers(cb_, 1 + cbn_);
130 }
131 return buffers(
132 &cb_[1 + cbi_], cbn_ - cbi_);
133 }
134
135 void
136 serializer::
137 consume(
138 std::size_t n) noexcept
139 {
140 BOOST_ASSERT(
141 st_ == state::ok);
142
143 // header
144 if(hbuf_.size() > 0)
145 {
146 if(n <= hbuf_.size())
147 {
148 hbuf_ += n;
149 return;
150 }
151
152 n -= hbuf_.size();
153 hbuf_ = {};
154 }
155
156 if(src_)
157 {
158 // source body
159 buf_.consume(n);
160
161 if( buf_.empty() &&
162 ! more_)
163 {
164 st_ = state::done;
165 }
166 }
167 else
168 {
169 // buffers body
170 while(n > 0)
171 {
172 // n was out of range
173 BOOST_ASSERT(cbi_ != cbn_);
174 auto i = cbi_ + 1;
175 if(n < cb_[i].size())
176 {
177 cb_[i] += n;
178 return;
179 }
180
181 n -= cb_[i].size();
182 ++cbi_;
183 }
184 st_ = state::done;
185 }
186 }
187
188 //------------------------------------------------
189
190 void
191 serializer::
192 init_impl()
193 {
194 BOOST_ASSERT(st_ == state::init);
195
196 // header
197 hbuf_ = { h_->buf, h_->size };
198
199 if(src_)
200 {
201 // source body
202 buf_ = { ws_.data(), ws_.size() };
203 }
204 else
205 {
206 // buffers body
207 }
208
209 st_ = state::ok;
210 }
211
212 } // http_proto
213 } // boost
214
215 #endif
216