Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:27

0001 //
0002 // Copyright (c) 2022 Alan de Freitas (alandefreitas at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/url
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         // end
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         // bad leading zero
0045         BOOST_URL_RETURN_EC(
0046             error::invalid);
0047     }
0048     if(! digit_chars(*it))
0049     {
0050         // expected digit
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             // integer overflow
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             // integer overflow
0097             BOOST_URL_RETURN_EC(
0098                 error::invalid);
0099         }
0100     }
0101 
0102     return u;
0103 }
0104 
0105 } // grammar
0106 } // urls
0107 } // boost
0108 
0109 #endif