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