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