1  
//
1  
//
2  
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
2  
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.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  

10  

11  
#include <boost/url/detail/config.hpp>
11  
#include <boost/url/detail/config.hpp>
12  
#include <boost/url/decode_view.hpp>
12  
#include <boost/url/decode_view.hpp>
13  
#include <boost/url/grammar/hexdig_chars.hpp>
13  
#include <boost/url/grammar/hexdig_chars.hpp>
14  
#include <ostream>
14  
#include <ostream>
15  

15  

16  
namespace boost {
16  
namespace boost {
17  
namespace urls {
17  
namespace urls {
18  

18  

19  
//------------------------------------------------
19  
//------------------------------------------------
20  

20  

21  
auto
21  
auto
22  
decode_view::
22  
decode_view::
23  
iterator::
23  
iterator::
24  
operator*() const noexcept ->
24  
operator*() const noexcept ->
25  
    reference
25  
    reference
26  
{
26  
{
27  
    if (space_as_plus_ &&
27  
    if (space_as_plus_ &&
28  
        *pos_ == '+')
28  
        *pos_ == '+')
29  
        return ' ';
29  
        return ' ';
30  
    if (*pos_ != '%')
30  
    if (*pos_ != '%')
31  
        return *pos_;
31  
        return *pos_;
32  
    auto d0 = grammar::hexdig_value(pos_[1]);
32  
    auto d0 = grammar::hexdig_value(pos_[1]);
33  
    auto d1 = grammar::hexdig_value(pos_[2]);
33  
    auto d1 = grammar::hexdig_value(pos_[2]);
34  
    return static_cast<char>(
34  
    return static_cast<char>(
35  
        ((static_cast<
35  
        ((static_cast<
36  
              unsigned char>(d0) << 4) +
36  
              unsigned char>(d0) << 4) +
37  
         (static_cast<
37  
         (static_cast<
38  
             unsigned char>(d1))));
38  
             unsigned char>(d1))));
39  
}
39  
}
40  

40  

41  
void
41  
void
42  
decode_view::
42  
decode_view::
43  
write(std::ostream& os) const
43  
write(std::ostream& os) const
44  
{
44  
{
45  
    auto it = begin();
45  
    auto it = begin();
46  
    auto const end_ = end();
46  
    auto const end_ = end();
47  
    while(it != end_)
47  
    while(it != end_)
48  
        os.put(*it++);
48  
        os.put(*it++);
49  
}
49  
}
50  

50  

51  
void
51  
void
52  
decode_view::
52  
decode_view::
53  
remove_prefix( size_type n )
53  
remove_prefix( size_type n )
54  
{
54  
{
55  
    BOOST_ASSERT(n <= dn_);
55  
    BOOST_ASSERT(n <= dn_);
56  
    auto it = begin();
56  
    auto it = begin();
57  
    auto n0 = n;
57  
    auto n0 = n;
58  
    while (n)
58  
    while (n)
59  
    {
59  
    {
60  
        ++it;
60  
        ++it;
61  
        --n;
61  
        --n;
62  
    }
62  
    }
63  
    n_ -= (it.base() - begin().base());
63  
    n_ -= (it.base() - begin().base());
64  
    dn_ -= n0;
64  
    dn_ -= n0;
65  
    p_ = it.base();
65  
    p_ = it.base();
66  
}
66  
}
67  

67  

68  
void
68  
void
69  
decode_view::
69  
decode_view::
70  
remove_suffix( size_type n )
70  
remove_suffix( size_type n )
71  
{
71  
{
72  
    BOOST_ASSERT(n <= dn_);
72  
    BOOST_ASSERT(n <= dn_);
73  
    auto it = end();
73  
    auto it = end();
74  
    auto n0 = n;
74  
    auto n0 = n;
75  
    while (n)
75  
    while (n)
76  
    {
76  
    {
77  
        --it;
77  
        --it;
78  
        --n;
78  
        --n;
79  
    }
79  
    }
80  
    n_ -= (end().base() - it.base());
80  
    n_ -= (end().base() - it.base());
81  
    dn_ -= n0;
81  
    dn_ -= n0;
82  
}
82  
}
83  

83  

84  
bool
84  
bool
85  
decode_view::
85  
decode_view::
86  
starts_with( core::string_view s ) const noexcept
86  
starts_with( core::string_view s ) const noexcept
87  
{
87  
{
88  
    if (s.size() > size())
88  
    if (s.size() > size())
89  
        return false;
89  
        return false;
90  
    auto it0 = begin();
90  
    auto it0 = begin();
91  
    auto it1 = s.begin();
91  
    auto it1 = s.begin();
92  
    std::size_t n = s.size();
92  
    std::size_t n = s.size();
93  
    while (n)
93  
    while (n)
94  
    {
94  
    {
95  
        if (*it0 != *it1)
95  
        if (*it0 != *it1)
96  
            return false;
96  
            return false;
97  
        ++it0;
97  
        ++it0;
98  
        ++it1;
98  
        ++it1;
99  
        --n;
99  
        --n;
100  
    }
100  
    }
101  
    return true;
101  
    return true;
102  
}
102  
}
103  

103  

104  
bool
104  
bool
105  
decode_view::
105  
decode_view::
106  
ends_with( core::string_view s ) const noexcept
106  
ends_with( core::string_view s ) const noexcept
107  
{
107  
{
 
108 +
    if (s.empty())
 
109 +
        return true;
108  
    if (s.size() > size())
110  
    if (s.size() > size())
109  
        return false;
111  
        return false;
110  
    auto it0 = end();
112  
    auto it0 = end();
111  
    auto it1 = s.end();
113  
    auto it1 = s.end();
112  
    std::size_t n = s.size();
114  
    std::size_t n = s.size();
113  
    --it0;
115  
    --it0;
114  
    --it1;
116  
    --it1;
115  
    while (n - 1)
117  
    while (n - 1)
116  
    {
118  
    {
117  
        if (*it0 != *it1)
119  
        if (*it0 != *it1)
118  
            return false;
120  
            return false;
119  
        --it0;
121  
        --it0;
120  
        --it1;
122  
        --it1;
121  
        --n;
123  
        --n;
122  
    }
124  
    }
123  
    return *it0 == *it1;
125  
    return *it0 == *it1;
124  
}
126  
}
125  

127  

126  
bool
128  
bool
127  
decode_view::
129  
decode_view::
128  
starts_with( char ch ) const noexcept
130  
starts_with( char ch ) const noexcept
129  
{
131  
{
130  
    return
132  
    return
131  
        !empty() &&
133  
        !empty() &&
132  
        front() == ch;
134  
        front() == ch;
133  
}
135  
}
134  

136  

135  
bool
137  
bool
136  
decode_view::
138  
decode_view::
137  
ends_with( char ch ) const noexcept
139  
ends_with( char ch ) const noexcept
138  
{
140  
{
139  
    return
141  
    return
140  
        !empty() &&
142  
        !empty() &&
141  
        back() == ch;
143  
        back() == ch;
142  
}
144  
}
143  

145  

144  
decode_view::const_iterator
146  
decode_view::const_iterator
145  
decode_view::
147  
decode_view::
146  
find( char ch ) const noexcept
148  
find( char ch ) const noexcept
147  
{
149  
{
148  
    auto it = begin();
150  
    auto it = begin();
149  
    auto end = this->end();
151  
    auto end = this->end();
150  
    while (it != end)
152  
    while (it != end)
151  
    {
153  
    {
152  
        if (*it == ch)
154  
        if (*it == ch)
153  
            return it;
155  
            return it;
154  
        ++it;
156  
        ++it;
155  
    }
157  
    }
156  
    return it;
158  
    return it;
157  
}
159  
}
158  

160  

159  
decode_view::const_iterator
161  
decode_view::const_iterator
160  
decode_view::
162  
decode_view::
161  
rfind( char ch ) const noexcept
163  
rfind( char ch ) const noexcept
162  
{
164  
{
163  
    if (empty())
165  
    if (empty())
164  
        return end();
166  
        return end();
165  
    auto it = end();
167  
    auto it = end();
166  
    auto begin = this->begin();
168  
    auto begin = this->begin();
167  
    --it;
169  
    --it;
168  
    while (it != begin)
170  
    while (it != begin)
169  
    {
171  
    {
170  
        if (*it == ch)
172  
        if (*it == ch)
171  
            return it;
173  
            return it;
172  
        --it;
174  
        --it;
173  
    }
175  
    }
174  
    if (*it == ch)
176  
    if (*it == ch)
175  
        return it;
177  
        return it;
176  
    return end();
178  
    return end();
177  
}
179  
}
178  

180  

179  
} // urls
181  
} // urls
180  
} // boost
182  
} // boost
181  

183