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