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

100.0% Lines (124 / 124) 100.0% 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 7315x params_iter_impl::
28 params_iter_impl(
29 7315x query_ref const& ref_) noexcept
30 7315x : ref(ref_)
31 7315x , index(0)
32 7315x , pos(0)
33 {
34 7315x if(index < ref_.nparam())
35 4337x setup();
36 7315x }
37
38 inline
39 12876x params_iter_impl::
40 params_iter_impl(
41 query_ref const& ref_,
42 12876x int) noexcept
43 12876x : ref(ref_)
44 12876x , index(ref_.nparam())
45 12876x , pos(ref_.size())
46 {
47 12876x }
48
49 inline
50 1700x params_iter_impl::
51 params_iter_impl(
52 query_ref const& ref_,
53 std::size_t pos_,
54 1700x std::size_t index_) noexcept
55 1700x : ref(ref_)
56 1700x , index(index_)
57 1700x , pos(pos_)
58 {
59 1700x BOOST_ASSERT(
60 pos <= ref.size());
61 1700x if(index < ref_.nparam())
62 1538x setup();
63 1700x }
64
65 // set up state for key/value at pos
66 inline
67 void
68 10164x params_iter_impl::
69 setup() noexcept
70 {
71 10164x dk = 1;
72 10164x dv = 0;
73 10164x auto const end = ref.end();
74 10164x BOOST_ASSERT(pos != ref.size());
75 10164x auto p0 = ref.begin() + pos;
76 10164x auto p = p0;
77 // key
78 for(;;)
79 {
80 37870x if( p == end ||
81 37312x *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 36943x if(*p == '=')
90 9237x break;
91 27706x if(*p == '%')
92 {
93 2460x BOOST_ASSERT(
94 end - p >= 3);
95 2460x dk += 2;
96 2460x p += 2;
97 }
98 27706x ++p;
99 }
100 9237x nk = 1 + p - p0;
101 9237x dk = nk - dk;
102 9237x p0 = p;
103
104 // value
105 for(;;)
106 {
107 51518x ++p;
108 51518x if( p == end ||
109 46803x *p == '&')
110 break;
111 42281x if(*p == '%')
112 {
113 5713x BOOST_ASSERT(
114 end - p >= 3);
115 5713x dv += 2;
116 5713x p += 2;
117 }
118 }
119 9237x nv = p - p0;
120 9237x dv = nv - dv - 1;
121 }
122
123 inline
124 void
125 8242x params_iter_impl::
126 increment() noexcept
127 {
128 8242x BOOST_ASSERT(
129 index < ref.nparam());
130 8242x pos += nk + nv;
131 8242x ++index;
132 8242x if(index < ref.nparam())
133 4289x setup();
134 8242x }
135
136 inline
137 void
138 1374x params_iter_impl::
139 decrement() noexcept
140 {
141 1374x BOOST_ASSERT(index > 0);
142 1374x --index;
143 1374x dk = 1; // for '&' or '?'
144 1374x dv = 1; // for '='
145 1374x auto const begin = ref.begin();
146 1374x BOOST_ASSERT(pos > 0);
147 1374x auto p1 = begin + (pos - 1);
148 1374x auto p = p1;
149 // find key or '='
150 for(;;)
151 {
152 7660x 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 7440x 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 7346x if(*p == '=')
173 {
174 // value
175 1060x nv = p1 - p; // with '='
176 1060x break;
177 }
178 6286x if(*p == '%')
179 147x dv += 2;
180 }
181 // find key and value
182 for(;;)
183 {
184 5436x if(p == begin)
185 {
186 // key and value
187 286x nk = 1 + p1 - p - nv; // with '?'
188 286x dk = nk - dk;
189 286x dv = nv - dv;
190 286x pos -= nk + nv;
191 286x return;
192 }
193 5150x if(*--p == '&')
194 {
195 // key and value
196 774x nk = p1 - p - nv; // with '&'
197 774x dk = nk - dk;
198 774x dv = nv - dv;
199 774x pos -= nk + nv;
200 774x return;
201 }
202 4376x if(*p == '=')
203 {
204 // value
205 36x nv = p1 - p; // with '='
206 36x dv += dk - 1;
207 36x dk = 1;
208 }
209 4340x else if(*p == '%')
210 {
211 60x dk += 2;
212 }
213 }
214 }
215
216 inline
217 param_pct_view
218 6656x params_iter_impl::
219 dereference() const noexcept
220 {
221 6656x BOOST_ASSERT(index < ref.nparam());
222 6656x BOOST_ASSERT(pos < ref.size());
223 6656x auto const p = ref.begin() + pos;
224 6656x if(nv)
225 return {
226 5801x make_pct_string_view_unsafe(
227 5801x p, nk - 1, dk),
228 make_pct_string_view_unsafe(
229 5801x 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 1005x params_iter_impl::
239 key() const noexcept
240 {
241 1005x BOOST_ASSERT(index < ref.nparam());
242 1005x BOOST_ASSERT(pos < ref.size());
243 1005x auto const p = ref.begin() + pos;
244 1005x return make_pct_string_view_unsafe(
245 1005x p, nk - 1, dk);
246 }
247
248 } // detail
249 } // urls
250 } // boost
251
252 #endif
253