include/boost/url/grammar/impl/unsigned_rule.hpp

100.0% Lines (40/40) 100.0% Functions (2/3) 94.7% Branches (36/38)
include/boost/url/grammar/impl/unsigned_rule.hpp
Line Branch Hits Source Code
1 //
2 // Copyright (c) 2022 Alan de Freitas (alandefreitas at gmail dot 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_GRAMMAR_IMPL_UNSIGNED_RULE_HPP
11 #define BOOST_URL_GRAMMAR_IMPL_UNSIGNED_RULE_HPP
12
13 #include <boost/url/grammar/error.hpp>
14 #include <boost/url/grammar/digit_chars.hpp>
15 #include <algorithm> // VFALCO grr..
16
17 namespace boost {
18 namespace urls {
19 namespace grammar {
20
21 template<class U>
22 BOOST_URL_CXX14_CONSTEXPR
23 auto
24 1951 unsigned_rule<U>::
25 parse(
26 char const*& it,
27 char const* end
28 ) const noexcept ->
29 system::result<value_type>
30 {
31
2/2
✓ Branch 0 taken 416 times.
✓ Branch 1 taken 1506 times.
1951 if(it == end)
32 {
33 // end
34 417 BOOST_URL_CONSTEXPR_RETURN_EC(
35 error::mismatch);
36 }
37
2/2
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 1463 times.
1534 if(*it == '0')
38 {
39 52 ++it;
40
3/4
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 43 times.
✗ Branch 3 not taken.
77 if( it == end ||
41
1/2
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
25 ! digit_chars(*it))
42 {
43 46 return U(0);
44 }
45 // bad leading zero
46 6 BOOST_URL_CONSTEXPR_RETURN_EC(
47 error::invalid);
48 }
49
2/2
✓ Branch 1 taken 1030 times.
✓ Branch 2 taken 433 times.
1482 if(! digit_chars(*it))
50 {
51 // expected digit
52 1031 BOOST_URL_CONSTEXPR_RETURN_EC(
53 error::mismatch);
54 }
55 451 constexpr U Digits10 =
56 std::numeric_limits<
57 U>::digits10;
58 451 constexpr U ten = 10;
59 451 char const* safe_end = nullptr;
60 451 if(static_cast<std::size_t>(
61
2/2
✓ Branch 0 taken 195 times.
✓ Branch 1 taken 238 times.
451 end - it) >= Digits10)
62 207 safe_end = it + Digits10;
63 else
64 244 safe_end = end;
65 451 U u = *it - '0';
66 451 ++it;
67
6/6
✓ Branch 0 taken 739 times.
✓ Branch 1 taken 235 times.
✓ Branch 2 taken 541 times.
✓ Branch 3 taken 198 times.
✓ Branch 4 taken 541 times.
✓ Branch 5 taken 433 times.
1819 while(it != safe_end &&
68 783 digit_chars(*it))
69 {
70 585 char const dig = *it - '0';
71 585 u = u * ten + dig;
72 585 ++it;
73 }
74
6/6
✓ Branch 0 taken 267 times.
✓ Branch 1 taken 166 times.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 235 times.
✓ Branch 4 taken 32 times.
✓ Branch 5 taken 401 times.
730 if( it != end &&
75 279 digit_chars(*it))
76 {
77 44 constexpr U Max = (
78 std::numeric_limits<
79 U>::max)();
80 constexpr
81 44 auto div = (Max / ten);
82 constexpr
83 44 char rem = (Max % ten);
84 44 char const dig = *it - '0';
85
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 10 times.
44 if( u > div || (
86
4/4
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 9 times.
31 u == div && dig > rem))
87 {
88 // integer overflow
89 23 BOOST_URL_CONSTEXPR_RETURN_EC(
90 error::invalid);
91 }
92 21 u = u * ten + dig;
93 21 ++it;
94
6/6
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 1 time.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 11 times.
28 if( it < end &&
95 7 digit_chars(*it))
96 {
97 // integer overflow
98 6 BOOST_URL_CONSTEXPR_RETURN_EC(
99 error::invalid);
100 }
101 }
102
103 422 return u;
104 }
105
106 } // grammar
107 } // urls
108 } // boost
109
110 #endif
111