include/boost/url/detail/impl/params_iter_impl.hpp

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