100.00% Lines (61/61) 100.00% Functions (14/14)
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   // 3   //
4   // Distributed under the Boost Software License, Version 1.0. (See accompanying 4   // Distributed under the Boost Software License, Version 1.0. (See accompanying
5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6   // 6   //
7   // Official repository: https://github.com/boostorg/url 7   // Official repository: https://github.com/boostorg/url
8   // 8   //
9   9  
10   #ifndef BOOST_URL_DETAIL_ANY_PARAMS_ITER_HPP 10   #ifndef BOOST_URL_DETAIL_ANY_PARAMS_ITER_HPP
11   #define BOOST_URL_DETAIL_ANY_PARAMS_ITER_HPP 11   #define BOOST_URL_DETAIL_ANY_PARAMS_ITER_HPP
12   12  
13   #include <boost/url/param.hpp> 13   #include <boost/url/param.hpp>
14   #include <boost/url/pct_string_view.hpp> 14   #include <boost/url/pct_string_view.hpp>
15   #include <boost/core/detail/static_assert.hpp> 15   #include <boost/core/detail/static_assert.hpp>
16   #include <cstddef> 16   #include <cstddef>
17   #include <iterator> 17   #include <iterator>
18   #include <type_traits> 18   #include <type_traits>
19   19  
20   namespace boost { 20   namespace boost {
21   namespace urls { 21   namespace urls {
22   namespace detail { 22   namespace detail {
23   23  
24   //------------------------------------------------ 24   //------------------------------------------------
25   // 25   //
26   // any_params_iter 26   // any_params_iter
27   // 27   //
28   //------------------------------------------------ 28   //------------------------------------------------
29   29  
30   /* An iterator to a type-erased, 30   /* An iterator to a type-erased,
31   possibly encoded sequence of 31   possibly encoded sequence of
32   query params_ref. 32   query params_ref.
33   */ 33   */
34   struct BOOST_SYMBOL_VISIBLE 34   struct BOOST_SYMBOL_VISIBLE
35   any_params_iter 35   any_params_iter
36   { 36   {
37   protected: 37   protected:
HITCBC 38   1695 any_params_iter( 38   1701 any_params_iter(
39   bool empty_, 39   bool empty_,
40   core::string_view s0_ = {}, 40   core::string_view s0_ = {},
41   core::string_view s1_ = {}) noexcept 41   core::string_view s1_ = {}) noexcept
HITCBC 42   1695 : s0(s0_) 42   1701 : s0(s0_)
HITCBC 43   1695 , s1(s1_) 43   1701 , s1(s1_)
HITCBC 44   1695 , empty(empty_) 44   1701 , empty(empty_)
45   { 45   {
HITCBC 46   1695 } 46   1701 }
47   47  
48   public: 48   public:
49   // these are adjusted 49   // these are adjusted
50   // when self-intersecting 50   // when self-intersecting
51   core::string_view s0; 51   core::string_view s0;
52   core::string_view s1; 52   core::string_view s1;
53   53  
54   // True if the sequence is empty 54   // True if the sequence is empty
55   bool empty = false; 55   bool empty = false;
56   56  
57   virtual 57   virtual
58   ~any_params_iter() noexcept = 0; 58   ~any_params_iter() noexcept = 0;
59   59  
60   // Rewind the iterator to the beginning 60   // Rewind the iterator to the beginning
61   virtual 61   virtual
62   void 62   void
63   rewind() noexcept = 0; 63   rewind() noexcept = 0;
64   64  
65   // Measure and increment current element. 65   // Measure and increment current element.
66   // Returns false on end of range. 66   // Returns false on end of range.
67   // n is increased by encoded size. 67   // n is increased by encoded size.
68   // Can throw on bad percent-escape 68   // Can throw on bad percent-escape
69   virtual 69   virtual
70   bool 70   bool
71   measure(std::size_t& n) = 0; 71   measure(std::size_t& n) = 0;
72   72  
73   // Copy and increment the current 73   // Copy and increment the current
74   // element. encoding is performed 74   // element. encoding is performed
75   // if needed. 75   // if needed.
76   virtual 76   virtual
77   void 77   void
78   copy( 78   copy(
79   char*& dest, 79   char*& dest,
80   char const* end) noexcept = 0; 80   char const* end) noexcept = 0;
81   }; 81   };
82   82  
83   //------------------------------------------------ 83   //------------------------------------------------
84   // 84   //
85   // query_string_iter 85   // query_string_iter
86   // 86   //
87   //------------------------------------------------ 87   //------------------------------------------------
88   88  
89   // A string of plain query params 89   // A string of plain query params
90   struct BOOST_SYMBOL_VISIBLE 90   struct BOOST_SYMBOL_VISIBLE
91   query_string_iter 91   query_string_iter
92   : any_params_iter 92   : any_params_iter
93   { 93   {
94   // ne = never empty 94   // ne = never empty
95   explicit 95   explicit
96   query_string_iter( 96   query_string_iter(
97   core::string_view s, 97   core::string_view s,
98   bool ne = false) noexcept; 98   bool ne = false) noexcept;
99   99  
100   private: 100   private:
101   core::string_view s_; 101   core::string_view s_;
102   std::size_t n_; 102   std::size_t n_;
103   char const* p_; 103   char const* p_;
104   bool at_end_; 104   bool at_end_;
105   105  
106   void rewind() noexcept override; 106   void rewind() noexcept override;
107   bool measure(std::size_t&) noexcept override; 107   bool measure(std::size_t&) noexcept override;
108   void copy(char*&, char const*) noexcept override; 108   void copy(char*&, char const*) noexcept override;
109   void increment() noexcept; 109   void increment() noexcept;
110   }; 110   };
111   111  
112   //------------------------------------------------ 112   //------------------------------------------------
113   // 113   //
114   // param_iter 114   // param_iter
115   // 115   //
116   //------------------------------------------------ 116   //------------------------------------------------
117   117  
118   // A 1-param range allowing 118   // A 1-param range allowing
119   // self-intersection 119   // self-intersection
120   struct BOOST_SYMBOL_VISIBLE 120   struct BOOST_SYMBOL_VISIBLE
121   single_param_iter 121   single_param_iter
122   : any_params_iter 122   : any_params_iter
123   { 123   {
124   explicit 124   explicit
125   single_param_iter( 125   single_param_iter(
126   param_view const&, 126   param_view const&,
127   bool space_as_plus) noexcept; 127   bool space_as_plus) noexcept;
128   128  
129   private: 129   private:
130   bool has_value_; 130   bool has_value_;
131   bool at_end_ = false; 131   bool at_end_ = false;
132   bool space_as_plus_ = false; 132   bool space_as_plus_ = false;
133   133  
134   void rewind() noexcept override; 134   void rewind() noexcept override;
135   bool measure(std::size_t&) noexcept override; 135   bool measure(std::size_t&) noexcept override;
136   void copy(char*&, char const*) noexcept override; 136   void copy(char*&, char const*) noexcept override;
137   }; 137   };
138   138  
139   //------------------------------------------------ 139   //------------------------------------------------
140   // 140   //
141   // params_iter_base 141   // params_iter_base
142   // 142   //
143   //------------------------------------------------ 143   //------------------------------------------------
144   144  
145   struct params_iter_base 145   struct params_iter_base
146   { 146   {
147   bool space_as_plus_ = true; 147   bool space_as_plus_ = true;
148   protected: 148   protected:
HITCBC 149   32 explicit params_iter_base( 149   32 explicit params_iter_base(
150   bool space_as_plus) noexcept 150   bool space_as_plus) noexcept
HITCBC 151   32 : space_as_plus_(space_as_plus) 151   32 : space_as_plus_(space_as_plus)
HITCBC 152   32 {} 152   32 {}
153   153  
154   // return encoded size 154   // return encoded size
155   void 155   void
156   measure_impl( 156   measure_impl(
157   std::size_t& n, 157   std::size_t& n,
158   param_view const& p) noexcept; 158   param_view const& p) noexcept;
159   159  
160   // encode to dest 160   // encode to dest
161   void 161   void
162   copy_impl( 162   copy_impl(
163   char*& dest, 163   char*& dest,
164   char const* end, 164   char const* end,
165   param_view const& v) noexcept; 165   param_view const& v) noexcept;
166   }; 166   };
167   167  
168   //------------------------------------------------ 168   //------------------------------------------------
169   169  
170   // A range of plain query params_ref 170   // A range of plain query params_ref
171   template<class FwdIt> 171   template<class FwdIt>
172   struct params_iter 172   struct params_iter
173   : any_params_iter 173   : any_params_iter
174   , private params_iter_base 174   , private params_iter_base
175   { 175   {
176   BOOST_CORE_STATIC_ASSERT( 176   BOOST_CORE_STATIC_ASSERT(
177   std::is_convertible< 177   std::is_convertible<
178   typename std::iterator_traits< 178   typename std::iterator_traits<
179   FwdIt>::reference, 179   FwdIt>::reference,
180   param_view>::value); 180   param_view>::value);
181   181  
HITCBC 182   32 params_iter( 182   32 params_iter(
183   FwdIt first, 183   FwdIt first,
184   FwdIt last, 184   FwdIt last,
185   bool space_as_plus) noexcept 185   bool space_as_plus) noexcept
186   : any_params_iter( 186   : any_params_iter(
HITCBC 187   1 first == last) 187   1 first == last)
188   , params_iter_base(space_as_plus) 188   , params_iter_base(space_as_plus)
HITCBC 189   32 , it0_(first) 189   32 , it0_(first)
HITCBC 190   32 , it_(first) 190   32 , it_(first)
HITCBC 191   33 , end_(last) 191   33 , end_(last)
192   { 192   {
HITCBC 193   32 } 193   32 }
194   194  
195   private: 195   private:
196   FwdIt it0_; 196   FwdIt it0_;
197   FwdIt it_; 197   FwdIt it_;
198   FwdIt end_; 198   FwdIt end_;
199   199  
200   void 200   void
HITCBC 201   32 rewind() noexcept override 201   32 rewind() noexcept override
202   { 202   {
HITCBC 203   32 it_ = it0_; 203   32 it_ = it0_;
HITCBC 204   32 } 204   32 }
205   205  
206   bool 206   bool
HITCBC 207   102 measure( 207   102 measure(
208   std::size_t& n) noexcept override 208   std::size_t& n) noexcept override
209   { 209   {
HITCBC 210   102 if(it_ == end_) 210   102 if(it_ == end_)
HITCBC 211   32 return false; 211   32 return false;
HITCBC 212   70 measure_impl(n, 212   70 measure_impl(n,
HITCBC 213   71 param_view(*it_++)); 213   71 param_view(*it_++));
HITCBC 214   70 return true; 214   70 return true;
215   } 215   }
216   216  
217   void 217   void
HITCBC 218   70 copy( 218   70 copy(
219   char*& dest, 219   char*& dest,
220   char const* end) noexcept override 220   char const* end) noexcept override
221   { 221   {
HITCBC 222   70 copy_impl(dest, end, 222   70 copy_impl(dest, end,
HITCBC 223   71 param_view(*it_++)); 223   71 param_view(*it_++));
HITCBC 224   70 } 224   70 }
225   }; 225   };
226   226  
227   //------------------------------------------------ 227   //------------------------------------------------
228   // 228   //
229   // param_encoded_iter 229   // param_encoded_iter
230   // 230   //
231   //------------------------------------------------ 231   //------------------------------------------------
232   232  
233   // A 1-param encoded range 233   // A 1-param encoded range
234   // allowing self-intersection 234   // allowing self-intersection
235   struct BOOST_SYMBOL_VISIBLE 235   struct BOOST_SYMBOL_VISIBLE
236   param_encoded_iter 236   param_encoded_iter
237   : any_params_iter 237   : any_params_iter
238   { 238   {
239   explicit 239   explicit
240   param_encoded_iter( 240   param_encoded_iter(
241   param_pct_view const&) noexcept; 241   param_pct_view const&) noexcept;
242   242  
243   private: 243   private:
244   bool has_value_; 244   bool has_value_;
245   bool at_end_ = false; 245   bool at_end_ = false;
246   246  
247   void rewind() noexcept override; 247   void rewind() noexcept override;
248   bool measure(std::size_t&) noexcept override; 248   bool measure(std::size_t&) noexcept override;
249   void copy(char*&, char const*) noexcept override; 249   void copy(char*&, char const*) noexcept override;
250   }; 250   };
251   251  
252   //------------------------------------------------ 252   //------------------------------------------------
253   // 253   //
254   // params_encoded_iter 254   // params_encoded_iter
255   // 255   //
256   //------------------------------------------------ 256   //------------------------------------------------
257   257  
258   // Validating and copying from 258   // Validating and copying from
259   // a string of encoded params 259   // a string of encoded params
260   struct params_encoded_iter_base 260   struct params_encoded_iter_base
261   { 261   {
262   protected: 262   protected:
263   static 263   static
264   void 264   void
265   measure_impl( 265   measure_impl(
266   std::size_t& n, 266   std::size_t& n,
267   param_view const& v) noexcept; 267   param_view const& v) noexcept;
268   268  
269   static 269   static
270   void 270   void
271   copy_impl( 271   copy_impl(
272   char*& dest, 272   char*& dest,
273   char const* end, 273   char const* end,
274   param_view const& v) noexcept; 274   param_view const& v) noexcept;
275   }; 275   };
276   276  
277   //------------------------------------------------ 277   //------------------------------------------------
278   278  
279   // A range of encoded query params_ref 279   // A range of encoded query params_ref
280   template<class FwdIt> 280   template<class FwdIt>
281   struct params_encoded_iter 281   struct params_encoded_iter
282   : any_params_iter 282   : any_params_iter
283   , private params_encoded_iter_base 283   , private params_encoded_iter_base
284   { 284   {
285   BOOST_CORE_STATIC_ASSERT( 285   BOOST_CORE_STATIC_ASSERT(
286   std::is_convertible< 286   std::is_convertible<
287   typename std::iterator_traits< 287   typename std::iterator_traits<
288   FwdIt>::reference, 288   FwdIt>::reference,
289   param_view>::value); 289   param_view>::value);
290   290  
HITCBC 291   29 params_encoded_iter( 291   29 params_encoded_iter(
292   FwdIt first, 292   FwdIt first,
293   FwdIt last) noexcept 293   FwdIt last) noexcept
294   : any_params_iter( 294   : any_params_iter(
HITCBC 295   1 first == last) 295   1 first == last)
HITCBC 296   29 , it0_(first) 296   29 , it0_(first)
HITCBC 297   29 , it_(first) 297   29 , it_(first)
HITCBC 298   30 , end_(last) 298   30 , end_(last)
299   { 299   {
HITCBC 300   29 } 300   29 }
301   301  
302   private: 302   private:
303   FwdIt it0_; 303   FwdIt it0_;
304   FwdIt it_; 304   FwdIt it_;
305   FwdIt end_; 305   FwdIt end_;
306   306  
307   void 307   void
HITCBC 308   24 rewind() noexcept override 308   24 rewind() noexcept override
309   { 309   {
HITCBC 310   24 it_ = it0_; 310   24 it_ = it0_;
HITCBC 311   24 } 311   24 }
312   312  
313   bool 313   bool
HITCBC 314   80 measure( 314   80 measure(
315   std::size_t& n) override 315   std::size_t& n) override
316   { 316   {
HITCBC 317   80 if(it_ == end_) 317   80 if(it_ == end_)
HITCBC 318   24 return false; 318   24 return false;
319   // throw on invalid input 319   // throw on invalid input
HITCBC 320   51 measure_impl(n, 320   51 measure_impl(n,
HITCBC 321   43 param_pct_view( 321   43 param_pct_view(
HITCBC 322   56 param_view(*it_++))); 322   56 param_view(*it_++)));
HITCBC 323   51 return true; 323   51 return true;
324   } 324   }
325   325  
326   void 326   void
HITCBC 327   51 copy( 327   51 copy(
328   char*& dest, 328   char*& dest,
329   char const* end 329   char const* end
330   ) noexcept override 330   ) noexcept override
331   { 331   {
HITCBC 332   51 copy_impl(dest, end, 332   51 copy_impl(dest, end,
HITCBC 333   51 param_view(*it_++)); 333   51 param_view(*it_++));
HITCBC 334   51 } 334   51 }
335   }; 335   };
336   336  
337   //------------------------------------------------ 337   //------------------------------------------------
338   // 338   //
339   // param_value_iter 339   // param_value_iter
340   // 340   //
341   //------------------------------------------------ 341   //------------------------------------------------
342   342  
343   // An iterator which outputs 343   // An iterator which outputs
344   // one value on an existing key 344   // one value on an existing key
345   struct param_value_iter 345   struct param_value_iter
346   : any_params_iter 346   : any_params_iter
347   { 347   {
HITCBC 348   9 param_value_iter( 348   9 param_value_iter(
349   std::size_t nk, 349   std::size_t nk,
350   core::string_view const& value, 350   core::string_view const& value,
351   bool has_value) noexcept 351   bool has_value) noexcept
HITCBC 352   9 : any_params_iter( 352   9 : any_params_iter(
353   false, 353   false,
354   value) 354   value)
HITCBC 355   9 , nk_(nk) 355   9 , nk_(nk)
HITCBC 356   9 , has_value_(has_value) 356   9 , has_value_(has_value)
357   { 357   {
HITCBC 358   9 } 358   9 }
359   359  
360   private: 360   private:
361   std::size_t nk_ = 0; 361   std::size_t nk_ = 0;
362   bool has_value_ = false; 362   bool has_value_ = false;
363   bool at_end_ = false; 363   bool at_end_ = false;
364   364  
365   void rewind() noexcept override; 365   void rewind() noexcept override;
366   bool measure(std::size_t&) noexcept override; 366   bool measure(std::size_t&) noexcept override;
367   void copy(char*&, char const*) noexcept override; 367   void copy(char*&, char const*) noexcept override;
368   }; 368   };
369   369  
370   //------------------------------------------------ 370   //------------------------------------------------
371   // 371   //
372   // param_encoded_value_iter 372   // param_encoded_value_iter
373   // 373   //
374   //------------------------------------------------ 374   //------------------------------------------------
375   375  
376   // An iterator which outputs one 376   // An iterator which outputs one
377   // encoded value on an existing key 377   // encoded value on an existing key
378   struct param_encoded_value_iter 378   struct param_encoded_value_iter
379   : any_params_iter 379   : any_params_iter
380   { 380   {
HITCBC 381   8 param_encoded_value_iter( 381   8 param_encoded_value_iter(
382   std::size_t nk, 382   std::size_t nk,
383   pct_string_view const& value, 383   pct_string_view const& value,
384   bool has_value) noexcept 384   bool has_value) noexcept
HITCBC 385   8 : any_params_iter( 385   8 : any_params_iter(
386   false, 386   false,
387   value) 387   value)
HITCBC 388   8 , nk_(nk) 388   8 , nk_(nk)
HITCBC 389   8 , has_value_(has_value) 389   8 , has_value_(has_value)
390   { 390   {
HITCBC 391   8 } 391   8 }
392   392  
393   private: 393   private:
394   std::size_t nk_ = 0; 394   std::size_t nk_ = 0;
395   bool has_value_ = false; 395   bool has_value_ = false;
396   bool at_end_ = false; 396   bool at_end_ = false;
397   397  
398   void rewind() noexcept override; 398   void rewind() noexcept override;
399   bool measure(std::size_t&) noexcept override; 399   bool measure(std::size_t&) noexcept override;
400   void copy(char*&, char const*) noexcept override; 400   void copy(char*&, char const*) noexcept override;
401   }; 401   };
402   402  
403   //------------------------------------------------ 403   //------------------------------------------------
404   404  
405   template<class FwdIt> 405   template<class FwdIt>
406   params_iter<FwdIt> 406   params_iter<FwdIt>
HITCBC 407   32 make_params_iter( 407   32 make_params_iter(
408   FwdIt first, FwdIt last, bool space_as_plus) 408   FwdIt first, FwdIt last, bool space_as_plus)
409   { 409   {
410   return params_iter< 410   return params_iter<
HITCBC 411   32 FwdIt>(first, last, space_as_plus); 411   32 FwdIt>(first, last, space_as_plus);
412   } 412   }
413   413  
414   template<class FwdIt> 414   template<class FwdIt>
415   params_encoded_iter<FwdIt> 415   params_encoded_iter<FwdIt>
HITCBC 416   29 make_params_encoded_iter( 416   29 make_params_encoded_iter(
417   FwdIt first, FwdIt last) 417   FwdIt first, FwdIt last)
418   { 418   {
419   return params_encoded_iter< 419   return params_encoded_iter<
HITCBC 420   29 FwdIt>(first, last); 420   29 FwdIt>(first, last);
421   } 421   }
422   422  
423   } // detail 423   } // detail
424   } // urls 424   } // urls
425   } // boost 425   } // boost
426   426  
427   #include <boost/url/detail/impl/any_params_iter.hpp> 427   #include <boost/url/detail/impl/any_params_iter.hpp>
428   428  
429   #endif 429   #endif