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

10  

10  
#ifndef BOOST_URL_RFC_IMPL_PCT_ENCODED_RULE_HPP
11  
#ifndef BOOST_URL_RFC_IMPL_PCT_ENCODED_RULE_HPP
11  
#define BOOST_URL_RFC_IMPL_PCT_ENCODED_RULE_HPP
12  
#define BOOST_URL_RFC_IMPL_PCT_ENCODED_RULE_HPP
12  

13  

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

17  

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

20  

20  
namespace detail {
21  
namespace detail {
21  

22  

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

89  

84  
} // detail
90  
} // detail
85  

91  

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

93  

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

106  

100  
} // urls
107  
} // urls
101  
} // boost
108  
} // boost
102  

109  

103  
#endif
110  
#endif