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  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
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)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/boostorg/url
7  
// Official repository: https://github.com/boostorg/url
8  
//
8  
//
9  

9  

10  
#include <boost/url/detail/config.hpp>
10  
#include <boost/url/detail/config.hpp>
11  
#include "h16_rule.hpp"
11  
#include "h16_rule.hpp"
12  
#include <boost/url/grammar/charset.hpp>
12  
#include <boost/url/grammar/charset.hpp>
13  
#include <boost/url/grammar/error.hpp>
13  
#include <boost/url/grammar/error.hpp>
14  
#include <boost/url/grammar/hexdig_chars.hpp>
14  
#include <boost/url/grammar/hexdig_chars.hpp>
15  
#include <boost/assert.hpp>
15  
#include <boost/assert.hpp>
16  

16  

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

20  

21  
auto
21  
auto
22  
h16_rule_t::
22  
h16_rule_t::
23  
parse(
23  
parse(
24  
    char const*& it,
24  
    char const*& it,
25  
    char const* end
25  
    char const* end
26  
        ) const noexcept ->
26  
        ) const noexcept ->
27  
    system::result<value_type>
27  
    system::result<value_type>
28  
{
28  
{
29  
    // VFALCO it might be impossible for
29  
    // VFALCO it might be impossible for
30  
    // this condition to be true (coverage)
30  
    // this condition to be true (coverage)
31  
    if(it == end)
31  
    if(it == end)
32  
    {
32  
    {
33  
        // end
33  
        // end
34  
        BOOST_URL_RETURN_EC(
34  
        BOOST_URL_RETURN_EC(
35  
            grammar::error::invalid);
35  
            grammar::error::invalid);
36  
    }
36  
    }
37  

37  

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

79  

80  
} // detail
80  
} // detail
81  
} // urls
81  
} // urls
82  
} // boost
82  
} // boost
83  

83