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