include/boost/url/impl/params_encoded_base.hpp

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