1  
//
1  
//
2  
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
2  
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3  
// Copyright (c) 2024 Alan de Freitas (alandefreitas@gmail.com)
3  
// Copyright (c) 2024 Alan de Freitas (alandefreitas@gmail.com)
4  
//
4  
//
5  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
6  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  
//
7  
//
8  
// Official repository: https://github.com/boostorg/url
8  
// Official repository: https://github.com/boostorg/url
9  
//
9  
//
10  

10  

11  
#ifndef BOOST_URL_RFC_DETAIL_IMPL_H16_RULE_HPP
11  
#ifndef BOOST_URL_RFC_DETAIL_IMPL_H16_RULE_HPP
12  
#define BOOST_URL_RFC_DETAIL_IMPL_H16_RULE_HPP
12  
#define BOOST_URL_RFC_DETAIL_IMPL_H16_RULE_HPP
13  

13  

14  
#include <boost/url/detail/config.hpp>
14  
#include <boost/url/detail/config.hpp>
15  
#include <boost/url/grammar/error.hpp>
15  
#include <boost/url/grammar/error.hpp>
16  
#include <boost/url/grammar/hexdig_chars.hpp>
16  
#include <boost/url/grammar/hexdig_chars.hpp>
17  

17  

18  
namespace boost {
18  
namespace boost {
19  
namespace urls {
19  
namespace urls {
20  
namespace detail {
20  
namespace detail {
21  

21  

22  
BOOST_URL_CXX20_CONSTEXPR_OR_INLINE
22  
BOOST_URL_CXX20_CONSTEXPR_OR_INLINE
23  
auto
23  
auto
24  
h16_rule_t::
24  
h16_rule_t::
25  
parse(
25  
parse(
26  
    char const*& it,
26  
    char const*& it,
27  
    char const* end
27  
    char const* end
28  
        ) const noexcept ->
28  
        ) const noexcept ->
29  
    system::result<value_type>
29  
    system::result<value_type>
30  
{
30  
{
31  
    // LCOV_EXCL_START
31  
    // LCOV_EXCL_START
32  
    // h16 is only called from ipv6_address_rule
32  
    // h16 is only called from ipv6_address_rule
33  
    // which ensures at least one char is available
33  
    // which ensures at least one char is available
34  
    if(it == end)
34  
    if(it == end)
35  
    {
35  
    {
36  
        BOOST_URL_CONSTEXPR_RETURN_EC(
36  
        BOOST_URL_CONSTEXPR_RETURN_EC(
37  
            grammar::error::invalid);
37  
            grammar::error::invalid);
38  
    }
38  
    }
39  
    // LCOV_EXCL_STOP
39  
    // LCOV_EXCL_STOP
40  

40  

41  
    std::uint16_t v;
41  
    std::uint16_t v;
42  
    for(;;)
42  
    for(;;)
43  
    {
43  
    {
44  
        auto d = grammar::hexdig_value(*it);
44  
        auto d = grammar::hexdig_value(*it);
45  
        if(d < 0)
45  
        if(d < 0)
46  
        {
46  
        {
47  
            // expected HEXDIG
47  
            // expected HEXDIG
48  
            BOOST_URL_CONSTEXPR_RETURN_EC(
48  
            BOOST_URL_CONSTEXPR_RETURN_EC(
49  
                grammar::error::invalid);
49  
                grammar::error::invalid);
50  
        }
50  
        }
51  
        v = d;
51  
        v = d;
52  
        ++it;
52  
        ++it;
53  
        if(it == end)
53  
        if(it == end)
54  
            break;
54  
            break;
55  
        d = grammar::hexdig_value(*it);
55  
        d = grammar::hexdig_value(*it);
56  
        if(d < 0)
56  
        if(d < 0)
57  
            break;
57  
            break;
58  
        v = (16 * v) + d;
58  
        v = (16 * v) + d;
59  
        ++it;
59  
        ++it;
60  
        if(it == end)
60  
        if(it == end)
61  
            break;
61  
            break;
62  
        d = grammar::hexdig_value(*it);
62  
        d = grammar::hexdig_value(*it);
63  
        if(d < 0)
63  
        if(d < 0)
64  
            break;
64  
            break;
65  
        v = (16 * v) + d;
65  
        v = (16 * v) + d;
66  
        ++it;
66  
        ++it;
67  
        if(it == end)
67  
        if(it == end)
68  
            break;
68  
            break;
69  
        d = grammar::hexdig_value(*it);
69  
        d = grammar::hexdig_value(*it);
70  
        if(d < 0)
70  
        if(d < 0)
71  
            break;
71  
            break;
72  
        v = (16 * v) + d;
72  
        v = (16 * v) + d;
73  
        ++it;
73  
        ++it;
74  
        break;
74  
        break;
75  
    }
75  
    }
76  
    return value_type{
76  
    return value_type{
77  
        static_cast<
77  
        static_cast<
78  
            unsigned char>(v / 256),
78  
            unsigned char>(v / 256),
79  
        static_cast<
79  
        static_cast<
80  
            unsigned char>(v % 256)};
80  
            unsigned char>(v % 256)};
81  
}
81  
}
82  

82  

83  
} // detail
83  
} // detail
84  
} // urls
84  
} // urls
85  
} // boost
85  
} // boost
86  

86  

87  

87  

88  
#endif
88  
#endif