TLA Line data 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 HIT 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
|