|
||||
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
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |