Line data Source code
1 : //
2 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 : // Copyright (c) 2023 Alan de Freitas (alandefreitas@gmail.com)
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/boostorg/url
9 : //
10 :
11 :
12 : #include <boost/url/detail/config.hpp>
13 : #include <boost/url/detail/any_params_iter.hpp>
14 : #include <boost/url/encode.hpp>
15 : #include <boost/core/detail/string_view.hpp>
16 : #include <boost/url/rfc/detail/charsets.hpp>
17 :
18 : namespace boost {
19 : namespace urls {
20 : namespace detail {
21 :
22 : /*
23 : When a string is transformed into a range of
24 : params, the empty string becomes ambiguous:
25 : it can be an empty range, or a range with
26 : one param. The value `not_empty` is used on
27 : construction to inform the transformation
28 : that the empty string should be treated as
29 : a one-element range. This simplifies
30 : edit_params().
31 : */
32 :
33 : //------------------------------------------------
34 : //
35 : // any_params_iter
36 : //
37 : //------------------------------------------------
38 :
39 147 : any_params_iter::
40 : ~any_params_iter() noexcept = default;
41 :
42 : //------------------------------------------------
43 : //
44 : // param_iter
45 : //
46 : //------------------------------------------------
47 :
48 24 : single_param_iter::
49 : single_param_iter(
50 : param_view const& p,
51 24 : bool space_as_plus) noexcept
52 : : any_params_iter(
53 : false,
54 : p.key,
55 : p.value)
56 24 : , has_value_(p.has_value)
57 24 : , space_as_plus_(space_as_plus)
58 : {
59 24 : }
60 :
61 : void
62 24 : single_param_iter::
63 : rewind() noexcept
64 : {
65 24 : at_end_ = false;
66 24 : }
67 :
68 : bool
69 48 : single_param_iter::
70 : measure(std::size_t& n) noexcept
71 : {
72 48 : if(at_end_)
73 24 : return false;
74 24 : encoding_opts opt;
75 24 : opt.space_as_plus = space_as_plus_;
76 24 : n += encoded_size(
77 : s0,
78 : detail::param_key_chars,
79 : opt);
80 24 : if(has_value_)
81 : {
82 24 : ++n; // '='
83 24 : n += encoded_size(
84 : s1,
85 : detail::param_value_chars,
86 : opt);
87 : }
88 24 : at_end_ = true;
89 24 : return true;
90 : }
91 :
92 : void
93 24 : single_param_iter::
94 : copy(
95 : char*& dest,
96 : char const* end) noexcept
97 : {
98 24 : BOOST_ASSERT(! at_end_);
99 24 : encoding_opts opt;
100 24 : opt.space_as_plus = space_as_plus_;
101 48 : dest += encode(
102 : dest,
103 24 : end - dest,
104 : s0,
105 : detail::param_key_chars,
106 : opt);
107 24 : if (has_value_)
108 : {
109 24 : *dest++ = '=';
110 24 : dest += encode(
111 : dest,
112 24 : end - dest,
113 : s1,
114 : detail::param_value_chars,
115 : opt);
116 : }
117 24 : }
118 :
119 : //------------------------------------------------
120 : //
121 : // params_iter_base
122 : //
123 : //------------------------------------------------
124 :
125 : void
126 70 : params_iter_base::
127 : measure_impl(
128 : std::size_t& n,
129 : param_view const& p) noexcept
130 : {
131 70 : encoding_opts opt;
132 70 : opt.space_as_plus = space_as_plus_;
133 70 : n += encoded_size(
134 : p.key,
135 : detail::param_key_chars,
136 : opt);
137 70 : if(p.has_value)
138 : {
139 58 : ++n; // '='
140 58 : n += encoded_size(
141 : p.value,
142 : detail::param_value_chars,
143 : opt);
144 : }
145 70 : }
146 :
147 : void
148 70 : params_iter_base::
149 : copy_impl(
150 : char*& dest,
151 : char const* end,
152 : param_view const& p) noexcept
153 : {
154 70 : encoding_opts opt;
155 70 : opt.space_as_plus = space_as_plus_;
156 140 : dest += encode(
157 : dest,
158 70 : end - dest,
159 : p.key,
160 : detail::param_key_chars,
161 : opt);
162 70 : if(p.has_value)
163 : {
164 58 : *dest++ = '=';
165 58 : dest += encode(
166 : dest,
167 58 : end - dest,
168 : p.value,
169 : detail::param_value_chars,
170 : opt);
171 : }
172 70 : }
173 :
174 : //------------------------------------------------
175 : //
176 : // param_encoded_iter
177 : //
178 : //------------------------------------------------
179 :
180 12 : param_encoded_iter::
181 : param_encoded_iter(
182 12 : param_pct_view const& p) noexcept
183 : : any_params_iter(
184 : false,
185 : p.key,
186 : p.value)
187 12 : , has_value_(p.has_value)
188 : {
189 12 : }
190 :
191 : void
192 12 : param_encoded_iter::
193 : rewind() noexcept
194 : {
195 12 : at_end_ = false;
196 12 : }
197 :
198 : bool
199 24 : param_encoded_iter::
200 : measure(std::size_t& n) noexcept
201 : {
202 24 : if(at_end_)
203 12 : return false;
204 12 : n += detail::re_encoded_size_unsafe(
205 : s0,
206 : detail::param_key_chars);
207 12 : if(has_value_)
208 12 : n += detail::re_encoded_size_unsafe(
209 : s1,
210 12 : detail::param_value_chars) + 1; // for '='
211 12 : at_end_ = true;
212 12 : return true;
213 : }
214 :
215 : void
216 12 : param_encoded_iter::
217 : copy(
218 : char*& dest,
219 : char const* end) noexcept
220 : {
221 12 : detail::re_encode_unsafe(
222 : dest,
223 : end,
224 : s0,
225 : detail::param_key_chars);
226 12 : if(has_value_)
227 : {
228 12 : *dest++ = '=';
229 12 : detail::re_encode_unsafe(
230 : dest,
231 : end,
232 : s1,
233 : detail::param_value_chars);
234 : }
235 12 : }
236 :
237 :
238 : //------------------------------------------------
239 : //
240 : // params_encoded_iter_base
241 : //
242 : //------------------------------------------------
243 :
244 : void
245 51 : params_encoded_iter_base::
246 : measure_impl(
247 : std::size_t& n,
248 : param_view const& p) noexcept
249 : {
250 51 : n += detail::re_encoded_size_unsafe(
251 : p.key,
252 : detail::param_key_chars);
253 51 : if(p.has_value)
254 42 : n += detail::re_encoded_size_unsafe(
255 : p.value,
256 42 : detail::param_value_chars) + 1; // for '='
257 51 : }
258 :
259 : void
260 51 : params_encoded_iter_base::
261 : copy_impl(
262 : char*& dest,
263 : char const* end,
264 : param_view const& p) noexcept
265 : {
266 51 : detail::re_encode_unsafe(
267 : dest,
268 : end,
269 : p.key,
270 : detail::param_key_chars);
271 51 : if(p.has_value)
272 : {
273 42 : *dest++ = '=';
274 42 : detail::re_encode_unsafe(
275 : dest,
276 : end,
277 : p.value,
278 : detail::param_value_chars);
279 : }
280 51 : }
281 :
282 : //------------------------------------------------
283 : //
284 : // param_value_iter
285 : //
286 : //------------------------------------------------
287 :
288 : void
289 9 : param_value_iter::
290 : rewind() noexcept
291 : {
292 9 : at_end_ = false;
293 9 : }
294 :
295 : bool
296 18 : param_value_iter::
297 : measure(
298 : std::size_t& n) noexcept
299 : {
300 18 : if(at_end_)
301 9 : return false;
302 9 : n += nk_; // skip key
303 9 : if(has_value_)
304 : {
305 5 : encoding_opts opt;
306 5 : opt.space_as_plus = false;
307 5 : n += encoded_size(
308 : s0,
309 : detail::param_value_chars,
310 5 : opt) + 1; // for '='
311 : }
312 9 : at_end_ = true;
313 9 : return true;
314 : }
315 :
316 : void
317 9 : param_value_iter::
318 : copy(char*& it, char const* end) noexcept
319 : {
320 9 : it += nk_; // skip key
321 9 : if(! has_value_)
322 4 : return;
323 5 : *it++ = '=';
324 5 : encoding_opts opt;
325 5 : opt.space_as_plus = false;
326 5 : it += encode(
327 : it,
328 5 : end - it,
329 : s0,
330 : detail::param_value_chars,
331 : opt);
332 : }
333 :
334 : //------------------------------------------------
335 : //
336 : // param_encoded_value_iter
337 : //
338 : //------------------------------------------------
339 :
340 : void
341 8 : param_encoded_value_iter::
342 : rewind() noexcept
343 : {
344 8 : at_end_ = false;
345 8 : }
346 :
347 : bool
348 16 : param_encoded_value_iter::
349 : measure(
350 : std::size_t& n) noexcept
351 : {
352 16 : if(at_end_)
353 8 : return false;
354 8 : n += nk_; // skip key
355 8 : if(has_value_)
356 : {
357 4 : n += detail::re_encoded_size_unsafe(
358 : s0,
359 4 : detail::param_value_chars) + 1; // for '='
360 : }
361 8 : at_end_ = true;
362 8 : return true;
363 : }
364 :
365 : void
366 8 : param_encoded_value_iter::
367 : copy(
368 : char*& dest,
369 : char const* end) noexcept
370 : {
371 8 : dest += nk_; // skip key
372 8 : if(! has_value_)
373 4 : return;
374 4 : *dest++ = '=';
375 4 : detail::re_encode_unsafe(
376 : dest,
377 : end,
378 : s0,
379 : detail::param_value_chars);
380 : }
381 :
382 : } // detail
383 : } // urls
384 : } // boost
385 :
|