Line data Source code
1 : //
2 : // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
3 : //
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)
6 : //
7 : // Official repository: https://github.com/boostorg/url
8 : //
9 :
10 : #ifndef BOOST_URL_IMPL_PCT_ENCODED_VIEW_HPP
11 : #define BOOST_URL_IMPL_PCT_ENCODED_VIEW_HPP
12 :
13 : #include <boost/url/grammar/type_traits.hpp>
14 : #include <boost/static_assert.hpp>
15 :
16 : namespace boost {
17 : namespace urls {
18 :
19 : class decode_view::iterator
20 : {
21 : char const* begin_ = nullptr;
22 : char const* pos_ = nullptr;
23 : bool space_as_plus_ = true;
24 :
25 : friend decode_view;
26 :
27 6356 : iterator(
28 : char const* str,
29 : bool space_as_plus) noexcept
30 6356 : : begin_(str)
31 6356 : , pos_(str)
32 6356 : , space_as_plus_(
33 : space_as_plus)
34 : {
35 6356 : }
36 :
37 : // end ctor
38 885 : iterator(
39 : char const* str,
40 : size_type n,
41 : bool space_as_plus) noexcept
42 885 : : begin_(str)
43 885 : , pos_(str + n)
44 885 : , space_as_plus_(space_as_plus)
45 : {
46 885 : }
47 :
48 : public:
49 : using value_type = char;
50 : using reference = char;
51 : using pointer = void const*;
52 : using const_reference = char;
53 : using size_type = std::size_t;
54 : using difference_type = std::ptrdiff_t;
55 : using iterator_category =
56 : std::bidirectional_iterator_tag;
57 :
58 2 : iterator() = default;
59 :
60 : iterator(iterator const&) = default;
61 :
62 : iterator&
63 : operator=(iterator const&) = default;
64 :
65 : BOOST_URL_DECL
66 : reference
67 : operator*() const noexcept;
68 :
69 : iterator&
70 4835 : operator++() noexcept
71 : {
72 4835 : BOOST_ASSERT(pos_ != nullptr);
73 4835 : if (*pos_ != '%')
74 4538 : ++pos_;
75 : else
76 297 : pos_ += 3;
77 4835 : return *this;
78 : }
79 :
80 : iterator&
81 1182 : operator--() noexcept
82 : {
83 1182 : BOOST_ASSERT(pos_ != begin_);
84 1182 : if (pos_ - begin_ < 3 ||
85 679 : pos_[-3] != '%')
86 1130 : --pos_;
87 : else
88 52 : pos_ -= 3;
89 1182 : return *this;
90 : }
91 :
92 : iterator
93 4668 : operator++(int) noexcept
94 : {
95 4668 : auto tmp = *this;
96 4668 : ++*this;
97 4668 : return tmp;
98 : }
99 :
100 : iterator
101 : operator--(int) noexcept
102 : {
103 : auto tmp = *this;
104 : --*this;
105 : return tmp;
106 : }
107 :
108 : char const*
109 7 : base()
110 : {
111 7 : return pos_;
112 : }
113 :
114 : bool
115 2992 : operator==(
116 : iterator const& other) const noexcept
117 : {
118 2992 : return pos_ == other.pos_;
119 : }
120 :
121 : bool
122 1962 : operator!=(
123 : iterator const& other) const noexcept
124 : {
125 1962 : return !(*this == other);
126 : }
127 : };
128 :
129 : //------------------------------------------------
130 :
131 : inline
132 : auto
133 6356 : decode_view::
134 : begin() const noexcept ->
135 : const_iterator
136 : {
137 6356 : return {p_, space_as_plus_};
138 : }
139 :
140 : inline
141 : auto
142 885 : decode_view::
143 : end() const noexcept ->
144 : const_iterator
145 : {
146 885 : return {p_, n_, space_as_plus_};
147 : }
148 :
149 : inline
150 : auto
151 3 : decode_view::
152 : front() const noexcept ->
153 : const_reference
154 : {
155 3 : BOOST_ASSERT( !empty() );
156 3 : return *begin();
157 : }
158 :
159 : inline
160 : auto
161 3 : decode_view::
162 : back() const noexcept ->
163 : const_reference
164 : {
165 3 : BOOST_ASSERT( !empty() );
166 3 : return *--end();
167 : }
168 :
169 : namespace detail {
170 :
171 : template <class T>
172 : BOOST_CXX14_CONSTEXPR
173 : int
174 3246 : decoded_strcmp(decode_view s0, T s1)
175 : {
176 3246 : auto const n0 = s0.size();
177 3246 : auto const n1 = s1.size();
178 3246 : auto n = (std::min)(n0, n1);
179 3246 : auto it0 = s0.begin();
180 3246 : auto it1 = s1.begin();
181 5157 : while (n--)
182 : {
183 4226 : const char c0 = *it0++;
184 4226 : const char c1 = *it1++;
185 4226 : if (c0 == c1)
186 1911 : continue;
187 2315 : return 1 - 2 * (static_cast<unsigned char>(c0)
188 4630 : < static_cast<unsigned char>(c1));
189 : }
190 931 : return 1 - (n0 == n1) - 2 * (n0 < n1);
191 : }
192 :
193 : } // detail
194 :
195 :
196 : #if defined(BOOST_NO_CXX14_CONSTEXPR)
197 : inline
198 : #else
199 : BOOST_CXX14_CONSTEXPR
200 : #endif
201 : int
202 2930 : decode_view::
203 : compare(core::string_view other) const noexcept
204 : {
205 2930 : return detail::decoded_strcmp(*this, other);
206 : }
207 :
208 : #if defined(BOOST_NO_CXX14_CONSTEXPR)
209 : inline
210 : #else
211 : BOOST_CXX14_CONSTEXPR
212 : #endif
213 : int
214 316 : decode_view::
215 : compare(decode_view other) const noexcept
216 : {
217 316 : return detail::decoded_strcmp(*this, other);
218 : }
219 :
220 : } // urls
221 : } // boost
222 :
223 : #endif
|