From afb91bc384168ed912e991ae436b8e8bbbde7d89 Mon Sep 17 00:00:00 2001 From: alandefreitas Date: Wed, 24 Aug 2022 21:11:28 -0300 Subject: [PATCH] refactor decode/encode functions fix #448, fix #438 --- doc/qbk/0.main.qbk | 2 +- doc/qbk/2.0.quicklook.qbk | 10 +- doc/qbk/3.3.authority.qbk | 2 +- doc/qbk/4.5.rfc3986.qbk | 2 +- doc/qbk/5.2.MutableString.qbk | 4 +- doc/qbk/quickref.xml | 16 +- example/magnet/magnet.cpp | 40 +- include/boost/url.hpp | 5 +- include/boost/url/authority_view.hpp | 20 +- .../url/{pct_encoding.hpp => decode.hpp} | 344 ++++-------------- include/boost/url/decode_opts.hpp | 44 +++ .../{pct_encoded_view.hpp => decode_view.hpp} | 106 +++--- include/boost/url/detail/any_path_iter.hpp | 6 +- include/boost/url/detail/any_query_iter.hpp | 6 +- .../{pct_encoded_view.hpp => decode_view.hpp} | 10 +- .../boost/url/detail/impl/any_path_iter.ipp | 30 +- .../boost/url/detail/impl/any_query_iter.ipp | 47 ++- .../{pct_encoded_view.ipp => decode_view.ipp} | 14 +- include/boost/url/detail/impl/normalize.ipp | 14 +- .../url/detail/impl/remove_dot_segments.ipp | 6 +- .../detail/impl/segments_iterator_impl.ipp | 6 +- include/boost/url/detail/impl/url_impl.ipp | 12 +- .../url/detail/segments_iterator_impl.hpp | 6 +- include/boost/url/detail/url_impl.hpp | 10 +- include/boost/url/encode.hpp | 226 ++++++++++++ include/boost/url/encode_opts.hpp | 41 +++ include/boost/url/error.hpp | 2 +- include/boost/url/grammar/all_chars.hpp | 88 +++++ include/boost/url/grammar/not_empty_rule.hpp | 2 +- include/boost/url/grammar/tuple_rule.hpp | 6 +- include/boost/url/impl/decode.hpp | 160 ++++++++ .../url/impl/{pct_encoding.ipp => decode.ipp} | 34 +- .../{pct_encoded_view.hpp => decode_view.hpp} | 17 +- .../{pct_encoded_view.ipp => decode_view.ipp} | 38 +- .../url/impl/{pct_encoding.hpp => encode.hpp} | 173 ++------- include/boost/url/impl/error.ipp | 4 +- include/boost/url/impl/params.hpp | 18 +- include/boost/url/impl/params.ipp | 8 +- include/boost/url/impl/params_encoded.hpp | 4 +- include/boost/url/impl/params_encoded.ipp | 2 +- .../boost/url/impl/params_encoded_view.ipp | 2 +- include/boost/url/impl/params_view.ipp | 2 +- include/boost/url/impl/query_param.ipp | 1 - include/boost/url/impl/segments.hpp | 7 +- include/boost/url/impl/segments_view.hpp | 8 +- include/boost/url/impl/url_base.ipp | 118 +++--- include/boost/url/impl/url_view_base.ipp | 4 +- include/boost/url/params.hpp | 2 +- include/boost/url/params_encoded_view.hpp | 3 +- include/boost/url/params_view.hpp | 13 +- include/boost/url/query_param.hpp | 34 +- .../boost/url/rfc/detail/hier_part_rule.hpp | 4 +- include/boost/url/rfc/detail/host_rule.hpp | 4 +- include/boost/url/rfc/detail/path_rules.hpp | 2 +- .../url/rfc/detail/relative_part_rule.hpp | 4 +- .../boost/url/rfc/detail/userinfo_rule.hpp | 6 +- include/boost/url/rfc/gen_delim_chars.hpp | 2 +- .../boost/url/rfc/impl/pct_encoded_rule.hpp | 8 +- include/boost/url/rfc/impl/query_rule.ipp | 2 +- include/boost/url/rfc/pchars.hpp | 2 +- include/boost/url/rfc/pct_encoded_rule.hpp | 11 +- include/boost/url/rfc/query_rule.hpp | 4 +- include/boost/url/rfc/reserved_chars.hpp | 2 +- include/boost/url/rfc/sub_delim_chars.hpp | 2 +- include/boost/url/rfc/unreserved_chars.hpp | 2 +- include/boost/url/segments.hpp | 10 +- include/boost/url/segments_view.hpp | 10 +- include/boost/url/src.hpp | 6 +- include/boost/url/url.natvis | 2 +- include/boost/url/url_base.hpp | 14 +- include/boost/url/url_view_base.hpp | 32 +- test/unit/CMakeLists.txt | 5 +- test/unit/Jamfile | 5 +- test/unit/{pct_encoding.cpp => decode.cpp} | 169 ++++----- .../{pct_encoded_view.cpp => decode_view.cpp} | 128 +++---- test/unit/doc_grammar.cpp | 2 +- test/unit/encode.cpp | 146 ++++++++ test/unit/error.cpp | 2 +- test/unit/grammar/not_empty_rule.cpp | 2 +- test/unit/grammar/tuple_rule.cpp | 4 +- test/unit/params_encoded_view.cpp | 2 +- test/unit/params_view.cpp | 2 +- test/unit/rfc/gen_delim_chars.cpp | 2 +- test/unit/rfc/pchars.cpp | 2 +- test/unit/rfc/pct_encoded_rule.cpp | 2 +- test/unit/rfc/query_rule.cpp | 4 +- test/unit/rfc/reserved_chars.cpp | 2 +- test/unit/rfc/sub_delim_chars.cpp | 2 +- test/unit/rfc/unreserved_chars.cpp | 2 +- test/unit/segments_view.cpp | 4 +- test/unit/snippets.cpp | 6 +- test/unit/url.cpp | 41 ++- 92 files changed, 1402 insertions(+), 1040 deletions(-) rename include/boost/url/{pct_encoding.hpp => decode.hpp} (52%) create mode 100644 include/boost/url/decode_opts.hpp rename include/boost/url/{pct_encoded_view.hpp => decode_view.hpp} (93%) rename include/boost/url/detail/{pct_encoded_view.hpp => decode_view.hpp} (78%) rename include/boost/url/detail/impl/{pct_encoded_view.ipp => decode_view.ipp} (69%) create mode 100644 include/boost/url/encode.hpp create mode 100644 include/boost/url/encode_opts.hpp create mode 100644 include/boost/url/grammar/all_chars.hpp create mode 100644 include/boost/url/impl/decode.hpp rename include/boost/url/impl/{pct_encoding.ipp => decode.ipp} (91%) rename include/boost/url/impl/{pct_encoded_view.hpp => decode_view.hpp} (95%) rename include/boost/url/impl/{pct_encoded_view.ipp => decode_view.ipp} (84%) rename include/boost/url/impl/{pct_encoding.hpp => encode.hpp} (52%) rename test/unit/{pct_encoding.cpp => decode.cpp} (72%) rename test/unit/{pct_encoded_view.cpp => decode_view.cpp} (77%) create mode 100644 test/unit/encode.cpp diff --git a/doc/qbk/0.main.qbk b/doc/qbk/0.main.qbk index e5ad0e2e..03c2e3b0 100644 --- a/doc/qbk/0.main.qbk +++ b/doc/qbk/0.main.qbk @@ -73,7 +73,7 @@ [def __params_encoded__ [link url.ref.boost__urls__params_encoded `params_encoded`]] [def __params_encoded_view__ [link url.ref.boost__urls__params_encoded_view `encoded_params_view`]] [def __pchars__ [link url.ref.boost__urls__pchars `pchars`]] -[def __pct_encoded_view__ [link url.ref.boost__urls__pct_encoded_view `pct_encoded_view`]] +[def __decode_view__ [link url.ref.boost__urls__encoded_view `decode_view`]] [def __pct_encoded_rule__ [link url.ref.boost__urls__pct_encoded_rule `pct_encoded_rule`]] [def __query_param_view__ [link url.ref.boost__urls__query_param_view `query_param_view`]] [def __result__ [link url.ref.boost__urls__result `result`]] diff --git a/doc/qbk/2.0.quicklook.qbk b/doc/qbk/2.0.quicklook.qbk index 32384efd..ee4957ee 100644 --- a/doc/qbk/2.0.quicklook.qbk +++ b/doc/qbk/2.0.quicklook.qbk @@ -146,7 +146,7 @@ of key/value pairs. ``` ]]] -These functions return __pct_encoded_view__, which are constant +These functions return __decode_view__, which are constant views referring to sub-ranges of the underlying URL string. By simply referencing the relevant portion of the URL string, its components can represent percent-decoded strings without any @@ -188,9 +188,9 @@ accessed through a __string_view__: ``` ]]] -[h3 Decoding] +[heading Percent-Encoding] -An instance of __pct_encoded_view__ provides a number of functions +An instance of __decode_view__ provides a number of functions to persist a decoded string: [table [[Code][Output]] [[ @@ -204,7 +204,7 @@ to persist a decoded string: ``` ]]] -__pct_encoded_view__ and its decoding functions are designed to +__decode_view__ and its decoding functions are designed to perform no memory allocations unless the algorithm where its being used needs the result to be in another container. The design also permits recycling objects to reuse their memory, and at least @@ -279,7 +279,7 @@ As with other __url_view__ functions which return encoded strings, the encoded segments container does not allocate memory. Instead it returns views to the corresponding portions of the underlying encoded buffer referenced by the URL. -As with other library functions, __pct_encoded_view__ permits accessing +As with other library functions, __decode_view__ permits accessing elements of composed elements while avoiding memory allocations entirely: [table [[Code][Output]] [[ diff --git a/doc/qbk/3.3.authority.qbk b/doc/qbk/3.3.authority.qbk index 785efa82..2d7bbb1b 100644 --- a/doc/qbk/3.3.authority.qbk +++ b/doc/qbk/3.3.authority.qbk @@ -36,7 +36,7 @@ be used to obtain the __authority_view__ from a __url_view__: [snippet_parsing_authority_3a] Notice that [link url.ref.boost__urls__url_view.authority `authority`] -does not return a __pct_encoded_view__. The reason is any decoded character +does not return a __decode_view__. The reason is any decoded character `/` could make it ambiguous with the path component. The authority is represented through an __authority_view__, a read-only container to a non-owning character buffer containing a valid authority. diff --git a/doc/qbk/4.5.rfc3986.qbk b/doc/qbk/4.5.rfc3986.qbk index 1934f282..5ec97ebe 100644 --- a/doc/qbk/4.5.rfc3986.qbk +++ b/doc/qbk/4.5.rfc3986.qbk @@ -47,7 +47,7 @@ strings which are percent-encoded. This function is passed the set of characters that may be used without escapes and returns a suitable rule. If the input is valid; that is, if there are no invalid escape sequences, the rule returns a -__pct_encoded_view__. This is a forward range of characters +__decode_view__. This is a forward range of characters which performs percent-decoding when iterated. It also supports equality and comparison to unencoded strings, without allocating memory. In the example below we parse the string `s` as a diff --git a/doc/qbk/5.2.MutableString.qbk b/doc/qbk/5.2.MutableString.qbk index 63f28acc..82cdb3fc 100644 --- a/doc/qbk/5.2.MutableString.qbk +++ b/doc/qbk/5.2.MutableString.qbk @@ -17,7 +17,7 @@ components of URLs and other things. [heading Related Identifiers] -* __pct_encoded_view__ +* __decode_view__ * [link url.ref.boost__urls__pct_encoded_rule `pct_encoded_rule`] [heading Requirements] @@ -73,6 +73,6 @@ In this table: [heading See also] -* __pct_encoded_view__ +* __decode_view__ [endsect] diff --git a/doc/qbk/quickref.xml b/doc/qbk/quickref.xml index fdacd3d6..3388e259 100644 --- a/doc/qbk/quickref.xml +++ b/doc/qbk/quickref.xml @@ -89,19 +89,16 @@ Functions - pct_decode - pct_decode_bytes_unchecked - pct_decode_unchecked - pct_encode - pct_encode_bytes - validate_pct_encoding + decode + encode + encoded_size Types - pct_decode_opts - pct_encode_opts - pct_encoded_view + decode_opts + decode_view + encode_opts @@ -148,6 +145,7 @@ absolute_uri_rule + all_chars authority_rule gen_delim_chars ipv4_address_rule diff --git a/example/magnet/magnet.cpp b/example/magnet/magnet.cpp index aa07d91d..9438c8ec 100644 --- a/example/magnet/magnet.cpp +++ b/example/magnet/magnet.cpp @@ -78,16 +78,16 @@ struct to_url { operator()(urls::query_param_view p); }; -/// Callable to convert param values to urls::pct_encoded_view +/// Callable to convert param values to urls::decode_view /** This callable converts the value of a - query parameter into a urls::pct_encoded_view. + query parameter into a urls::decode_view. This callable is used as a transform function for the keys_view. */ struct to_decoded_value { - urls::pct_encoded_view + urls::decode_view operator()(urls::query_param_view p) { return p.value; @@ -201,7 +201,7 @@ public: using keys_view = filtered_view< urls::params_view, - urls::pct_encoded_view, + urls::decode_view, is_url_with_key, to_decoded_value>; @@ -288,7 +288,7 @@ public: @return Keyword topic */ - urls::optional + boost::optional keyword_topic() const noexcept; /// Return manifest topics @@ -321,7 +321,7 @@ public: @return Display name */ - urls::optional + boost::optional display_name() const noexcept; // The payload data served over HTTP(S) @@ -355,7 +355,7 @@ public: @return Web seed */ - urls::optional + boost::optional param(urls::string_view key) const noexcept; friend @@ -366,12 +366,12 @@ public: } private: - // get a query parameter as a urls::pct_encoded_view - urls::optional + // get a query parameter as a urls::decode_view + boost::optional decoded_param(urls::string_view key) const noexcept; // get a query parameter as a urls::url_view - urls::optional + boost::optional url_param(urls::string_view key) const noexcept; friend magnet_link_rule_t; @@ -382,7 +382,7 @@ is_exact_topic:: operator()(urls::query_param_view p) { // These comparisons use the lazy - // operator== for urls::pct_encoded_view + // operator== for urls::decode_view // For instance, the comparison also works // if the underlying key is "%78%74"/ if (p.key == "xt") @@ -503,7 +503,7 @@ magnet_link_view::acceptable_sources(MutableString& buffer) const is_url_with_key{"as", buffer}}; } -urls::optional +boost::optional magnet_link_view::keyword_topic() const noexcept { return decoded_param("kt"); @@ -519,7 +519,7 @@ magnet_link_view::manifest_topics(MutableString& buffer) const is_url_with_key{"mt", buffer}}; } -urls::optional +boost::optional magnet_link_view::display_name() const noexcept { return decoded_param("dn"); @@ -535,7 +535,7 @@ magnet_link_view::web_seed(MutableString& buffer) const is_url_with_key{"ws", buffer}}; } -urls::optional +boost::optional magnet_link_view::param(urls::string_view key) const noexcept { urls::params_view ps = u_.params(); @@ -552,30 +552,30 @@ magnet_link_view::param(urls::string_view key) const noexcept auto first = p.key.begin(); auto mid = std::next(p.key.begin(), 2); auto last = p.key.end(); - urls::pct_encoded_view prefix( + urls::decode_view prefix( urls::string_view(first.base(), mid.base())); - urls::pct_encoded_view suffix( + urls::decode_view suffix( urls::string_view(mid.base(), last.base())); if (prefix == "x." && suffix == key && p.has_value) - return urls::pct_encoded_view(p.value); + return urls::decode_view(p.value); ++it; } return boost::none; } -urls::optional +boost::optional magnet_link_view::decoded_param(urls::string_view key) const noexcept { urls::params_encoded_view ps = u_.encoded_params(); auto it = ps.find(key); if (it != ps.end() && (*it).has_value) - return urls::pct_encoded_view((*it).value); + return urls::decode_view((*it).value); return boost::none; } -urls::optional +boost::optional magnet_link_view::url_param(urls::string_view key) const noexcept { urls::params_encoded_view ps = u_.encoded_params(); diff --git a/include/boost/url.hpp b/include/boost/url.hpp index 19f32c6d..ff9a9586 100644 --- a/include/boost/url.hpp +++ b/include/boost/url.hpp @@ -13,6 +13,8 @@ #include #include +#include +#include #include #include #include @@ -22,8 +24,7 @@ #include #include #include -#include -#include +#include #include #include #include diff --git a/include/boost/url/authority_view.hpp b/include/boost/url/authority_view.hpp index f0837a53..9ca13ff3 100644 --- a/include/boost/url/authority_view.hpp +++ b/include/boost/url/authority_view.hpp @@ -14,8 +14,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -382,10 +382,10 @@ public: @ref has_userinfo, @ref encoded_userinfo. */ - pct_encoded_view + decode_view userinfo() const noexcept { - pct_decode_opts opt; + decode_opts opt; opt.plus_to_space = false; return detail::access::construct( encoded_userinfo(), @@ -467,10 +467,10 @@ public: @ref has_password, @ref password. */ - pct_encoded_view + decode_view user() const noexcept { - pct_decode_opts opt; + decode_opts opt; opt.plus_to_space = false; return detail::access::construct( encoded_user(), u_.decoded_[id_user], opt); @@ -577,10 +577,10 @@ public: @ref has_password, @ref password. */ - pct_encoded_view + decode_view password() const noexcept { - pct_decode_opts opt; + decode_opts opt; opt.plus_to_space = false; return detail::access::construct( encoded_password(), u_.decoded_[id_pass], opt); @@ -722,10 +722,10 @@ public: @ref port, @ref port_number. */ - pct_encoded_view + decode_view host() const noexcept { - pct_decode_opts opt; + decode_opts opt; opt.plus_to_space = false; return detail::access::construct( encoded_host(), u_.decoded_[id_host], opt); diff --git a/include/boost/url/pct_encoding.hpp b/include/boost/url/decode.hpp similarity index 52% rename from include/boost/url/pct_encoding.hpp rename to include/boost/url/decode.hpp index d18dcf25..e50b2ddf 100644 --- a/include/boost/url/pct_encoding.hpp +++ b/include/boost/url/decode.hpp @@ -8,45 +8,21 @@ // Official repository: https://github.com/CPPAlliance/url // -#ifndef BOOST_URL_PCT_ENCODING_HPP -#define BOOST_URL_PCT_ENCODING_HPP +#ifndef BOOST_URL_DECODE_HPP +#define BOOST_URL_DECODE_HPP #include -#include +#include +#include #include +#include #include -#include +#include namespace boost { namespace urls { -/** Options for removing percent-encoding from strings - - @see - @ref pct_decode, - @ref pct_decode_bytes_unchecked, - @ref pct_decode_unchecked, - @ref validate_pct_encoding. -*/ -struct pct_decode_opts -{ - /** True if null characters are allowed in decoded output - */ - bool allow_null = true; - - /** True if PLUS ('+') decodes into SP (space, ' ') - - @par Specification - @li - application/x-www-form-urlencoded (w3.org) - */ - bool plus_to_space = true; - - /** True if decoding a non-normal string is an error - */ - bool non_normal_is_error = false; -}; - +namespace detail { /** Validate a percent encoded string and return the number of decoded bytes This function examines the characters in @@ -63,8 +39,8 @@ struct pct_decode_opts This validates and calculates the decoded length of a valid percent-encoded string. @code error_code ec; - std::size_t decoded_size = validate_pct_encoding( "Program%20Files", - ec, pchars, pct_decode_opts{} ); + std::size_t decoded_size = validate_encoding( "Program%20Files", + ec, pchars, decode_opts{} ); assert( ! ec.failed() ); assert( decoded_size == 13 ); @endcode @@ -73,8 +49,8 @@ struct pct_decode_opts This shows how validation can fail using an error code. @code error_code ec; - std::size_t decoded_size = validate_pct_encoding( "bad%escape", - ec, pchars, pct_decode_opts{}); + std::size_t decoded_size = validate_encoding( "bad%escape", + ec, pchars, decode_opts{}); assert( ec.failed() ); @endcode @@ -103,18 +79,16 @@ struct pct_decode_opts 2.1. Percent-Encoding (rfc3986) @see - @ref pct_decode, - @ref pct_decode_bytes_unchecked, - @ref pct_decode_opts, - @ref pct_decode_unchecked, + @ref decode, + @ref decode_opts, */ template< class CharSet> result -validate_pct_encoding( +validate_encoding( string_view s, - CharSet const& allowed, - pct_decode_opts const& opt = {}) noexcept; + decode_opts const& opt, + CharSet const& allowed) noexcept; /** Validate a percent encoded string and return the number of decoded bytes @@ -131,8 +105,8 @@ validate_pct_encoding( This validates and calculates the decoded length of a valid percent-encoded string. @code error_code ec; - std::size_t decoded_size = validate_pct_encoding( "Program%20Files", - ec, pct_decode_opts{} ); + std::size_t decoded_size = validate_encoding( "Program%20Files", + ec, decode_opts{} ); assert( ! ec.failed() ); assert( decoded_size == 13 ); @endcode @@ -141,8 +115,8 @@ validate_pct_encoding( This shows how validation can fail using an error code. @code error_code ec; - std::size_t decoded_size = validate_pct_encoding( "bad%escape", - ec, pct_decode_opts{} ); + std::size_t decoded_size = validate_encoding( "bad%escape", + ec, decode_opts{} ); assert( ec.failed() ); @endcode @@ -163,16 +137,16 @@ validate_pct_encoding( 2.1. Percent-Encoding (rfc3986) @see - @ref pct_decode, - @ref pct_decode_bytes_unchecked, - @ref pct_decode_opts, - @ref pct_decode_unchecked, + @ref decode, + @ref decode_bytes_unchecked, + @ref decode_opts, + @ref decode_unchecked, */ BOOST_URL_DECL result -validate_pct_encoding( +validate_encoding( string_view s, - pct_decode_opts const& opt = {}) noexcept; + decode_opts const& opt = {}) noexcept; /** Write a string with percent-decoding into a buffer. @@ -189,8 +163,8 @@ validate_pct_encoding( @code char *dest = new char[MAX_LENGTH]; error_code ec; - std::size_t decoded_size = pct_decode( dest, dest + MAX_LENGTH, - "Program%20Files", ec, pchars, pct_decode_opts{}); + std::size_t decoded_size = decode( dest, dest + MAX_LENGTH, + "Program%20Files", ec, pchars, decode_opts{}); assert( ! ec.failed() ); assert( decoded_size == 13 ); @@ -232,20 +206,17 @@ validate_pct_encoding( >2.1. Percent-Encoding (rfc3986) @see - @ref pct_decode_bytes_unchecked, - @ref pct_decode_opts, - @ref pct_decode_unchecked. - @ref validate_pct_encoding. + @ref decode_opts. */ template< class CharSet> result -pct_decode( +decode( char* dest, char const* end, string_view s, - CharSet const& allowed, - pct_decode_opts const& opt = {}) noexcept; + decode_opts const& opt, + CharSet const& allowed) noexcept; /** Write a string with percent-decoding into a buffer. @@ -262,8 +233,8 @@ pct_decode( @code char *dest = new char[MAX_LENGTH]; error_code ec; - std::size_t decoded_size = pct_decode( dest, dest + MAX_LENGTH, - "Program%20Files", ec, pct_decode_opts{}); + std::size_t decoded_size = decode( dest, dest + MAX_LENGTH, + "Program%20Files", ec, decode_opts{}); assert( ! ec.failed() ); assert( decoded_size == 13 ); @@ -294,18 +265,18 @@ pct_decode( >2.1. Percent-Encoding (rfc3986) @see - @ref pct_decode_bytes_unchecked, - @ref pct_decode_opts, - @ref pct_decode_unchecked. - @ref validate_pct_encoding. + @ref decode_bytes_unchecked, + @ref decode_opts, + @ref decode_unchecked. + @ref validate_encoding. */ BOOST_URL_DECL result -pct_decode( +decode( char* dest, char const* end, string_view s, - pct_decode_opts const& opt = {}) noexcept; + decode_opts const& opt = {}) noexcept; /** Return the number of bytes needed to hold the string with percent-decoding applied. @@ -318,7 +289,7 @@ pct_decode( @par Example @code - std::size_t size = pct_decode_bytes_unchecked( "Program%20Files" ); + std::size_t size = decode_bytes_unchecked( "Program%20Files" ); assert( size == 13 ); @endcode @@ -334,13 +305,10 @@ pct_decode( null terminator. @param s The string to inspect. - - @see - @ref validate_pct_encoding. */ BOOST_URL_DECL std::size_t -pct_decode_bytes_unchecked( +decode_bytes_unchecked( string_view s) noexcept; /** Apply percent-decoding to a string @@ -355,7 +323,7 @@ pct_decode_bytes_unchecked( @par Example @code char *dest = new char[MAX_LENGTH]; - std::size_t decoded_size = pct_decode_unchecked( dest, dest + MAX_LENGTH, + std::size_t decoded_size = decode_unchecked( dest, dest + MAX_LENGTH, "Program%20Files" ); assert( decoded_size == 13 ); @@ -383,76 +351,44 @@ pct_decode_bytes_unchecked( */ BOOST_URL_DECL std::size_t -pct_decode_unchecked( +decode_unchecked( char* dest, char const* end, string_view s, - pct_decode_opts const& opt = {}) noexcept; + decode_opts const& opt = {}) noexcept; +} -//------------------------------------------------ +/** Validate and decode a string view -/** Options for applying percent-encoding to strings. + This function returns a view that applies + percent-decoding to the given percent-encoded + string, by converting escape sequences into + their character equivalent. - Instances of this type may be provided - to percent-encoding algorithms to - customize their behavior. + The function validates the input string + and returns a view of the decoded bytes. + If the input string is invalid, the result + contains an error. - @see - @ref pct_encode, - @ref pct_encode_bytes. -*/ -struct pct_encode_opts -{ - /** True if space (SP, ' ') encodes into PLUS ('+'). - - @par Specification - @li - application/x-www-form-urlencoded (w3.org) - */ - bool space_to_plus = false; -}; - -/** Return the number of bytes needed to store a string with percent-encoding applied - - This function examines the characters in - the string to determine the number of bytes - necessary if the string were to be percent - encoded using the given options and character - set. No encoding is actually performed. - - @par Example 1 - Find the number of bytes needed to encode a string without transforming - ' ' to '+'. + @par Example @code - pct_encode_opts opt; - opt.space_to_plus = false; - std::size_t n = pct_encode_bytes( "My Stuff", pchars, opt ); + result< decode_view > r = decode( "Program%20Files" ); + assert( r.has_value() ); - assert( n == 10 ); - @endcode - - @par Example 2 - Find the number of bytes needed to encode a string when transforming - ' ' to '+'. - @code - pct_encode_opts opt; - opt.space_to_plus = true; - std::size_t n = pct_encode_bytes( "My Stuff", opt, pchars ); - - assert( n == 8 ); + decode_view v = *r; + assert( v == "Program Files" ); + assert( v.size() == 13 ); + assert( v.encoded().size() == 15 ); @endcode @par Exception Safety Throws nothing. - @return The number of bytes needed, - excluding any null terminator. + @return The number of bytes written to + the destination buffer, which does not + include any null termination. - @param s The string to encode. - - @param opt The options for encoding. If - this parameter is omitted, the default - options will be used. + @param s The string to decode. @param allowed The set of characters allowed to appear unescaped. @@ -462,158 +398,28 @@ struct pct_encode_opts special. The character set is ignored if `opt.non_normal_is_error == false`. - @par Specification - @li 2.1. Percent-Encoding (rfc3986) - - @see - @ref pct_decode, - @ref pct_encode, - @ref pct_encode_opts. -*/ -template -std::size_t -pct_encode_bytes( - string_view s, - CharSet const& allowed, - pct_encode_opts const& opt = {}) noexcept; - -/** Write a string with percent-encoding into a buffer. - - This function applies percent-encoding to - the given plain string, by escaping all - characters that are not in the specified - CharSet. - The output is written to the destination, - and will be truncated if there is - insufficient space. - - @par Example - @code - char *dest = new char[MAX_LENGTH]; - std::size_t encoded_size = pct_encode( dest, dest + MAX_LENGTH, - "Program Files", pct_encode_opts{}, pchars ); - - assert( encoded_size == 15 ); - assert( strncmp( "Program%20Files", dest, encoded_size ) == 0 ); - @endcode - - @par Exception Safety - Throws nothing. - - @return `true` if the output was large - enough to hold the entire result. - - @param[in, out] dest A pointer to the - beginning of the output buffer. Upon - return, the argument will be changed - to one past the last character written. - - @param end A pointer to one past the end - of the output buffer. - - @param s The string to encode. - - @param opt The options for encoding. If + @param opt The options for decoding. If this parameter is omitted, the default options will be used. - @param allowed The set of characters - allowed to appear unescaped. - This type must satisfy the requirements - of CharSet. If this parameter is - omitted, then no characters are considered - special. The character set is ignored if - `opt.non_normal_is_error == false`. - @par Specification @li 2.1. Percent-Encoding (rfc3986) @see - @ref pct_decode, - @ref pct_encode, - @ref pct_encode_bytes. + @ref decode_opts, + @ref validate_encoding. */ -template -std::size_t -pct_encode( - char* dest, - char const* end, +template< class CharSet = grammar::all_chars_t > +result< decode_view > +decode( string_view s, - CharSet const& allowed, - pct_encode_opts const& opt = {}); - -/** Return a string with percent-encoding applied - - This function applies percent-encoding to - the given plain string, by escaping all - characters that are not in the specified - CharSet. - The result is returned as a - `std::basic_string`, using the optionally - specified allocator. - - @par Example - @code - pct_encode_opts opt; - opt.space_to_plus = true; - std::string s = pct_encode( "My Stuff", opt, pchars ); - - assert( s == "My+Stuff" ); - @endcode - - @par Exception Safety - Calls to allocate may throw. - - @return A `std::basic_string` holding the - encoded string, using the specified - allocator. - - @param s The string to encode. - - @param opt The options for encoding. If - this parameter is omitted, the default - options will be used. - - @param allowed The set of characters - allowed to appear unescaped. - This type must satisfy the requirements - of CharSet. If this parameter is - omitted, then no characters are considered - special. The character set is ignored if - `opt.non_normal_is_error == false`. - - @param a An optional allocator the returned - string will use. If this parameter is omitted, - the default allocator is used. In this case - the return type will be `std::string`. - - @par Specification - @li 2.1. Percent-Encoding (rfc3986) - - @see - @ref pct_encode, - @ref pct_encode_bytes, - @ref pct_encode_opts, -*/ -template< - class CharSet, - class Allocator = - std::allocator > -std::basic_string, - Allocator> -pct_encode_to_string( - string_view s, - CharSet const& allowed, - pct_encode_opts const& opt = {}, - Allocator const& a = {}); + decode_opts const& opt = {}, + CharSet const& allowed = {}); } // urls } // boost -#include +#include #endif diff --git a/include/boost/url/decode_opts.hpp b/include/boost/url/decode_opts.hpp new file mode 100644 index 00000000..43e462d2 --- /dev/null +++ b/include/boost/url/decode_opts.hpp @@ -0,0 +1,44 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// Copyright (c) 2022 Alan 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/CPPAlliance/url +// + +#ifndef BOOST_URL_DECODE_OPTS_HPP +#define BOOST_URL_DECODE_OPTS_HPP + +namespace boost { +namespace urls { + +/** Options for removing percent-encoding from strings + + @see + @ref decode +*/ +struct decode_opts +{ + /** True if null characters are allowed in decoded output + */ + bool allow_null = true; + + /** True if PLUS ('+') decodes into SP (space, ' ') + + @par Specification + @li + application/x-www-form-urlencoded (w3.org) + */ + bool plus_to_space = true; + + /** True if decoding a non-normal string is an error + */ + bool non_normal_is_error = false; +}; + +} // urls +} // boost + +#endif diff --git a/include/boost/url/pct_encoded_view.hpp b/include/boost/url/decode_view.hpp similarity index 93% rename from include/boost/url/pct_encoded_view.hpp rename to include/boost/url/decode_view.hpp index a6a29ae3..1ac5d2ec 100644 --- a/include/boost/url/pct_encoded_view.hpp +++ b/include/boost/url/decode_view.hpp @@ -12,8 +12,8 @@ #include #include -#include -#include +#include +#include #include #include #include @@ -72,7 +72,7 @@ class copied_strings_base; is constructed extends unmodified until the view is no longer accessed. */ -class pct_encoded_view +class decode_view { char const* p_ = nullptr; std::size_t n_ = 0; @@ -87,15 +87,15 @@ class pct_encoded_view // unchecked constructor BOOST_URL_DECL explicit - pct_encoded_view( + decode_view( string_view s, std::size_t n, - pct_decode_opts opt = {}) noexcept; + decode_opts opt = {}) noexcept; /** Return a view whose buffer does not overlap, copying if necessary */ BOOST_URL_DECL - pct_encoded_view + decode_view maybe_copy( grammar::detail::copied_strings_base& sp) const; @@ -140,7 +140,7 @@ public: Default-constructed objects represent the empty string. */ - pct_encoded_view() noexcept = default; + decode_view() noexcept = default; /** Constructor @@ -166,9 +166,9 @@ public: */ BOOST_URL_DECL explicit - pct_encoded_view( + decode_view( string_view s, - pct_decode_opts opt = {}); + decode_opts opt = {}); //-------------------------------------------- // @@ -260,10 +260,10 @@ public: /** Return the decode options for this view */ - pct_decode_opts + decode_opts options() const noexcept { - pct_decode_opts opt; + decode_opts opt; opt.plus_to_space = plus_to_space_; return opt; } @@ -317,7 +317,7 @@ public: @par Example @code - void f( pct_encoded_view s ) + void f( decode_view s ) { thread_local static std::string tmp; @@ -362,7 +362,7 @@ public: @par Example @code - void f( pct_encoded_view s ) + void f( decode_view s ) { thread_local static std::string tmp; @@ -471,7 +471,7 @@ public: */ BOOST_URL_DECL int - compare(pct_encoded_view other) const noexcept; + compare(decode_view other) const noexcept; //-------------------------------------------- @@ -490,8 +490,8 @@ public: friend bool operator==( - pct_encoded_view s0, - pct_encoded_view s1) noexcept + decode_view s0, + decode_view s1) noexcept { return s0.compare(s1) == 0; } @@ -511,8 +511,8 @@ public: friend bool operator!=( - pct_encoded_view s0, - pct_encoded_view s1) noexcept + decode_view s0, + decode_view s1) noexcept { return s0.compare(s1) != 0; } @@ -532,8 +532,8 @@ public: friend bool operator<( - pct_encoded_view s0, - pct_encoded_view s1) noexcept + decode_view s0, + decode_view s1) noexcept { return s0.compare(s1) < 0; } @@ -553,8 +553,8 @@ public: friend bool operator<=( - pct_encoded_view s0, - pct_encoded_view s1) noexcept + decode_view s0, + decode_view s1) noexcept { return s0.compare(s1) <= 0; } @@ -574,8 +574,8 @@ public: friend bool operator>( - pct_encoded_view s0, - pct_encoded_view s1) noexcept + decode_view s0, + decode_view s1) noexcept { return s0.compare(s1) > 0; } @@ -595,8 +595,8 @@ public: friend bool operator>=( - pct_encoded_view s0, - pct_encoded_view s1) noexcept + decode_view s0, + decode_view s1) noexcept { return s0.compare(s1) >= 0; } @@ -628,14 +628,14 @@ public: String, string_view>::value && ! std::is_same::type, - pct_encoded_view>::value, + decode_view>::value, bool >::type #else bool #endif operator==( - pct_encoded_view s0, + decode_view s0, String const& s1) noexcept { return s0.compare(string_view(s1)) == 0; @@ -666,14 +666,14 @@ public: String, string_view>::value && ! std::is_same::type, - pct_encoded_view>::value, + decode_view>::value, bool >::type #else bool #endif operator!=( - pct_encoded_view s0, + decode_view s0, String const& s1) noexcept { return s0.compare(string_view(s1)) != 0; @@ -704,14 +704,14 @@ public: String, string_view>::value && ! std::is_same::type, - pct_encoded_view>::value, + decode_view>::value, bool >::type #else bool #endif operator<( - pct_encoded_view s0, + decode_view s0, String const& s1) noexcept { return s0.compare(string_view(s1)) < 0; @@ -742,14 +742,14 @@ public: String, string_view>::value && ! std::is_same::type, - pct_encoded_view>::value, + decode_view>::value, bool >::type #else bool #endif operator<=( - pct_encoded_view s0, + decode_view s0, String const& s1) noexcept { return s0.compare(string_view(s1)) <= 0; @@ -780,14 +780,14 @@ public: String, string_view>::value && ! std::is_same::type, - pct_encoded_view>::value, + decode_view>::value, bool >::type #else bool #endif operator>( - pct_encoded_view s0, + decode_view s0, String const& s1) noexcept { return s0.compare(string_view(s1)) > 0; @@ -818,14 +818,14 @@ public: String, string_view>::value && ! std::is_same::type, - pct_encoded_view>::value, + decode_view>::value, bool >::type #else bool #endif operator>=( - pct_encoded_view s0, + decode_view s0, String const& s1) noexcept { return s0.compare(string_view(s1)) >= 0; @@ -858,7 +858,7 @@ public: String, string_view>::value && ! std::is_same::type, - pct_encoded_view>::value, + decode_view>::value, bool >::type #else @@ -866,7 +866,7 @@ public: #endif operator==( String const& s0, - pct_encoded_view s1) noexcept + decode_view s1) noexcept { return s1.compare(string_view(s0)) == 0; } @@ -896,7 +896,7 @@ public: String, string_view>::value && ! std::is_same::type, - pct_encoded_view>::value, + decode_view>::value, bool >::type #else @@ -904,7 +904,7 @@ public: #endif operator!=( String const& s0, - pct_encoded_view s1) noexcept + decode_view s1) noexcept { return s1.compare(string_view(s0)) != 0; } @@ -934,7 +934,7 @@ public: String, string_view>::value && ! std::is_same::type, - pct_encoded_view>::value, + decode_view>::value, bool >::type #else @@ -942,7 +942,7 @@ public: #endif operator<( String const& s0, - pct_encoded_view s1) noexcept + decode_view s1) noexcept { return s1.compare(string_view(s0)) > 0; } @@ -972,7 +972,7 @@ public: String, string_view>::value && ! std::is_same::type, - pct_encoded_view>::value, + decode_view>::value, bool >::type #else @@ -980,7 +980,7 @@ public: #endif operator<=( String const& s0, - pct_encoded_view s1) noexcept + decode_view s1) noexcept { return s1.compare(string_view(s0)) >= 0; } @@ -1010,7 +1010,7 @@ public: String, string_view>::value && ! std::is_same::type, - pct_encoded_view>::value, + decode_view>::value, bool >::type #else @@ -1018,7 +1018,7 @@ public: #endif operator>( String const& s0, - pct_encoded_view s1) noexcept + decode_view s1) noexcept { return s1.compare(string_view(s0)) < 0; } @@ -1048,7 +1048,7 @@ public: String, string_view>::value && ! std::is_same::type, - pct_encoded_view>::value, + decode_view>::value, bool >::type #else @@ -1056,7 +1056,7 @@ public: #endif operator>=( String const& s0, - pct_encoded_view s1) noexcept + decode_view s1) noexcept { return s1.compare(string_view(s0)) <= 0; } @@ -1068,7 +1068,7 @@ public: std::ostream& operator<<( std::ostream& os, - pct_encoded_view const& s) + decode_view const& s) { // hidden friend s.write(os); @@ -1096,11 +1096,11 @@ inline std::ostream& operator<<( std::ostream& os, - pct_encoded_view const& s); + decode_view const& s); } // urls } // boost -#include +#include #endif diff --git a/include/boost/url/detail/any_path_iter.hpp b/include/boost/url/detail/any_path_iter.hpp index 130476cd..fed897d6 100644 --- a/include/boost/url/detail/any_path_iter.hpp +++ b/include/boost/url/detail/any_path_iter.hpp @@ -111,8 +111,8 @@ class BOOST_SYMBOL_VISIBLE public any_path_iter { std::size_t n_; - pct_encoded_view::const_iterator p_; - pct_encoded_view::const_iterator end_; + decode_view::const_iterator p_; + decode_view::const_iterator end_; bool done_{false}; void @@ -121,7 +121,7 @@ class BOOST_SYMBOL_VISIBLE public: explicit view_path_iter( - pct_encoded_view s) noexcept; + decode_view s) noexcept; bool measure( diff --git a/include/boost/url/detail/any_query_iter.hpp b/include/boost/url/detail/any_query_iter.hpp index c0962e23..003e3117 100644 --- a/include/boost/url/detail/any_query_iter.hpp +++ b/include/boost/url/detail/any_query_iter.hpp @@ -104,8 +104,8 @@ public: class view_query_iter : public any_query_iter { - pct_encoded_view::const_iterator p_; - pct_encoded_view::const_iterator end_; + decode_view::const_iterator p_; + decode_view::const_iterator end_; std::size_t n_; bool done_{false}; @@ -115,7 +115,7 @@ class view_query_iter public: explicit view_query_iter( - pct_encoded_view s) noexcept; + decode_view s) noexcept; bool measure( diff --git a/include/boost/url/detail/pct_encoded_view.hpp b/include/boost/url/detail/decode_view.hpp similarity index 78% rename from include/boost/url/detail/pct_encoded_view.hpp rename to include/boost/url/detail/decode_view.hpp index 5a58f17a..660fa26f 100644 --- a/include/boost/url/detail/pct_encoded_view.hpp +++ b/include/boost/url/detail/decode_view.hpp @@ -10,23 +10,25 @@ #ifndef BOOST_URL_DETAIL_PCT_ENCODED_VIEW_HPP #define BOOST_URL_DETAIL_PCT_ENCODED_VIEW_HPP +#include + namespace boost { namespace urls { -class pct_encoded_view; +class decode_view; namespace detail { struct access { - // construct unchecked pct_encoded_view + // construct unchecked decode_view BOOST_URL_DECL static - pct_encoded_view + decode_view construct( string_view s, std::size_t n, - pct_decode_opts const& opt = {}) noexcept; + decode_opts const& opt = {}) noexcept; }; } // detail diff --git a/include/boost/url/detail/impl/any_path_iter.ipp b/include/boost/url/detail/impl/any_path_iter.ipp index 42fa4fcf..3d3d42de 100644 --- a/include/boost/url/detail/impl/any_path_iter.ipp +++ b/include/boost/url/detail/impl/any_path_iter.ipp @@ -12,7 +12,8 @@ #include #include -#include +#include +#include #include namespace boost { @@ -75,8 +76,7 @@ measure( if(! p_) return false; string_view s(p_, n_); - auto rn = urls::validate_pct_encoding( - s, pchars, {}); + auto rn = urls::decode(s, {}, pchars); if( !rn ) { ec = rn.error(); @@ -160,8 +160,8 @@ measure( if(! p_) return false; string_view s(p_, n_); - n += urls::pct_encode_bytes( - s, pchars); + n += urls::encoded_size( + s, {}, pchars); increment(); return true; } @@ -173,10 +173,11 @@ copy( char const* end) noexcept { BOOST_ASSERT(p_ != nullptr); - dest += pct_encode( + dest += encode( dest, end, string_view(p_, n_), + {}, pchars); increment(); } @@ -207,7 +208,7 @@ increment() noexcept view_path_iter:: view_path_iter( - pct_encoded_view s) noexcept + decode_view s) noexcept : n_(0) , end_(s.end()) { @@ -241,7 +242,7 @@ measure( return false; auto it = p_; auto end = std::next(p_, n_); - n += pct_encode_bytes_impl(it, end, pchars); + n += encoded_size_impl(it, end, {}, pchars); increment(); return true; } @@ -255,8 +256,8 @@ copy( BOOST_ASSERT(!done_); auto it = p_; auto last = std::next(p_, n_); - dest += pct_encode_impl( - dest, end, it, last, pchars); + dest += encode_impl( + dest, end, it, last, {}, pchars); increment(); } @@ -269,8 +270,7 @@ measure_impl( std::size_t& n, error_code& ec) noexcept { - auto rn = urls::validate_pct_encoding( - s, pchars, {}); + auto rn = urls::decode(s, {}, pchars); if( !rn ) { ec = rn.error(); @@ -307,7 +307,7 @@ measure_impl( string_view s, std::size_t& n) noexcept { - n += pct_encode_bytes(s, pchars); + n += encoded_size(s, {}, pchars); } void @@ -317,8 +317,8 @@ copy_impl( char*& dest, char const* end) noexcept { - dest += pct_encode( - dest, end, s, pchars); + dest += encode( + dest, end, s, {}, pchars); } } // detail diff --git a/include/boost/url/detail/impl/any_query_iter.ipp b/include/boost/url/detail/impl/any_query_iter.ipp index 85b3ab33..c44deab0 100644 --- a/include/boost/url/detail/impl/any_query_iter.ipp +++ b/include/boost/url/detail/impl/any_query_iter.ipp @@ -71,8 +71,7 @@ measure( if(! p_) return false; string_view s(p_, n_); - auto rn = urls::validate_pct_encoding( - s, query_chars, {}); + auto rn = urls::decode(s, {}, query_chars); if( !rn ) { ec = rn.error(); @@ -153,8 +152,7 @@ measure( if(! p_) return false; string_view s(p_, n_); - n += urls::pct_encode_bytes( - s, query_chars); + n += encoded_size(s, {}, query_chars); increment(); return true; } @@ -166,9 +164,10 @@ copy( char const* end) noexcept { BOOST_ASSERT(p_ != nullptr); - dest += pct_encode( + dest += encode( dest, end, string_view(p_, n_), + {}, query_chars); increment(); } @@ -199,7 +198,7 @@ increment() noexcept view_query_iter:: view_query_iter( - pct_encoded_view s) noexcept + decode_view s) noexcept : end_(s.end()) , n_(0) { @@ -230,8 +229,8 @@ measure( return false; auto it = p_; auto end = std::next(p_, n_); - n += pct_encode_bytes_impl( - it, end, query_chars); + n += encoded_size_impl( + it, end, {}, query_chars); increment(); return true; } @@ -245,10 +244,10 @@ copy( BOOST_ASSERT(!done_); auto it = p_; auto last = std::next(p_, n_); - dest += pct_encode_impl( + dest += encode_impl( dest, end, it, last, - query_chars); + {}, query_chars); increment(); } @@ -262,10 +261,10 @@ measure_impl( std::size_t& n, error_code& ec) noexcept { - pct_decode_opts opt; + decode_opts opt; opt.plus_to_space = true; - auto rn = validate_pct_encoding( - key, query_chars, opt); + auto rn = detail::validate_encoding( + key, opt, query_chars); if( !rn ) { ec = rn.error(); @@ -274,8 +273,8 @@ measure_impl( n += key.size(); if(value) { - rn = validate_pct_encoding( - *value, query_chars, opt); + rn = detail::validate_encoding( + *value, opt, query_chars); if( !rn ) { ec = rn.error(); @@ -332,11 +331,11 @@ measure_impl( string_view const* value, std::size_t& n) noexcept { - n += pct_encode_bytes(key, query_chars); + n += encoded_size(key, {}, query_chars); if(value) { ++n; // '=' - n += pct_encode_bytes(*value, query_chars); + n += encoded_size(*value, {}, query_chars); } } @@ -348,13 +347,13 @@ copy_impl( char*& dest, char const* end) noexcept { - dest += pct_encode( - dest, end, key, query_chars); + dest += encode( + dest, end, key, {}, query_chars); if(value) { *dest++ = '='; - dest += pct_encode( - dest, end, *value, query_chars); + dest += encode( + dest, end, *value, {}, query_chars); } } @@ -371,7 +370,7 @@ measure_impl( if(value) { ++n; // '=' - n += pct_encode_bytes(*value, query_chars); + n += encoded_size(*value, {}, query_chars); } } @@ -392,8 +391,8 @@ copy_impl( if(value) { *dest++ = '='; - dest += pct_encode( - dest, end, *value, query_chars); + dest += encode( + dest, end, *value, {}, query_chars); } } diff --git a/include/boost/url/detail/impl/pct_encoded_view.ipp b/include/boost/url/detail/impl/decode_view.ipp similarity index 69% rename from include/boost/url/detail/impl/pct_encoded_view.ipp rename to include/boost/url/detail/impl/decode_view.ipp index 885b5a13..0b88bebd 100644 --- a/include/boost/url/detail/impl/pct_encoded_view.ipp +++ b/include/boost/url/detail/impl/decode_view.ipp @@ -10,26 +10,26 @@ #ifndef BOOST_URL_DETAIL_IMPL_PCT_ENCODED_VIEW_IPP #define BOOST_URL_DETAIL_IMPL_PCT_ENCODED_VIEW_IPP -#include -#include +#include +#include namespace boost { namespace urls { -class pct_encoded_view; +class decode_view; namespace detail { -// construct unchecked pct_encoded_view -pct_encoded_view +// construct unchecked decode_view +decode_view access:: construct( string_view s, std::size_t n, - pct_decode_opts const& opt) noexcept + decode_opts const& opt) noexcept { // AFREITAS: move that inline - return pct_encoded_view(s, n, opt); + return decode_view(s, n, opt); } } // detail diff --git a/include/boost/url/detail/impl/normalize.ipp b/include/boost/url/detail/impl/normalize.ipp index 01bc025b..d0748c2b 100644 --- a/include/boost/url/detail/impl/normalize.ipp +++ b/include/boost/url/detail/impl/normalize.ipp @@ -32,7 +32,7 @@ pop_encoded_front( } else { - pct_decode_unchecked( + detail::decode_unchecked( &c, &c + 1, s.substr(0, 3)); @@ -61,8 +61,8 @@ compare_encoded( if (c1 < c0) return 1; } - n0 += pct_decode_bytes_unchecked(lhs); - n1 += pct_decode_bytes_unchecked(rhs); + n0 += detail::decode_bytes_unchecked(lhs); + n1 += detail::decode_bytes_unchecked(rhs); if (n0 == n1) return 0; if (n0 < n1) @@ -106,8 +106,8 @@ ci_compare_encoded( if (c1 < c0) return 1; } - n0 += pct_decode_bytes_unchecked(lhs); - n1 += pct_decode_bytes_unchecked(rhs); + n0 += detail::decode_bytes_unchecked(lhs); + n1 += detail::decode_bytes_unchecked(rhs); if (n0 == n1) return 0; if (n0 < n1) @@ -201,7 +201,7 @@ path_starts_with( ++it; return; } - pct_decode_unchecked( + detail::decode_unchecked( &c, &c + 1, string_view(it, 3)); @@ -250,7 +250,7 @@ path_ends_with( c = *--end; return; } - pct_decode_unchecked( + detail::decode_unchecked( &c, &c + 1, string_view(std::prev( diff --git a/include/boost/url/detail/impl/remove_dot_segments.ipp b/include/boost/url/detail/impl/remove_dot_segments.ipp index 8af92afc..d2110331 100644 --- a/include/boost/url/detail/impl/remove_dot_segments.ipp +++ b/include/boost/url/detail/impl/remove_dot_segments.ipp @@ -195,7 +195,7 @@ path_pop_back( string_view& s ) return c; } char c = 0; - pct_decode_unchecked( + detail::decode_unchecked( &c, &c + 1, s.substr(s.size() - 3)); if (c != '/') { @@ -408,7 +408,7 @@ normalized_path_compare( if(end - it < 3) return n; char c = 0; - pct_decode_unchecked( + detail::decode_unchecked( &c, &c + 1, string_view(it, 3)); @@ -478,7 +478,7 @@ normalized_path_compare( return c; } char c = 0; - pct_decode_unchecked( + detail::decode_unchecked( &c, &c + 1, s.substr(s.size() - 3)); if (c != '/') { diff --git a/include/boost/url/detail/impl/segments_iterator_impl.ipp b/include/boost/url/detail/impl/segments_iterator_impl.ipp index 79eb5b0a..51f8b8ef 100644 --- a/include/boost/url/detail/impl/segments_iterator_impl.ipp +++ b/include/boost/url/detail/impl/segments_iterator_impl.ipp @@ -56,13 +56,13 @@ segments_iterator_impl( begin_ += n; } -pct_encoded_view +decode_view segments_iterator_impl:: dereference() const noexcept { - pct_decode_opts opt; + decode_opts opt; opt.plus_to_space = false; - return pct_encoded_view(t_.encoded(), opt); + return decode_view(t_.encoded(), opt); } diff --git a/include/boost/url/detail/impl/url_impl.ipp b/include/boost/url/detail/impl/url_impl.ipp index 0a1588cb..a069246d 100644 --- a/include/boost/url/detail/impl/url_impl.ipp +++ b/include/boost/url/detail/impl/url_impl.ipp @@ -31,8 +31,8 @@ apply_scheme( void url_impl:: apply_userinfo( - pct_encoded_view const& user, - pct_encoded_view const* pass) noexcept + decode_view const& user, + decode_view const* pass) noexcept { // this function is for // authority_view_rule only @@ -63,7 +63,7 @@ apply_host( host_type ht, string_view s, unsigned char const* addr, - pct_encoded_view const& name) noexcept + decode_view const& name) noexcept { // this function is for // authority_view_rule only @@ -132,7 +132,7 @@ apply_path( set_size(id_path, s.size()); // VFALCO we are decoding twice decoded_[id_path] = - pct_decode_bytes_unchecked(s); + detail::decode_bytes_unchecked(s); nseg_ = detail::path_segments(s, nseg); } @@ -149,13 +149,13 @@ apply_query( // the string. once for the range and // again for the decoded size. decoded_[id_query] = - pct_decode_bytes_unchecked(s); + detail::decode_bytes_unchecked(s); } void url_impl:: apply_frag( - pct_encoded_view s) noexcept + decode_view s) noexcept { set_size(id_frag, s.encoded().size() + 1); diff --git a/include/boost/url/detail/segments_iterator_impl.hpp b/include/boost/url/detail/segments_iterator_impl.hpp index 9fefad71..5f4f413d 100644 --- a/include/boost/url/detail/segments_iterator_impl.hpp +++ b/include/boost/url/detail/segments_iterator_impl.hpp @@ -12,7 +12,7 @@ #define BOOST_URL_DETAIL_SEGMENTS_ITERATOR_IMPL_HPP #include -#include +#include #include namespace boost { @@ -26,7 +26,7 @@ struct segments_iterator_impl char const* pos_ = nullptr; char const* next_ = nullptr; char const* end_ = nullptr; - pct_encoded_view t_; + decode_view t_; BOOST_URL_DECL segments_iterator_impl( @@ -49,7 +49,7 @@ struct segments_iterator_impl segments_iterator_impl const&) noexcept = default; BOOST_URL_DECL - pct_encoded_view + decode_view dereference() const noexcept; BOOST_URL_DECL diff --git a/include/boost/url/detail/url_impl.hpp b/include/boost/url/detail/url_impl.hpp index 61e877b0..ff907958 100644 --- a/include/boost/url/detail/url_impl.hpp +++ b/include/boost/url/detail/url_impl.hpp @@ -11,7 +11,7 @@ #define BOOST_URL_DETAIL_URL_IMPL_HPP #include -#include +#include #include #include #include @@ -82,15 +82,15 @@ struct url_impl : parts_base void collapse(int, int, std::size_t) noexcept; void apply_scheme(string_view) noexcept; - void apply_userinfo(pct_encoded_view const&, - pct_encoded_view const*) noexcept; + void apply_userinfo(decode_view const&, + decode_view const*) noexcept; void apply_host(host_type, string_view, - unsigned char const*, pct_encoded_view const&) noexcept; + unsigned char const*, decode_view const&) noexcept; void apply_port(string_view, unsigned short) noexcept; void apply_authority(authority_view const&) noexcept; void apply_path(string_view, std::size_t) noexcept; void apply_query(string_view, std::size_t) noexcept; - void apply_frag(pct_encoded_view) noexcept; + void apply_frag(decode_view) noexcept; }; //------------------------------------------------ diff --git a/include/boost/url/encode.hpp b/include/boost/url/encode.hpp new file mode 100644 index 00000000..d0d3e185 --- /dev/null +++ b/include/boost/url/encode.hpp @@ -0,0 +1,226 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// Copyright (c) 2022 Alan 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/CPPAlliance/url +// + +#ifndef BOOST_URL_ENCODE_HPP +#define BOOST_URL_ENCODE_HPP + +#include +#include +#include +#include + +namespace boost { +namespace urls { + +/** Return the number of bytes needed to store a string with percent-encoding applied + + This function examines the characters in + the string to determine the number of bytes + necessary if the string were to be percent + encoded using the given options and character + set. No encoding is actually performed. + + @par Example 1 + Find the number of bytes needed to encode a string without transforming + ' ' to '+'. + @code + encode_opts opt; + opt.space_to_plus = false; + std::size_t n = encoded_size( "My Stuff", pchars, opt ); + + assert( n == 10 ); + @endcode + + @par Example 2 + Find the number of bytes needed to encode a string when transforming + ' ' to '+'. + @code + encode_opts opt; + opt.space_to_plus = true; + std::size_t n = encoded_size( "My Stuff", opt, pchars ); + + assert( n == 8 ); + @endcode + + @par Exception Safety + Throws nothing. + + @return The number of bytes needed, + excluding any null terminator. + + @param s The string to encode. + + @param opt The options for encoding. If + this parameter is omitted, the default + options will be used. + + @param allowed The set of characters + allowed to appear unescaped. + This type must satisfy the requirements + of CharSet. If this parameter is + omitted, then no characters are considered + special. The character set is ignored if + `opt.non_normal_is_error == false`. + + @par Specification + @li 2.1. Percent-Encoding (rfc3986) + + @see + @ref decode, + @ref encode, + @ref encode_opts. +*/ +template +std::size_t +encoded_size( + string_view s, + encode_opts const& opt = {}, + CharSet const& allowed = {}) noexcept; + +/** Write a string with percent-encoding into a buffer. + + This function applies percent-encoding to + the given plain string, by escaping all + characters that are not in the specified + CharSet. + The output is written to the destination, + and will be truncated if there is + insufficient space. + + @par Example + @code + char *dest = new char[MAX_LENGTH]; + std::size_t encoded_size = encode( dest, dest + MAX_LENGTH, + "Program Files", encode_opts{}, pchars ); + + assert( encoded_size == 15 ); + assert( strncmp( "Program%20Files", dest, encoded_size ) == 0 ); + @endcode + + @par Exception Safety + Throws nothing. + + @return `true` if the output was large + enough to hold the entire result. + + @param[in, out] dest A pointer to the + beginning of the output buffer. Upon + return, the argument will be changed + to one past the last character written. + + @param end A pointer to one past the end + of the output buffer. + + @param s The string to encode. + + @param opt The options for encoding. If + this parameter is omitted, the default + options will be used. + + @param allowed The set of characters + allowed to appear unescaped. + This type must satisfy the requirements + of CharSet. If this parameter is + omitted, then no characters are considered + special. The character set is ignored if + `opt.non_normal_is_error == false`. + + @par Specification + @li 2.1. Percent-Encoding (rfc3986) + + @see + @ref decode, + @ref encode, + @ref encoded_size. +*/ +template +std::size_t +encode( + char* dest, + char const* end, + string_view s, + encode_opts const& opt = {}, + CharSet const& allowed = {}); + +/** Return a string with percent-encoding applied + + This function applies percent-encoding to + the given plain string, by escaping all + characters that are not in the specified + CharSet. + The result is returned as a + `std::basic_string`, using the optionally + specified allocator. + + @par Example + @code + encode_opts opt; + opt.space_to_plus = true; + std::string s = encode( "My Stuff", opt, pchars ); + + assert( s == "My+Stuff" ); + @endcode + + @par Exception Safety + Calls to allocate may throw. + + @return A `std::basic_string` holding the + encoded string, using the specified + allocator. + + @param s The string to encode. + + @param allowed The set of characters + allowed to appear unescaped. + This type must satisfy the requirements + of CharSet. If this parameter is + omitted, then no characters are considered + special. The character set is ignored if + `opt.non_normal_is_error == false`. + + @param opt The options for encoding. If + this parameter is omitted, the default + options will be used. + + @param a An optional allocator the returned + string will use. If this parameter is omitted, + the default allocator is used. In this case + the return type will be `std::string`. + + @par Specification + @li 2.1. Percent-Encoding (rfc3986) + + @see + @ref encode, + @ref encoded_size, + @ref encode_opts, +*/ +template< + class CharSet = grammar::all_chars_t, + class Allocator = + std::allocator > +std::basic_string, + Allocator> +encode_to_string( + string_view s, + encode_opts const& opt = {}, + CharSet const& allowed = {}, + Allocator const& a = {}); + +} // urls +} // boost + +#include + +#endif diff --git a/include/boost/url/encode_opts.hpp b/include/boost/url/encode_opts.hpp new file mode 100644 index 00000000..12f45ca7 --- /dev/null +++ b/include/boost/url/encode_opts.hpp @@ -0,0 +1,41 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// Copyright (c) 2022 Alan 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/CPPAlliance/url +// + +#ifndef BOOST_URL_ENCODE_OPTS_HPP +#define BOOST_URL_ENCODE_OPTS_HPP + +namespace boost { +namespace urls { + +/** Options for applying percent-encoding to strings. + + Instances of this type may be provided + to percent-encoding algorithms to + customize their behavior. + + @see + @ref encode, + @ref encoded_size. +*/ +struct encode_opts +{ + /** True if space (SP, ' ') encodes into PLUS ('+'). + + @par Specification + @li + application/x-www-form-urlencoded (w3.org) + */ + bool space_to_plus = false; +}; + +} // urls +} // boost + +#endif diff --git a/include/boost/url/error.hpp b/include/boost/url/error.hpp index 74db6760..8dc6c82d 100644 --- a/include/boost/url/error.hpp +++ b/include/boost/url/error.hpp @@ -58,7 +58,7 @@ enum class error This error condition is fatal. */ - incomplete_pct_encoding, + incomplete_encoding, /** * Missing hexadecimal digit. diff --git a/include/boost/url/grammar/all_chars.hpp b/include/boost/url/grammar/all_chars.hpp new file mode 100644 index 00000000..57352f2e --- /dev/null +++ b/include/boost/url/grammar/all_chars.hpp @@ -0,0 +1,88 @@ +// +// Copyright (c) 2021 Vinnie Falco (vinnie dot falco at gmail dot 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/CPPAlliance/url +// + +#ifndef BOOST_URL_GRAMMAR_ALL_CHARS_HPP +#define BOOST_URL_GRAMMAR_ALL_CHARS_HPP + +#include +#include + +namespace boost { +namespace urls { +namespace grammar { + +/** The set of all characters + + @par Example + Character sets are used with rules and the + functions @ref find_if and @ref find_if_not. + @code + result< string_view > rv = parse( "JohnDoe", token_rule( all_chars ) ); + @endcode + + @par BNF + @code + ALL = %x00-FF + @endcode + + @see + @ref find_if, + @ref find_if_not, + @ref parse, + @ref token_rule. +*/ +#ifdef BOOST_URL_DOCS +constexpr __implementation_defined__ all_chars; +#else +struct all_chars_t +{ + constexpr + all_chars_t() noexcept = default; + + constexpr + bool + operator()(char) const noexcept + { + return true; + } + +#ifdef BOOST_URL_USE_SSE2 + char const* + find_if( + char const* first, + char const* last) const noexcept + { + return detail::find_if_pred( + *this, first, last); + } + + char const* + find_if_not( + char const* first, + char const* last) const noexcept + { + return detail::find_if_not_pred( + *this, first, last); + } +#endif +}; + +/** A character set containing all characters. + + @see + @ref all_chars_t +*/ +constexpr all_chars_t all_chars{}; +#endif + +} // grammar +} // urls +} // boost + +#endif diff --git a/include/boost/url/grammar/not_empty_rule.hpp b/include/boost/url/grammar/not_empty_rule.hpp index c2ab575e..69d6ed72 100644 --- a/include/boost/url/grammar/not_empty_rule.hpp +++ b/include/boost/url/grammar/not_empty_rule.hpp @@ -32,7 +32,7 @@ namespace grammar { @par Example Rules are used with the function @ref parse. @code - result< pct_encoded_view > rv = parse( "Program%20Files", + result< decode_view > rv = parse( "Program%20Files", not_empty_rule( pct_encoded_rule( unreserved_chars ) ) ); @endcode diff --git a/include/boost/url/grammar/tuple_rule.hpp b/include/boost/url/grammar/tuple_rule.hpp index c87a65c5..6c4b7cbe 100644 --- a/include/boost/url/grammar/tuple_rule.hpp +++ b/include/boost/url/grammar/tuple_rule.hpp @@ -196,7 +196,7 @@ struct squelch_rule_t @par Example 1 With `squelch`: @code - result< std::tuple< pct_encoded_view, string_view > > rv = parse( + result< std::tuple< decode_view, string_view > > rv = parse( "www.example.com:443", tuple_rule( pct_encoded_rule(unreserved_chars + '-' + '.'), @@ -207,7 +207,7 @@ struct squelch_rule_t @par Example 2 Without `squelch`: @code - result< std::tuple< pct_encoded_view, string_view, string_view > > rv = parse( + result< std::tuple< decode_view, string_view, string_view > > rv = parse( "www.example.com:443", tuple_rule( pct_encoded_rule(unreserved_chars + '-' + '.'), @@ -223,7 +223,7 @@ struct squelch_rule_t @ref parse, @ref tuple_rule, @ref token_rule, - @ref pct_encoded_view, + @ref decode_view, @ref pct_encoded_rule, @ref unreserved_chars. */ diff --git a/include/boost/url/impl/decode.hpp b/include/boost/url/impl/decode.hpp new file mode 100644 index 00000000..efed9a30 --- /dev/null +++ b/include/boost/url/impl/decode.hpp @@ -0,0 +1,160 @@ +// +// 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/CPPAlliance/url +// + +#ifndef BOOST_URL_IMPL_DECODE_HPP +#define BOOST_URL_IMPL_DECODE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace urls { + +namespace detail { +template +result +validate_encoding( + string_view s, + decode_opts const& opt, + CharSet const& allowed) noexcept +{ + // CharSet must satisfy is_charset + BOOST_STATIC_ASSERT( + grammar::is_charset::value); + + // we can't accept plus to space if '+' is not allowed + BOOST_ASSERT(! opt.plus_to_space || allowed('+')); + + std::size_t n = 0; + char const* it = s.data(); + char const* end = it + s.size(); + while(it != end) + { + if( ! opt.allow_null && + *it == '\0') + { + // null in input + BOOST_URL_RETURN_EC( + error::illegal_null); + } + if (*it != '%') + { + if(allowed(*it)) + { + // unreserved + ++n; + ++it; + continue; + } + // reserved character in input + BOOST_URL_RETURN_EC( + error::illegal_reserved_char); + } + else + { + // escaped + ++it; + if(end - it < 2) + { + // missing HEXDIG + BOOST_URL_RETURN_EC( + error::missing_pct_hexdig); + } + auto d0 = grammar::hexdig_value(it[0]); + auto d1 = grammar::hexdig_value(it[1]); + if( d0 < 0 || d1 < 0) + { + // expected HEXDIG + BOOST_URL_RETURN_EC( + error::bad_pct_hexdig); + } + it += 2; + char const c = static_cast( + ((static_cast< + unsigned char>(d0) << 4) + + (static_cast< + unsigned char>(d1)))); + if( ! opt.allow_null && + c == '\0') + { + // escaped null + BOOST_URL_RETURN_EC( + error::illegal_null); + } + if( opt.non_normal_is_error && + allowed(c)) + { + // escaped unreserved char + BOOST_URL_RETURN_EC( + error::non_canonical); + } + ++n; + } + } + BOOST_ASSERT(it == end); + return n; +} + +//------------------------------------------------ + +template +result +decode( + char* dest, + char const* end, + string_view s, + decode_opts const& opt, + CharSet const& allowed) noexcept +{ + // CharSet must satisfy is_charset + BOOST_STATIC_ASSERT( + grammar::is_charset::value); + + auto const rn = + detail::validate_encoding( + s, opt, allowed); + if( !rn ) + return rn; + auto const n1 = + detail::decode_unchecked( + dest, end, s, opt); + if(n1 < *rn) + { + return error::no_space; + } + return n1; +} +} + +template< class CharSet > +auto +decode( + string_view s, + decode_opts const& opt, + CharSet const& allowed) -> + result< decode_view > +{ + result rn = + detail::validate_encoding(s, opt, allowed); + if (rn.has_error()) + return rn.error(); + return detail::access::construct(s, *rn, opt); +} + +} // urls +} // boost + +#endif diff --git a/include/boost/url/impl/pct_encoding.ipp b/include/boost/url/impl/decode.ipp similarity index 91% rename from include/boost/url/impl/pct_encoding.ipp rename to include/boost/url/impl/decode.ipp index 4e6dec6d..6bcb5e8f 100644 --- a/include/boost/url/impl/pct_encoding.ipp +++ b/include/boost/url/impl/decode.ipp @@ -10,15 +10,16 @@ #ifndef BOOST_URL_IMPL_PCT_ENCODING_IPP #define BOOST_URL_IMPL_PCT_ENCODING_IPP -#include +#include #include #include namespace boost { namespace urls { +namespace detail { std::size_t -pct_decode_bytes_unchecked( +decode_bytes_unchecked( string_view s) noexcept { auto it = s.data(); @@ -43,11 +44,11 @@ pct_decode_bytes_unchecked( } std::size_t -pct_decode_unchecked( +decode_unchecked( char* const dest0, char const* end, string_view s, - pct_decode_opts const& opt) noexcept + decode_opts const& opt) noexcept { auto const decode_hex = []( char const* it) @@ -131,10 +132,8 @@ pct_decode_unchecked( return dest - dest0; } -namespace detail -{ result -validate_pct_encoding( +validate_encoding( string_view s, std::true_type) noexcept { @@ -170,7 +169,7 @@ validate_pct_encoding( } result -validate_pct_encoding( +validate_encoding( string_view s, std::false_type) noexcept { @@ -217,34 +216,33 @@ validate_pct_encoding( } return s.size() - pcts * 2; } -} result -validate_pct_encoding( +validate_encoding( string_view s, - pct_decode_opts const& opt) noexcept + decode_opts const& opt) noexcept { if (opt.allow_null) - return detail::validate_pct_encoding( + return detail::validate_encoding( s, std::true_type{}); else - return detail::validate_pct_encoding( + return detail::validate_encoding( s, std::false_type{}); } result -pct_decode( +decode( char* dest, char const* end, string_view s, - pct_decode_opts const& opt) noexcept + decode_opts const& opt) noexcept { auto const rn = - validate_pct_encoding(s, opt); + detail::validate_encoding(s, opt); if( !rn ) return rn; auto const n1 = - pct_decode_unchecked( + detail::decode_unchecked( dest, end, s, opt); if(n1 < *rn) { @@ -253,7 +251,7 @@ pct_decode( return n1; } - +} // detail } // urls } // boost diff --git a/include/boost/url/impl/pct_encoded_view.hpp b/include/boost/url/impl/decode_view.hpp similarity index 95% rename from include/boost/url/impl/pct_encoded_view.hpp rename to include/boost/url/impl/decode_view.hpp index 5b45fde2..e02bedb0 100644 --- a/include/boost/url/impl/pct_encoded_view.hpp +++ b/include/boost/url/impl/decode_view.hpp @@ -11,17 +11,18 @@ #define BOOST_URL_IMPL_PCT_ENCODED_VIEW_HPP #include +#include namespace boost { namespace urls { -class pct_encoded_view::iterator +class decode_view::iterator { char const* begin_{nullptr}; char const* pos_{nullptr}; bool plus_to_space_{true}; - friend pct_encoded_view; + friend decode_view; iterator( char const* str, @@ -124,7 +125,7 @@ public: inline auto -pct_encoded_view:: +decode_view:: begin() const noexcept -> const_iterator { @@ -133,7 +134,7 @@ begin() const noexcept -> inline auto -pct_encoded_view:: +decode_view:: end() const noexcept -> const_iterator { @@ -142,7 +143,7 @@ end() const noexcept -> inline auto -pct_encoded_view:: +decode_view:: front() const noexcept -> const_reference { @@ -152,7 +153,7 @@ front() const noexcept -> inline auto -pct_encoded_view:: +decode_view:: back() const noexcept -> const_reference { @@ -162,7 +163,7 @@ back() const noexcept -> template MutableString& -pct_encoded_view:: +decode_view:: assign_to( MutableString& s) const { @@ -183,7 +184,7 @@ assign_to( template MutableString& -pct_encoded_view:: +decode_view:: append_to( MutableString& s) const { diff --git a/include/boost/url/impl/pct_encoded_view.ipp b/include/boost/url/impl/decode_view.ipp similarity index 84% rename from include/boost/url/impl/pct_encoded_view.ipp rename to include/boost/url/impl/decode_view.ipp index c4c26ae6..cad11840 100644 --- a/include/boost/url/impl/pct_encoded_view.ipp +++ b/include/boost/url/impl/decode_view.ipp @@ -10,7 +10,7 @@ #ifndef BOOST_URL_IMPL_PCT_ENCODED_VIEW_IPP #define BOOST_URL_IMPL_PCT_ENCODED_VIEW_IPP -#include +#include #include #include @@ -18,7 +18,7 @@ namespace boost { namespace urls { auto -pct_encoded_view:: +decode_view:: iterator:: operator*() const noexcept -> reference @@ -40,11 +40,11 @@ operator*() const noexcept -> //------------------------------------------------ // unchecked constructor -pct_encoded_view:: -pct_encoded_view( +decode_view:: +decode_view( string_view str, std::size_t n, - pct_decode_opts opt) noexcept + decode_opts opt) noexcept : p_(str.data()) , n_(str.size()) , dn_(n) @@ -52,30 +52,30 @@ pct_encoded_view( { } -pct_encoded_view:: -pct_encoded_view( +decode_view:: +decode_view( string_view str, - pct_decode_opts opt) + decode_opts opt) : p_(str.data()) , n_(str.size()) , plus_to_space_(opt.plus_to_space) { opt.non_normal_is_error = false; - auto rn = validate_pct_encoding(str, opt); + auto rn = detail::validate_encoding(str, opt); if ( !rn ) detail::throw_invalid_argument(); dn_ = *rn; } -pct_encoded_view -pct_encoded_view:: +decode_view +decode_view:: maybe_copy( grammar::detail::copied_strings_base& sp) const { - pct_decode_opts opt; + decode_opts opt; opt.plus_to_space = plus_to_space_; - return pct_encoded_view( + return decode_view( sp.maybe_copy(encoded()), dn_, opt); @@ -84,7 +84,7 @@ maybe_copy( //------------------------------------------------ auto -pct_encoded_view:: +decode_view:: copy( char* dest, size_type count, @@ -105,7 +105,7 @@ namespace detail { template int -decoded_strcmp(pct_encoded_view s0, T s1) +decoded_strcmp(decode_view s0, T s1) { auto const n0 = s0.size(); auto const n1 = s1.size(); @@ -127,21 +127,21 @@ decoded_strcmp(pct_encoded_view s0, T s1) } // detail int -pct_encoded_view:: +decode_view:: compare(string_view other) const noexcept { return detail::decoded_strcmp(*this, other); } int -pct_encoded_view:: -compare(pct_encoded_view other) const noexcept +decode_view:: +compare(decode_view other) const noexcept { return detail::decoded_strcmp(*this, other); } void -pct_encoded_view:: +decode_view:: write(std::ostream& os) const { auto it = begin(); diff --git a/include/boost/url/impl/pct_encoding.hpp b/include/boost/url/impl/encode.hpp similarity index 52% rename from include/boost/url/impl/pct_encoding.hpp rename to include/boost/url/impl/encode.hpp index 0e5e0677..9ac99a85 100644 --- a/include/boost/url/impl/pct_encoding.hpp +++ b/include/boost/url/impl/encode.hpp @@ -7,12 +7,14 @@ // Official repository: https://github.com/CPPAlliance/url // -#ifndef BOOST_URL_IMPL_PCT_ENCODING_HPP -#define BOOST_URL_IMPL_PCT_ENCODING_HPP +#ifndef BOOST_URL_IMPL_ENCODE_HPP +#define BOOST_URL_IMPL_ENCODE_HPP #include #include -#include +#include +#include +#include #include #include #include @@ -21,132 +23,15 @@ namespace boost { namespace urls { -template -result -validate_pct_encoding( - string_view s, - CharSet const& allowed, - pct_decode_opts const& opt) noexcept -{ - // CharSet must satisfy is_charset - BOOST_STATIC_ASSERT( - grammar::is_charset::value); - - // can't have % in charset - BOOST_ASSERT(! allowed('%')); - - // we can't accept plus to space if '+' is not allowed - BOOST_ASSERT(! opt.plus_to_space || allowed('+')); - - std::size_t n = 0; - char const* it = s.data(); - char const* end = it + s.size(); - while(it != end) - { - if( ! opt.allow_null && - *it == '\0') - { - // null in input - BOOST_URL_RETURN_EC( - error::illegal_null); - } - if(allowed(*it)) - { - // unreserved - ++n; - ++it; - continue; - } - if(*it == '%') - { - // escaped - ++it; - if(end - it < 2) - { - // missing HEXDIG - BOOST_URL_RETURN_EC( - error::missing_pct_hexdig); - } - auto d0 = grammar::hexdig_value(it[0]); - auto d1 = grammar::hexdig_value(it[1]); - if( d0 < 0 || d1 < 0) - { - // expected HEXDIG - BOOST_URL_RETURN_EC( - error::bad_pct_hexdig); - } - it += 2; - char const c = static_cast( - ((static_cast< - unsigned char>(d0) << 4) + - (static_cast< - unsigned char>(d1)))); - if( ! opt.allow_null && - c == '\0') - { - // escaped null - BOOST_URL_RETURN_EC( - error::illegal_null); - } - if( opt.non_normal_is_error && - allowed(c)) - { - // escaped unreserved char - BOOST_URL_RETURN_EC( - error::non_canonical); - } - ++n; - continue; - } - // reserved character in input - BOOST_URL_RETURN_EC( - error::illegal_reserved_char); - } - BOOST_ASSERT(it == end); - return n; -} - -//------------------------------------------------ - -template -result -pct_decode( - char* dest, - char const* end, - string_view s, - CharSet const& allowed, - pct_decode_opts const& opt) noexcept -{ - // CharSet must satisfy is_charset - BOOST_STATIC_ASSERT( - grammar::is_charset::value); - - auto const rn = - validate_pct_encoding( - s, allowed, opt); - if( !rn ) - return rn; - auto const n1 = - pct_decode_unchecked( - dest, end, s, opt); - if(n1 < *rn) - { - return error::no_space; - } - return n1; -} - -//------------------------------------------------ - namespace detail { template std::size_t -pct_encode_bytes_impl( +encoded_size_impl( Iter it, Iter const end, - CharSet const& allowed, - pct_encode_opts const& opt = {}) noexcept + encode_opts const& opt = {}, + CharSet const& allowed = {}) noexcept { // CharSet must satisfy is_charset BOOST_STATIC_ASSERT( @@ -186,31 +71,31 @@ pct_encode_bytes_impl( template std::size_t -pct_encode_bytes( +encoded_size( string_view s, - CharSet const& allowed, - pct_encode_opts const& opt) noexcept + encode_opts const& opt, + CharSet const& allowed) noexcept { - return detail::pct_encode_bytes_impl( + return detail::encoded_size_impl( s.data(), s.data() + s.size(), - allowed, - opt); + opt, + allowed); } //------------------------------------------------ namespace detail { -template +template std::size_t -pct_encode_impl( +encode_impl( char* dest, char const* const end, Iter p, Iter last, - CharSet const& allowed, - pct_encode_opts const& opt = {}) + encode_opts const& opt = {}, + CharSet const& allowed = {}) { // CharSet must satisfy is_charset BOOST_STATIC_ASSERT( @@ -283,20 +168,20 @@ pct_encode_impl( template std::size_t -pct_encode( +encode( char* dest, char const* const end, string_view s, - CharSet const& allowed, - pct_encode_opts const& opt) + encode_opts const& opt, + CharSet const& allowed) { - return detail::pct_encode_impl( + return detail::encode_impl( dest, end, s.data(), s.data() + s.size(), - allowed, - opt); + opt, + allowed); } //------------------------------------------------ @@ -307,10 +192,10 @@ template< std::basic_string, Allocator> -pct_encode_to_string( +encode_to_string( string_view s, + encode_opts const& opt, CharSet const& allowed, - pct_encode_opts const& opt, Allocator const& a) { // CharSet must satisfy is_charset @@ -324,12 +209,12 @@ pct_encode_to_string( if(s.empty()) return r; auto const n = - pct_encode_bytes(s, allowed, opt); + encoded_size(s, opt, allowed); r.resize(n); char* dest = &r[0]; char const* end = dest + n; - auto const n1 = pct_encode( - dest, end, s, allowed, opt); + auto const n1 = encode( + dest, end, s, opt, allowed); BOOST_ASSERT(n1 == n); (void)n1; return r; diff --git a/include/boost/url/impl/error.ipp b/include/boost/url/impl/error.ipp index a1c92073..c84721fb 100644 --- a/include/boost/url/impl/error.ipp +++ b/include/boost/url/impl/error.ipp @@ -43,7 +43,7 @@ case error::illegal_reserved_char: return "illegal reserved char"; case error::non_canonical: return "non canonical"; case error::bad_pct_hexdig: return "bad hexdig in pct-encoding"; -case error::incomplete_pct_encoding: return "incomplete pct-encoding"; +case error::incomplete_encoding: return "incomplete pct-encoding"; case error::missing_pct_hexdig: return "missing hexdig in pct-encoding"; case error::no_space: return "no space"; case error::not_a_base: return "not a base"; @@ -60,7 +60,7 @@ case error::not_a_base: return "not a base"; return {ev, *this}; case error::bad_pct_hexdig: -case error::incomplete_pct_encoding: +case error::incomplete_encoding: case error::missing_pct_hexdig: return grammar::condition::fatal; } diff --git a/include/boost/url/impl/params.hpp b/include/boost/url/impl/params.hpp index ff0e5aeb..27ae5934 100644 --- a/include/boost/url/impl/params.hpp +++ b/include/boost/url/impl/params.hpp @@ -372,8 +372,8 @@ replace( using detail:: make_plain_params_iter; query_param_view v{ - pct_encoded_view(key), - pct_encoded_view(value), + decode_view(key), + decode_view(value), true }; BOOST_ASSERT(pos.impl_.begin_ == u_->encoded_query().data()); @@ -404,7 +404,7 @@ replace( u_->encoded_query().data() + u_->encoded_query().size()); query_param_view v{ - pct_encoded_view(key), {}, false}; + decode_view(key), {}, false}; u_->edit_params( pos.impl_.i_, pos.impl_.i_ + 1, @@ -427,8 +427,8 @@ insert( return insert( before, query_param_view{ - pct_encoded_view(key), - pct_encoded_view(value), + decode_view(key), + decode_view(value), true }); } @@ -443,7 +443,7 @@ insert( return insert( before, query_param_view{ - pct_encoded_view(key), {}, false}); + decode_view(key), {}, false}); } //------------------------------------------------ @@ -468,7 +468,7 @@ append( { return insert( end(), query_param_view{ - pct_encoded_view(key), {}, false}); + decode_view(key), {}, false}); } inline @@ -481,8 +481,8 @@ append( { return insert( end(), query_param_view{ - pct_encoded_view(key), - pct_encoded_view(value), + decode_view(key), + decode_view(value), true}); } diff --git a/include/boost/url/impl/params.ipp b/include/boost/url/impl/params.ipp index 3b7221c1..641005d1 100644 --- a/include/boost/url/impl/params.ipp +++ b/include/boost/url/impl/params.ipp @@ -37,10 +37,10 @@ remove_value( u_->encoded_query().size()); auto r = u_->param(pos.impl_.i_); query_param_view v{ - pct_encoded_view(string_view{ + decode_view(string_view{ u_->s_ + r.pos + 1, r.nk - 1}), - pct_encoded_view{}, + decode_view{}, false}; u_->edit_params( pos.impl_.i_, @@ -65,8 +65,8 @@ replace_value( u_->s_ + r.pos + 1, r.nk - 1}; query_param_view v{ - pct_encoded_view(key), - pct_encoded_view(value), + decode_view(key), + decode_view(value), true }; BOOST_ASSERT(pos.impl_.begin_ == u_->encoded_query().data()); diff --git a/include/boost/url/impl/params_encoded.hpp b/include/boost/url/impl/params_encoded.hpp index f5b390ae..0ce4473e 100644 --- a/include/boost/url/impl/params_encoded.hpp +++ b/include/boost/url/impl/params_encoded.hpp @@ -447,8 +447,8 @@ replace( using detail:: make_enc_params_iter; query_param_view v{ - pct_encoded_view(key), - pct_encoded_view{}, + decode_view(key), + decode_view{}, false}; u_->edit_params( pos.impl_.i_, diff --git a/include/boost/url/impl/params_encoded.ipp b/include/boost/url/impl/params_encoded.ipp index 1c6f415f..db9d5067 100644 --- a/include/boost/url/impl/params_encoded.ipp +++ b/include/boost/url/impl/params_encoded.ipp @@ -204,7 +204,7 @@ find( auto const end_ = end(); while(from != end_) { - if (pct_encoded_view(from.encoded_key()) == key) + if (decode_view(from.encoded_key()) == key) break; ++from; } diff --git a/include/boost/url/impl/params_encoded_view.ipp b/include/boost/url/impl/params_encoded_view.ipp index b152199c..861bba52 100644 --- a/include/boost/url/impl/params_encoded_view.ipp +++ b/include/boost/url/impl/params_encoded_view.ipp @@ -119,7 +119,7 @@ find( // //------------------------------------------------ -result +result parse_query_params( string_view s) noexcept { diff --git a/include/boost/url/impl/params_view.ipp b/include/boost/url/impl/params_view.ipp index 0eb443cc..7ea409b9 100644 --- a/include/boost/url/impl/params_view.ipp +++ b/include/boost/url/impl/params_view.ipp @@ -27,7 +27,7 @@ namespace urls { auto params_view:: at(string_view key) const -> - pct_encoded_view + decode_view { query_param_view r; auto it = find(key); diff --git a/include/boost/url/impl/query_param.ipp b/include/boost/url/impl/query_param.ipp index 605be244..6c82fb73 100644 --- a/include/boost/url/impl/query_param.ipp +++ b/include/boost/url/impl/query_param.ipp @@ -12,7 +12,6 @@ #define BOOST_URL_IMPL_QUERY_PARAM_IPP #include -#include namespace boost { namespace urls { diff --git a/include/boost/url/impl/segments.hpp b/include/boost/url/impl/segments.hpp index 7a262bd2..7c9fa3c3 100644 --- a/include/boost/url/impl/segments.hpp +++ b/include/boost/url/impl/segments.hpp @@ -12,7 +12,6 @@ #define BOOST_URL_IMPL_SEGMENTS_HPP #include -#include #include #include #include @@ -51,7 +50,7 @@ class segments::iterator public: using value_type = std::string; - using reference = pct_encoded_view; + using reference = decode_view; using pointer = void const*; using difference_type = std::ptrdiff_t; using iterator_category = @@ -170,7 +169,7 @@ inline auto segments:: front() const -> - pct_encoded_view + decode_view { BOOST_ASSERT(! empty()); return *begin(); @@ -180,7 +179,7 @@ inline auto segments:: back() const -> - pct_encoded_view + decode_view { BOOST_ASSERT(! empty()); return *std::prev(end()); diff --git a/include/boost/url/impl/segments_view.hpp b/include/boost/url/impl/segments_view.hpp index e37da79a..42f7221a 100644 --- a/include/boost/url/impl/segments_view.hpp +++ b/include/boost/url/impl/segments_view.hpp @@ -42,7 +42,7 @@ class segments_view:: public: using value_type = std::string; - using reference = pct_encoded_view; + using reference = decode_view; using pointer = void const*; using difference_type = std::ptrdiff_t; using iterator_category = @@ -55,7 +55,7 @@ public: iterator& operator=(iterator const&) noexcept = default; - pct_encoded_view + decode_view operator*() const noexcept { return impl_.dereference(); @@ -127,7 +127,7 @@ is_absolute() const noexcept //------------------------------------------------ inline -pct_encoded_view +decode_view segments_view:: front() const noexcept { @@ -136,7 +136,7 @@ front() const noexcept } inline -pct_encoded_view +decode_view segments_view:: back() const noexcept { diff --git a/include/boost/url/impl/url_base.ipp b/include/boost/url/impl/url_base.ipp index 6ca7fd7c..3073153e 100644 --- a/include/boost/url/impl/url_base.ipp +++ b/include/boost/url/impl/url_base.ipp @@ -258,11 +258,11 @@ set_user(string_view s) this->string()); s = buf.maybe_copy(s); check_invariants(); - auto const n = pct_encode_bytes( - s, detail::user_chars); + auto const n = encoded_size( + s, {}, detail::user_chars); auto dest = set_user_impl(n); - pct_encode(dest, u_.get(id_pass).data(), - s, detail::user_chars); + encode(dest, u_.get(id_pass).data(), + s, {}, detail::user_chars); u_.decoded_[id_user] = s.size(); check_invariants(); return *this; @@ -270,7 +270,7 @@ set_user(string_view s) url_base& url_base:: -set_user(pct_encoded_view s) +set_user(decode_view s) { grammar::detail::copied_strings< BOOST_URL_STACK_BYTES> buf( @@ -278,17 +278,17 @@ set_user(pct_encoded_view s) s = s.maybe_copy(buf); check_invariants(); auto const n = - detail::pct_encode_bytes_impl( + detail::encoded_size_impl( s.begin(), s.end(), - detail::user_chars); + {}, detail::user_chars); auto dest = set_user_impl(n); - detail::pct_encode_impl( + detail::encode_impl( dest, u_.get(id_pass).data(), s.begin(), s.end(), - detail::user_chars); + {}, detail::user_chars); u_.decoded_[id_user] = s.size(); check_invariants(); return *this; @@ -304,15 +304,15 @@ set_encoded_user( this->string()); s = buf.maybe_copy(s); check_invariants(); - auto const rn = - validate_pct_encoding( + auto const rv = + decode( s, - detail::user_chars, - {}); - if( !rn ) + {}, + detail::user_chars); + if( !rv ) detail::throw_invalid_argument(); auto dest = set_user_impl(s.size()); - u_.decoded_[id_user] = *rn; + u_.decoded_[id_user] = rv->size(); if(! s.empty()) { BOOST_ASSERT(dest != nullptr); @@ -381,13 +381,14 @@ set_password(string_view s) this->string()); s = buf.maybe_copy(s); check_invariants(); - auto const n = pct_encode_bytes( - s, detail::password_chars); + auto const n = encoded_size( + s, {}, detail::password_chars); auto dest = set_password_impl(n); - pct_encode( + encode( dest, u_.get(id_host).data() - 1, s, + {}, detail::password_chars); u_.decoded_[id_pass] = s.size(); check_invariants(); @@ -396,7 +397,7 @@ set_password(string_view s) url_base& url_base:: -set_password(pct_encoded_view s) +set_password(decode_view s) { grammar::detail::copied_strings< BOOST_URL_STACK_BYTES> buf( @@ -404,17 +405,17 @@ set_password(pct_encoded_view s) s = s.maybe_copy(buf); check_invariants(); auto const n = - detail::pct_encode_bytes_impl( + detail::encoded_size_impl( s.begin(), s.end(), - detail::password_chars); + {}, detail::password_chars); auto dest = set_password_impl(n); - detail::pct_encode_impl( + detail::encode_impl( dest, u_.get(id_host).data() - 1, s.begin(), s.end(), - detail::password_chars); + {}, detail::password_chars); u_.decoded_[id_pass] = s.size(); check_invariants(); return *this; @@ -430,13 +431,13 @@ set_encoded_password( this->string()); s = buf.maybe_copy(s); check_invariants(); - auto const rn = validate_pct_encoding( - s, detail::password_chars, {}); - if( !rn ) + auto const rv = decode( + s, {}, detail::password_chars); + if( !rv ) detail::throw_invalid_argument(); auto dest = set_password_impl(s.size()); - u_.decoded_[id_pass] = *rn; + u_.decoded_[id_pass] = rv->size(); if(! s.empty()) { BOOST_ASSERT(dest != nullptr); @@ -495,13 +496,14 @@ set_userinfo( this->string()); s = buf.maybe_copy(s); check_invariants(); - auto const n = pct_encode_bytes( - s, detail::userinfo_chars); + auto const n = encoded_size( + s, {}, detail::userinfo_chars); auto dest = set_userinfo_impl(n); - pct_encode( + encode( dest, u_.get(id_host).data() - 1, s, + {}, detail::userinfo_chars); auto pct_s = u_.get(id_user, id_host); auto pct_sep = pct_s.find_first_of(':'); @@ -524,7 +526,7 @@ set_userinfo( url_base& url_base:: set_userinfo( - pct_encoded_view s) + decode_view s) { grammar::detail::copied_strings< BOOST_URL_STACK_BYTES> buf( @@ -532,17 +534,17 @@ set_userinfo( s = s.maybe_copy(buf); check_invariants(); auto const n = - detail::pct_encode_bytes_impl( + detail::encoded_size_impl( s.begin(), s.end(), - detail::userinfo_chars); + {}, detail::userinfo_chars); auto dest = set_userinfo_impl(n); - detail::pct_encode_impl( + detail::encode_impl( dest, u_.get(id_host).data() - 1, s.begin(), s.end(), - detail::userinfo_chars); + {}, detail::userinfo_chars); auto pct_s = u_.get(id_user, id_host); auto pct_sep = pct_s.find_first_of(':'); if (pct_sep != string_view::npos) @@ -686,13 +688,14 @@ set_host( return set_host(r.value()); } check_invariants(); - auto const n = pct_encode_bytes( - s, detail::host_chars); + auto const n = encoded_size( + s, {}, detail::host_chars); auto dest = set_host_impl(n); - pct_encode( + encode( dest, u_.get(id_path).data(), s, + {}, detail::host_chars); u_.decoded_[id_host] = s.size(); u_.host_type_ = @@ -704,7 +707,7 @@ set_host( url_base& url_base:: set_host( - pct_encoded_view s) + decode_view s) { grammar::detail::copied_strings< BOOST_URL_STACK_BYTES> buf( @@ -717,15 +720,15 @@ set_host( return set_host(r.value()); } check_invariants(); - auto const n = detail::pct_encode_bytes_impl( - s.begin(), s.end(), detail::host_chars); + auto const n = detail::encoded_size_impl( + s.begin(), s.end(), {}, detail::host_chars); auto dest = set_host_impl(n); - detail::pct_encode_impl( + detail::encode_impl( dest, u_.get(id_path).data(), s.begin(), s.end(), - detail::host_chars); + {}, detail::host_chars); u_.decoded_[id_host] = s.size(); u_.host_type_ = urls::host_type::name; @@ -1407,7 +1410,7 @@ set_path( url_base& url_base:: set_path( - pct_encoded_view s) + decode_view s) { grammar::detail::copied_strings< BOOST_URL_STACK_BYTES> buf( @@ -1637,7 +1640,7 @@ set_encoded_query( detail::enc_query_iter(s), true); u_.decoded_[id_query] = - pct_decode_bytes_unchecked( + detail::decode_bytes_unchecked( encoded_query()); check_invariants(); return *this; @@ -1661,7 +1664,7 @@ set_query( detail::plain_query_iter(s), true); u_.decoded_[id_query] = - pct_decode_bytes_unchecked( + detail::decode_bytes_unchecked( encoded_query()); return *this; } @@ -1669,7 +1672,7 @@ set_query( url_base& url_base:: set_query( - pct_encoded_view s) + decode_view s) { if (s.empty()) remove_query(); @@ -1684,7 +1687,7 @@ set_query( detail::view_query_iter(s), true); u_.decoded_[id_query] = - pct_decode_bytes_unchecked( + detail::decode_bytes_unchecked( encoded_query()); return *this; } @@ -1745,13 +1748,14 @@ set_fragment(string_view s) this->string()); s = buf.maybe_copy(s); check_invariants(); - auto const n = pct_encode_bytes( - s, detail::fragment_chars); + auto const n = encoded_size( + s, {}, detail::fragment_chars); auto dest = set_fragment_impl(n); - pct_encode( + encode( dest, u_.get(id_end).data(), s, + {}, detail::fragment_chars); u_.decoded_[id_frag] = s.size(); check_invariants(); @@ -1761,7 +1765,7 @@ set_fragment(string_view s) url_base& url_base:: set_fragment( - pct_encoded_view s) + decode_view s) { grammar::detail::copied_strings< BOOST_URL_STACK_BYTES> buf( @@ -1769,17 +1773,17 @@ set_fragment( s = s.maybe_copy(buf); check_invariants(); auto const n = - detail::pct_encode_bytes_impl( + detail::encoded_size_impl( s.begin(), s.end(), - detail::fragment_chars); + {}, detail::fragment_chars); auto dest = set_fragment_impl(n); - detail::pct_encode_impl( + detail::encode_impl( dest, u_.get(id_end).data(), s.begin(), s.end(), - detail::fragment_chars); + {}, detail::fragment_chars); u_.decoded_[id_frag] = s.size(); check_invariants(); return *this; @@ -2016,7 +2020,7 @@ normalize_octets_impl( break; // decode unreserved octets - pct_decode_unchecked( + detail::decode_unchecked( &buf, &buf + 1, string_view(it, 3)); diff --git a/include/boost/url/impl/url_view_base.ipp b/include/boost/url/impl/url_view_base.ipp index 4ef4519f..de984fa5 100644 --- a/include/boost/url/impl/url_view_base.ipp +++ b/include/boost/url/impl/url_view_base.ipp @@ -310,7 +310,7 @@ encoded_hostname() const noexcept return s; } -pct_encoded_view +decode_view url_view_base:: hostname() const noexcept { @@ -342,7 +342,7 @@ hostname() const noexcept break; } } - pct_decode_opts opt; + decode_opts opt; opt.plus_to_space = false; return detail::access::construct( s, n, opt); diff --git a/include/boost/url/params.hpp b/include/boost/url/params.hpp index 6efea77d..f934c4fc 100644 --- a/include/boost/url/params.hpp +++ b/include/boost/url/params.hpp @@ -12,8 +12,8 @@ #define BOOST_URL_PARAMS_HPP #include +#include #include -#include #include #include #include diff --git a/include/boost/url/params_encoded_view.hpp b/include/boost/url/params_encoded_view.hpp index 6dd5883a..50cbffe4 100644 --- a/include/boost/url/params_encoded_view.hpp +++ b/include/boost/url/params_encoded_view.hpp @@ -78,7 +78,6 @@ class params_encoded_view : private detail::parts_base { friend class url_view_base; - friend struct query_rule_t; string_view s_; std::size_t n_ = 0; @@ -412,7 +411,7 @@ public: @ref result. */ BOOST_URL_DECL -result +result parse_query_params( string_view s) noexcept; diff --git a/include/boost/url/params_view.hpp b/include/boost/url/params_view.hpp index 2a5cf63c..33794beb 100644 --- a/include/boost/url/params_view.hpp +++ b/include/boost/url/params_view.hpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include @@ -31,6 +31,7 @@ class params_view { friend class url_view_base; friend class params_encoded_view; + friend struct query_rule_t; string_view s_; std::size_t n_ = 0; @@ -138,6 +139,14 @@ public: // //-------------------------------------------- + /** Return the encoded string referenced by the container + */ + string_view + encoded_string() const noexcept + { + return s_; + } + /** Access the specified element, with bounds checking. Returns a constant reference to the mapped value of @@ -156,7 +165,7 @@ public: @throw std::out_of_range if no such element exists. */ BOOST_URL_DECL - pct_encoded_view + decode_view at(string_view key) const; //-------------------------------------------- diff --git a/include/boost/url/query_param.hpp b/include/boost/url/query_param.hpp index 33578daf..152e685a 100644 --- a/include/boost/url/query_param.hpp +++ b/include/boost/url/query_param.hpp @@ -13,7 +13,7 @@ #include #include -#include +#include namespace boost { namespace urls { @@ -49,7 +49,7 @@ struct query_param_view { /** The percent-decoded key */ - pct_encoded_view key; + decode_view key; /** The percent-decoded value @@ -58,7 +58,7 @@ struct query_param_view A value that is present with an empty string is distinct from a value that is absent. */ - pct_encoded_view value; + decode_view value; /** True if the value is present @@ -84,8 +84,8 @@ struct query_param_view /// Constructor query_param_view( - pct_encoded_view key_, - pct_encoded_view value_ = {}, + decode_view key_, + decode_view value_ = {}, bool has_value_ = false ) noexcept : key(key_) , value(value_) @@ -157,8 +157,8 @@ struct query_param_encoded_view /// Constructor query_param_encoded_view( - pct_encoded_view key_, - pct_encoded_view value_ = {}, + decode_view key_, + decode_view value_ = {}, bool has_value_ = false ) noexcept : key(key_.encoded()) , value(value_.encoded()) @@ -172,12 +172,12 @@ struct query_param_encoded_view { if(has_value) return { - pct_encoded_view(key), - pct_encoded_view(value), + decode_view(key), + decode_view(value), true }; return { - pct_encoded_view(key), - pct_encoded_view(), + decode_view(key), + decode_view(), false }; } @@ -271,8 +271,8 @@ struct query_param /** Constructor */ query_param( - pct_encoded_view const& key_, - pct_encoded_view const& value_, + decode_view const& key_, + decode_view const& value_, bool has_value_) : key(key_.to_string()) , value(value_.to_string()) @@ -298,12 +298,12 @@ struct query_param { if(has_value) return { - pct_encoded_view(key), - pct_encoded_view(value), + decode_view(key), + decode_view(value), true }; return { - pct_encoded_view(key), - pct_encoded_view(), + decode_view(key), + decode_view(), false }; } diff --git a/include/boost/url/rfc/detail/hier_part_rule.hpp b/include/boost/url/rfc/detail/hier_part_rule.hpp index 94205105..98ec3ad0 100644 --- a/include/boost/url/rfc/detail/hier_part_rule.hpp +++ b/include/boost/url/rfc/detail/hier_part_rule.hpp @@ -11,7 +11,7 @@ #define BOOST_URL_RFC_DETAIL_HIER_PART_RULE_HPP #include -#include +#include #include #include @@ -40,7 +40,7 @@ struct hier_part_rule_t bool has_authority = false; authority_view authority; grammar::range< - pct_encoded_view> path; + decode_view> path; }; BOOST_URL_DECL diff --git a/include/boost/url/rfc/detail/host_rule.hpp b/include/boost/url/rfc/detail/host_rule.hpp index b29366d6..1338b453 100644 --- a/include/boost/url/rfc/detail/host_rule.hpp +++ b/include/boost/url/rfc/detail/host_rule.hpp @@ -11,7 +11,7 @@ #define BOOST_URL_RFC_DETAIL_HOST_RULE_HPP #include -#include +#include #include #include #include @@ -45,7 +45,7 @@ struct host_rule_t urls::host_type::none; string_view match; unsigned char addr[16] = {}; - pct_encoded_view name; + decode_view name; }; auto diff --git a/include/boost/url/rfc/detail/path_rules.hpp b/include/boost/url/rfc/detail/path_rules.hpp index 0a74802a..41903c36 100644 --- a/include/boost/url/rfc/detail/path_rules.hpp +++ b/include/boost/url/rfc/detail/path_rules.hpp @@ -104,7 +104,7 @@ constexpr __implementation_defined__ segment_ns_rule; #else struct segment_ns_rule_t { - using value_type = pct_encoded_view; + using value_type = decode_view; BOOST_URL_DECL result diff --git a/include/boost/url/rfc/detail/relative_part_rule.hpp b/include/boost/url/rfc/detail/relative_part_rule.hpp index 64b06c60..a9d2cc5d 100644 --- a/include/boost/url/rfc/detail/relative_part_rule.hpp +++ b/include/boost/url/rfc/detail/relative_part_rule.hpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include @@ -46,7 +46,7 @@ struct relative_part_rule_t { bool has_authority = false; decltype(authority_rule)::value_type authority; - grammar::range path; + grammar::range path; }; auto diff --git a/include/boost/url/rfc/detail/userinfo_rule.hpp b/include/boost/url/rfc/detail/userinfo_rule.hpp index 6e393bdf..2c8a4e50 100644 --- a/include/boost/url/rfc/detail/userinfo_rule.hpp +++ b/include/boost/url/rfc/detail/userinfo_rule.hpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include namespace boost { @@ -37,9 +37,9 @@ struct userinfo_rule_t { struct value_type { - pct_encoded_view user; + decode_view user; bool has_password = false; - pct_encoded_view password; + decode_view password; }; auto diff --git a/include/boost/url/rfc/gen_delim_chars.hpp b/include/boost/url/rfc/gen_delim_chars.hpp index 3a14201d..899e02d9 100644 --- a/include/boost/url/rfc/gen_delim_chars.hpp +++ b/include/boost/url/rfc/gen_delim_chars.hpp @@ -23,7 +23,7 @@ namespace urls { the functions @ref grammar::find_if and @ref grammar::find_if_not. @code - result< pct_encoded_view > rv = grammar::parse( "Program%20Files", pct_encoded_rule( gen_delim_chars ) ); + result< decode_view > rv = grammar::parse( "Program%20Files", pct_encoded_rule( gen_delim_chars ) ); @endcode @par BNF diff --git a/include/boost/url/rfc/impl/pct_encoded_rule.hpp b/include/boost/url/rfc/impl/pct_encoded_rule.hpp index f0a8a5f0..429f0bc2 100644 --- a/include/boost/url/rfc/impl/pct_encoded_rule.hpp +++ b/include/boost/url/rfc/impl/pct_encoded_rule.hpp @@ -10,8 +10,8 @@ #ifndef BOOST_URL_RFC_IMPL_PCT_ENCODED_RULE_HPP #define BOOST_URL_RFC_IMPL_PCT_ENCODED_RULE_HPP -#include #include +#include namespace boost { namespace urls { @@ -20,11 +20,11 @@ namespace detail { template auto -parse_pct_encoded( +parse_encoded( char const*& it, char const* end, CharSet const& cs) noexcept -> - result + result { auto const start = it; // VFALCO TODO @@ -94,7 +94,7 @@ parse( char const* end) const noexcept -> result { - return detail::parse_pct_encoded( + return detail::parse_encoded( it, end, cs_); } diff --git a/include/boost/url/rfc/impl/query_rule.ipp b/include/boost/url/rfc/impl/query_rule.ipp index a7c2f802..4f06e9f0 100644 --- a/include/boost/url/rfc/impl/query_rule.ipp +++ b/include/boost/url/rfc/impl/query_rule.ipp @@ -11,7 +11,7 @@ #define BOOST_URL_RFC_IMPL_QUERY_RULE_IPP #include -#include +#include #include #include #include diff --git a/include/boost/url/rfc/pchars.hpp b/include/boost/url/rfc/pchars.hpp index 735ffa8a..62ece999 100644 --- a/include/boost/url/rfc/pchars.hpp +++ b/include/boost/url/rfc/pchars.hpp @@ -24,7 +24,7 @@ namespace urls { the functions @ref grammar::find_if and @ref grammar::find_if_not. @code - result< pct_encoded_view > rv = grammar::parse( "Program%20Files", pchars ); + result< decode_view > rv = grammar::parse( "Program%20Files", pchars ); @endcode @par BNF diff --git a/include/boost/url/rfc/pct_encoded_rule.hpp b/include/boost/url/rfc/pct_encoded_rule.hpp index 41923edb..ae42dc42 100644 --- a/include/boost/url/rfc/pct_encoded_rule.hpp +++ b/include/boost/url/rfc/pct_encoded_rule.hpp @@ -11,8 +11,7 @@ #define BOOST_URL_RFC_PCT_ENCODED_RULE_HPP #include -#include -#include +#include #include #include #include @@ -31,7 +30,7 @@ namespace urls { @par Value Type @code - using value_type = pct_encoded_view; + using value_type = decode_view; @endcode @par Example @@ -39,7 +38,7 @@ namespace urls { @code // pchar = unreserved / pct-encoded / sub-delims / ":" / "@" - result< pct_encoded_view > rv = grammar::parse( "Program%20Files", pct_encoded_rule( pchars ) ); + result< decode_view > rv = grammar::parse( "Program%20Files", pct_encoded_rule( pchars ) ); @endcode @par BNF @@ -59,7 +58,7 @@ namespace urls { @see @ref grammar::parse, @ref pchars, - @ref pct_encoded_view. + @ref decode_view. */ #ifdef BOOST_URL_DOCS /**@{*/ @@ -72,7 +71,7 @@ pct_encoded_rule( CharSet const& cs ) noexcept; template struct pct_encoded_rule_t { - using value_type = pct_encoded_view; + using value_type = decode_view; template friend diff --git a/include/boost/url/rfc/query_rule.hpp b/include/boost/url/rfc/query_rule.hpp index a2efb098..878af087 100644 --- a/include/boost/url/rfc/query_rule.hpp +++ b/include/boost/url/rfc/query_rule.hpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include @@ -62,7 +62,7 @@ constexpr __implementation_defined__ query_rule; struct query_rule_t { using value_type = - params_encoded_view; + params_view; BOOST_URL_DECL result diff --git a/include/boost/url/rfc/reserved_chars.hpp b/include/boost/url/rfc/reserved_chars.hpp index 0b823e81..49451fcf 100644 --- a/include/boost/url/rfc/reserved_chars.hpp +++ b/include/boost/url/rfc/reserved_chars.hpp @@ -23,7 +23,7 @@ namespace urls { the functions @ref grammar::find_if and @ref grammar::find_if_not. @code - result< pct_encoded_view > rv = grammar::parse( "Program%20Files", pct_encoded_rule( reserved_chars ) ); + result< decode_view > rv = grammar::parse( "Program%20Files", pct_encoded_rule( reserved_chars ) ); @endcode @par Specification diff --git a/include/boost/url/rfc/sub_delim_chars.hpp b/include/boost/url/rfc/sub_delim_chars.hpp index 371626d8..88076335 100644 --- a/include/boost/url/rfc/sub_delim_chars.hpp +++ b/include/boost/url/rfc/sub_delim_chars.hpp @@ -23,7 +23,7 @@ namespace urls { the functions @ref grammar::find_if and @ref grammar::find_if_not. @code - result< pct_encoded_view > = grammar::parse( "Program%20Files", pct_encoded_rule( sub_delim_chars ) ); + result< decode_view > = grammar::parse( "Program%20Files", pct_encoded_rule( sub_delim_chars ) ); @endcode @par BNF diff --git a/include/boost/url/rfc/unreserved_chars.hpp b/include/boost/url/rfc/unreserved_chars.hpp index 3eec558a..44b18e9e 100644 --- a/include/boost/url/rfc/unreserved_chars.hpp +++ b/include/boost/url/rfc/unreserved_chars.hpp @@ -23,7 +23,7 @@ namespace urls { the functions @ref grammar::find_if and @ref grammar::find_if_not. @code - result< pct_encoded_view > rv = grammar::parse( "Program%20Files", pct_encoded_rule( unreserved_chars ) ); + result< decode_view > rv = grammar::parse( "Program%20Files", pct_encoded_rule( unreserved_chars ) ); @endcode @par BNF diff --git a/include/boost/url/segments.hpp b/include/boost/url/segments.hpp index c5ec6bc5..ae3d4fcd 100644 --- a/include/boost/url/segments.hpp +++ b/include/boost/url/segments.hpp @@ -12,7 +12,7 @@ #define BOOST_URL_SEGMENTS_HPP #include -#include +#include #include #include #include @@ -107,10 +107,10 @@ public: This type does not make a copy of a segment and ownership is retained by the container. */ - using reference = pct_encoded_view; + using reference = decode_view; /// @copydoc reference - using const_reference = pct_encoded_view; + using const_reference = decode_view; /** An unsigned integer type */ @@ -275,7 +275,7 @@ public: @par Complexity Constant. */ - pct_encoded_view + decode_view front() const; /** Access the last element. @@ -288,7 +288,7 @@ public: @par Complexity Constant. */ - pct_encoded_view + decode_view back() const; //-------------------------------------------- diff --git a/include/boost/url/segments_view.hpp b/include/boost/url/segments_view.hpp index 5434cba6..b90266d6 100644 --- a/include/boost/url/segments_view.hpp +++ b/include/boost/url/segments_view.hpp @@ -12,7 +12,7 @@ #define BOOST_URL_SEGMENTS_VIEW_HPP #include -#include +#include #include #include @@ -75,10 +75,10 @@ public: and ownership is retained by the container. */ - using reference = pct_encoded_view; + using reference = decode_view; /// @copydoc reference - using const_reference = pct_encoded_view; + using const_reference = decode_view; /** The unsigned integer type used to represent size. */ @@ -163,7 +163,7 @@ public: @par Complexity Constant. */ - pct_encoded_view + decode_view front() const noexcept; /** Access the last element. @@ -176,7 +176,7 @@ public: @par Complexity Constant. */ - pct_encoded_view + decode_view back() const noexcept; //-------------------------------------------- diff --git a/include/boost/url/src.hpp b/include/boost/url/src.hpp index 35ff80b2..be11067c 100644 --- a/include/boost/url/src.hpp +++ b/include/boost/url/src.hpp @@ -29,18 +29,19 @@ in a translation unit of the program. #include #include +#include #include #include #include #include #include #include -#include #include #include #include #include +#include #include #include #include @@ -48,8 +49,7 @@ in a translation unit of the program. #include #include #include -#include -#include +#include #include #include #include diff --git a/include/boost/url/url.natvis b/include/boost/url/url.natvis index 2c9f80e8..75e6df7b 100644 --- a/include/boost/url/url.natvis +++ b/include/boost/url/url.natvis @@ -5,7 +5,7 @@ {(addr_>>24)}.{(addr_>>16)%256}.{(addr_>>8)%256}.{addr_%256} - + {p_,[n_]s} {p_,[n_]s} ({dn_}) diff --git a/include/boost/url/url_base.hpp b/include/boost/url/url_base.hpp index 05ad9275..398e3a86 100644 --- a/include/boost/url/url_base.hpp +++ b/include/boost/url/url_base.hpp @@ -285,7 +285,7 @@ public: BOOST_URL_DECL url_base& set_user( - pct_encoded_view s); + decode_view s); /** Set the user. @@ -360,7 +360,7 @@ public: BOOST_URL_DECL url_base& set_password( - pct_encoded_view s); + decode_view s); /** Set the password. @@ -501,7 +501,7 @@ public: BOOST_URL_DECL url_base& set_userinfo( - pct_encoded_view s); + decode_view s); //-------------------------------------------- @@ -620,7 +620,7 @@ public: BOOST_URL_DECL url_base& set_host( - pct_encoded_view s); + decode_view s); /** Set the host @@ -980,7 +980,7 @@ public: BOOST_URL_DECL url_base& set_path( - pct_encoded_view s); + decode_view s); /** Return the path segments @@ -1148,7 +1148,7 @@ public: BOOST_URL_DECL url_base& set_query( - pct_encoded_view s); + decode_view s); /** Return the query parameters @@ -1290,7 +1290,7 @@ public: BOOST_URL_DECL url_base& set_fragment( - pct_encoded_view s); + decode_view s); //-------------------------------------------- // diff --git a/include/boost/url/url_view_base.hpp b/include/boost/url/url_view_base.hpp index aeedb3fb..5ac29da6 100644 --- a/include/boost/url/url_view_base.hpp +++ b/include/boost/url/url_view_base.hpp @@ -18,11 +18,9 @@ #include #include #include -#include #include #include #include -#include #include #include #include @@ -568,10 +566,10 @@ public: @ref encoded_userinfo, @ref has_userinfo. */ - pct_encoded_view + decode_view userinfo() const noexcept { - pct_decode_opts opt; + decode_opts opt; opt.plus_to_space = false; string_view s = encoded_userinfo(); return @@ -654,10 +652,10 @@ public: @ref has_password, @ref password. */ - pct_encoded_view + decode_view user() const noexcept { - pct_decode_opts opt; + decode_opts opt; opt.plus_to_space = false; string_view s = encoded_user(); return @@ -764,10 +762,10 @@ public: @ref has_password, @ref user. */ - pct_encoded_view + decode_view password() const noexcept { - pct_decode_opts opt; + decode_opts opt; opt.plus_to_space = false; string_view s = encoded_password(); return @@ -910,10 +908,10 @@ public: @ref port, @ref port_number. */ - pct_encoded_view + decode_view host() const noexcept { - pct_decode_opts opt; + decode_opts opt; opt.plus_to_space = false; string_view s = encoded_host(); return @@ -1010,7 +1008,7 @@ public: @ref port_number. */ BOOST_URL_DECL - pct_encoded_view + decode_view hostname() const noexcept; /** Return the host as an IPv4 address @@ -1431,10 +1429,10 @@ public: @ref encoded_query, @ref has_query. */ - pct_encoded_view + decode_view path() const noexcept { - pct_decode_opts opt; + decode_opts opt; opt.plus_to_space = false; string_view s = encoded_path(); return @@ -1666,10 +1664,10 @@ public: @ref encoded_query, @ref has_query. */ - pct_encoded_view + decode_view query() const noexcept { - pct_decode_opts opt; + decode_opts opt; opt.plus_to_space = true; string_view s = encoded_query(); return @@ -1837,10 +1835,10 @@ public: @ref encoded_fragment, @ref has_fragment. */ - pct_encoded_view + decode_view fragment() const noexcept { - pct_decode_opts opt; + decode_opts opt; opt.plus_to_space = false; string_view s = encoded_fragment(); return diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 86a5a210..262fb0df 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -20,6 +20,8 @@ set(BOOST_URL_TESTS_FILES authority_view.cpp doc_container.cpp doc_grammar.cpp + decode.cpp + encode.cpp error.cpp error_types.cpp grammar.cpp @@ -32,8 +34,7 @@ set(BOOST_URL_TESTS_FILES params_encoded.cpp params_encoded_view.cpp params_view.cpp - pct_encoded_view.cpp - pct_encoding.cpp + decode_view.cpp query_param.cpp scheme.cpp segments.cpp diff --git a/test/unit/Jamfile b/test/unit/Jamfile index 8ba22231..133cf738 100644 --- a/test/unit/Jamfile +++ b/test/unit/Jamfile @@ -25,6 +25,9 @@ local SOURCES = authority_view.cpp error.cpp error_types.cpp + encode.cpp + decode.cpp + decode_view.cpp grammar.cpp host_type.cpp ipv4_address.cpp @@ -34,8 +37,6 @@ local SOURCES = params_encoded.cpp params_encoded_view.cpp params_view.cpp - pct_encoded_view.cpp - pct_encoding.cpp query_param.cpp scheme.cpp segments.cpp diff --git a/test/unit/pct_encoding.cpp b/test/unit/decode.cpp similarity index 72% rename from test/unit/pct_encoding.cpp rename to test/unit/decode.cpp index 6acae53d..bbf2232e 100644 --- a/test/unit/pct_encoding.cpp +++ b/test/unit/decode.cpp @@ -1,5 +1,6 @@ // // 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) @@ -8,16 +9,18 @@ // // Test that header file is self-contained. -#include +#include #include #include "test_suite.hpp" +#include +#include #include namespace boost { namespace urls { -class pct_encoding_test +class decode_test { public: struct test_chars @@ -30,16 +33,6 @@ public: } }; - struct test_chars_null - { - constexpr - bool - operator()(char c) const noexcept - { - return c == 'A' || c == '\0'; - } - }; - //-------------------------------------------- struct string_param : string_view @@ -58,29 +51,38 @@ public: constexpr grammar::lut_chars CS1("A+"); constexpr grammar::lut_chars CS2 = CS1 + '\0'; grammar::lut_chars const* pcs = &CS1; - pct_decode_opts opt; + decode_opts opt; auto const good = [&]( string_param s0, string_param s1) { - // validate_pct_encoding + // decode -> decode_view { - auto rn = validate_pct_encoding( - s0, *pcs, opt); + auto const r = decode(s0, opt, *pcs); + if (BOOST_TEST(r.has_value())) + { + BOOST_TEST_EQ(r->size(), s1.size()); + BOOST_TEST_EQ(*r, s1); + } + } + // detail::validate_encoding + { + auto rn = detail::validate_encoding( + s0, opt, *pcs); if(! BOOST_TEST(! rn.has_error())) return; BOOST_TEST_EQ(*rn, s1.size()); } - // pct_decode to buffer + // decode to buffer { char buf[16]; for(std::size_t i = 0; i < sizeof(buf); ++i) { - auto const rn = pct_decode( + auto const rn = detail::decode( buf, buf + i, - s0, *pcs, opt); + s0, opt, *pcs); if(i < s1.size()) { BOOST_TEST( @@ -96,37 +98,37 @@ public: break; } } - // pct_decode() -> std::string + // decode() -> std::string { std::string s; - s.resize(pct_decode_bytes_unchecked(s0)); + s.resize(detail::decode_bytes_unchecked(s0)); auto rn = - pct_decode(&s[0], &s[0] + s.size(), s0, opt); + detail::decode(&s[0], &s[0] + s.size(), s0, opt); BOOST_TEST(rn.has_value()); s.resize(*rn); BOOST_TEST_EQ(s, s1); } - // pct_decode() -> std::basic_string + // decode() -> std::basic_string { using A = std::allocator; std::basic_string, A> s(A{}); - s.resize(pct_decode_bytes_unchecked(s0)); - auto rn = pct_decode(&s[0], &s[0] + s.size(), s0, opt); + s.resize(detail::decode_bytes_unchecked(s0)); + auto rn = detail::decode(&s[0], &s[0] + s.size(), s0, opt); BOOST_TEST(rn.has_value()); BOOST_TEST_EQ(s, s1); } - // pct_decode_bytes_unchecked + // detail::decode_bytes_unchecked { auto const n = - pct_decode_bytes_unchecked(s0); + detail::decode_bytes_unchecked(s0); BOOST_TEST_EQ(n, s1.size()); } - // pct_decode_unchecked + // decode_unchecked { char buf[16]; auto const n = - pct_decode_unchecked( + detail::decode_unchecked( buf, buf + sizeof(buf), s0, opt); BOOST_TEST_EQ(n, s1.size()); @@ -138,32 +140,32 @@ public: auto const bad = [&]( string_param s) { - // validate_pct_encoding + // detail::validate_encoding { - auto rn = validate_pct_encoding( - s, test_chars{}, opt); + auto rn = detail::validate_encoding( + s, opt, test_chars{}); BOOST_TEST(rn.has_error()); if (!rn.has_error()) BOOST_TEST_EQ(s, ""); } - // pct_decode to buffer + // decode to buffer { char buf[16]; - auto rn = pct_decode(buf, + auto rn = detail::decode(buf, buf + sizeof(buf), - s, *pcs, opt); + s, opt, *pcs); BOOST_TEST(rn.has_error()); } - // pct_decode_bytes_unchecked + // detail::decode_bytes_unchecked { // don't crash - pct_decode_bytes_unchecked(s); + detail::decode_bytes_unchecked(s); } - // pct_decode_unchecked + // detail::decode_unchecked { // don't crash char buf[16]; - pct_decode_unchecked( + detail::decode_unchecked( buf, buf + sizeof(buf), s, opt); } @@ -177,7 +179,7 @@ public: { std::memset( buf, 0xff, sizeof(buf)); - pct_decode_unchecked(buf, + detail::decode_unchecked(buf, buf + i, s, opt); string_view s1(buf, sizeof(buf)); BOOST_TEST(s1.find(' ') == @@ -334,32 +336,32 @@ public: string_view m0, bool space_to_plus = false) { - // pct_encode_bytes + // encoded_size { - pct_encode_opts opt; + encode_opts opt; opt.space_to_plus = space_to_plus; - BOOST_TEST(pct_encode_bytes( - s, test_chars{}, opt) == + BOOST_TEST(encoded_size( + s, opt, test_chars{}) == m0.size()); } - // pct_encode + // encode { - pct_encode_opts opt; + encode_opts opt; opt.space_to_plus = space_to_plus; std::string t; t.resize( - pct_encode_bytes(s, test_chars{}, opt)); - pct_encode( - &t[0], &t[0] + t.size(), s, test_chars{}, opt); + encoded_size(s, opt, test_chars{})); + encode( + &t[0], &t[0] + t.size(), s, opt, test_chars{}); BOOST_TEST(t == m0); } - pct_encode_opts opt; + encode_opts opt; opt.space_to_plus = space_to_plus; - auto const m = pct_encode_to_string( - s, test_chars{}, opt); + auto const m = encode_to_string( + s, opt, test_chars{}); if(! BOOST_TEST(m == m0)) return; char buf[64]; @@ -370,8 +372,8 @@ public: { char* dest = buf; char const* end = buf + i; - std::size_t n = pct_encode( - dest, end, s, test_chars{}, opt); + std::size_t n = encode( + dest, end, s, opt, test_chars{}); string_view r(buf, n); if(n == m.size()) { @@ -385,63 +387,20 @@ public: } }; - void - testEncode() - { - check("", ""); - check(" ", "%20"); - check("A", "A"); - check("B", "%42"); - check("AB", "A%42"); - check("A B", "A%20%42"); - - check("", "", true); - check(" ", "+", true); - check("A", "A", true); - check("B", "%42", true); - check("AB", "A%42", true); - check("A B", "A+%42", true); - } - - void - testEncodeExtras() - { - // space_to_plus - { - BOOST_TEST(pct_encode_to_string( - " ", test_chars{}, {}) == "%20"); - pct_encode_opts opt; - BOOST_TEST_EQ(opt.space_to_plus, false); - BOOST_TEST(pct_encode_to_string( - " ", test_chars{}, opt) == "%20"); - BOOST_TEST(pct_encode_to_string( - "A", test_chars{}, opt) == "A"); - BOOST_TEST(pct_encode_to_string( - " A+", test_chars{}, opt) == "%20A+"); - opt.space_to_plus = true; - BOOST_TEST(pct_encode_to_string( - " ", test_chars{}, opt) == "+"); - BOOST_TEST(pct_encode_to_string( - "A", test_chars{}, opt) == "A"); - BOOST_TEST(pct_encode_to_string( - " A+", test_chars{}, opt) == "+A+"); - } - } - void testValidate() { auto check = []( string_view s, error_code ec, - pct_decode_opts opt) + decode_opts opt) { - auto r = validate_pct_encoding(s, opt); + auto r = detail::validate_encoding(s, opt); BOOST_TEST(r.has_error()); BOOST_TEST(r.error() == ec); }; - pct_decode_opts opt; + decode_opts opt; opt.allow_null = true; check("%a", error::missing_pct_hexdig, opt); check("%ar", error::bad_pct_hexdig, opt); @@ -455,14 +414,14 @@ public: { std::string dest; dest.resize(1); - result r = pct_decode( + result r = detail::decode( &dest[0], &dest[1], "%a", opt); BOOST_TEST_EQ(r.error(), error::missing_pct_hexdig); } { std::string dest; dest.resize(1); - result r = pct_decode( + result r = detail::decode( &dest[0], &dest[1], "%aa%aa", opt); BOOST_TEST_EQ(r.error(), error::no_space); } @@ -472,15 +431,13 @@ public: run() { testDecoding(); - testEncode(); - testEncodeExtras(); testValidate(); } }; TEST_SUITE( - pct_encoding_test, - "boost.url.pct_encoding"); + decode_test, + "boost.url.decode"); } // urls } // boost diff --git a/test/unit/pct_encoded_view.cpp b/test/unit/decode_view.cpp similarity index 77% rename from test/unit/pct_encoded_view.cpp rename to test/unit/decode_view.cpp index a48eaec1..ddb26289 100644 --- a/test/unit/pct_encoded_view.cpp +++ b/test/unit/decode_view.cpp @@ -8,7 +8,7 @@ // // Test that header file is self-contained. -#include +#include #include #include @@ -18,15 +18,15 @@ namespace boost { namespace urls { -struct pct_encoded_view_test +struct decode_view_test { string_view str = "a%20uri+test"; string_view dec_str = "a uri test"; string_view no_plus_dec_str = "a uri+test"; const std::size_t dn = 10; - pct_decode_opts no_plus_opt; + decode_opts no_plus_opt; - pct_encoded_view_test() + decode_view_test() { no_plus_opt.plus_to_space = false; } @@ -34,80 +34,80 @@ struct pct_encoded_view_test void testDecodedView() { - // pct_encoded_view() + // decode_view() { - pct_encoded_view s; + decode_view s; BOOST_TEST_EQ(s, ""); BOOST_TEST_EQ(s.size(), 0u); BOOST_TEST_EQ(s.encoded().size(), 0u); } - // pct_encoded_view(char const*) + // decode_view(char const*) { - pct_encoded_view s(str.data()); + decode_view s(str.data()); BOOST_TEST_EQ(s, dec_str); BOOST_TEST_EQ(s.size(), dn); BOOST_TEST_EQ(s.encoded().size(), str.size()); } - // pct_encoded_view(char const*, bool plus_to_space) + // decode_view(char const*, bool plus_to_space) { - pct_encoded_view + decode_view s(str.data(), no_plus_opt); BOOST_TEST_EQ(s, no_plus_dec_str); BOOST_TEST_EQ(s.size(), dn); BOOST_TEST_EQ(s.encoded().size(), str.size()); } - // pct_encoded_view(string_view) + // decode_view(string_view) { - pct_encoded_view s(str); + decode_view s(str); BOOST_TEST_EQ(s, dec_str); BOOST_TEST_EQ(s.size(), dn); BOOST_TEST_EQ(s.encoded().size(), str.size()); } - // pct_encoded_view(string_view, bool plus_to_space) + // decode_view(string_view, bool plus_to_space) { - pct_encoded_view s(str, no_plus_opt); + decode_view s(str, no_plus_opt); BOOST_TEST_EQ(s, no_plus_dec_str); BOOST_TEST_EQ(s.size(), dn); BOOST_TEST_EQ(s.encoded().size(), str.size()); } #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) - // pct_encoded_view(string_view) + // decode_view(string_view) { std::string_view std_str = str; - pct_encoded_view s(std_str); + decode_view s(std_str); BOOST_TEST_EQ(s, dec_str); BOOST_TEST_EQ(s.size(), dn); BOOST_TEST_EQ(s.encoded().size(), str.size()); } - // pct_encoded_view(string_view, bool plus_to_space) + // decode_view(string_view, bool plus_to_space) { std::string_view std_str = str; - pct_encoded_view s(std_str, no_plus_opt); + decode_view s(std_str, no_plus_opt); BOOST_TEST_EQ(s, no_plus_dec_str); BOOST_TEST_EQ(s.size(), dn); BOOST_TEST_EQ(s.encoded().size(), str.size()); } #endif - // pct_encoded_view(string_view) + // decode_view(string_view) { std::string ss(str); - pct_encoded_view s(ss); + decode_view s(ss); BOOST_TEST_EQ(s, dec_str); BOOST_TEST_EQ(s.size(), dn); BOOST_TEST_EQ(s.encoded().size(), str.size()); } - // pct_encoded_view(string_view, bool plus_to_space) + // decode_view(string_view, bool plus_to_space) { std::string ss(str); - pct_encoded_view s(ss, no_plus_opt); + decode_view s(ss, no_plus_opt); BOOST_TEST_EQ(s, no_plus_dec_str); BOOST_TEST_EQ(s.size(), dn); BOOST_TEST_EQ(s.encoded().size(), str.size()); @@ -119,20 +119,20 @@ struct pct_encoded_view_test { // begin() { - pct_encoded_view s(str); + decode_view s(str); BOOST_TEST_EQ(*s.begin(), s.front()); BOOST_TEST_NE(s.begin(), - pct_encoded_view::iterator{}); + decode_view::iterator{}); } // end() { - pct_encoded_view s(str); + decode_view s(str); auto l = s.end(); --l; BOOST_TEST_EQ(*l, s.back()); BOOST_TEST_NE(l, - pct_encoded_view::iterator{}); + decode_view::iterator{}); } } @@ -141,19 +141,19 @@ struct pct_encoded_view_test { // front() { - pct_encoded_view s(str); + decode_view s(str); BOOST_TEST_EQ(s.front(), 'a'); } // back() { - pct_encoded_view s(str); + decode_view s(str); BOOST_TEST_EQ(s.back(), 't'); } // encoded().data() { - pct_encoded_view s(str); + decode_view s(str); BOOST_TEST_EQ(s.encoded().data(), str.data()); } } @@ -163,34 +163,34 @@ struct pct_encoded_view_test { // size() { - pct_encoded_view s(str); + decode_view s(str); BOOST_TEST_EQ(s.size(), dn); } // encoded().size() { - pct_encoded_view s(str); + decode_view s(str); BOOST_TEST_EQ(s.encoded().size(), str.size()); } // encoded().length() { - pct_encoded_view s(str); + decode_view s(str); BOOST_TEST_EQ(s.encoded().length(), str.size()); } // encoded().max_size() { - pct_encoded_view s(str); + decode_view s(str); BOOST_TEST_GT(s.encoded().max_size(), 0u); } // empty() { - pct_encoded_view s; + decode_view s; BOOST_TEST(s.empty()); - pct_encoded_view s2(str); + decode_view s2(str); BOOST_TEST_NOT(s2.empty()); } } @@ -200,7 +200,7 @@ struct pct_encoded_view_test { // copy() { - pct_encoded_view s(str); + decode_view s(str); std::string out(s.size(), ' '); s.copy(&out[0], s.size()); BOOST_TEST_EQ(s, dec_str); @@ -212,7 +212,7 @@ struct pct_encoded_view_test { // compare() { - pct_encoded_view s(str); + decode_view s(str); BOOST_TEST_EQ(s.compare(dec_str), 0); BOOST_TEST_EQ(s.compare("a a"), 1); BOOST_TEST_EQ(s.compare("a z"), -1); @@ -222,13 +222,13 @@ struct pct_encoded_view_test // operators { - pct_encoded_view s(str); + decode_view s(str); - // pct_encoded_view + // decode_view { - pct_encoded_view s0(str); - pct_encoded_view s1("a%20tri+test"); - pct_encoded_view s2("a%20vri+test"); + decode_view s0(str); + decode_view s1("a%20tri+test"); + decode_view s2("a%20vri+test"); BOOST_TEST(s == s0); BOOST_TEST_NOT(s == s1); BOOST_TEST(s != s2); @@ -306,13 +306,13 @@ struct pct_encoded_view_test { // to_string() { - pct_encoded_view s(str); + decode_view s(str); BOOST_TEST_EQ(s.to_string(), dec_str); } // append_to() { - pct_encoded_view s(str); + decode_view s(str); std::string o = "init "; s.append_to(o); @@ -324,7 +324,7 @@ struct pct_encoded_view_test // assign_to() { - pct_encoded_view s(str); + decode_view s(str); std::string o = "init "; s.assign_to(o); BOOST_TEST_EQ(o, dec_str); @@ -336,7 +336,7 @@ struct pct_encoded_view_test { BOOST_TEST(sv == dec_str); }; - pct_encoded_view s(str); + decode_view s(str); f(s.to_string()); } @@ -346,7 +346,7 @@ struct pct_encoded_view_test { BOOST_TEST(sv == dec_str); }; - pct_encoded_view s(str); + decode_view s(str); f(s.to_string().c_str()); } } @@ -357,7 +357,7 @@ struct pct_encoded_view_test // operator<< { std::stringstream ss; - pct_encoded_view s(str); + decode_view s(str); ss << s; BOOST_TEST_EQ(ss.str(), dec_str); } @@ -368,7 +368,7 @@ struct pct_encoded_view_test { { std::stringstream ss; - urls::pct_encoded_view ds("test+string"); + urls::decode_view ds("test+string"); // no warning about object slicing ss << ds; } @@ -380,7 +380,7 @@ struct pct_encoded_view_test b = a; BOOST_TEST_EQ(b.size(), dn); }; - break_stuff(pct_encoded_view{str}.to_string()); + break_stuff(decode_view{str}.to_string()); } { @@ -398,11 +398,11 @@ struct pct_encoded_view_test boost::ignore_unused(s, dn); } }; - A a1(pct_encoded_view{str}.to_string(), dn); - A a2(std::string_view(pct_encoded_view{str}.to_string()), dn); - A a3 = std::string_view(pct_encoded_view{str}.to_string()); + A a1(decode_view{str}.to_string(), dn); + A a2(std::string_view(decode_view{str}.to_string()), dn); + A a3 = std::string_view(decode_view{str}.to_string()); // https://en.cppreference.com/w/cpp/language/copy_initialization#Notes - // A a4 = pct_encoded_view{str}.to_string(); + // A a4 = decode_view{str}.to_string(); boost::ignore_unused(a1, a2, a3); #endif struct B @@ -418,31 +418,31 @@ struct pct_encoded_view_test boost::ignore_unused(s, dn); } }; - B b1(pct_encoded_view{str}.to_string(), dn); + B b1(decode_view{str}.to_string(), dn); B b2(string_view( - pct_encoded_view{str}.to_string()), dn); + decode_view{str}.to_string()), dn); B b3 = string_view( - pct_encoded_view{str}.to_string()); + decode_view{str}.to_string()); // https://en.cppreference.com/w/cpp/language/copy_initialization#Notes - // B b4 = pct_encoded_view{str}.to_string(); + // B b4 = decode_view{str}.to_string(); boost::ignore_unused(b1, b2, b3); } { #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) auto f1 = []( std::string_view ) {}; - f1(pct_encoded_view{str}.to_string()); + f1(decode_view{str}.to_string()); #endif auto f2 = []( urls::string_view ) {}; - f2(pct_encoded_view{str}.to_string()); + f2(decode_view{str}.to_string()); auto f3 = []( std::string const& ) {}; - f3(pct_encoded_view{str}.to_string()); + f3(decode_view{str}.to_string()); auto f4 = []( std::basic_string, std::allocator> const&) {}; - f4(pct_encoded_view{str}.to_string()); + f4(decode_view{str}.to_string()); } } @@ -462,8 +462,8 @@ struct pct_encoded_view_test }; TEST_SUITE( - pct_encoded_view_test, - "boost.url.pct_encoded_view"); + decode_view_test, + "boost.url.decode_view"); } // urls } // boost diff --git a/test/unit/doc_grammar.cpp b/test/unit/doc_grammar.cpp index c6defceb..b441a6a9 100644 --- a/test/unit/doc_grammar.cpp +++ b/test/unit/doc_grammar.cpp @@ -290,7 +290,7 @@ struct doc_grammar_test { string_view s; //[code_grammar_5_1 - result< pct_encoded_view > rv = parse( s, pct_encoded_rule( pchars ) ); + result< decode_view > rv = parse( s, pct_encoded_rule( pchars ) ); //] } { diff --git a/test/unit/encode.cpp b/test/unit/encode.cpp new file mode 100644 index 00000000..b3dc21a1 --- /dev/null +++ b/test/unit/encode.cpp @@ -0,0 +1,146 @@ +// +// 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/CPPAlliance/url +// + +// Test that header file is self-contained. +#include + +#include "test_suite.hpp" +#include + +namespace boost { +namespace urls { + +class encode_test +{ +public: + struct test_chars + { + constexpr + bool + operator()(char c) const noexcept + { + return c == 'A' || c == '+'; + } + }; + + void + check( + string_view s, + string_view m0, + bool space_to_plus = false) + { + // encoded_size + { + encode_opts opt; + opt.space_to_plus = + space_to_plus; + BOOST_TEST(encoded_size( + s, opt, test_chars{}) == + m0.size()); + } + // encode + { + encode_opts opt; + opt.space_to_plus = + space_to_plus; + std::string t; + t.resize( + encoded_size(s, opt, test_chars{})); + encode( + &t[0], &t[0] + t.size(), s, opt, test_chars{}); + BOOST_TEST(t == m0); + } + encode_opts opt; + opt.space_to_plus = + space_to_plus; + auto const m = encode_to_string( + s, opt, test_chars{}); + if(! BOOST_TEST(m == m0)) + return; + char buf[64]; + BOOST_ASSERT( + m.size() < sizeof(buf)); + for(std::size_t i = 0; + i <= sizeof(buf); ++i) + { + char* dest = buf; + char const* end = buf + i; + std::size_t n = encode( + dest, end, s, opt, test_chars{}); + string_view r(buf, n); + if(n == m.size()) + { + BOOST_TEST_EQ(i, m.size()); + BOOST_TEST_EQ(r, m); + break; + } + BOOST_TEST( + string_view(buf, n) == + m.substr(0, n)); + } + }; + + void + testEncode() + { + check("", ""); + check(" ", "%20"); + check("A", "A"); + check("B", "%42"); + check("AB", "A%42"); + check("A B", "A%20%42"); + + check("", "", true); + check(" ", "+", true); + check("A", "A", true); + check("B", "%42", true); + check("AB", "A%42", true); + check("A B", "A+%42", true); + } + + void + testEncodeExtras() + { + // space_to_plus + { + BOOST_TEST(encode_to_string( + " ", {}, test_chars{}) == "%20"); + encode_opts opt; + BOOST_TEST_EQ(opt.space_to_plus, false); + BOOST_TEST(encode_to_string( + " ", opt, test_chars{}) == "%20"); + BOOST_TEST(encode_to_string( + "A", opt, test_chars{}) == "A"); + BOOST_TEST(encode_to_string( + " A+", opt, test_chars{}) == "%20A+"); + opt.space_to_plus = true; + BOOST_TEST(encode_to_string( + " ", opt, test_chars{}) == "+"); + BOOST_TEST(encode_to_string( + "A", opt, test_chars{}) == "A"); + BOOST_TEST(encode_to_string( + " A+", opt, test_chars{}) == "+A+"); + } + } + + void + run() + { + testEncode(); + testEncodeExtras(); + } +}; + +TEST_SUITE( + encode_test, + "boost.url.encode"); + +} // urls +} // boost diff --git a/test/unit/error.cpp b/test/unit/error.cpp index 3b7c5e34..68aad47c 100644 --- a/test/unit/error.cpp +++ b/test/unit/error.cpp @@ -54,7 +54,7 @@ public: check(error::non_canonical); check(grammar::condition::fatal, error::bad_pct_hexdig); - check(grammar::condition::fatal, error::incomplete_pct_encoding); + check(grammar::condition::fatal, error::incomplete_encoding); check(grammar::condition::fatal, error::missing_pct_hexdig); check(error::no_space); diff --git a/test/unit/grammar/not_empty_rule.cpp b/test/unit/grammar/not_empty_rule.cpp index b09e3f92..158eb08e 100644 --- a/test/unit/grammar/not_empty_rule.cpp +++ b/test/unit/grammar/not_empty_rule.cpp @@ -35,7 +35,7 @@ struct not_empty_rule_test // javadoc { - result< pct_encoded_view > rv = parse( "Program%20Files", + result< decode_view > rv = parse( "Program%20Files", not_empty_rule( pct_encoded_rule( unreserved_chars ) ) ); (void)rv; diff --git a/test/unit/grammar/tuple_rule.cpp b/test/unit/grammar/tuple_rule.cpp index 9ffc0e65..849c57e4 100644 --- a/test/unit/grammar/tuple_rule.cpp +++ b/test/unit/grammar/tuple_rule.cpp @@ -57,7 +57,7 @@ struct tuple_rule_test void testSquelch() { - result< std::tuple< pct_encoded_view, string_view > > r1 = + result< std::tuple< decode_view, string_view > > r1 = parse( "www.example.com:443", tuple_rule( @@ -66,7 +66,7 @@ struct tuple_rule_test token_rule( digit_chars ) ) ); result< std::tuple< - pct_encoded_view, string_view, string_view > > r2 = + decode_view, string_view, string_view > > r2 = parse( "www.example.com:443", tuple_rule( diff --git a/test/unit/params_encoded_view.cpp b/test/unit/params_encoded_view.cpp index 600a3d89..8efcf687 100644 --- a/test/unit/params_encoded_view.cpp +++ b/test/unit/params_encoded_view.cpp @@ -269,7 +269,7 @@ public: // parse_query_params(string_view) { params_view u = parse_query_params( - "a=1&b=2+2&c=%61%70%70%6c%65").value().decoded(); + "a=1&b=2+2&c=%61%70%70%6c%65").value(); BOOST_TEST_EQ(u.at("b"), "2 2"); BOOST_TEST_EQ(u.at("c"), "apple"); diff --git a/test/unit/params_view.cpp b/test/unit/params_view.cpp index 81dc9b0f..7f6dc87c 100644 --- a/test/unit/params_view.cpp +++ b/test/unit/params_view.cpp @@ -192,7 +192,7 @@ public: { { params_view u = parse_query_params( - "a=1&b=2+2&c=%61%70%70%6c%65").value().decoded(); + "a=1&b=2+2&c=%61%70%70%6c%65").value(); BOOST_TEST_EQ(u.at("b"), "2 2"); BOOST_TEST_EQ(u.at("c"), "apple"); } diff --git a/test/unit/rfc/gen_delim_chars.cpp b/test/unit/rfc/gen_delim_chars.cpp index afada835..d0529279 100644 --- a/test/unit/rfc/gen_delim_chars.cpp +++ b/test/unit/rfc/gen_delim_chars.cpp @@ -25,7 +25,7 @@ struct gen_delim_chars_test { // javadoc { - result< pct_encoded_view > rv = grammar::parse( "Program%20Files", pct_encoded_rule( gen_delim_chars ) ); + result< decode_view > rv = grammar::parse( "Program%20Files", pct_encoded_rule( gen_delim_chars ) ); (void)rv; } diff --git a/test/unit/rfc/pchars.cpp b/test/unit/rfc/pchars.cpp index a9867a06..c4215e0c 100644 --- a/test/unit/rfc/pchars.cpp +++ b/test/unit/rfc/pchars.cpp @@ -25,7 +25,7 @@ struct pchars_test { // javadoc { - result< pct_encoded_view > rv = grammar::parse( "Program%20Files", pct_encoded_rule( pchars ) ); + result< decode_view > rv = grammar::parse( "Program%20Files", pct_encoded_rule( pchars ) ); (void)rv; } test_char_set( diff --git a/test/unit/rfc/pct_encoded_rule.cpp b/test/unit/rfc/pct_encoded_rule.cpp index 1653411e..7e214cd6 100644 --- a/test/unit/rfc/pct_encoded_rule.cpp +++ b/test/unit/rfc/pct_encoded_rule.cpp @@ -26,7 +26,7 @@ public: { // javadoc { - result< pct_encoded_view > rv = grammar::parse( "Program%20Files", pct_encoded_rule( pchars ) ); + result< decode_view > rv = grammar::parse( "Program%20Files", pct_encoded_rule( pchars ) ); (void)rv; } } diff --git a/test/unit/rfc/query_rule.cpp b/test/unit/rfc/query_rule.cpp index d6f5ac47..e81ef55f 100644 --- a/test/unit/rfc/query_rule.cpp +++ b/test/unit/rfc/query_rule.cpp @@ -39,7 +39,7 @@ public: check( string_view s, std::initializer_list< - query_param_encoded_view> i) + query_param_view> i) { auto rv = grammar::parse( s, query_rule); @@ -72,7 +72,7 @@ public: { // javadoc { - result< params_encoded_view > rv = grammar::parse( "format=web&id=42&compact", query_rule ); + result< params_view > rv = grammar::parse( "format=web&id=42&compact", query_rule ); (void)rv; } diff --git a/test/unit/rfc/reserved_chars.cpp b/test/unit/rfc/reserved_chars.cpp index 805c2235..bf2c1956 100644 --- a/test/unit/rfc/reserved_chars.cpp +++ b/test/unit/rfc/reserved_chars.cpp @@ -25,7 +25,7 @@ struct reserved_chars_test { // javadoc { - result< pct_encoded_view > rv = grammar::parse( "Program%20Files", pct_encoded_rule( reserved_chars ) ); + result< decode_view > rv = grammar::parse( "Program%20Files", pct_encoded_rule( reserved_chars ) ); (void)rv; } diff --git a/test/unit/rfc/sub_delim_chars.cpp b/test/unit/rfc/sub_delim_chars.cpp index 42686ad2..18a674aa 100644 --- a/test/unit/rfc/sub_delim_chars.cpp +++ b/test/unit/rfc/sub_delim_chars.cpp @@ -25,7 +25,7 @@ struct sub_delim_chars_test { // javadoc { - result< pct_encoded_view > rv = grammar::parse( "Program%20Files", pct_encoded_rule( sub_delim_chars ) ); + result< decode_view > rv = grammar::parse( "Program%20Files", pct_encoded_rule( sub_delim_chars ) ); (void)rv; } diff --git a/test/unit/rfc/unreserved_chars.cpp b/test/unit/rfc/unreserved_chars.cpp index 51906338..cf889288 100644 --- a/test/unit/rfc/unreserved_chars.cpp +++ b/test/unit/rfc/unreserved_chars.cpp @@ -25,7 +25,7 @@ struct unreserved_chars_test { // javadoc { - result< pct_encoded_view > rv = grammar::parse( "Program%20Files", pct_encoded_rule( unreserved_chars ) ); + result< decode_view > rv = grammar::parse( "Program%20Files", pct_encoded_rule( unreserved_chars ) ); (void)rv; } diff --git a/test/unit/segments_view.cpp b/test/unit/segments_view.cpp index a52001f0..17a4c445 100644 --- a/test/unit/segments_view.cpp +++ b/test/unit/segments_view.cpp @@ -73,7 +73,7 @@ public: sv = f(s).value().decoded()); // forward { - std::vector v1; + std::vector v1; std::copy( sv.begin(), sv.end(), @@ -82,7 +82,7 @@ public: } // reverse { - std::vector v1; + std::vector v1; std::copy( reverse(sv.end()), reverse(sv.begin()), diff --git a/test/unit/snippets.cpp b/test/unit/snippets.cpp index 4b17da8c..4ddd0446 100644 --- a/test/unit/snippets.cpp +++ b/test/unit/snippets.cpp @@ -539,14 +539,14 @@ parsing_authority() } { struct resolve_f { - pct_encoded_view - operator()(pct_encoded_view h) + decode_view + operator()(decode_view h) { return h; } } resolve; struct write_request_f { - void operator()(pct_encoded_view) {} + void operator()(decode_view) {} void operator()(ipv4_address) {} void operator()(ipv6_address) {} } write_request; diff --git a/test/unit/url.cpp b/test/unit/url.cpp index 74df13b5..a7381972 100644 --- a/test/unit/url.cpp +++ b/test/unit/url.cpp @@ -13,6 +13,7 @@ #include #include +#include #include "test_suite.hpp" @@ -269,9 +270,9 @@ public: url u = parse_uri_reference(s1).value(); BOOST_TEST( u.set_user(s2).string() == s3); - auto s = pct_encode_to_string( - s2, unreserved_chars + sub_delim_chars); - u.set_user(pct_encoded_view(s)); + auto s = encode_to_string( + s2, {}, unreserved_chars + sub_delim_chars); + u.set_user(decode_view(s)); BOOST_TEST(u.string() == s3); BOOST_TEST_EQ(u.user(), s2); BOOST_TEST(u.has_userinfo()); @@ -417,12 +418,12 @@ public: url u = parse_uri_reference(s1).value(); BOOST_TEST( u.set_password(s2).string() == s3); - auto s = pct_encode_to_string( - s2, unreserved_chars + + auto s = encode_to_string( + s2, {}, unreserved_chars + sub_delim_chars + ':'); BOOST_TEST( u.set_password( - pct_encoded_view(s)).string() == s3); + decode_view(s)).string() == s3); BOOST_TEST_EQ(u.password(), s2); BOOST_TEST(u.has_userinfo()); }; @@ -573,12 +574,12 @@ public: url u = parse_uri_reference(s1).value(); BOOST_TEST_EQ( u.set_userinfo(s2).string(), s3); - auto s = pct_encode_to_string( - s2, unreserved_chars + + auto s = encode_to_string( + s2, {}, unreserved_chars + sub_delim_chars + ':'); BOOST_TEST( u.set_userinfo( - pct_encoded_view(s)).string() == s3); + decode_view(s)).string() == s3); BOOST_TEST_EQ(u.userinfo(), s2); BOOST_TEST(u.has_userinfo()); }; @@ -806,7 +807,7 @@ public: } { url u; - u.set_host(pct_encoded_view("1.2.3.4")); + u.set_host(decode_view("1.2.3.4")); BOOST_TEST_EQ(u.string(), "//1.2.3.4"); BOOST_TEST(u.host_type() == host_type::ipv4); @@ -861,7 +862,7 @@ public: // reg-name { url u; - u.set_host(pct_encoded_view("example.com")); + u.set_host(decode_view("example.com")); BOOST_TEST_EQ(u.string(), "//example.com"); BOOST_TEST(u.host_type() == host_type::name); @@ -1421,8 +1422,8 @@ public: url u = parse_uri_reference(s0).value(); u.set_path(arg); BOOST_TEST_EQ(u.string(), match); - auto s = pct_encode_to_string(arg, pchars); - u.set_path(pct_encoded_view(s)); + auto s = encode_to_string(arg, {}, pchars); + u.set_path(decode_view(s)); BOOST_TEST_EQ(u.string(), match); }; check( @@ -1578,11 +1579,11 @@ public: BOOST_TEST_EQ(u.query(), q); u.remove_query(); - auto s = pct_encode_to_string( - q, detail::query_chars); - pct_decode_opts opt; + auto s = encode_to_string( + q, {}, detail::query_chars); + decode_opts opt; opt.plus_to_space = true; - auto es = pct_encoded_view(s, opt); + auto es = decode_view(s, opt); u.set_query(es); BOOST_TEST(u.has_query()); BOOST_TEST_EQ(u.string(), us); @@ -1776,9 +1777,9 @@ public: BOOST_TEST_EQ(u.encoded_fragment(), ef); BOOST_TEST_EQ(u.fragment(), f); - auto s = pct_encode_to_string( - f, detail::fragment_chars); - u.set_fragment(pct_encoded_view(s)); + auto s = encode_to_string( + f, {}, detail::fragment_chars); + u.set_fragment(decode_view(s)); BOOST_TEST(u.has_fragment()); BOOST_TEST_EQ(u.string(), h); BOOST_TEST_EQ(u.encoded_fragment(), ef);