File indexing completed on 2025-01-18 09:53:27
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_URL_GRAMMAR_IMPL_UNSIGNED_RULE_HPP
0011 #define BOOST_URL_GRAMMAR_IMPL_UNSIGNED_RULE_HPP
0012
0013 #include <boost/url/grammar/error.hpp>
0014 #include <boost/url/grammar/digit_chars.hpp>
0015 #include <algorithm> // VFALCO grr..
0016
0017 namespace boost {
0018 namespace urls {
0019 namespace grammar {
0020
0021 template<class U>
0022 auto
0023 unsigned_rule<U>::
0024 parse(
0025 char const*& it,
0026 char const* end
0027 ) const noexcept ->
0028 system::result<value_type>
0029 {
0030 if(it == end)
0031 {
0032
0033 BOOST_URL_RETURN_EC(
0034 error::mismatch);
0035 }
0036 if(*it == '0')
0037 {
0038 ++it;
0039 if( it == end ||
0040 ! digit_chars(*it))
0041 {
0042 return U(0);
0043 }
0044
0045 BOOST_URL_RETURN_EC(
0046 error::invalid);
0047 }
0048 if(! digit_chars(*it))
0049 {
0050
0051 BOOST_URL_RETURN_EC(
0052 error::mismatch);
0053 }
0054 static constexpr U Digits10 =
0055 std::numeric_limits<
0056 U>::digits10;
0057 static constexpr U ten = 10;
0058 char const* safe_end;
0059 if(static_cast<std::size_t>(
0060 end - it) >= Digits10)
0061 safe_end = it + Digits10;
0062 else
0063 safe_end = end;
0064 U u = *it - '0';
0065 ++it;
0066 while(it != safe_end &&
0067 digit_chars(*it))
0068 {
0069 char const dig = *it - '0';
0070 u = u * ten + dig;
0071 ++it;
0072 }
0073 if( it != end &&
0074 digit_chars(*it))
0075 {
0076 static constexpr U Max = (
0077 std::numeric_limits<
0078 U>::max)();
0079 static constexpr
0080 auto div = (Max / ten);
0081 static constexpr
0082 char rem = (Max % ten);
0083 char const dig = *it - '0';
0084 if( u > div || (
0085 u == div && dig > rem))
0086 {
0087
0088 BOOST_URL_RETURN_EC(
0089 error::invalid);
0090 }
0091 u = u * ten + dig;
0092 ++it;
0093 if( it < end &&
0094 digit_chars(*it))
0095 {
0096
0097 BOOST_URL_RETURN_EC(
0098 error::invalid);
0099 }
0100 }
0101
0102 return u;
0103 }
0104
0105 }
0106 }
0107 }
0108
0109 #endif