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  
#ifndef BOOST_URL_RFC_IMPL_PCT_ENCODED_RULE_HPP
10  
#ifndef BOOST_URL_RFC_IMPL_PCT_ENCODED_RULE_HPP
11  
#define BOOST_URL_RFC_IMPL_PCT_ENCODED_RULE_HPP
11  
#define BOOST_URL_RFC_IMPL_PCT_ENCODED_RULE_HPP
12  

12  

13  
#include <boost/url/grammar/charset.hpp>
13  
#include <boost/url/grammar/charset.hpp>
14  
#include <boost/url/grammar/error.hpp>
14  
#include <boost/url/grammar/error.hpp>
15  
#include <boost/url/grammar/hexdig_chars.hpp>
15  
#include <boost/url/grammar/hexdig_chars.hpp>
16  

16  

17  
namespace boost {
17  
namespace boost {
18  
namespace urls {
18  
namespace urls {
19  

19  

20  
namespace detail {
20  
namespace detail {
21  

21  

22  
template<class CharSet>
22  
template<class CharSet>
23  
auto
23  
auto
24  
parse_encoded(
24  
parse_encoded(
25  
    char const*& it,
25  
    char const*& it,
26  
    char const* end,
26  
    char const* end,
27  
    CharSet const& cs) noexcept ->
27  
    CharSet const& cs) noexcept ->
28  
        system::result<pct_string_view>
28  
        system::result<pct_string_view>
29  
{
29  
{
30  
    auto const start = it;
30  
    auto const start = it;
31  
    std::size_t n = 0;
31  
    std::size_t n = 0;
32  
    char const* it0;
32  
    char const* it0;
33  
skip:
33  
skip:
34  
    it0 = it;
34  
    it0 = it;
35  
    it = grammar::find_if_not(
35  
    it = grammar::find_if_not(
36  
        it0, end, cs);
36  
        it0, end, cs);
37  
    n += it - it0;
37  
    n += it - it0;
38  
    if(it == end)
38  
    if(it == end)
39  
        goto finish;
39  
        goto finish;
40  
    if(*it != '%')
40  
    if(*it != '%')
41  
        goto finish;
41  
        goto finish;
42  
    for(;;)
42  
    for(;;)
43  
    {
43  
    {
44  
        ++it;
44  
        ++it;
45  
        if(it == end)
45  
        if(it == end)
46  
        {
46  
        {
47  
            // expected HEXDIG
47  
            // expected HEXDIG
48  
            BOOST_URL_RETURN_EC(
48  
            BOOST_URL_RETURN_EC(
49  
                grammar::error::invalid);
49  
                grammar::error::invalid);
50  
        }
50  
        }
51  
        auto r = grammar::hexdig_value(*it);
51  
        auto r = grammar::hexdig_value(*it);
52  
        if(r < 0)
52  
        if(r < 0)
53  
        {
53  
        {
54  
            // expected HEXDIG
54  
            // expected HEXDIG
55  
            BOOST_URL_RETURN_EC(
55  
            BOOST_URL_RETURN_EC(
56  
                grammar::error::invalid);
56  
                grammar::error::invalid);
57  
        }
57  
        }
58  
        ++it;
58  
        ++it;
59  
        if(it == end)
59  
        if(it == end)
60  
        {
60  
        {
61  
            // expected HEXDIG
61  
            // expected HEXDIG
62  
            BOOST_URL_RETURN_EC(
62  
            BOOST_URL_RETURN_EC(
63  
                grammar::error::invalid);
63  
                grammar::error::invalid);
64  
        }
64  
        }
65  
        r = grammar::hexdig_value(*it);
65  
        r = grammar::hexdig_value(*it);
66  
        if(r < 0)
66  
        if(r < 0)
67  
        {
67  
        {
68  
            // expected HEXDIG
68  
            // expected HEXDIG
69  
            BOOST_URL_RETURN_EC(
69  
            BOOST_URL_RETURN_EC(
70  
                grammar::error::invalid);
70  
                grammar::error::invalid);
71  
        }
71  
        }
72  
        ++n;
72  
        ++n;
73  
        ++it;
73  
        ++it;
74  
        if(it == end)
74  
        if(it == end)
75  
            break;
75  
            break;
76  
        if(*it != '%')
76  
        if(*it != '%')
77  
            goto skip;
77  
            goto skip;
78  
    }
78  
    }
79  
finish:
79  
finish:
80  
    return make_pct_string_view_unsafe(
80  
    return make_pct_string_view_unsafe(
81  
        start, it - start, n);
81  
        start, it - start, n);
82  
}
82  
}
83  

83  

84  
} // detail
84  
} // detail
85  

85  

86  
//------------------------------------------------
86  
//------------------------------------------------
87  

87  

88  
template<class CharSet>
88  
template<class CharSet>
89  
auto
89  
auto
90  
implementation_defined::pct_encoded_rule_t<CharSet>::
90  
implementation_defined::pct_encoded_rule_t<CharSet>::
91  
parse(
91  
parse(
92  
    char const*& it,
92  
    char const*& it,
93  
    char const* end) const noexcept ->
93  
    char const* end) const noexcept ->
94  
        system::result<value_type>
94  
        system::result<value_type>
95  
{
95  
{
96  
    return detail::parse_encoded(
96  
    return detail::parse_encoded(
97  
        it, end, cs_);
97  
        it, end, cs_);
98  
}
98  
}
99  

99  

100  
} // urls
100  
} // urls
101  
} // boost
101  
} // boost
102  

102  

103  
#endif
103  
#endif