Line | Branch | Exec | Source |
---|---|---|---|
1 | // | ||
2 | // Copyright (c) 2022 Alan de Freitas (alandefreitas@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_PCT_FORMAT_IPP | ||
11 | #define BOOST_URL_DETAIL_IMPL_PCT_FORMAT_IPP | ||
12 | |||
13 | #include <boost/url/detail/config.hpp> | ||
14 | #include <boost/url/detail/pct_format.hpp> | ||
15 | #include <boost/url/grammar/parse.hpp> | ||
16 | #include <boost/url/grammar/unsigned_rule.hpp> | ||
17 | |||
18 | namespace boost { | ||
19 | namespace urls { | ||
20 | namespace detail { | ||
21 | |||
22 | std::size_t | ||
23 | 250 | pct_vmeasure( | |
24 | grammar::lut_chars const& cs, | ||
25 | format_parse_context& pctx, | ||
26 | measure_context& mctx) | ||
27 | { | ||
28 | 250 | auto it0 = pctx.begin(); | |
29 | 250 | auto end = pctx.end(); | |
30 |
2/2✓ Branch 0 taken 295 times.
✓ Branch 1 taken 193 times.
|
488 | while( it0 != end ) |
31 | { | ||
32 | // look for replacement id | ||
33 | 295 | char const* it1 = it0; | |
34 | 467 | while( | |
35 |
2/2✓ Branch 0 taken 707 times.
✓ Branch 1 taken 55 times.
|
762 | it1 != end && |
36 |
2/2✓ Branch 0 taken 467 times.
✓ Branch 1 taken 240 times.
|
707 | *it1 != '{' ) |
37 | { | ||
38 | 467 | ++it1; | |
39 | } | ||
40 | |||
41 | // output literal prefix | ||
42 |
2/2✓ Branch 0 taken 117 times.
✓ Branch 1 taken 178 times.
|
295 | if( it0 != it1 ) |
43 | { | ||
44 |
2/2✓ Branch 0 taken 467 times.
✓ Branch 1 taken 117 times.
|
584 | for (char const* i = it0; i != it1; ++i) |
45 | 467 | mctx.advance_to( mctx.out() + measure_one(*i, cs)); | |
46 | } | ||
47 | |||
48 | // over | ||
49 |
2/2✓ Branch 0 taken 55 times.
✓ Branch 1 taken 240 times.
|
295 | if( it1 == end ) |
50 | { | ||
51 | 55 | break; | |
52 | } | ||
53 | |||
54 | // enter replacement id | ||
55 | 240 | ++it1; | |
56 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 240 times.
|
240 | BOOST_ASSERT(it1 != end); |
57 | |||
58 | // handle escaped replacement (second '{') | ||
59 | // there's no "{{" in URL templates because | ||
60 | // '{'s are not allowed in URLs | ||
61 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 240 times.
|
240 | BOOST_ASSERT(*it1 != '{'); |
62 | /* | ||
63 | if( *it1 == '{' ) | ||
64 | { | ||
65 | mctx.advance_to( mctx.out() + measure_one('{', cs)); | ||
66 | ++it1; | ||
67 | // this was not a real replacement, | ||
68 | // so we just keep moving | ||
69 | continue; | ||
70 | } | ||
71 | */ | ||
72 | |||
73 | |||
74 | // parse {id} or {id:specs} | ||
75 | 240 | char const* id_start = it1; | |
76 | 570 | while (it1 != end && | |
77 |
3/4✓ Branch 0 taken 405 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 364 times.
✓ Branch 3 taken 41 times.
|
405 | *it1 != ':' && |
78 |
2/2✓ Branch 0 taken 165 times.
✓ Branch 1 taken 199 times.
|
364 | *it1 != '}') |
79 | { | ||
80 | 165 | ++it1; | |
81 | } | ||
82 | 240 | core::string_view id(id_start, it1); | |
83 | |||
84 | // move to specs start | ||
85 |
1/2✓ Branch 0 taken 240 times.
✗ Branch 1 not taken.
|
240 | if (it1 != end && |
86 |
2/2✓ Branch 0 taken 41 times.
✓ Branch 1 taken 199 times.
|
240 | *it1 == ':') |
87 | 41 | ++it1; | |
88 | 240 | pctx.advance_to( it1 ); | |
89 | |||
90 | // get format_arg to use | ||
91 | auto idv = grammar::parse( | ||
92 | 240 | id, grammar::unsigned_rule<std::size_t>{}); | |
93 |
2/2✓ Branch 1 taken 27 times.
✓ Branch 2 taken 213 times.
|
240 | if (idv) |
94 | { | ||
95 |
1/2✓ Branch 3 taken 27 times.
✗ Branch 4 not taken.
|
27 | mctx.arg( *idv ).measure( pctx, mctx, cs ); |
96 | } | ||
97 |
2/2✓ Branch 1 taken 26 times.
✓ Branch 2 taken 187 times.
|
213 | else if (!id.empty()) |
98 | { | ||
99 |
1/2✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
|
26 | mctx.arg( id ).measure( pctx, mctx, cs ); |
100 | } | ||
101 | else | ||
102 | { | ||
103 | 187 | std::size_t arg_id = pctx.next_arg_id(); | |
104 |
2/2✓ Branch 2 taken 185 times.
✓ Branch 3 taken 2 times.
|
187 | mctx.arg( arg_id ).measure( pctx, mctx, cs ); |
105 | } | ||
106 | |||
107 | |||
108 | 238 | it1 = pctx.begin(); | |
109 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 238 times.
|
238 | BOOST_ASSERT(*it1 == '}'); |
110 | 238 | it0 = it1 + 1; | |
111 | } | ||
112 | |||
113 | 248 | return mctx.out(); | |
114 | } | ||
115 | |||
116 | char* | ||
117 | 245 | pct_vformat( | |
118 | grammar::lut_chars const& cs, | ||
119 | format_parse_context& pctx, | ||
120 | format_context& fctx) | ||
121 | { | ||
122 | 245 | auto it0 = pctx.begin(); | |
123 | 245 | auto end = pctx.end(); | |
124 |
2/2✓ Branch 0 taken 290 times.
✓ Branch 1 taken 191 times.
|
481 | while( it0 != end ) |
125 | { | ||
126 | // look for replacement id | ||
127 | 290 | char const* it1 = it0; | |
128 | 458 | while( | |
129 |
2/2✓ Branch 0 taken 694 times.
✓ Branch 1 taken 54 times.
|
748 | it1 != end && |
130 |
2/2✓ Branch 0 taken 458 times.
✓ Branch 1 taken 236 times.
|
694 | *it1 != '{' ) |
131 | { | ||
132 | 458 | ++it1; | |
133 | } | ||
134 | |||
135 | // output literal prefix | ||
136 |
2/2✓ Branch 0 taken 116 times.
✓ Branch 1 taken 174 times.
|
290 | if( it0 != it1 ) |
137 | { | ||
138 |
2/2✓ Branch 0 taken 458 times.
✓ Branch 1 taken 116 times.
|
574 | for (char const* i = it0; i != it1; ++i) |
139 | { | ||
140 | 458 | char* o = fctx.out(); | |
141 | 458 | encode_one(o, *i, cs); | |
142 | 458 | fctx.advance_to(o); | |
143 | } | ||
144 | } | ||
145 | |||
146 | // over | ||
147 |
2/2✓ Branch 0 taken 54 times.
✓ Branch 1 taken 236 times.
|
290 | if( it1 == end ) |
148 | { | ||
149 | 54 | break; | |
150 | } | ||
151 | |||
152 | // enter replacement id | ||
153 | 236 | ++it1; | |
154 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 236 times.
|
236 | BOOST_ASSERT(it1 != end); |
155 | |||
156 | // handle escaped replacement (second '{') | ||
157 | // there's no "{{" in URL templates because | ||
158 | // '{'s are not allowed in URLs | ||
159 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 236 times.
|
236 | BOOST_ASSERT(*it1 != '{'); |
160 | /* | ||
161 | if( *it1 == '{' ) | ||
162 | { | ||
163 | char* o = fctx.out(); | ||
164 | encode_one(o, '{', cs); | ||
165 | fctx.advance_to(o); | ||
166 | ++it1; | ||
167 | // this was not a real replacement, | ||
168 | // so we just keep moving | ||
169 | continue; | ||
170 | } | ||
171 | */ | ||
172 | |||
173 | // parse {id} or {id:specs} | ||
174 | 236 | char const* id_start = it1; | |
175 | 566 | while (it1 != end && | |
176 |
3/4✓ Branch 0 taken 401 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 362 times.
✓ Branch 3 taken 39 times.
|
401 | *it1 != ':' && |
177 |
2/2✓ Branch 0 taken 165 times.
✓ Branch 1 taken 197 times.
|
362 | *it1 != '}') |
178 | { | ||
179 | 165 | ++it1; | |
180 | } | ||
181 | 236 | core::string_view id(id_start, it1); | |
182 | |||
183 | // move to specs part | ||
184 |
1/2✓ Branch 0 taken 236 times.
✗ Branch 1 not taken.
|
236 | if (it1 != end && |
185 |
2/2✓ Branch 0 taken 39 times.
✓ Branch 1 taken 197 times.
|
236 | *it1 == ':') |
186 | 39 | ++it1; | |
187 | 236 | pctx.advance_to( it1 ); | |
188 | |||
189 | // get format_arg to use | ||
190 | auto idv = grammar::parse( | ||
191 | 236 | id, grammar::unsigned_rule<std::size_t>{}); | |
192 |
2/2✓ Branch 1 taken 27 times.
✓ Branch 2 taken 209 times.
|
236 | if (idv) |
193 | { | ||
194 |
1/2✓ Branch 3 taken 27 times.
✗ Branch 4 not taken.
|
27 | fctx.arg( *idv ).format( pctx, fctx, cs ); |
195 | } | ||
196 |
2/2✓ Branch 1 taken 26 times.
✓ Branch 2 taken 183 times.
|
209 | else if (!id.empty()) |
197 | { | ||
198 |
1/2✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
|
26 | fctx.arg( id ).format( pctx, fctx, cs ); |
199 | } | ||
200 | else | ||
201 | { | ||
202 | 183 | std::size_t arg_id = pctx.next_arg_id(); | |
203 |
1/2✓ Branch 2 taken 183 times.
✗ Branch 3 not taken.
|
183 | fctx.arg( arg_id ).format( pctx, fctx, cs ); |
204 | } | ||
205 | |||
206 | 236 | it1 = pctx.begin(); | |
207 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 236 times.
|
236 | BOOST_ASSERT(*it1 == '}'); |
208 | 236 | it0 = it1 + 1; | |
209 | } | ||
210 | |||
211 | 245 | return fctx.out(); | |
212 | } | ||
213 | |||
214 | } // detail | ||
215 | } // urls | ||
216 | } // boost | ||
217 | |||
218 | #endif | ||
219 |