Line data Source code
1 : //
2 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 : // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
4 : //
5 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 : //
8 : // Official repository: https://github.com/boostorg/url
9 : //
10 :
11 : #ifndef BOOST_URL_SEGMENTS_ENCODED_BASE_HPP
12 : #define BOOST_URL_SEGMENTS_ENCODED_BASE_HPP
13 :
14 : #include <boost/url/detail/config.hpp>
15 : #include <boost/url/ignore_case.hpp>
16 : #include <boost/url/pct_string_view.hpp>
17 : #include <boost/url/detail/url_impl.hpp>
18 : #include <iosfwd>
19 :
20 : namespace boost {
21 : namespace urls {
22 :
23 : /** Percent-encoded path segment helper base
24 :
25 : Implements the shared encoded-segment
26 : algorithms reused by @ref segments_encoded_view
27 : and @ref segments_encoded_ref. It is not
28 : intended to be instantiated directly; use
29 : one of those concrete containers instead.
30 :
31 : @par Containers
32 : @li @ref segments_ref
33 : @li @ref segments_view
34 : @li @ref segments_encoded_ref
35 : @li @ref segments_encoded_view
36 : */
37 : class BOOST_URL_DECL segments_encoded_base
38 : {
39 : detail::path_ref ref_;
40 :
41 : friend class url_view_base;
42 : friend class segments_encoded_ref;
43 : friend class segments_encoded_view;
44 :
45 : segments_encoded_base(
46 : detail::path_ref const& ref) noexcept;
47 1 : segments_encoded_base() = default;
48 : segments_encoded_base(
49 : segments_encoded_base const&) = default;
50 : segments_encoded_base& operator=(
51 : segments_encoded_base const&) = default;
52 :
53 : public:
54 : /** A Bidirectional iterator to a path segment
55 :
56 : Objects of this type allow iteration
57 : through the segments in the path.
58 : Strings returned by iterators may
59 : contain percent escapes.
60 : The values returned are read-only;
61 : changes to segments must be made
62 : through the container instead, if the
63 : container supports modification.
64 :
65 : <br>
66 :
67 : The strings produced when iterators
68 : are dereferenced refer to the underlying
69 : character buffer.
70 : Ownership is not transferred; the caller
71 : is responsible for ensuring that the
72 : lifetime of the buffer extends until
73 : it is no longer referenced by any
74 : container or iterator.
75 : */
76 : class iterator;
77 :
78 : /// @copydoc iterator
79 : using const_iterator = iterator;
80 :
81 : /** The value type
82 :
83 : Values of this type represent a segment
84 : where unique ownership is retained by
85 : making a copy.
86 :
87 : @par Example
88 : @code
89 : segments_encoded_base::value_type ps( url_view( "/path/to/file.txt" ).encoded_segments().back() );
90 : @endcode
91 : */
92 : using value_type = std::string;
93 :
94 : /** The reference type
95 :
96 : This is the type of value returned when
97 : iterators of the view are dereferenced.
98 : */
99 : using reference = pct_string_view;
100 :
101 : /// @copydoc reference
102 : using const_reference = pct_string_view;
103 :
104 : /** An unsigned integer type used to represent size.
105 : */
106 : using size_type = std::size_t;
107 :
108 : /** A signed integer type used to represent differences.
109 : */
110 : using difference_type = std::ptrdiff_t;
111 :
112 : //--------------------------------------------
113 : //
114 : // Observers
115 : //
116 : //--------------------------------------------
117 :
118 : /** Return the maximum number of characters possible
119 :
120 : This represents the largest number of
121 : characters that are possible in a path,
122 : not including any null terminator.
123 :
124 : @par Exception Safety
125 : Throws nothing.
126 :
127 : @return The maximum number of characters possible.
128 : */
129 : static
130 : constexpr
131 : std::size_t
132 : max_size() noexcept
133 : {
134 : return BOOST_URL_MAX_SIZE;
135 : }
136 :
137 : /** Return the referenced character buffer.
138 :
139 : This function returns the character
140 : buffer referenced by the view.
141 : The returned string may contain
142 : percent escapes.
143 :
144 : @par Example
145 : @code
146 : assert( url_view( "/path/to/file.txt" ).encoded_segments().buffer() == "/path/to/file.txt" );
147 : @endcode
148 :
149 : @par Complexity
150 : Constant.
151 :
152 : @par Exception Safety
153 : Throws nothing.
154 :
155 : @return A string view of the buffer.
156 : */
157 : pct_string_view
158 : buffer() const noexcept;
159 :
160 : /** Returns true if this references an absolute path.
161 :
162 : Absolute paths always start with a
163 : forward slash ('/').
164 :
165 : @par Example
166 : @code
167 : assert( url_view( "/path/to/file.txt" ).encoded_segments().is_absolute() == true );
168 : @endcode
169 :
170 : @par Complexity
171 : Constant.
172 :
173 : @par Exception Safety
174 : Throws nothing.
175 :
176 : @return `true` if the path is absolute, otherwise `false`.
177 : */
178 : bool
179 : is_absolute() const noexcept;
180 :
181 : /** Return true if there are no segments
182 :
183 : @par Example
184 : @code
185 : assert( ! url_view( "/index.htm" ).encoded_segments().empty() );
186 : @endcode
187 :
188 : @par Complexity
189 : Constant.
190 :
191 : @par Exception Safety
192 : Throws nothing.
193 :
194 : @return `true` if there are no segments, otherwise `false`.
195 : */
196 : bool
197 : empty() const noexcept;
198 :
199 : /** Return the number of segments
200 :
201 : @par Example
202 : @code
203 : assert( url_view( "/path/to/file.txt" ).encoded_segments().size() == 3 );
204 : @endcode
205 :
206 : @par Complexity
207 : Constant.
208 :
209 : @par Exception Safety
210 : Throws nothing.
211 :
212 : @return The number of segments.
213 : */
214 : std::size_t
215 : size() const noexcept;
216 :
217 : /** Return the first segment
218 :
219 : This function returns a string with the
220 : first segment of the path without any
221 : leading or trailing '/' separators.
222 : The returned string may contain
223 : percent escapes.
224 :
225 : @par Preconditions
226 : @code
227 : this->empty() == false
228 : @endcode
229 :
230 : @par Effects
231 : @code
232 : return *begin();
233 : @endcode
234 :
235 : @par Example
236 : @code
237 : assert( url_view( "/path/to/file.txt" ).encoded_segments().front() == "path" );
238 : @endcode
239 :
240 : @par Complexity
241 : Constant.
242 :
243 : @par Exception Safety
244 : Throws nothing.
245 :
246 : @return The first segment.
247 : */
248 : pct_string_view
249 : front() const noexcept;
250 :
251 : /** Return the last segment
252 :
253 : This function returns a string with the
254 : last segment of the path without any
255 : leading or trailing '/' separators.
256 : The returned string may contain
257 : percent escapes.
258 :
259 : @par Preconditions
260 : @code
261 : this->empty() == false
262 : @endcode
263 :
264 : @par Example
265 : @code
266 : assert( url_view( "/path/to/file.txt" ).encoded_segments().back() == "file.txt" );
267 : @endcode
268 :
269 : @par Preconditions
270 : @code
271 : this->empty() == false
272 : @endcode
273 :
274 : @par Effects
275 : @code
276 : return *--end();
277 : @endcode
278 :
279 : @par Complexity
280 : Constant.
281 :
282 : @par Exception Safety
283 : Throws nothing.
284 :
285 : @return The last segment.
286 : */
287 : pct_string_view
288 : back() const noexcept;
289 :
290 : /** Return an iterator to the beginning
291 :
292 : @par Complexity
293 : Linear in `this->front().size()` or
294 : constant if `this->empty()`.
295 :
296 : @par Exception Safety
297 : Throws nothing.
298 :
299 : @return An iterator to the first segment.
300 : */
301 : iterator
302 : begin() const noexcept;
303 :
304 : /** Return an iterator to the end
305 :
306 : @par Complexity
307 : Constant.
308 :
309 : @par Exception Safety
310 : Throws nothing.
311 :
312 : @return An iterator to one past the last segment.
313 : */
314 : iterator
315 : end() const noexcept;
316 : };
317 :
318 : //------------------------------------------------
319 :
320 : /** Format to an output stream
321 :
322 : Any percent-escapes are emitted as-is;
323 : no decoding is performed.
324 :
325 : @par Complexity
326 : Linear in `ps.buffer().size()`.
327 :
328 : @par Effects
329 : @code
330 : return os << ps.buffer();
331 : @endcode
332 :
333 : @param os The output stream to write to.
334 : @param ps The object to format.
335 : @return A reference to the output stream.
336 : */
337 : BOOST_URL_DECL
338 : std::ostream&
339 : operator<<(
340 : std::ostream& os,
341 : segments_encoded_base const& ps);
342 :
343 : } // urls
344 : } // boost
345 :
346 : #include <boost/url/impl/segments_encoded_base.hpp>
347 :
348 : #endif
|