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

80.8% Lines (97/120) 100.0% List of functions (2/3)
unsigned_rule.hpp
f(x) Functions (3)
Line TLA 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_CXX20_CONSTEXPR
23 auto
24 2224x unsigned_rule<U>::
25 parse(
26 char const*& it,
27 char const* end
28 ) const noexcept ->
29 system::result<value_type>
30 {
31 2224x if(it == end)
32 {
33 // end
34 425x BOOST_URL_CONSTEXPR_RETURN_EC(
35 error::mismatch);
36 }
37 1799x if(*it == '0')
38 {
39 52x ++it;
40 77x if( it == end ||
41 25x ! digit_chars(*it))
42 {
43 46x return U(0);
44 }
45 // bad leading zero
46 6x BOOST_URL_CONSTEXPR_RETURN_EC(
47 error::invalid);
48 }
49 1747x if(! digit_chars(*it))
50 {
51 // expected digit
52 1045x BOOST_URL_CONSTEXPR_RETURN_EC(
53 error::mismatch);
54 }
55 702x constexpr U Digits10 =
56 std::numeric_limits<
57 U>::digits10;
58 702x constexpr U ten = 10;
59 702x char const* safe_end = nullptr;
60 702x if(static_cast<std::size_t>(
61 702x end - it) >= Digits10)
62 298x safe_end = it + Digits10;
63 else
64 404x safe_end = end;
65 702x U u = *it - '0';
66 702x ++it;
67 2932x while(it != safe_end &&
68 1218x digit_chars(*it))
69 {
70 1012x char const dig = *it - '0';
71 1012x u = u * ten + dig;
72 1012x ++it;
73 }
74 1072x if( it != end &&
75 370x digit_chars(*it))
76 {
77 45x constexpr U Max = (
78 std::numeric_limits<
79 U>::max)();
80 constexpr
81 45x auto div = (Max / ten);
82 constexpr
83 45x char rem = (Max % ten);
84 45x char const dig = *it - '0';
85 45x if( u > div || (
86 32x u == div && dig > rem))
87 {
88 // integer overflow
89 23x BOOST_URL_CONSTEXPR_RETURN_EC(
90 error::invalid);
91 }
92 22x u = u * ten + dig;
93 22x ++it;
94 30x if( it < end &&
95 8x digit_chars(*it))
96 {
97 // integer overflow
98 6x BOOST_URL_CONSTEXPR_RETURN_EC(
99 error::invalid);
100 }
101 }
102
103 673x return u;
104 }
105
106 } // grammar
107 } // urls
108 } // boost
109
110 #endif
111