LCOV - code coverage report
Current view: top level - url/grammar/impl - unsigned_rule.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 40 40
Test Date: 2026-02-13 15:53:22 Functions: 100.0 % 4 4

            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_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         1951 :     if(it == end)
      32              :     {
      33              :         // end
      34          417 :         BOOST_URL_CONSTEXPR_RETURN_EC(
      35              :             error::mismatch);
      36              :     }
      37         1534 :     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         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          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         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          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           44 :         if( u > div || (
      86           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           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
        

Generated by: LCOV version 2.3