Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:29

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_PARAM_HPP
0012 #define BOOST_URL_PARAM_HPP
0013 
0014 #include <boost/url/detail/config.hpp>
0015 #include <boost/url/detail/optional_string.hpp>
0016 #include <boost/url/pct_string_view.hpp>
0017 #include <cstddef>
0018 #include <string>
0019 
0020 namespace boost {
0021 namespace urls {
0022 
0023 #ifndef BOOST_URL_DOCS
0024 struct param_pct_view;
0025 struct param_view;
0026 #endif
0027 
0028 /** The type of no_value
0029 */
0030 struct no_value_t
0031 {
0032 };
0033 
0034 /** Constant indicating no value in a param
0035 */
0036 constexpr no_value_t no_value{};
0037 
0038 //------------------------------------------------
0039 
0040 /** A query parameter
0041 
0042     Objects of this type represent a single key
0043     and value pair in a query string where a key
0044     is always present and may be empty, while the
0045     presence of a value is indicated by
0046     @ref has_value equal to true.
0047     An empty value is distinct from no value.
0048 
0049     Depending on where the object was obtained,
0050     the strings may or may not contain percent
0051     escapes.
0052 
0053     For most usages, key comparisons are
0054     case-sensitive and duplicate keys in
0055     a query are possible. However, it is
0056     the authority that has final control
0057     over how the query is interpreted.
0058 
0059     @par BNF
0060     @code
0061     query-params    = query-param *( "&" query-param )
0062     query-param     = key [ "=" value ]
0063     key             = *qpchar
0064     value           = *( qpchar / "=" )
0065     @endcode
0066 
0067     @par Specification
0068     @li <a href="https://en.wikipedia.org/wiki/Query_string"
0069         >Query string (Wikipedia)</a>
0070 
0071     @see
0072         @ref param_view,
0073         @ref param_pct_view.
0074 */
0075 struct param
0076 {
0077     /** The key
0078 
0079         For most usages, key comparisons are
0080         case-sensitive and duplicate keys in
0081         a query are possible. However, it is
0082         the authority that has final control
0083         over how the query is interpreted.
0084     */
0085     std::string key;
0086 
0087     /** The value
0088 
0089         The presence of a value is indicated by
0090         @ref has_value equal to true.
0091         An empty value is distinct from no value.
0092     */
0093     std::string value;
0094 
0095     /** True if a value is present
0096 
0097         The presence of a value is indicated by
0098         `has_value == true`.
0099         An empty value is distinct from no value.
0100     */
0101     bool has_value = false;
0102 
0103     /** Constructor
0104 
0105         Default constructed query parameters
0106         have an empty key and no value.
0107 
0108         @par Example
0109         @code
0110         param qp;
0111         @endcode
0112 
0113         @par Postconditions
0114         @code
0115         this->key == "" && this->value == "" && this->has_value == false
0116         @endcode
0117 
0118         @par Complexity
0119         Constant.
0120 
0121         @par Exception Safety
0122         Throws nothing.
0123     */
0124     param() = default;
0125 
0126     /** Constructor
0127 
0128         Upon construction, this acquires
0129         ownership of the members of other
0130         via move construction. The moved
0131         from object is as if default
0132         constructed.
0133 
0134         @par Complexity
0135         Constant.
0136 
0137         @par Exception Safety
0138         Throws nothing.
0139 
0140         @par other The object to construct from.
0141     */
0142     param(param&& other) noexcept
0143         : key(std::move(other.key))
0144         , value(std::move(other.value))
0145         , has_value(other.has_value)
0146     {
0147     #ifdef BOOST_URL_COW_STRINGS
0148         // for copy-on-write std::string
0149         other.key.clear();
0150         other.value.clear();
0151     #endif
0152         other.has_value = false;
0153     }
0154 
0155     /** Constructor
0156 
0157         Upon construction, this becomes a copy
0158         of `other`.
0159 
0160         @par Postconditions
0161         @code
0162         this->key == other.key && this->value == other.value && this->has_value == other.has_value
0163         @endcode
0164 
0165         @par Complexity
0166         Linear in `other.key.size() + other.value.size()`.
0167 
0168         @par Exception Safety
0169         Calls to allocate may throw.
0170 
0171         @par other The object to construct from.
0172     */
0173     param(param const& other) = default;
0174 
0175     /** Assignment
0176 
0177         Upon assignment, this acquires
0178         ownership of the members of other
0179         via move assignment. The moved
0180         from object is as if default
0181         constructed.
0182 
0183         @par Complexity
0184         Constant.
0185 
0186         @par Exception Safety
0187         Throws nothing.
0188 
0189         @par other The object to assign from.
0190     */
0191     param&
0192     operator=(param&& other) noexcept
0193     {
0194         key = std::move(other.key);
0195         value = std::move(other.value);
0196         has_value = other.has_value;
0197     #ifdef BOOST_URL_COW_STRINGS
0198         // for copy-on-write std::string
0199         other.key.clear();
0200         other.value.clear();
0201     #endif
0202         other.has_value = false;
0203         return *this;
0204     }
0205 
0206     /** Assignment
0207 
0208         Upon assignment, this becomes a copy
0209         of `other`.
0210 
0211         @par Postconditions
0212         @code
0213         this->key == other.key && this->value == other.value && this->has_value == other.has_value
0214         @endcode
0215 
0216         @par Complexity
0217         Linear in `other.key.size() + other.value.size()`.
0218 
0219         @par Exception Safety
0220         Calls to allocate may throw.
0221 
0222         @par other The object to assign from.
0223     */
0224     param& operator=(
0225         param const&) = default;
0226 
0227     //--------------------------------------------
0228 
0229     /** Constructor
0230 
0231         This constructs a parameter with a key
0232         and value.
0233 
0234         No validation is performed on the strings.
0235         Ownership of the key and value is acquired
0236         by making copies.
0237 
0238         @par Example
0239         @code
0240         param qp( "key", "value" );
0241         @endcode
0242 
0243         @code
0244         param qp( "key", optional<core::string_view>("value") );
0245         @endcode
0246 
0247         @code
0248         param qp( "key", boost::none );
0249         @endcode
0250 
0251         @code
0252         param qp( "key", nullptr );
0253         @endcode
0254 
0255         @code
0256         param qp( "key", no_value );
0257         @endcode
0258 
0259         @par Postconditions
0260         @code
0261         this->key == key && this->value == value && this->has_value == true
0262         @endcode
0263 
0264         @par Complexity
0265         Linear in `key.size() + value.size()`.
0266 
0267         @par Exception Safety
0268         Calls to allocate may throw.
0269 
0270         @tparam OptionalString An optional string
0271         type, such as `core::string_view`,
0272         `std::nullptr`, @ref no_value_t, or
0273         `optional<core::string_view>`.
0274 
0275         @param key, value The key and value to set.
0276     */
0277     template <class OptionalString>
0278     param(
0279         core::string_view key,
0280         OptionalString const& value)
0281         : param(key, detail::get_optional_string(value))
0282     {
0283     }
0284 
0285     /** Assignment
0286 
0287         The members of `other` are copied,
0288         re-using already existing string capacity.
0289 
0290         @par Postconditions
0291         @code
0292         this->key == other.key && this->value == other.value && this->has_value == other.has_value
0293         @endcode
0294 
0295         @par Complexity
0296         Linear in `other.key.size() + other.value.size()`.
0297 
0298         @par Exception Safety
0299         Calls to allocate may throw.
0300 
0301         @param other The parameter to copy.
0302     */
0303     param&
0304     operator=(param_view const& other);
0305 
0306     /** Assignment
0307 
0308         The members of `other` are copied,
0309         re-using already existing string capacity.
0310 
0311         @par Postconditions
0312         @code
0313         this->key == other.key && this->value == other.value && this->has_value == other.has_value
0314         @endcode
0315 
0316         @par Complexity
0317         Linear in `other.key.size() + other.value.size()`.
0318 
0319         @par Exception Safety
0320         Calls to allocate may throw.
0321 
0322         @param other The parameter to copy.
0323     */
0324     param&
0325     operator=(param_pct_view const& other);
0326 
0327 #ifndef BOOST_URL_DOCS
0328     // arrow support
0329     param const*
0330     operator->() const noexcept
0331     {
0332         return this;
0333     }
0334 
0335     // aggregate construction
0336     param(
0337         core::string_view key,
0338         core::string_view value,
0339         bool has_value) noexcept
0340         : key(key)
0341         , value(has_value
0342             ? value
0343             : core::string_view())
0344         , has_value(has_value)
0345     {
0346     }
0347 #endif
0348 
0349 private:
0350     param(
0351         core::string_view key,
0352         detail::optional_string const& value)
0353         : param(key, value.s, value.b)
0354     {
0355     }
0356 };
0357 
0358 //------------------------------------------------
0359 
0360 /** A query parameter
0361 
0362     Objects of this type represent a single key
0363     and value pair in a query string where a key
0364     is always present and may be empty, while the
0365     presence of a value is indicated by
0366     @ref has_value equal to true.
0367     An empty value is distinct from no value.
0368 
0369     Depending on where the object was obtained,
0370     the strings may or may not contain percent
0371     escapes.
0372 
0373     For most usages, key comparisons are
0374     case-sensitive and duplicate keys in
0375     a query are possible. However, it is
0376     the authority that has final control
0377     over how the query is interpreted.
0378 
0379     <br>
0380 
0381     Keys and values in this object reference
0382     external character buffers.
0383     Ownership of the buffers is not transferred;
0384     the caller is responsible for ensuring that
0385     the assigned buffers remain valid until
0386     they are no longer referenced.
0387 
0388     @par BNF
0389     @code
0390     query-params    = query-param *( "&" query-param )
0391     query-param     = key [ "=" value ]
0392     key             = *qpchar
0393     value           = *( qpchar / "=" )
0394     @endcode
0395 
0396     @par Specification
0397     @li <a href="https://en.wikipedia.org/wiki/Query_string"
0398         >Query string (Wikipedia)</a>
0399 
0400     @see
0401         @ref param,
0402         @ref param_pct_view.
0403 */
0404 struct param_view
0405 {
0406     /** The key
0407 
0408         For most usages, key comparisons are
0409         case-sensitive and duplicate keys in
0410         a query are possible. However, it is
0411         the authority that has final control
0412         over how the query is interpreted.
0413     */
0414     core::string_view key;
0415 
0416     /** The value
0417 
0418         The presence of a value is indicated by
0419         @ref has_value equal to true.
0420         An empty value is distinct from no value.
0421     */
0422     core::string_view value;
0423 
0424     /** True if a value is present
0425 
0426         The presence of a value is indicated by
0427         `has_value == true`.
0428         An empty value is distinct from no value.
0429     */
0430     bool has_value = false;
0431 
0432     //--------------------------------------------
0433 
0434     /** Constructor
0435 
0436         Default constructed query parameters
0437         have an empty key and no value.
0438 
0439         @par Example
0440         @code
0441         param_view qp;
0442         @endcode
0443 
0444         @par Postconditions
0445         @code
0446         this->key == "" && this->value == "" && this->has_value == false
0447         @endcode
0448 
0449         @par Complexity
0450         Constant.
0451 
0452         @par Exception Safety
0453         Throws nothing.
0454     */
0455     param_view() = default;
0456 
0457     /** Constructor
0458 
0459         This constructs a parameter with a key
0460         and value.
0461         No validation is performed on the strings.
0462         The new key and value reference
0463         the same corresponding underlying
0464         character buffers.
0465         Ownership of the buffers is not transferred;
0466         the caller is responsible for ensuring that
0467         the assigned buffers remain valid until
0468         they are no longer referenced.
0469 
0470         @par Example
0471         @code
0472         param_view qp( "key", "value" );
0473         @endcode
0474 
0475         @par Postconditions
0476         @code
0477         this->key.data() == key.data() && this->value.data() == value.data() && this->has_value == true
0478         @endcode
0479 
0480         @par Complexity
0481         Constant.
0482 
0483         @par Exception Safety
0484         Throws nothing.
0485 
0486         @tparam OptionalString An optional string
0487         type, such as `core::string_view`,
0488         `std::nullptr`, @ref no_value_t, or
0489         `optional<core::string_view>`.
0490 
0491         @param key, value The key and value to set.
0492     */
0493     template <class OptionalString>
0494     param_view(
0495         core::string_view key,
0496         OptionalString const& value) noexcept
0497         : param_view(key, detail::get_optional_string(value))
0498     {
0499     }
0500 
0501     /** Constructor
0502 
0503         This function constructs a param
0504         which references the character buffers
0505         representing the key and value in another
0506         container.
0507         Ownership of the buffers is not transferred;
0508         the caller is responsible for ensuring that
0509         the assigned buffers remain valid until
0510         they are no longer referenced.
0511 
0512         @par Example
0513         @code
0514         param qp( "key", "value" );
0515         param_view qpv( qp );
0516         @endcode
0517 
0518         @par Postconditions
0519         @code
0520         this->key == key && this->value == value && this->has_value == other.has_value
0521         @endcode
0522 
0523         @par Complexity
0524         Constant.
0525 
0526         @par Exception Safety
0527         Throws nothing.
0528 
0529         @param other The param to reference
0530     */
0531     param_view(
0532         param const& other) noexcept
0533         : param_view(
0534             other.key,
0535             other.value,
0536             other.has_value)
0537     {
0538     }
0539 
0540     /** Conversion
0541 
0542         This function performs a conversion from
0543         a reference-like query parameter to one
0544         retaining ownership of the strings by
0545         making a copy.
0546         No validation is performed on the strings.
0547 
0548         @par Complexity
0549         Linear in `this->key.size() + this->value.size()`.
0550 
0551         @par Exception Safety
0552         Calls to allocate may throw.
0553     */
0554     explicit
0555     operator
0556     param()
0557     {
0558         return { key, value, has_value };
0559     }
0560 
0561 #ifndef BOOST_URL_DOCS
0562     // arrow support
0563     param_view const*
0564     operator->() const noexcept
0565     {
0566         return this;
0567     }
0568 
0569     // aggregate construction
0570     param_view(
0571         core::string_view key_,
0572         core::string_view value_,
0573         bool has_value_) noexcept
0574         : key(key_)
0575         , value(has_value_
0576             ? value_
0577             : core::string_view())
0578         , has_value(has_value_)
0579     {
0580     }
0581 #endif
0582 
0583 private:
0584     param_view(
0585         core::string_view key,
0586         detail::optional_string const& value)
0587         : param_view(key, value.s, value.b)
0588     {
0589     }
0590 };
0591 
0592 //------------------------------------------------
0593 
0594 /** A query parameter
0595 
0596     Objects of this type represent a single key
0597     and value pair in a query string where a key
0598     is always present and may be empty, while the
0599     presence of a value is indicated by
0600     @ref has_value equal to true.
0601     An empty value is distinct from no value.
0602 
0603     The strings may have percent escapes, and
0604     offer an additional invariant: they never
0605     contain an invalid percent-encoding.
0606 
0607     For most usages, key comparisons are
0608     case-sensitive and duplicate keys in
0609     a query are possible. However, it is
0610     the authority that has final control
0611     over how the query is interpreted.
0612 
0613     <br>
0614 
0615     Keys and values in this object reference
0616     external character buffers.
0617     Ownership of the buffers is not transferred;
0618     the caller is responsible for ensuring that
0619     the assigned buffers remain valid until
0620     they are no longer referenced.
0621 
0622     @par BNF
0623     @code
0624     query-params    = query-param *( "&" query-param )
0625     query-param     = key [ "=" value ]
0626     key             = *qpchar
0627     value           = *( qpchar / "=" )
0628     @endcode
0629 
0630     @par Specification
0631     @li <a href="https://en.wikipedia.org/wiki/Query_string"
0632         >Query string (Wikipedia)</a>
0633 
0634     @see
0635         @ref param,
0636         @ref param_view.
0637 */
0638 struct param_pct_view
0639 {
0640     /** The key
0641 
0642         For most usages, key comparisons are
0643         case-sensitive and duplicate keys in
0644         a query are possible. However, it is
0645         the authority that has final control
0646         over how the query is interpreted.
0647     */
0648     pct_string_view key;
0649 
0650     /** The value
0651 
0652         The presence of a value is indicated by
0653         @ref has_value equal to true.
0654         An empty value is distinct from no value.
0655     */
0656     pct_string_view value;
0657 
0658     /** True if a value is present
0659 
0660         The presence of a value is indicated by
0661         `has_value == true`.
0662         An empty value is distinct from no value.
0663     */
0664     bool has_value = false;
0665 
0666     //--------------------------------------------
0667 
0668     /** Constructor
0669 
0670         Default constructed query parameters
0671         have an empty key and no value.
0672 
0673         @par Example
0674         @code
0675         param_pct_view qp;
0676         @endcode
0677 
0678         @par Postconditions
0679         @code
0680         this->key == "" && this->value == "" && this->has_value == false
0681         @endcode
0682 
0683         @par Complexity
0684         Constant.
0685 
0686         @par Exception Safety
0687         Throws nothing.
0688     */
0689     param_pct_view() = default;
0690 
0691     /** Constructor
0692 
0693         This constructs a parameter with a key
0694         and value, which may both contain percent
0695         escapes.
0696         The new key and value reference
0697         the same corresponding underlying
0698         character buffers.
0699         Ownership of the buffers is not transferred;
0700         the caller is responsible for ensuring that
0701         the assigned buffers remain valid until
0702         they are no longer referenced.
0703 
0704         @par Example
0705         @code
0706         param_pct_view qp( "key", "value" );
0707         @endcode
0708 
0709         @par Postconditions
0710         @code
0711         this->key.data() == key.data() && this->value.data() == value.data() && this->has_value == true
0712         @endcode
0713 
0714         @par Complexity
0715         Linear in `key.size() + value.size()`.
0716 
0717         @par Exception Safety
0718         Exceptions thrown on invalid input.
0719 
0720         @throw system_error
0721         `key` or `value` contains an invalid percent-encoding.
0722 
0723         @param key, value The key and value to set.
0724     */
0725     param_pct_view(
0726         pct_string_view key,
0727         pct_string_view value) noexcept
0728         : key(key)
0729         , value(value)
0730         , has_value(true)
0731     {
0732     }
0733 
0734     /** Constructor
0735 
0736         This constructs a parameter with a key
0737         and optional value, which may both
0738         contain percent escapes.
0739 
0740         The new key and value reference
0741         the same corresponding underlying
0742         character buffers.
0743 
0744         Ownership of the buffers is not transferred;
0745         the caller is responsible for ensuring that
0746         the assigned buffers remain valid until
0747         they are no longer referenced.
0748 
0749         @par Example
0750         @code
0751         param_pct_view qp( "key", optional<core::string_view>("value") );
0752         @endcode
0753 
0754         @par Postconditions
0755         @code
0756         this->key.data() == key.data() && this->value->data() == value->data() && this->has_value == true
0757         @endcode
0758 
0759         @par Complexity
0760         Linear in `key.size() + value->size()`.
0761 
0762         @par Exception Safety
0763         Exceptions thrown on invalid input.
0764 
0765         @throw system_error
0766         `key` or `value` contains an invalid percent-encoding.
0767 
0768         @tparam OptionalString An optional
0769         `core::string_view` type, such as
0770         `boost::optional<core::string_view>` or
0771         `std::optional<core::string_view>`.
0772 
0773         @param key, value The key and value to set.
0774     */
0775     template <class OptionalString>
0776     param_pct_view(
0777         pct_string_view key,
0778         OptionalString const& value)
0779         : param_pct_view(key, detail::get_optional_string(value))
0780     {
0781     }
0782 
0783     /** Construction
0784 
0785         This converts a param which may
0786         contain unvalidated percent-escapes into
0787         a param whose key and value are
0788         guaranteed to contain strings with no
0789         invalid percent-escapes, otherwise
0790         an exception is thrown.
0791 
0792         The new key and value reference
0793         the same corresponding underlying
0794         character buffers.
0795         Ownership of the buffers is not transferred;
0796         the caller is responsible for ensuring that
0797         the assigned buffers remain valid until
0798         they are no longer referenced.
0799 
0800         @par Example
0801         @code
0802         param_pct_view qp( param_view( "key", "value" ) );
0803         @endcode
0804 
0805         @par Complexity
0806         Linear in `key.size() + value.size()`.
0807 
0808         @par Exception Safety
0809         Exceptions thrown on invalid input.
0810 
0811         @throw system_error
0812         `key` or `value` contains an invalid percent escape.
0813 
0814         @param p The param to construct from.
0815     */
0816     explicit
0817     param_pct_view(
0818         param_view const& p)
0819         : key(p.key)
0820         , value(p.has_value
0821             ? pct_string_view(p.value)
0822             : pct_string_view())
0823         , has_value(p.has_value)
0824     {
0825     }
0826 
0827     /** Conversion
0828 
0829         This function performs a conversion from
0830         a reference-like query parameter to one
0831         retaining ownership of the strings by
0832         making a copy.
0833 
0834         @par Complexity
0835         Linear in `this->key.size() + this->value.size()`.
0836 
0837         @par Exception Safety
0838         Calls to allocate may throw.
0839     */
0840     explicit
0841     operator
0842     param() const
0843     {
0844         return param(
0845             static_cast<std::string>(key),
0846             static_cast<std::string>(value),
0847             has_value);
0848     }
0849 
0850     operator
0851     param_view() const noexcept
0852     {
0853         return param_view(
0854             key, value, has_value);
0855     }
0856 
0857 #ifndef BOOST_URL_DOCS
0858     // arrow support
0859     param_pct_view const*
0860     operator->() const noexcept
0861     {
0862         return this;
0863     }
0864 
0865     // aggregate construction
0866     param_pct_view(
0867         pct_string_view key,
0868         pct_string_view value,
0869         bool has_value) noexcept
0870         : key(key)
0871         , value(has_value
0872             ? value
0873             : pct_string_view())
0874         , has_value(has_value)
0875     {
0876     }
0877 #endif
0878 
0879 private:
0880     param_pct_view(
0881         pct_string_view key,
0882         detail::optional_string const& value)
0883         : param_pct_view(key, value.s, value.b)
0884     {
0885     }
0886 };
0887 
0888 //------------------------------------------------
0889 
0890 inline
0891 param&
0892 param::
0893 operator=(
0894     param_view const& other)
0895 {
0896     // VFALCO operator= assignment
0897     // causes a loss of original capacity:
0898     // https://godbolt.org/z/nYef8445K
0899     //
0900     // key = other.key;
0901     // value = other.value;
0902 
0903     // preserve capacity
0904     key.assign(
0905         other.key.data(),
0906         other.key.size());
0907     value.assign(
0908         other.value.data(),
0909         other.value.size());
0910     has_value = other.has_value;
0911     return *this;
0912 }
0913 
0914 inline
0915 param&
0916 param::
0917 operator=(
0918     param_pct_view const& other)
0919 {
0920     // preserve capacity
0921     key.assign(
0922         other.key.data(),
0923         other.key.size());
0924     value.assign(
0925         other.value.data(),
0926         other.value.size());
0927     has_value = other.has_value;
0928     return *this;
0929 }
0930 
0931 } // urls
0932 } // boost
0933 
0934 #endif