Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:52:42

0001 //
0002 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
0003 // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
0004 //
0005 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0006 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 // Official repository: https://github.com/boostorg/url
0009 //
0010 
0011 #ifndef BOOST_URL_PARAMS_ENCODED_BASE_HPP
0012 #define BOOST_URL_PARAMS_ENCODED_BASE_HPP
0013 
0014 #include <boost/url/detail/config.hpp>
0015 #include <boost/url/ignore_case.hpp>
0016 #include <boost/url/param.hpp>
0017 #include <boost/url/detail/params_iter_impl.hpp>
0018 #include <boost/url/detail/url_impl.hpp>
0019 #include <iosfwd>
0020 
0021 namespace boost {
0022 namespace urls {
0023 
0024 /** Common functionality for containers
0025 
0026     This base class is used by the library
0027     to provide common member functions for
0028     containers. This cannot be instantiated
0029     directly; Instead, use one of the
0030     containers or functions:
0031 
0032     @par Containers
0033     @li @ref params_ref
0034     @li @ref params_view
0035     @li @ref params_encoded_ref
0036     @li @ref params_encoded_view
0037 */
0038 class BOOST_URL_DECL params_encoded_base
0039 {
0040     friend class url_view_base;
0041     friend class params_encoded_ref;
0042     friend class params_encoded_view;
0043 
0044     detail::query_ref ref_;
0045 
0046     params_encoded_base() = default;
0047     params_encoded_base(
0048         params_encoded_base const&) = default;
0049     params_encoded_base& operator=(
0050         params_encoded_base const&) = default;
0051     params_encoded_base(
0052         detail::query_ref const& ref) noexcept;
0053 
0054 public:
0055     /** A Bidirectional iterator to a query parameter
0056 
0057         Objects of this type allow iteration
0058         through the parameters in the query.
0059         Strings returned by iterators may
0060         contain percent escapes.
0061         The values returned are read-only;
0062         changes to parameters must be made
0063         through the container instead, if the
0064         container supports modification.
0065 
0066         <br>
0067 
0068         The strings produced when iterators
0069         are dereferenced refer to the underlying
0070         character buffer.
0071         Ownership is not transferred; the caller
0072         is responsible for ensuring that the
0073         lifetime of the buffer extends until
0074         it is no longer referenced by any
0075         container or iterator.
0076     */
0077 #ifdef BOOST_URL_DOCS
0078     using iterator = __see_below__;
0079 #else
0080 
0081     /** A Bidirectional iterator to a query parameter
0082 
0083         Objects of this type allow iteration
0084         through the parameters in the query.
0085         Strings returned by iterators may
0086         contain percent escapes.
0087         The values returned are read-only;
0088         changes to parameters must be made
0089         through the container instead, if the
0090         container supports modification.
0091 
0092         <br>
0093 
0094         The strings produced when iterators
0095         are dereferenced refer to the underlying
0096         character buffer.
0097         Ownership is not transferred; the caller
0098         is responsible for ensuring that the
0099         lifetime of the buffer extends until
0100         it is no longer referenced by any
0101         container or iterator.
0102     */
0103     class iterator;
0104 #endif
0105 
0106     /// @copydoc iterator
0107     using const_iterator = iterator;
0108 
0109     /** The value type
0110 
0111         Values of this type represent parameters
0112         whose strings retain unique ownership by
0113         making a copy.
0114 
0115         @par Example
0116         @code
0117         params_encoded_view::value_type qp( *url_view( "?first=John&last=Doe" ).params().find( "first" ) );
0118         @endcode
0119 
0120         @see
0121             @ref param.
0122     */
0123     using value_type = param;
0124 
0125     /** The reference type
0126 
0127         This is the type of value returned when
0128         iterators of the view are dereferenced.
0129 
0130         @see
0131             @ref param_view.
0132     */
0133     using reference = param_pct_view;
0134 
0135     /// @copydoc reference
0136     using const_reference = param_pct_view;
0137 
0138     /** An unsigned integer type to represent sizes.
0139     */
0140     using size_type = std::size_t;
0141 
0142     /** A signed integer type used to represent differences.
0143     */
0144     using difference_type = std::ptrdiff_t;
0145 
0146     //--------------------------------------------
0147     //
0148     // Observers
0149     //
0150     //--------------------------------------------
0151 
0152     /** Return the maximum number of characters possible
0153 
0154         This represents the largest number of
0155         characters that are possible in a path,
0156         not including any null terminator.
0157 
0158         @par Exception Safety
0159         Throws nothing.
0160 
0161         @return The maximum number of characters possible.
0162     */
0163     static
0164     constexpr
0165     std::size_t
0166     max_size() noexcept
0167     {
0168         return BOOST_URL_MAX_SIZE;
0169     }
0170 
0171     /** Return the query corresponding to these params
0172 
0173         This function returns the query string
0174         referenced by the container.
0175         The returned string may contain
0176         percent escapes.
0177 
0178         @par Example
0179         @code
0180         assert( url_view( "?first=John&last=Doe" ).encoded_params().buffer() == "first=John&last=Doe" );
0181         @endcode
0182 
0183         @par Complexity
0184         Constant.
0185 
0186         @par Exception Safety
0187         Throws nothing.
0188 
0189         @par BNF
0190         @code
0191         query-params    = query-param *( "&" query-param )
0192         query-param     = key [ "=" value ]
0193         key             = *qpchar
0194         value           = *( qpchar / "=" )
0195         @endcode
0196 
0197         @par Specification
0198         @li <a href="https://en.wikipedia.org/wiki/Query_string"
0199             >Query string (Wikipedia)</a>
0200 
0201         @return The query string.
0202 
0203     */
0204     pct_string_view
0205     buffer() const noexcept;
0206 
0207     /** Return true if there are no params
0208 
0209         @par Example
0210         @code
0211         assert( ! url_view( "?key=value" ).encoded_params().empty() );
0212         @endcode
0213 
0214         @par Complexity
0215         Constant.
0216 
0217         @par Exception Safety
0218         Throws nothing.
0219 
0220         @return `true` if there are no params.
0221     */
0222     bool
0223     empty() const noexcept;
0224 
0225     /** Return the number of params
0226     
0227         @par Example
0228         @code
0229         assert( url_view( "?key=value").encoded_params().size() == 1 );
0230         @endcode
0231 
0232         @par Complexity
0233         Constant.
0234 
0235         @par Exception Safety
0236         Throws nothing.
0237 
0238         @return The number of params.
0239     */
0240     std::size_t
0241     size() const noexcept;
0242 
0243     /** Return an iterator to the beginning
0244 
0245         @par Complexity
0246         Linear in the size of the first param.
0247 
0248         @par Exception Safety
0249         Throws nothing.
0250 
0251         @return An iterator to the beginning.
0252     */
0253     iterator
0254     begin() const noexcept;
0255 
0256     /** Return an iterator to the end
0257 
0258         @par Complexity
0259         Constant.
0260 
0261         @par Exception Safety
0262         Throws nothing.
0263 
0264         @return An iterator to the end.
0265     */
0266     iterator
0267     end() const noexcept;
0268 
0269     //--------------------------------------------
0270 
0271     /** Return true if a matching key exists
0272 
0273         This function examines the parameters
0274         in the container to find a match for
0275         the specified key,
0276         which may contain percent escapes.
0277         The comparison is performed as if all
0278         escaped characters were decoded first.
0279 
0280         @par Example
0281         @code
0282         assert( url_view( "?first=John&last=Doe" ).encoded_params().contains( "first" ) );
0283         @endcode
0284 
0285         @par Complexity
0286         Linear in `this->buffer().size()`.
0287 
0288         @par Exception Safety
0289         Exceptions thrown on invalid input.
0290 
0291         @throw system_error
0292         `key` contains an invalid percent-encoding.
0293 
0294         @param key The key to match.
0295         By default, a case-sensitive
0296         comparison is used.
0297 
0298         @param ic An optional parameter. If
0299         the value @ref ignore_case is passed
0300         here, the comparison is
0301         case-insensitive.
0302 
0303         @return `true` if a matching key exists.
0304     */
0305     bool
0306     contains(
0307         pct_string_view key,
0308         ignore_case_param ic = {}) const noexcept;
0309 
0310     /** Return the number of matching keys
0311 
0312         This function examines the parameters
0313         in the container to find the number of
0314         matches for the specified key,
0315         which may contain percent escapes.
0316         The comparison is performed as if all
0317         escaped characters were decoded first.
0318 
0319         @par Example
0320         @code
0321         assert( url_view( "?first=John&last=Doe" ).encoded_params().count( "first" ) == 1 );
0322         @endcode
0323 
0324         @par Complexity
0325         Linear in `this->buffer().size()`.
0326 
0327         @par Exception Safety
0328         Exceptions thrown on invalid input.
0329 
0330         @throw system_error
0331         `key` contains an invalid percent-encoding.
0332 
0333         @param key The key to match.
0334         By default, a case-sensitive
0335         comparison is used.
0336 
0337         @param ic An optional parameter. If
0338         the value @ref ignore_case is passed
0339         here, the comparison is
0340         case-insensitive.
0341 
0342         @return The number of matching keys.
0343     */
0344     std::size_t
0345     count(
0346         pct_string_view key,
0347         ignore_case_param ic = {}) const noexcept;
0348 
0349     /** Find a matching key
0350 
0351         This function examines the parameters
0352         in the container to find a match for
0353         the specified key,
0354         which may contain percent escapes.
0355         The comparison is performed as if all
0356         escaped characters were decoded first.
0357 
0358         <br>
0359 
0360         The search starts from the first param
0361         and proceeds forward until either the
0362         key is found or the end of the range is
0363         reached, in which case `end()` is
0364         returned.
0365 
0366         @par Example
0367         @code
0368         assert( url_view( "?first=John&last=Doe" ).encoded_params().find( "First", ignore_case )->value == "John" );
0369         @endcode
0370 
0371         @par Effects
0372         @code
0373         return this->find( this->begin(), key, ic );
0374         @endcode
0375 
0376         @par Complexity
0377         Linear in `this->buffer().size()`.
0378 
0379         @par Exception Safety
0380         Exceptions thrown on invalid input.
0381 
0382         @throw system_error
0383         `key` contains an invalid percent-encoding.
0384 
0385         @return an iterator to the param
0386 
0387         @param key The key to match.
0388         By default, a case-sensitive
0389         comparison is used.
0390 
0391         @param ic An optional parameter. If
0392         the value @ref ignore_case is passed
0393         here, the comparison is
0394         case-insensitive.
0395     */
0396     iterator
0397     find(
0398         pct_string_view key,
0399         ignore_case_param ic = {}) const noexcept;
0400 
0401     /** Find a matching key
0402 
0403         This function examines the parameters
0404         in the container to find a match for
0405         the specified key, which may contain
0406         percent escapes.
0407         The comparison is performed as if all
0408         escaped characters were decoded first.
0409 
0410         <br>
0411 
0412         The search starts at `from`
0413         and proceeds forward until either the
0414         key is found or the end of the range is
0415         reached, in which case `end()` is
0416         returned.
0417 
0418         @par Example
0419         @code
0420         url_view u( "?First=John&Last=Doe" );
0421 
0422         assert( u.encoded_params().find( "first" ) != u.encoded_params().find( "first", ignore_case ) );
0423         @endcode
0424 
0425         @par Complexity
0426         Linear in `this->buffer().size()`.
0427 
0428         @par Exception Safety
0429         Exceptions thrown on invalid input.
0430 
0431         @throw system_error
0432         `key` contains an invalid percent-encoding.
0433 
0434         @return an iterator to the param
0435 
0436         @param from The position to begin the
0437             search from. This can be `end()`.
0438 
0439         @param key The key to match.
0440         By default, a case-sensitive
0441         comparison is used.
0442 
0443         @param ic An optional parameter. If
0444         the value @ref ignore_case is passed
0445         here, the comparison is
0446         case-insensitive.
0447     */
0448     iterator
0449     find(
0450         iterator from,
0451         pct_string_view key,
0452         ignore_case_param ic = {}) const noexcept;
0453 
0454     /** Find a matching key
0455     
0456         This function examines the parameters
0457         in the container to find a match for
0458         the specified key, which may contain
0459         percent escapes.
0460         The comparison is performed as if all
0461         escaped characters were decoded first.
0462 
0463         <br>
0464 
0465         The search starts from the last param
0466         and proceeds backwards until either the
0467         key is found or the beginning of the
0468         range is reached, in which case `end()`
0469         is returned.
0470 
0471         @par Example
0472         @code
0473         assert( url_view( "?first=John&last=Doe" ).encoded_params().find_last( "last" )->value == "Doe" );
0474         @endcode
0475 
0476         @par Complexity
0477         Linear in `this->buffer().size()`.
0478 
0479         @par Exception Safety
0480         Exceptions thrown on invalid input.
0481 
0482         @throw system_error
0483         `key` contains an invalid percent-encoding.
0484 
0485         @return an iterator to the param
0486 
0487         @param key The key to match.
0488         By default, a case-sensitive
0489         comparison is used.
0490 
0491         @param ic An optional parameter. If
0492         the value @ref ignore_case is passed
0493         here, the comparison is
0494         case-insensitive.
0495     */
0496     iterator
0497     find_last(
0498         pct_string_view key,
0499         ignore_case_param ic = {}) const noexcept;
0500 
0501     /** Find a matching key
0502     
0503         This function examines the parameters
0504         in the container to find a match for
0505         the specified key, which may contain
0506         percent escapes.
0507         The comparison is performed as if all
0508         escaped characters were decoded first.
0509 
0510         <br>
0511 
0512         The search starts prior to `before`
0513         and proceeds backwards until either the
0514         key is found or the beginning of the
0515         range is reached, in which case `end()`
0516         is returned.
0517 
0518         @par Example
0519         @code
0520         url_view u( "?First=John&Last=Doe" );
0521 
0522         assert( u.encoded_params().find_last( "last" ) != u.encoded_params().find_last( "last", ignore_case ) );
0523         @endcode
0524 
0525         @par Complexity
0526         Linear in `this->buffer().size()`.
0527 
0528         @return an iterator to the param
0529 
0530         @param before One past the position
0531         to begin the search from. This can
0532         be `end()`.
0533 
0534         @param key The key to match.
0535         By default, a case-sensitive
0536         comparison is used.
0537 
0538         @param ic An optional parameter. If
0539         the value @ref ignore_case is passed
0540         here, the comparison is
0541         case-insensitive.
0542     */
0543     iterator
0544     find_last(
0545         iterator before,
0546         pct_string_view key,
0547         ignore_case_param ic = {}) const noexcept;
0548 
0549 private:
0550     detail::params_iter_impl
0551     find_impl(
0552         detail::params_iter_impl,
0553         pct_string_view,
0554         ignore_case_param) const noexcept;
0555 
0556     detail::params_iter_impl
0557     find_last_impl(
0558         detail::params_iter_impl,
0559         pct_string_view,
0560         ignore_case_param) const noexcept;
0561 };
0562 
0563 //------------------------------------------------
0564 
0565 /** Format to an output stream
0566 
0567     Any percent-escapes are emitted as-is;
0568     no decoding is performed.
0569 
0570     @par Complexity
0571     Linear in `ps.buffer().size()`.
0572 
0573     @par Effects
0574     @code
0575     return os << ps.buffer();
0576     @endcode
0577 
0578     @param os The output stream to write to
0579     @param qp The params to write
0580     @return A reference to the output stream, for chaining
0581 */
0582 BOOST_URL_DECL
0583 std::ostream&
0584 operator<<(
0585     std::ostream& os,
0586     params_encoded_base const& qp);
0587 
0588 } // urls
0589 } // boost
0590 
0591 #include <boost/url/impl/params_encoded_base.hpp>
0592 
0593 #endif