include/boost/url/impl/params_base.hpp

100.0% Lines (128/128) 100.0% Functions (28/28)
include/boost/url/impl/params_base.hpp
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2022 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 #ifndef BOOST_URL_IMPL_PARAMS_BASE_HPP
12 #define BOOST_URL_IMPL_PARAMS_BASE_HPP
13
14 #include <boost/url/detail/params_iter_impl.hpp>
15 #include <boost/url/decode_view.hpp>
16 #include <boost/url/grammar/ci_string.hpp>
17 #include <iterator>
18 #include <ostream>
19 #include <string>
20
21 namespace boost {
22 namespace urls {
23
24 //------------------------------------------------
25
26 class BOOST_SYMBOL_VISIBLE params_base::iterator
27 {
28 detail::params_iter_impl it_;
29 bool space_as_plus_ = true;
30
31 friend class params_base;
32 friend class params_ref;
33
34 iterator(
35 detail::query_ref const& ref,
36 encoding_opts opt) noexcept;
37
38 iterator(
39 detail::query_ref const& impl,
40 encoding_opts opt,
41 int) noexcept;
42
43 183 iterator(
44 detail::params_iter_impl const& it,
45 encoding_opts opt) noexcept
46 183 : it_(it)
47 183 , space_as_plus_(opt.space_as_plus)
48 {
49 183 }
50
51 public:
52 using value_type = params_base::value_type;
53 using reference = params_base::reference;
54 using pointer = reference;
55 using difference_type =
56 params_base::difference_type;
57 using iterator_category =
58 std::bidirectional_iterator_tag;
59
60 4 iterator() = default;
61 iterator(iterator const&) = default;
62 iterator& operator=(
63 iterator const&) noexcept = default;
64
65 iterator&
66 861 operator++() noexcept
67 {
68 861 it_.increment();
69 861 return *this;
70 }
71
72 iterator
73 367 operator++(int) noexcept
74 {
75 367 auto tmp = *this;
76 367 ++*this;
77 367 return tmp;
78 }
79
80 iterator&
81 730 operator--() noexcept
82 {
83 730 it_.decrement();
84 730 return *this;
85 }
86
87 iterator
88 365 operator--(int) noexcept
89 {
90 365 auto tmp = *this;
91 365 --*this;
92 365 return tmp;
93 }
94
95 reference
96 operator*() const;
97
98 // the return value is too expensive
99 pointer operator->() const = delete;
100
101 bool
102 768 operator==(
103 iterator const& other) const noexcept
104 {
105 768 return it_.equal(other.it_);
106 }
107
108 bool
109 106 operator!=(
110 iterator const& other) const noexcept
111 {
112 106 return ! it_.equal(other.it_);
113 }
114 };
115
116
117 //------------------------------------------------
118
119 inline
120 326 params_base::
121 iterator::
122 iterator(
123 detail::query_ref const& ref,
124 326 encoding_opts opt) noexcept
125 326 : it_(ref)
126 326 , space_as_plus_(opt.space_as_plus)
127 {
128 326 }
129
130 inline
131 247 params_base::
132 iterator::
133 iterator(
134 detail::query_ref const& ref,
135 encoding_opts opt,
136 247 int) noexcept
137 247 : it_(ref, 0)
138 247 , space_as_plus_(opt.space_as_plus)
139 {
140 247 }
141
142
143 inline
144 auto
145 826 params_base::
146 iterator::
147 operator*() const ->
148 reference
149
150 {
151 826 encoding_opts opt;
152 826 opt.space_as_plus =
153 826 space_as_plus_;
154 param_pct_view p =
155 826 it_.dereference();
156 return reference(
157 1652 p.key.decode(opt),
158 1652 p.value.decode(opt),
159 4130 p.has_value);
160 }
161
162 //------------------------------------------------
163 //
164 // params_base
165 //
166 //------------------------------------------------
167
168 inline
169 1 params_base::
170 1 params_base() noexcept
171 // space_as_plus = true
172 1 : opt_(true, false, false)
173 {
174 1 }
175
176 inline
177 bool
178 28 params_base::
179 contains(
180 core::string_view key,
181 ignore_case_param ic) const noexcept
182 {
183 28 return find(
184 56 begin(),key, ic) != end();
185 }
186
187 inline
188 auto
189 42 params_base::
190 find(
191 core::string_view key,
192 ignore_case_param ic) const noexcept ->
193 iterator
194 {
195 return iterator(
196 42 find_impl(
197 84 begin().it_, key, ic),
198 42 opt_);
199 }
200
201 inline
202 auto
203 60 params_base::
204 find(
205 iterator it,
206 core::string_view key,
207 ignore_case_param ic) const noexcept ->
208 iterator
209 {
210 return iterator(
211 120 find_impl(
212 it.it_, key, ic),
213 60 opt_);
214 }
215
216 inline
217 auto
218 4 params_base::
219 find_last(
220 core::string_view key,
221 ignore_case_param ic) const noexcept ->
222 iterator
223 {
224 return iterator(
225 4 find_last_impl(
226 8 end().it_, key, ic),
227 4 opt_);
228 }
229
230 inline
231 auto
232 9 params_base::
233 find_last(
234 iterator it,
235 core::string_view key,
236 ignore_case_param ic) const noexcept ->
237 iterator
238 {
239 return iterator(
240 18 find_last_impl(
241 it.it_, key, ic),
242 9 opt_);
243 }
244
245 inline
246 312 params_base::
247 params_base(
248 detail::query_ref const& ref,
249 312 encoding_opts opt) noexcept
250 312 : ref_(ref)
251 312 , opt_(opt)
252 {
253 312 }
254
255 inline
256 pct_string_view
257 13 params_base::
258 buffer() const noexcept
259 {
260 13 return ref_.buffer();
261 }
262
263 inline
264 bool
265 5 params_base::
266 empty() const noexcept
267 {
268 5 return ref_.nparam() == 0;
269 }
270
271 inline
272 std::size_t
273 222 params_base::
274 size() const noexcept
275 {
276 222 return ref_.nparam();
277 }
278
279 inline
280 auto
281 326 params_base::
282 begin() const noexcept ->
283 iterator
284 {
285 326 return iterator(ref_, opt_);
286 }
287
288 inline
289 auto
290 247 params_base::
291 end() const noexcept ->
292 iterator
293 {
294 247 return {ref_, opt_, 0};
295 }
296
297 //------------------------------------------------
298
299 inline
300 std::size_t
301 29 params_base::
302 count(
303 core::string_view key,
304 ignore_case_param ic) const noexcept
305 {
306 29 std::size_t n = 0;
307 29 auto it = find(key, ic);
308 29 auto const end_ = end();
309 57 while(it != end_)
310 {
311 28 ++n;
312 28 ++it;
313 28 it = find(it, key, ic);
314 }
315 29 return n;
316 }
317
318 inline
319 std::string
320 8 params_base::
321 get_or(
322 core::string_view key,
323 core::string_view value,
324 ignore_case_param ic) const
325 {
326 8 auto it = find_impl(
327 8 begin().it_, key, ic);
328 8 detail::params_iter_impl end_(ref_, 0);
329 8 if(it.equal(end_))
330 2 return std::string(value);
331
332 6 param_pct_view const p = it.dereference();
333 6 if(! p.has_value)
334 1 return std::string();
335
336 5 auto opt = opt_;
337 5 return p.value.decode(opt);
338 }
339
340 //------------------------------------------------
341 //
342 // (implementation)
343 //
344 //------------------------------------------------
345
346 inline
347 detail::params_iter_impl
348 110 params_base::
349 find_impl(
350 detail::params_iter_impl it,
351 core::string_view key,
352 ignore_case_param ic) const noexcept
353 {
354 110 detail::params_iter_impl end_(ref_, 0);
355 110 if(! ic)
356 {
357 for(;;)
358 {
359 323 if(it.equal(end_))
360 33 return it;
361 290 if(*it.key() == key)
362 39 return it;
363 251 it.increment();
364 }
365 }
366 for(;;)
367 {
368 129 if(it.equal(end_))
369 10 return it;
370 119 if( grammar::ci_is_equal(
371 238 *it.key(), key))
372 28 return it;
373 91 it.increment();
374 }
375 }
376
377 inline
378 detail::params_iter_impl
379 13 params_base::
380 find_last_impl(
381 detail::params_iter_impl it,
382 core::string_view key,
383 ignore_case_param ic) const noexcept
384 {
385 13 detail::params_iter_impl begin_(ref_);
386 13 if(! ic)
387 {
388 for(;;)
389 {
390 13 if(it.equal(begin_))
391 2 return { ref_, 0 };
392 11 it.decrement();
393 11 if(*it.key() == key)
394 5 return it;
395 }
396 }
397 for(;;)
398 {
399 9 if(it.equal(begin_))
400 1 return { ref_, 0 };
401 8 it.decrement();
402 8 if(grammar::ci_is_equal(
403 16 *it.key(), key))
404 5 return it;
405 }
406 }
407
408 //------------------------------------------------
409
410 inline
411 std::ostream&
412 1 operator<<(
413 std::ostream& os,
414 params_base const& qp)
415 {
416 1 os << qp.buffer();
417 1 return os;
418 }
419
420 } // urls
421 } // boost
422
423 #endif
424