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 | |||
11 | #include <boost/url/detail/config.hpp> | ||
12 | #include <boost/url/encode.hpp> | ||
13 | #include <boost/url/detail/format_args.hpp> | ||
14 | #include "boost/url/detail/replacement_field_rule.hpp" | ||
15 | #include <boost/url/grammar/delim_rule.hpp> | ||
16 | #include <boost/url/grammar/optional_rule.hpp> | ||
17 | #include <boost/url/grammar/parse.hpp> | ||
18 | #include <boost/url/grammar/tuple_rule.hpp> | ||
19 | #include <boost/url/grammar/unsigned_rule.hpp> | ||
20 | |||
21 | namespace boost { | ||
22 | namespace urls { | ||
23 | namespace detail { | ||
24 | |||
25 | std::size_t | ||
26 | 68 | get_uvalue( core::string_view a ) | |
27 | { | ||
28 | 68 | core::string_view str(a); | |
29 | 68 | auto rv = grammar::parse( | |
30 | 68 | str, grammar::unsigned_rule<std::size_t>{}); | |
31 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 66 times.
|
68 | if (rv) |
32 | 2 | return *rv; | |
33 | 66 | return 0; | |
34 | } | ||
35 | |||
36 | std::size_t | ||
37 | 68 | get_uvalue( char a ) | |
38 | { | ||
39 | 68 | core::string_view str(&a, 1); | |
40 |
1/2✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
|
136 | return get_uvalue(str); |
41 | } | ||
42 | |||
43 | char const* | ||
44 | 369 | formatter<core::string_view>:: | |
45 | parse(format_parse_context& ctx) | ||
46 | { | ||
47 | 369 | char const* it = ctx.begin(); | |
48 | 369 | char const* end = ctx.end(); | |
49 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 369 times.
|
369 | BOOST_ASSERT(it != end); |
50 | |||
51 | // fill / align | ||
52 |
2/2✓ Branch 0 taken 107 times.
✓ Branch 1 taken 262 times.
|
369 | if (end - it > 2) |
53 | { | ||
54 |
1/2✓ Branch 0 taken 107 times.
✗ Branch 1 not taken.
|
107 | if (*it != '{' && |
55 |
2/2✓ Branch 0 taken 21 times.
✓ Branch 1 taken 86 times.
|
107 | *it != '}' && |
56 |
2/2✓ Branch 0 taken 19 times.
✓ Branch 1 taken 2 times.
|
21 | (*(it + 1) == '<' || |
57 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 12 times.
|
19 | *(it + 1) == '>' || |
58 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5 times.
|
7 | *(it + 1) == '^')) |
59 | { | ||
60 | 16 | fill = *it; | |
61 | 16 | align = *(it + 1); | |
62 | 16 | it += 2; | |
63 | } | ||
64 | } | ||
65 | |||
66 | // align | ||
67 |
2/2✓ Branch 0 taken 353 times.
✓ Branch 1 taken 16 times.
|
369 | if (align == '\0' && |
68 |
1/2✓ Branch 0 taken 353 times.
✗ Branch 1 not taken.
|
353 | (*it == '<' || |
69 |
1/2✓ Branch 0 taken 353 times.
✗ Branch 1 not taken.
|
353 | *it == '>' || |
70 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 349 times.
|
353 | *it == '^')) |
71 | { | ||
72 | 4 | align = *it++; | |
73 | } | ||
74 | |||
75 | // width | ||
76 | 369 | char const* it0 = it; | |
77 | 369 | constexpr auto width_rule = | |
78 | grammar::variant_rule( | ||
79 | grammar::unsigned_rule<std::size_t>{}, | ||
80 | grammar::tuple_rule( | ||
81 | grammar::squelch( | ||
82 | grammar::delim_rule('{')), | ||
83 | grammar::optional_rule( | ||
84 | arg_id_rule), | ||
85 | grammar::squelch( | ||
86 | grammar::delim_rule('}')))); | ||
87 |
1/2✓ Branch 1 taken 369 times.
✗ Branch 2 not taken.
|
369 | auto rw = grammar::parse(it, end, width_rule); |
88 |
2/2✓ Branch 1 taken 349 times.
✓ Branch 2 taken 20 times.
|
369 | if (!rw) |
89 | { | ||
90 | // rewind | ||
91 | 349 | it = it0; | |
92 | } | ||
93 |
1/2✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
|
20 | else if (align != '\0') |
94 | { | ||
95 | // width is ignored when align is '\0' | ||
96 |
2/2✓ Branch 2 taken 10 times.
✓ Branch 3 taken 10 times.
|
20 | if (rw->index() == 0) |
97 | { | ||
98 | // unsigned_rule | ||
99 |
1/2✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
|
10 | width = variant2::get<0>(*rw); |
100 | } | ||
101 | else | ||
102 | { | ||
103 | // arg_id: store the id idx or string | ||
104 |
1/2✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
|
10 | auto& arg_id = variant2::get<1>(*rw); |
105 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 8 times.
|
10 | if (!arg_id) |
106 | { | ||
107 | // empty arg_id, use and consume | ||
108 | // the next arg idx | ||
109 | 2 | width_idx = ctx.next_arg_id(); | |
110 | } | ||
111 |
3/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 4 times.
|
8 | else if (arg_id->index() == 0) |
112 | { | ||
113 | // string identifier | ||
114 |
2/4✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
|
4 | width_name = variant2::get<0>(*arg_id); |
115 | } | ||
116 | else | ||
117 | { | ||
118 | // integer identifier: use the | ||
119 | // idx of this format_arg | ||
120 |
2/4✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
|
4 | width_idx = variant2::get<1>(*arg_id); |
121 | } | ||
122 | } | ||
123 | } | ||
124 | |||
125 | // type is parsed but doesn't have to | ||
126 | // be stored for strings | ||
127 |
2/2✓ Branch 0 taken 366 times.
✓ Branch 1 taken 3 times.
|
369 | if (*it == 'c' || |
128 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 346 times.
|
366 | *it == 's') |
129 | { | ||
130 | 23 | ++it; | |
131 | } | ||
132 | |||
133 | // we should have arrived at the end now | ||
134 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 368 times.
|
369 | if (*it != '}') |
135 | { | ||
136 | 1 | urls::detail::throw_invalid_argument(); | |
137 | } | ||
138 | |||
139 | 368 | return it; | |
140 | 369 | } | |
141 | |||
142 | std::size_t | ||
143 | 185 | formatter<core::string_view>:: | |
144 | measure( | ||
145 | core::string_view str, | ||
146 | measure_context& ctx, | ||
147 | grammar::lut_chars const& cs) const | ||
148 | { | ||
149 | 185 | std::size_t w = width; | |
150 |
4/4✓ Branch 0 taken 182 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 180 times.
|
367 | if (width_idx != std::size_t(-1) || |
151 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 180 times.
|
182 | !width_name.empty()) |
152 | { | ||
153 | 5 | get_width_from_args( | |
154 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
5 | width_idx, width_name, ctx.args(), w); |
155 | } | ||
156 | |||
157 | 185 | std::size_t n = ctx.out(); | |
158 |
2/2✓ Branch 1 taken 9 times.
✓ Branch 2 taken 176 times.
|
185 | if (str.size() < w) |
159 | 9 | n += measure_one(fill, cs) * (w - str.size()); | |
160 | |||
161 | 185 | return n + encoded_size(str, cs); | |
162 | } | ||
163 | |||
164 | char* | ||
165 | 183 | formatter<core::string_view>:: | |
166 | format(core::string_view str, format_context& ctx, grammar::lut_chars const& cs) const | ||
167 | { | ||
168 | 183 | std::size_t w = width; | |
169 |
4/4✓ Branch 0 taken 180 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 178 times.
|
363 | if (width_idx != std::size_t(-1) || |
170 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 178 times.
|
180 | !width_name.empty()) |
171 | { | ||
172 | 5 | get_width_from_args( | |
173 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
5 | width_idx, width_name, ctx.args(), w); |
174 | } | ||
175 | |||
176 | 183 | std::size_t lpad = 0; | |
177 | 183 | std::size_t rpad = 0; | |
178 |
2/2✓ Branch 1 taken 9 times.
✓ Branch 2 taken 174 times.
|
183 | if (str.size() < w) |
179 | { | ||
180 | 9 | std::size_t pad = w - str.size(); | |
181 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
9 | switch (align) |
182 | { | ||
183 | 1 | case '<': | |
184 | 1 | rpad = pad; | |
185 | 1 | break; | |
186 | 6 | case '>': | |
187 | 6 | lpad = pad; | |
188 | 6 | break; | |
189 | 2 | case '^': | |
190 | 2 | lpad = w / 2; | |
191 | 2 | rpad = pad - lpad; | |
192 | 2 | break; | |
193 | } | ||
194 | } | ||
195 | |||
196 | // unsafe `encode`, assuming `out` has | ||
197 | // enough capacity | ||
198 | 183 | char* out = ctx.out(); | |
199 |
2/2✓ Branch 0 taken 27 times.
✓ Branch 1 taken 183 times.
|
210 | for (std::size_t i = 0; i < lpad; ++i) |
200 | 27 | encode_one(out, fill, cs); | |
201 |
2/2✓ Branch 2 taken 695 times.
✓ Branch 3 taken 183 times.
|
878 | for (char c: str) |
202 | 695 | encode_one(out, c, cs); | |
203 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 183 times.
|
190 | for (std::size_t i = 0; i < rpad; ++i) |
204 | 7 | encode_one(out, fill, cs); | |
205 | 183 | return out; | |
206 | } | ||
207 | |||
208 | void | ||
209 | 28 | get_width_from_args( | |
210 | std::size_t arg_idx, | ||
211 | core::string_view arg_name, | ||
212 | format_args args, | ||
213 | std::size_t& w) | ||
214 | { | ||
215 | // check arg_id | ||
216 |
1/2✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
|
28 | format_arg warg; |
217 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 10 times.
|
28 | if (arg_idx != std::size_t(-1)) |
218 | { | ||
219 | // identifier | ||
220 | 18 | warg = args.get(arg_idx); | |
221 | } | ||
222 | else | ||
223 | { | ||
224 | // unsigned integer | ||
225 | 10 | warg = args.get(arg_name); | |
226 | } | ||
227 | |||
228 | // get unsigned int value from that format arg | ||
229 | 28 | w = warg.value(); | |
230 | 28 | } | |
231 | |||
232 | char const* | ||
233 | 97 | integer_formatter_impl:: | |
234 | parse(format_parse_context& ctx) | ||
235 | { | ||
236 | 97 | char const* it = ctx.begin(); | |
237 | 97 | char const* end = ctx.end(); | |
238 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 97 times.
|
97 | BOOST_ASSERT(it != end); |
239 | |||
240 | // fill / align | ||
241 |
2/2✓ Branch 0 taken 57 times.
✓ Branch 1 taken 40 times.
|
97 | if (end - it > 2) |
242 | { | ||
243 |
1/2✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
|
57 | if (*it != '{' && |
244 |
2/2✓ Branch 0 taken 53 times.
✓ Branch 1 taken 4 times.
|
57 | *it != '}' && |
245 |
2/2✓ Branch 0 taken 49 times.
✓ Branch 1 taken 4 times.
|
53 | (*(it + 1) == '<' || |
246 |
2/2✓ Branch 0 taken 27 times.
✓ Branch 1 taken 22 times.
|
49 | *(it + 1) == '>' || |
247 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 23 times.
|
27 | *(it + 1) == '^')) |
248 | { | ||
249 | 30 | fill = *it; | |
250 | 30 | align = *(it + 1); | |
251 | 30 | it += 2; | |
252 | } | ||
253 | } | ||
254 | |||
255 | // align | ||
256 |
2/2✓ Branch 0 taken 67 times.
✓ Branch 1 taken 30 times.
|
97 | if (align == '\0' && |
257 |
1/2✓ Branch 0 taken 67 times.
✗ Branch 1 not taken.
|
67 | (*it == '<' || |
258 |
2/2✓ Branch 0 taken 59 times.
✓ Branch 1 taken 8 times.
|
67 | *it == '>' || |
259 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 55 times.
|
59 | *it == '^')) |
260 | { | ||
261 | 12 | align = *it++; | |
262 | } | ||
263 | |||
264 | // sign | ||
265 |
2/2✓ Branch 0 taken 91 times.
✓ Branch 1 taken 6 times.
|
97 | if (*it == '+' || |
266 |
1/2✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
|
91 | *it == '-' || |
267 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 85 times.
|
91 | *it == ' ') |
268 | { | ||
269 | 12 | sign = *it++; | |
270 | } | ||
271 | |||
272 | // # | ||
273 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 95 times.
|
97 | if (*it == '#') |
274 | { | ||
275 | // alternate form not supported | ||
276 | 2 | ++it; | |
277 | } | ||
278 | |||
279 | // 0 | ||
280 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 89 times.
|
97 | if (*it == '0') |
281 | { | ||
282 | 8 | zeros = *it++; | |
283 | } | ||
284 | |||
285 | // width | ||
286 | 97 | char const* it0 = it; | |
287 | 97 | constexpr auto width_rule = grammar::variant_rule( | |
288 | grammar::unsigned_rule<std::size_t>{}, | ||
289 | grammar::tuple_rule( | ||
290 | grammar::squelch( | ||
291 | grammar::delim_rule('{')), | ||
292 | grammar::optional_rule( | ||
293 | arg_id_rule), | ||
294 | grammar::squelch( | ||
295 | grammar::delim_rule('}')))); | ||
296 |
1/2✓ Branch 1 taken 97 times.
✗ Branch 2 not taken.
|
97 | auto rw = grammar::parse(it, end, width_rule); |
297 |
2/2✓ Branch 1 taken 55 times.
✓ Branch 2 taken 42 times.
|
97 | if (!rw) |
298 | { | ||
299 | // rewind | ||
300 | 55 | it = it0; | |
301 | } | ||
302 |
1/2✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
|
42 | else if (align != '\0') |
303 | { | ||
304 | // width is ignored when align is '\0' | ||
305 |
2/2✓ Branch 2 taken 24 times.
✓ Branch 3 taken 18 times.
|
42 | if (rw->index() == 0) |
306 | { | ||
307 | // unsigned_rule | ||
308 |
1/2✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
|
24 | width = variant2::get<0>(*rw); |
309 | } | ||
310 | else | ||
311 | { | ||
312 | // arg_id: store the id idx or string | ||
313 |
1/2✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
|
18 | auto& arg_id = variant2::get<1>(*rw); |
314 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 14 times.
|
18 | if (!arg_id) |
315 | { | ||
316 | // empty arg_id, use and consume | ||
317 | // the next arg idx | ||
318 | 4 | width_idx = ctx.next_arg_id(); | |
319 | } | ||
320 |
3/4✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 8 times.
|
14 | else if (arg_id->index() == 0) |
321 | { | ||
322 | // string identifier | ||
323 |
2/4✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
|
6 | width_name = variant2::get<0>(*arg_id); |
324 | } | ||
325 | else | ||
326 | { | ||
327 | // integer identifier: use the | ||
328 | // idx of this format_arg | ||
329 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
8 | width_idx = variant2::get<1>(*arg_id); |
330 | } | ||
331 | } | ||
332 | } | ||
333 | |||
334 | // type is parsed but doesn't have to | ||
335 | // be stored for strings | ||
336 |
2/2✓ Branch 0 taken 55 times.
✓ Branch 1 taken 42 times.
|
97 | if (*it == 'd') |
337 | { | ||
338 | // we don't include other presentation | ||
339 | // modes for integers as they are not | ||
340 | // recommended or generally used in | ||
341 | // urls | ||
342 | 55 | ++it; | |
343 | } | ||
344 | |||
345 | // we should have arrived at the end now | ||
346 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 96 times.
|
97 | if (*it != '}') |
347 | { | ||
348 | 1 | urls::detail::throw_invalid_argument(); | |
349 | } | ||
350 | |||
351 | 96 | return it; | |
352 | 97 | } | |
353 | |||
354 | std::size_t | ||
355 | 34 | integer_formatter_impl:: | |
356 | measure( | ||
357 | long long int v, | ||
358 | measure_context& ctx, | ||
359 | grammar::lut_chars const& cs) const | ||
360 | { | ||
361 | 34 | std::size_t dn = 0; | |
362 | 34 | std::size_t n = 0; | |
363 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 33 times.
|
34 | if (v < 0) |
364 | { | ||
365 | 1 | dn += measure_one('-', cs); | |
366 | 1 | ++n; | |
367 | 1 | v *= -1; | |
368 | } | ||
369 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 29 times.
|
33 | else if (sign != '-') |
370 | { | ||
371 | 4 | dn += measure_one(sign, cs); | |
372 | 4 | ++n; | |
373 | } | ||
374 | do | ||
375 | { | ||
376 | 67 | int d = v % 10; | |
377 | 67 | v /= 10; | |
378 | 67 | dn += measure_one('0' + static_cast<char>(d), cs); | |
379 | 67 | ++n; | |
380 | } | ||
381 |
2/2✓ Branch 0 taken 33 times.
✓ Branch 1 taken 34 times.
|
67 | while (v > 0); |
382 | |||
383 | 34 | std::size_t w = width; | |
384 |
4/4✓ Branch 0 taken 31 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 29 times.
|
65 | if (width_idx != std::size_t(-1) || |
385 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 29 times.
|
31 | !width_name.empty()) |
386 | { | ||
387 | 5 | get_width_from_args( | |
388 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
5 | width_idx, width_name, ctx.args(), w); |
389 | } | ||
390 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 22 times.
|
34 | if (w > n) |
391 | { | ||
392 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
|
12 | if (!zeros) |
393 | 9 | dn += measure_one(fill, cs) * (w - n); | |
394 | else | ||
395 | 3 | dn += measure_one('0', cs) * (w - n); | |
396 | } | ||
397 | 34 | return ctx.out() + dn; | |
398 | } | ||
399 | |||
400 | std::size_t | ||
401 | 14 | integer_formatter_impl:: | |
402 | measure( | ||
403 | unsigned long long int v, | ||
404 | measure_context& ctx, | ||
405 | grammar::lut_chars const& cs) const | ||
406 | { | ||
407 | 14 | std::size_t dn = 0; | |
408 | 14 | std::size_t n = 0; | |
409 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12 times.
|
14 | if (sign != '-') |
410 | { | ||
411 | 2 | dn += measure_one(sign, cs); | |
412 | 2 | ++n; | |
413 | } | ||
414 | do | ||
415 | { | ||
416 | 53 | int d = v % 10; | |
417 | 53 | v /= 10; | |
418 | 53 | dn += measure_one('0' + static_cast<char>(d), cs); | |
419 | 53 | ++n; | |
420 | } | ||
421 |
2/2✓ Branch 0 taken 39 times.
✓ Branch 1 taken 14 times.
|
53 | while (v != 0); |
422 | |||
423 | 14 | std::size_t w = width; | |
424 |
4/4✓ Branch 0 taken 11 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 10 times.
|
25 | if (width_idx != std::size_t(-1) || |
425 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 10 times.
|
11 | !width_name.empty()) |
426 | { | ||
427 | 4 | get_width_from_args( | |
428 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | width_idx, width_name, ctx.args(), w); |
429 | } | ||
430 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
|
14 | if (w > n) |
431 | { | ||
432 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
|
8 | if (!zeros) |
433 | 7 | dn += measure_one(fill, cs) * (w - n); | |
434 | else | ||
435 | 1 | dn += measure_one('0', cs) * (w - n); | |
436 | } | ||
437 | 14 | return ctx.out() + dn; | |
438 | } | ||
439 | |||
440 | char* | ||
441 | 34 | integer_formatter_impl:: | |
442 | format( | ||
443 | long long int v, | ||
444 | format_context& ctx, | ||
445 | grammar::lut_chars const& cs) const | ||
446 | { | ||
447 | // get n digits | ||
448 | 34 | long long int v0 = v; | |
449 | 34 | long long int p = 1; | |
450 | 34 | std::size_t n = 0; | |
451 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 33 times.
|
34 | if (v < 0) |
452 | { | ||
453 | 1 | v *= - 1; | |
454 | 1 | ++n; | |
455 | } | ||
456 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 29 times.
|
33 | else if (sign != '-') |
457 | { | ||
458 | 4 | ++n; | |
459 | } | ||
460 | do | ||
461 | { | ||
462 |
2/2✓ Branch 0 taken 33 times.
✓ Branch 1 taken 34 times.
|
67 | if (v >= 10) |
463 | 33 | p *= 10; | |
464 | 67 | v /= 10; | |
465 | 67 | ++n; | |
466 | } | ||
467 |
2/2✓ Branch 0 taken 33 times.
✓ Branch 1 taken 34 times.
|
67 | while (v > 0); |
468 | static constexpr auto m = | ||
469 | std::numeric_limits<long long int>::digits10; | ||
470 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
|
34 | BOOST_ASSERT(n <= m + 1); |
471 | ignore_unused(m); | ||
472 | |||
473 | // get pad | ||
474 | 34 | std::size_t w = width; | |
475 |
4/4✓ Branch 0 taken 31 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 29 times.
|
65 | if (width_idx != std::size_t(-1) || |
476 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 29 times.
|
31 | !width_name.empty()) |
477 | { | ||
478 | 5 | get_width_from_args( | |
479 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
5 | width_idx, width_name, ctx.args(), w); |
480 | } | ||
481 | 34 | std::size_t lpad = 0; | |
482 | 34 | std::size_t rpad = 0; | |
483 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 22 times.
|
34 | if (w > n) |
484 | { | ||
485 | 12 | std::size_t pad = w - n; | |
486 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 9 times.
|
12 | if (zeros) |
487 | { | ||
488 | 3 | lpad = pad; | |
489 | } | ||
490 | else | ||
491 | { | ||
492 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
9 | switch (align) |
493 | { | ||
494 | 1 | case '<': | |
495 | 1 | rpad = pad; | |
496 | 1 | break; | |
497 | 6 | case '>': | |
498 | 6 | lpad = pad; | |
499 | 6 | break; | |
500 | 2 | case '^': | |
501 | 2 | lpad = pad / 2; | |
502 | 2 | rpad = pad - lpad; | |
503 | 2 | break; | |
504 | } | ||
505 | } | ||
506 | } | ||
507 | |||
508 | // write | ||
509 | 34 | v = v0; | |
510 | 34 | char* out = ctx.out(); | |
511 |
2/2✓ Branch 0 taken 31 times.
✓ Branch 1 taken 3 times.
|
34 | if (!zeros) |
512 | { | ||
513 |
2/2✓ Branch 0 taken 28 times.
✓ Branch 1 taken 31 times.
|
59 | for (std::size_t i = 0; i < lpad; ++i) |
514 | 28 | encode_one(out, fill, cs); | |
515 | } | ||
516 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 33 times.
|
34 | if (v < 0) |
517 | { | ||
518 | 1 | encode_one(out, '-', cs); | |
519 | 1 | v *= -1; | |
520 | 1 | --n; | |
521 | } | ||
522 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 29 times.
|
33 | else if (sign != '-') |
523 | { | ||
524 | 4 | encode_one(out, sign, cs); | |
525 | 4 | --n; | |
526 | } | ||
527 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 31 times.
|
34 | if (zeros) |
528 | { | ||
529 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 3 times.
|
13 | for (std::size_t i = 0; i < lpad; ++i) |
530 | 10 | encode_one(out, '0', cs); | |
531 | } | ||
532 |
2/2✓ Branch 0 taken 67 times.
✓ Branch 1 taken 34 times.
|
101 | while (n) |
533 | { | ||
534 | 67 | unsigned long long int d = v / p; | |
535 | 67 | encode_one(out, '0' + static_cast<char>(d), cs); | |
536 | 67 | --n; | |
537 | 67 | v %= p; | |
538 | 67 | p /= 10; | |
539 | } | ||
540 |
2/2✓ Branch 0 taken 31 times.
✓ Branch 1 taken 3 times.
|
34 | if (!zeros) |
541 | { | ||
542 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 31 times.
|
39 | for (std::size_t i = 0; i < rpad; ++i) |
543 | 8 | encode_one(out, fill, cs); | |
544 | } | ||
545 | 34 | return out; | |
546 | } | ||
547 | |||
548 | char* | ||
549 | 14 | integer_formatter_impl:: | |
550 | format( | ||
551 | unsigned long long int v, | ||
552 | format_context& ctx, | ||
553 | grammar::lut_chars const& cs) const | ||
554 | { | ||
555 | // get n digits | ||
556 | 14 | unsigned long long int v0 = v; | |
557 | 14 | unsigned long long int p = 1; | |
558 | 14 | std::size_t n = 0; | |
559 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12 times.
|
14 | if (sign != '-') |
560 | { | ||
561 | 2 | ++n; | |
562 | } | ||
563 | do | ||
564 | { | ||
565 |
2/2✓ Branch 0 taken 39 times.
✓ Branch 1 taken 14 times.
|
53 | if (v >= 10) |
566 | 39 | p *= 10; | |
567 | 53 | v /= 10; | |
568 | 53 | ++n; | |
569 | } | ||
570 |
2/2✓ Branch 0 taken 39 times.
✓ Branch 1 taken 14 times.
|
53 | while (v > 0); |
571 | static constexpr auto m = | ||
572 | std::numeric_limits<unsigned long long int>::digits10; | ||
573 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
|
14 | BOOST_ASSERT(n <= m + 1); |
574 | ignore_unused(m); | ||
575 | |||
576 | // get pad | ||
577 | 14 | std::size_t w = width; | |
578 |
4/4✓ Branch 0 taken 11 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 10 times.
|
25 | if (width_idx != std::size_t(-1) || |
579 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 10 times.
|
11 | !width_name.empty()) |
580 | { | ||
581 | 4 | get_width_from_args( | |
582 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | width_idx, width_name, ctx.args(), w); |
583 | } | ||
584 | 14 | std::size_t lpad = 0; | |
585 | 14 | std::size_t rpad = 0; | |
586 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
|
14 | if (w > n) |
587 | { | ||
588 | 8 | std::size_t pad = w - n; | |
589 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
|
8 | if (zeros) |
590 | { | ||
591 | 1 | lpad = pad; | |
592 | } | ||
593 | else | ||
594 | { | ||
595 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
7 | switch (align) |
596 | { | ||
597 | 1 | case '<': | |
598 | 1 | rpad = pad; | |
599 | 1 | break; | |
600 | 5 | case '>': | |
601 | 5 | lpad = pad; | |
602 | 5 | break; | |
603 | 1 | case '^': | |
604 | 1 | lpad = pad / 2; | |
605 | 1 | rpad = pad - lpad; | |
606 | 1 | break; | |
607 | } | ||
608 | } | ||
609 | } | ||
610 | |||
611 | // write | ||
612 | 14 | v = v0; | |
613 | 14 | char* out = ctx.out(); | |
614 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1 times.
|
14 | if (!zeros) |
615 | { | ||
616 |
2/2✓ Branch 0 taken 22 times.
✓ Branch 1 taken 13 times.
|
35 | for (std::size_t i = 0; i < lpad; ++i) |
617 | 22 | encode_one(out, fill, cs); | |
618 | } | ||
619 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12 times.
|
14 | if (sign != '-') |
620 | { | ||
621 | 2 | encode_one(out, sign, cs); | |
622 | 2 | --n; | |
623 | } | ||
624 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 13 times.
|
14 | if (zeros) |
625 | { | ||
626 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
|
5 | for (std::size_t i = 0; i < lpad; ++i) |
627 | 4 | encode_one(out, '0', cs); | |
628 | } | ||
629 |
2/2✓ Branch 0 taken 53 times.
✓ Branch 1 taken 14 times.
|
67 | while (n) |
630 | { | ||
631 | 53 | unsigned long long int d = v / p; | |
632 | 53 | encode_one(out, '0' + static_cast<char>(d), cs); | |
633 | 53 | --n; | |
634 | 53 | v %= p; | |
635 | 53 | p /= 10; | |
636 | } | ||
637 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1 times.
|
14 | if (!zeros) |
638 | { | ||
639 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 13 times.
|
19 | for (std::size_t i = 0; i < rpad; ++i) |
640 | 6 | encode_one(out, fill, cs); | |
641 | } | ||
642 | 14 | return out; | |
643 | } | ||
644 | |||
645 | } // detail | ||
646 | } // urls | ||
647 | } // boost | ||
648 | |||
649 |