| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 |
- //
- // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
- // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
- //
- // Distributed under the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- //
- // Official repository: https://github.com/boostorg/url
- //
- #ifndef BOOST_URL_SEGMENTS_ENCODED_VIEW_HPP
- #define BOOST_URL_SEGMENTS_ENCODED_VIEW_HPP
- #include <boost/url/detail/config.hpp>
- #include <boost/url/error_types.hpp>
- #include <boost/url/segments_encoded_base.hpp>
- #include <boost/url/segments_view.hpp>
- #include <boost/core/detail/string_view.hpp>
- #include <iosfwd>
- #include <utility>
- namespace boost {
- namespace urls {
- /** A view representing path segments in a URL
- Objects of this type are used to interpret
- the path as a bidirectional view of segment
- strings.
- The view does not retain ownership of the
- elements and instead references the original
- character buffer. The caller is responsible
- for ensuring that the lifetime of the buffer
- extends until it is no longer referenced.
- @par Example
- @code
- url_view u( "/path/to/file.txt" );
- segments_encoded_view ps = u.encoded_segments();
- assert( ps.buffer().data() == u.buffer().data() );
- @endcode
- Strings produced when elements are returned
- have type @ref param_pct_view and represent
- encoded strings. Strings passed to member
- functions may contain percent escapes, and
- throw exceptions on invalid inputs.
- @par Iterator Invalidation
- Changes to the underlying character buffer
- can invalidate iterators which reference it.
- @see
- @ref segments_view,
- @ref segments_encoded_ref,
- @ref segments_ref.
- */
- class segments_encoded_view
- : public segments_encoded_base
- {
- friend class url_view_base;
- friend class segments_encoded_ref;
- segments_encoded_view(
- detail::path_ref const& ref) noexcept;
- public:
- /** Constructor
- Default-constructed segments have
- zero elements.
- @par Example
- @code
- segments_encoded_view ps;
- @endcode
- @par Effects
- @code
- return segments_encoded_view( "" );
- @endcode
- @par Complexity
- Constant.
- @par Exception Safety
- Throws nothing.
- */
- segments_encoded_view() = default;
- /** Constructor
- After construction, both views
- reference the same character buffer.
- Ownership is not transferred; the caller
- is responsible for ensuring the lifetime
- of the buffer extends until it is no
- longer referenced.
- @par Postconditions
- @code
- this->buffer().data() == other.buffer().data()
- @endcode
- @par Complexity
- Constant.
- @par Exception Safety
- Throws nothing
- */
- segments_encoded_view(
- segments_encoded_view const&) noexcept = default;
- /** Constructor
- This function constructs segments from
- a valid path string, which can contain
- percent escapes.
- Upon construction, the view references
- the character buffer pointed to by `s`.
- caller is responsible for ensuring
- that the lifetime of the buffer
- extends until the view is destroyed.
- @par Example
- @code
- segments_encoded_view ps( "/path/to/file.txt" );
- @endcode
- @par Effects
- @code
- return parse_path( s ).value();
- @endcode
- @par Postconditions
- @code
- this->buffer().data() == s.data()
- @endcode
- @par Complexity
- Linear in `s`.
- @par Exception Safety
- Exceptions thrown on invalid input.
- @throw system_error
- `s` contains an invalid path.
- @param s The string to parse.
- @par BNF
- @code
- path = [ "/" ] [ segment *( "/" segment ) ]
- segment = *pchar
- @endcode
- @par Specification
- @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
- >3.3. Path</a>
- */
- BOOST_URL_DECL
- segments_encoded_view(
- core::string_view s);
- /** Constructor
- This function creates a new @ref segments_encoded_view
- from a pair of iterators referring to
- elements of another encoded segments
- view. The resulting view references
- the same underlying character buffer
- as the original.
- The constructed view preserves the
- original absolute flag when `first`
- selects the first segment and otherwise
- produces an absolute subview: if the
- source path is relative and `first ==
- ps.begin()` the new view is relative,
- and in every other case the subview is
- absolute with the separator immediately
- preceding `*first` retained at the front.
- This ensures the underlying text can be
- reconstructed by concatenating the buffers
- of adjacent subviews.
- The caller is responsible for ensuring
- that the lifetime of the original buffer
- extends until the constructed view
- is no longer referenced.
- @par Example
- @code
- segments_encoded_view ps( "/path/to/file.txt" );
- segments_encoded_view sub(
- std::next(ps.begin()),
- ps.end());
- segments_encoded_view first_half(
- ps.begin(),
- std::next(ps.begin()));
- // sub represents "/to/file.txt"
- std::string combined(
- first_half.buffer().data(),
- first_half.buffer().size());
- combined.append(
- sub.buffer().data(),
- sub.buffer().size());
- BOOST_ASSERT(combined == ps.buffer());
- @endcode
- @par Preconditions
- The iterators must be valid and belong to
- the same @ref segments_encoded_view.
- @par Postconditions
- `sub.buffer()` references characters in the
- original `ps.buffer()`.
- @par Complexity
- Constant
- @par Exception Safety
- Throws nothing.
- @param first The beginning iterator.
- @param last The ending iterator.
- */
- BOOST_URL_DECL
- segments_encoded_view(
- iterator first,
- iterator last) noexcept;
- /** Assignment
- After assignment, both views
- reference the same underlying character
- buffer.
- Ownership is not transferred; the caller
- is responsible for ensuring the lifetime
- of the buffer extends until it is no
- longer referenced.
- @par Postconditions
- @code
- this->buffer().data() == other.buffer().data()
- @endcode
- @par Complexity
- Constant
- @par Exception Safety
- Throws nothing
- @param other The segments to copy.
- @return Reference to this object
- */
- segments_encoded_view&
- operator=(
- segments_encoded_view const& other) = default;
- /** Conversion
- This conversion returns a new view which
- references the same underlying character
- buffer, and whose iterators and members
- return ordinary strings with decoding
- applied to any percent escapes.
- Ownership is not transferred; the caller
- is responsible for ensuring the lifetime
- of the buffer extends until it is no
- longer referenced.
- @par Example
- @code
- segments_view ps = parse_path( "/path/to/file.txt" ).value();
- @endcode
- @par Postconditions
- @code
- segments_view( *this ).buffer().data() == this->buffer().data()
- @endcode
- @par Complexity
- Constant
- @par Exception Safety
- Throws nothing
- @return A view of the segments.
- */
- BOOST_URL_DECL
- operator
- segments_view() const noexcept;
- //--------------------------------------------
- BOOST_URL_DECL
- friend
- system::result<segments_encoded_view>
- parse_path(core::string_view s) noexcept;
- };
- } // urls
- } // boost
- #endif
|