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