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 7297x params_iter_impl::
28 params_iter_impl(
29 7297x query_ref const& ref_) noexcept
30 7297x : ref(ref_)
31 7297x , index(0)
32 7297x , pos(0)
33 {
34 7297x if(index < ref_.nparam())
35 4319x setup();
36 7297x }
37
38 inline
39 12856x params_iter_impl::
40 params_iter_impl(
41 query_ref const& ref_,
42 12856x int) noexcept
43 12856x : ref(ref_)
44 12856x , index(ref_.nparam())
45 12856x , pos(ref_.size())
46 {
47 12856x }
48
49 inline
50 1696x params_iter_impl::
51 params_iter_impl(
52 query_ref const& ref_,
53 std::size_t pos_,
54 1696x std::size_t index_) noexcept
55 1696x : ref(ref_)
56 1696x , index(index_)
57 1696x , pos(pos_)
58 {
59 1696x BOOST_ASSERT(
60 pos <= ref.size());
61 1696x if(index < ref_.nparam())
62 1534x setup();
63 1696x }
64
65 // set up state for key/value at pos
66 inline
67 void
68 10134x params_iter_impl::
69 setup() noexcept
70 {
71 10134x dk = 1;
72 10134x dv = 0;
73 10134x auto const end = ref.end();
74 10134x BOOST_ASSERT(pos != ref.size());
75 10134x auto p0 = ref.begin() + pos;
76 10134x auto p = p0;
77 // key
78 for(;;)
79 {
80 37712x if( p == end ||
81 37154x *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 36785x if(*p == '=')
90 9207x break;
91 27578x if(*p == '%')
92 {
93 2460x BOOST_ASSERT(
94 end - p >= 3);
95 2460x dk += 2;
96 2460x p += 2;
97 }
98 27578x ++p;
99 }
100 9207x nk = 1 + p - p0;
101 9207x dk = nk - dk;
102 9207x p0 = p;
103
104 // value
105 for(;;)
106 {
107 51370x ++p;
108 51370x if( p == end ||
109 46663x *p == '&')
110 break;
111 42163x if(*p == '%')
112 {
113 5683x BOOST_ASSERT(
114 end - p >= 3);
115 5683x dv += 2;
116 5683x p += 2;
117 }
118 }
119 9207x nv = p - p0;
120 9207x dv = nv - dv - 1;
121 }
122
123 inline
124 void
125 8234x params_iter_impl::
126 increment() noexcept
127 {
128 8234x BOOST_ASSERT(
129 index < ref.nparam());
130 8234x pos += nk + nv;
131 8234x ++index;
132 8234x if(index < ref.nparam())
133 4281x setup();
134 8234x }
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 981x params_iter_impl::
239 key() const noexcept
240 {
241 981x BOOST_ASSERT(index < ref.nparam());
242 981x BOOST_ASSERT(pos < ref.size());
243 981x auto const p = ref.begin() + pos;
244 981x return make_pct_string_view_unsafe(
245 981x p, nk - 1, dk);
246 }
247
248 } // detail
249 } // urls
250 } // boost
251
252 #endif
253