100.00% Lines (124/124) 100.00% Functions (8/8)
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_IMPL_PARAMS_ITER_IMPL_HPP 10   #ifndef BOOST_URL_DETAIL_IMPL_PARAMS_ITER_IMPL_HPP
11   #define BOOST_URL_DETAIL_IMPL_PARAMS_ITER_IMPL_HPP 11   #define BOOST_URL_DETAIL_IMPL_PARAMS_ITER_IMPL_HPP
12   12  
13   #include <boost/assert.hpp> 13   #include <boost/assert.hpp>
14   14  
15   namespace boost { 15   namespace boost {
16   namespace urls { 16   namespace urls {
17   namespace detail { 17   namespace detail {
18   18  
19   /* index zero-based index of param 19   /* index zero-based index of param
20   pos offset from start 0 = '?' 20   pos offset from start 0 = '?'
21   nk size of key with '?' or '&' 21   nk size of key with '?' or '&'
22   nv size of value with '=' 22   nv size of value with '='
23   dk decoded key size no '?' or '&' 23   dk decoded key size no '?' or '&'
24   dv decoded value size no '=' 24   dv decoded value size no '='
25   */ 25   */
26   inline 26   inline
HITCBC 27   7292 params_iter_impl:: 27   7297 params_iter_impl::
28   params_iter_impl( 28   params_iter_impl(
HITCBC 29   7292 query_ref const& ref_) noexcept 29   7297 query_ref const& ref_) noexcept
HITCBC 30   7292 : ref(ref_) 30   7297 : ref(ref_)
HITCBC 31   7292 , index(0) 31   7297 , index(0)
HITCBC 32   7292 , pos(0) 32   7297 , pos(0)
33   { 33   {
HITCBC 34   7292 if(index < ref_.nparam()) 34   7297 if(index < ref_.nparam())
HITCBC 35   4315 setup(); 35   4319 setup();
HITCBC 36   7292 } 36   7297 }
37   37  
38   inline 38   inline
HITCBC 39   12849 params_iter_impl:: 39   12856 params_iter_impl::
40   params_iter_impl( 40   params_iter_impl(
41   query_ref const& ref_, 41   query_ref const& ref_,
HITCBC 42   12849 int) noexcept 42   12856 int) noexcept
HITCBC 43   12849 : ref(ref_) 43   12856 : ref(ref_)
HITCBC 44   12849 , index(ref_.nparam()) 44   12856 , index(ref_.nparam())
HITCBC 45   12849 , pos(ref_.size()) 45   12856 , pos(ref_.size())
46   { 46   {
HITCBC 47   12849 } 47   12856 }
48   48  
49   inline 49   inline
HITCBC 50   1690 params_iter_impl:: 50   1696 params_iter_impl::
51   params_iter_impl( 51   params_iter_impl(
52   query_ref const& ref_, 52   query_ref const& ref_,
53   std::size_t pos_, 53   std::size_t pos_,
HITCBC 54   1690 std::size_t index_) noexcept 54   1696 std::size_t index_) noexcept
HITCBC 55   1690 : ref(ref_) 55   1696 : ref(ref_)
HITCBC 56   1690 , index(index_) 56   1696 , index(index_)
HITCBC 57   1690 , pos(pos_) 57   1696 , pos(pos_)
58   { 58   {
HITCBC 59   1690 BOOST_ASSERT( 59   1696 BOOST_ASSERT(
60   pos <= ref.size()); 60   pos <= ref.size());
HITCBC 61   1690 if(index < ref_.nparam()) 61   1696 if(index < ref_.nparam())
HITCBC 62   1529 setup(); 62   1534 setup();
HITCBC 63   1690 } 63   1696 }
64   64  
65   // set up state for key/value at pos 65   // set up state for key/value at pos
66   inline 66   inline
67   void 67   void
HITCBC 68   10123 params_iter_impl:: 68   10134 params_iter_impl::
69   setup() noexcept 69   setup() noexcept
70   { 70   {
HITCBC 71   10123 dk = 1; 71   10134 dk = 1;
HITCBC 72   10123 dv = 0; 72   10134 dv = 0;
HITCBC 73   10123 auto const end = ref.end(); 73   10134 auto const end = ref.end();
HITCBC 74   10123 BOOST_ASSERT(pos != ref.size()); 74   10134 BOOST_ASSERT(pos != ref.size());
HITCBC 75   10123 auto p0 = ref.begin() + pos; 75   10134 auto p0 = ref.begin() + pos;
HITCBC 76   10123 auto p = p0; 76   10134 auto p = p0;
77   // key 77   // key
78   for(;;) 78   for(;;)
79   { 79   {
HITCBC 80   37690 if( p == end || 80   37712 if( p == end ||
HITCBC 81   37132 *p == '&') 81   37154 *p == '&')
82   { 82   {
83   // no value 83   // no value
HITCBC 84   927 nk = 1 + p - p0; 84   927 nk = 1 + p - p0;
HITCBC 85   927 dk = nk - dk; 85   927 dk = nk - dk;
HITCBC 86   927 nv = 0; 86   927 nv = 0;
HITCBC 87   927 return; 87   927 return;
88   } 88   }
HITCBC 89   36763 if(*p == '=') 89   36785 if(*p == '=')
HITCBC 90   9196 break; 90   9207 break;
HITCBC 91   27567 if(*p == '%') 91   27578 if(*p == '%')
92   { 92   {
HITCBC 93   2460 BOOST_ASSERT( 93   2460 BOOST_ASSERT(
94   end - p >= 3); 94   end - p >= 3);
HITCBC 95   2460 dk += 2; 95   2460 dk += 2;
HITCBC 96   2460 p += 2; 96   2460 p += 2;
97   } 97   }
HITCBC 98   27567 ++p; 98   27578 ++p;
99   } 99   }
HITCBC 100   9196 nk = 1 + p - p0; 100   9207 nk = 1 + p - p0;
HITCBC 101   9196 dk = nk - dk; 101   9207 dk = nk - dk;
HITCBC 102   9196 p0 = p; 102   9207 p0 = p;
103   103  
104   // value 104   // value
105   for(;;) 105   for(;;)
106   { 106   {
HITCBC 107   51348 ++p; 107   51370 ++p;
HITCBC 108   51348 if( p == end || 108   51370 if( p == end ||
HITCBC 109   46649 *p == '&') 109   46663 *p == '&')
110   break; 110   break;
HITCBC 111   42152 if(*p == '%') 111   42163 if(*p == '%')
112   { 112   {
HITCBC 113   5683 BOOST_ASSERT( 113   5683 BOOST_ASSERT(
114   end - p >= 3); 114   end - p >= 3);
HITCBC 115   5683 dv += 2; 115   5683 dv += 2;
HITCBC 116   5683 p += 2; 116   5683 p += 2;
117   } 117   }
118   } 118   }
HITCBC 119   9196 nv = p - p0; 119   9207 nv = p - p0;
HITCBC 120   9196 dv = nv - dv - 1; 120   9207 dv = nv - dv - 1;
121   } 121   }
122   122  
123   inline 123   inline
124   void 124   void
HITCBC 125   8230 params_iter_impl:: 125   8234 params_iter_impl::
126   increment() noexcept 126   increment() noexcept
127   { 127   {
HITCBC 128   8230 BOOST_ASSERT( 128   8234 BOOST_ASSERT(
129   index < ref.nparam()); 129   index < ref.nparam());
HITCBC 130   8230 pos += nk + nv; 130   8234 pos += nk + nv;
HITCBC 131   8230 ++index; 131   8234 ++index;
HITCBC 132   8230 if(index < ref.nparam()) 132   8234 if(index < ref.nparam())
HITCBC 133   4279 setup(); 133   4281 setup();
HITCBC 134   8230 } 134   8234 }
135   135  
136   inline 136   inline
137   void 137   void
HITCBC 138   1370 params_iter_impl:: 138   1370 params_iter_impl::
139   decrement() noexcept 139   decrement() noexcept
140   { 140   {
HITCBC 141   1370 BOOST_ASSERT(index > 0); 141   1370 BOOST_ASSERT(index > 0);
HITCBC 142   1370 --index; 142   1370 --index;
HITCBC 143   1370 dk = 1; // for '&' or '?' 143   1370 dk = 1; // for '&' or '?'
HITCBC 144   1370 dv = 1; // for '=' 144   1370 dv = 1; // for '='
HITCBC 145   1370 auto const begin = ref.begin(); 145   1370 auto const begin = ref.begin();
HITCBC 146   1370 BOOST_ASSERT(pos > 0); 146   1370 BOOST_ASSERT(pos > 0);
HITCBC 147   1370 auto p1 = begin + (pos - 1); 147   1370 auto p1 = begin + (pos - 1);
HITCBC 148   1370 auto p = p1; 148   1370 auto p = p1;
149   // find key or '=' 149   // find key or '='
150   for(;;) 150   for(;;)
151   { 151   {
HITCBC 152   7634 if(p == begin) 152   7634 if(p == begin)
153   { 153   {
154   // key 154   // key
HITCBC 155   220 nk = 1 + p1 - p; // with '?' 155   220 nk = 1 + p1 - p; // with '?'
HITCBC 156   220 dk = nk - dv; 156   220 dk = nk - dv;
HITCBC 157   220 nv = 0; 157   220 nv = 0;
HITCBC 158   220 dv = 0; 158   220 dv = 0;
HITCBC 159   220 pos -= nk; 159   220 pos -= nk;
HITCBC 160   220 return; 160   220 return;
161   } 161   }
HITCBC 162   7414 else if(*--p == '&') 162   7414 else if(*--p == '&')
163   { 163   {
164   // key 164   // key
HITCBC 165   94 nk = p1 - p; // with '&' 165   94 nk = p1 - p; // with '&'
HITCBC 166   94 dk = nk - dv; 166   94 dk = nk - dv;
HITCBC 167   94 nv = 0; 167   94 nv = 0;
HITCBC 168   94 dv = 0; 168   94 dv = 0;
HITCBC 169   94 pos -= nk; 169   94 pos -= nk;
HITCBC 170   94 return; 170   94 return;
171   } 171   }
HITCBC 172   7320 if(*p == '=') 172   7320 if(*p == '=')
173   { 173   {
174   // value 174   // value
HITCBC 175   1056 nv = p1 - p; // with '=' 175   1056 nv = p1 - p; // with '='
HITCBC 176   1056 break; 176   1056 break;
177   } 177   }
HITCBC 178   6264 if(*p == '%') 178   6264 if(*p == '%')
HITCBC 179   144 dv += 2; 179   144 dv += 2;
180   } 180   }
181   // find key and value 181   // find key and value
182   for(;;) 182   for(;;)
183   { 183   {
HITCBC 184   5414 if(p == begin) 184   5414 if(p == begin)
185   { 185   {
186   // key and value 186   // key and value
HITCBC 187   284 nk = 1 + p1 - p - nv; // with '?' 187   284 nk = 1 + p1 - p - nv; // with '?'
HITCBC 188   284 dk = nk - dk; 188   284 dk = nk - dk;
HITCBC 189   284 dv = nv - dv; 189   284 dv = nv - dv;
HITCBC 190   284 pos -= nk + nv; 190   284 pos -= nk + nv;
HITCBC 191   284 return; 191   284 return;
192   } 192   }
HITCBC 193   5130 if(*--p == '&') 193   5130 if(*--p == '&')
194   { 194   {
195   // key and value 195   // key and value
HITCBC 196   772 nk = p1 - p - nv; // with '&' 196   772 nk = p1 - p - nv; // with '&'
HITCBC 197   772 dk = nk - dk; 197   772 dk = nk - dk;
HITCBC 198   772 dv = nv - dv; 198   772 dv = nv - dv;
HITCBC 199   772 pos -= nk + nv; 199   772 pos -= nk + nv;
HITCBC 200   772 return; 200   772 return;
201   } 201   }
HITCBC 202   4358 if(*p == '=') 202   4358 if(*p == '=')
203   { 203   {
204   // value 204   // value
HITCBC 205   36 nv = p1 - p; // with '=' 205   36 nv = p1 - p; // with '='
HITCBC 206   36 dv += dk - 1; 206   36 dv += dk - 1;
HITCBC 207   36 dk = 1; 207   36 dk = 1;
208   } 208   }
HITCBC 209   4322 else if(*p == '%') 209   4322 else if(*p == '%')
210   { 210   {
HITCBC 211   60 dk += 2; 211   60 dk += 2;
212   } 212   }
213   } 213   }
214   } 214   }
215   215  
216   inline 216   inline
217   param_pct_view 217   param_pct_view
HITCBC 218   6644 params_iter_impl:: 218   6644 params_iter_impl::
219   dereference() const noexcept 219   dereference() const noexcept
220   { 220   {
HITCBC 221   6644 BOOST_ASSERT(index < ref.nparam()); 221   6644 BOOST_ASSERT(index < ref.nparam());
HITCBC 222   6644 BOOST_ASSERT(pos < ref.size()); 222   6644 BOOST_ASSERT(pos < ref.size());
HITCBC 223   6644 auto const p = ref.begin() + pos; 223   6644 auto const p = ref.begin() + pos;
HITCBC 224   6644 if(nv) 224   6644 if(nv)
225   return { 225   return {
HITCBC 226   5789 make_pct_string_view_unsafe( 226   5789 make_pct_string_view_unsafe(
HITCBC 227   5789 p, nk - 1, dk), 227   5789 p, nk - 1, dk),
228   make_pct_string_view_unsafe( 228   make_pct_string_view_unsafe(
HITCBC 229   5789 p + nk, nv - 1, dv)}; 229   5789 p + nk, nv - 1, dv)};
230   return { 230   return {
231   make_pct_string_view_unsafe( 231   make_pct_string_view_unsafe(
HITCBC 232   855 p, nk - 1, dk), 232   855 p, nk - 1, dk),
HITCBC 233   855 no_value}; 233   855 no_value};
234   } 234   }
235   235  
236   inline 236   inline
237   pct_string_view 237   pct_string_view
HITCBC 238   980 params_iter_impl:: 238   981 params_iter_impl::
239   key() const noexcept 239   key() const noexcept
240   { 240   {
HITCBC 241   980 BOOST_ASSERT(index < ref.nparam()); 241   981 BOOST_ASSERT(index < ref.nparam());
HITCBC 242   980 BOOST_ASSERT(pos < ref.size()); 242   981 BOOST_ASSERT(pos < ref.size());
HITCBC 243   980 auto const p = ref.begin() + pos; 243   981 auto const p = ref.begin() + pos;
HITCBC 244   980 return make_pct_string_view_unsafe( 244   981 return make_pct_string_view_unsafe(
HITCBC 245   980 p, nk - 1, dk); 245   981 p, nk - 1, dk);
246   } 246   }
247   247  
248   } // detail 248   } // detail
249   } // urls 249   } // urls
250   } // boost 250   } // boost
251   251  
252   #endif 252   #endif