123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426 |
- //
- // Copyright (c) 2019 Vinnie Falco (vinnie.falco@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/boostorg/url
- //
- #ifndef BOOST_URL_DETAIL_ANY_PARAMS_ITER_HPP
- #define BOOST_URL_DETAIL_ANY_PARAMS_ITER_HPP
- #include <boost/url/param.hpp>
- #include <boost/url/pct_string_view.hpp>
- #include <boost/static_assert.hpp>
- #include <cstddef>
- #include <iterator>
- #include <type_traits>
- namespace boost {
- namespace urls {
- namespace detail {
- //------------------------------------------------
- //
- // any_params_iter
- //
- //------------------------------------------------
- /* An iterator to a type-erased,
- possibly encoded sequence of
- query params_ref.
- */
- struct BOOST_SYMBOL_VISIBLE
- any_params_iter
- {
- protected:
- any_params_iter(
- bool empty_,
- core::string_view s0_ = {},
- core::string_view s1_ = {}) noexcept
- : s0(s0_)
- , s1(s1_)
- , empty(empty_)
- {
- }
- public:
- // these are adjusted
- // when self-intersecting
- core::string_view s0;
- core::string_view s1;
- // True if the sequence is empty
- bool empty = false;
- BOOST_URL_DECL
- virtual
- ~any_params_iter() noexcept = 0;
- // Rewind the iterator to the beginning
- virtual
- void
- rewind() noexcept = 0;
- // Measure and increment current element
- // element.
- // Returns false on end of range.
- // n is increased by encoded size.
- // Can throw on bad percent-escape
- virtual
- bool
- measure(std::size_t& n) = 0;
- // Copy and increment the current
- // element. encoding is performed
- // if needed.
- virtual
- void
- copy(
- char*& dest,
- char const* end) noexcept = 0;
- };
- //------------------------------------------------
- //
- // query_iter
- //
- //------------------------------------------------
- // A string of plain query params
- struct BOOST_SYMBOL_VISIBLE
- query_iter
- : any_params_iter
- {
- // ne = never empty
- BOOST_URL_DECL
- explicit
- query_iter(
- core::string_view s,
- bool ne = false) noexcept;
- private:
- core::string_view s_;
- std::size_t n_;
- char const* p_;
- bool at_end_;
- void rewind() noexcept override;
- bool measure(std::size_t&) noexcept override;
- void copy(char*&, char const*) noexcept override;
- void increment() noexcept;
- };
- //------------------------------------------------
- //
- // param_iter
- //
- //------------------------------------------------
- // A 1-param range allowing
- // self-intersection
- struct BOOST_SYMBOL_VISIBLE
- param_iter
- : any_params_iter
- {
- explicit
- param_iter(
- param_view const&) noexcept;
- private:
- bool has_value_;
- bool at_end_ = false;
- void rewind() noexcept override;
- bool measure(std::size_t&) noexcept override;
- void copy(char*&, char const*) noexcept override;
- };
- //------------------------------------------------
- //
- // params_iter_base
- //
- //------------------------------------------------
- struct params_iter_base
- {
- protected:
- // return encoded size
- BOOST_URL_DECL
- static
- void
- measure_impl(
- std::size_t& n,
- param_view const& p) noexcept;
- // encode to dest
- BOOST_URL_DECL
- static
- void
- copy_impl(
- char*& dest,
- char const* end,
- param_view const& v) noexcept;
- };
- //------------------------------------------------
- // A range of plain query params_ref
- template<class FwdIt>
- struct params_iter
- : any_params_iter
- , private params_iter_base
- {
- BOOST_STATIC_ASSERT(
- std::is_convertible<
- typename std::iterator_traits<
- FwdIt>::reference,
- param_view>::value);
- params_iter(
- FwdIt first,
- FwdIt last) noexcept
- : any_params_iter(
- first == last)
- , it0_(first)
- , it_(first)
- , end_(last)
- {
- }
- private:
- FwdIt it0_;
- FwdIt it_;
- FwdIt end_;
- void
- rewind() noexcept override
- {
- it_ = it0_;
- }
- bool
- measure(
- std::size_t& n) noexcept override
- {
- if(it_ == end_)
- return false;
- measure_impl(n,
- param_view(*it_++));
- return true;
- }
- void
- copy(
- char*& dest,
- char const* end) noexcept override
- {
- copy_impl(dest, end,
- param_view(*it_++));
- }
- };
- //------------------------------------------------
- //
- // param_encoded_iter
- //
- //------------------------------------------------
- // A 1-param encoded range
- // allowing self-intersection
- struct BOOST_SYMBOL_VISIBLE
- param_encoded_iter
- : any_params_iter
- {
- explicit
- param_encoded_iter(
- param_pct_view const&) noexcept;
- private:
- bool has_value_;
- bool at_end_ = false;
- void rewind() noexcept override;
- bool measure(std::size_t&) noexcept override;
- void copy(char*&, char const*) noexcept override;
- };
- //------------------------------------------------
- //
- // params_encoded_iter
- //
- //------------------------------------------------
- // Validating and copying from
- // a string of encoded params
- struct params_encoded_iter_base
- {
- protected:
- BOOST_URL_DECL
- static
- void
- measure_impl(
- std::size_t& n,
- param_view const& v) noexcept;
- BOOST_URL_DECL
- static
- void
- copy_impl(
- char*& dest,
- char const* end,
- param_view const& v) noexcept;
- };
- //------------------------------------------------
- // A range of encoded query params_ref
- template<class FwdIt>
- struct params_encoded_iter
- : any_params_iter
- , private params_encoded_iter_base
- {
- BOOST_STATIC_ASSERT(
- std::is_convertible<
- typename std::iterator_traits<
- FwdIt>::reference,
- param_view>::value);
- params_encoded_iter(
- FwdIt first,
- FwdIt last) noexcept
- : any_params_iter(
- first == last)
- , it0_(first)
- , it_(first)
- , end_(last)
- {
- }
- private:
- FwdIt it0_;
- FwdIt it_;
- FwdIt end_;
- void
- rewind() noexcept override
- {
- it_ = it0_;
- }
- bool
- measure(
- std::size_t& n) override
- {
- if(it_ == end_)
- return false;
- // throw on invalid input
- measure_impl(n,
- param_pct_view(
- param_view(*it_++)));
- return true;
- }
- void
- copy(
- char*& dest,
- char const* end
- ) noexcept override
- {
- copy_impl(dest, end,
- param_view(*it_++));
- }
- };
- //------------------------------------------------
- //
- // param_value_iter
- //
- //------------------------------------------------
- // An iterator which outputs
- // one value on an existing key
- struct param_value_iter
- : any_params_iter
- {
- param_value_iter(
- std::size_t nk,
- core::string_view const& value,
- bool has_value) noexcept
- : any_params_iter(
- false,
- value)
- , nk_(nk)
- , has_value_(has_value)
- {
- }
- private:
- std::size_t nk_ = 0;
- bool has_value_ = false;
- bool at_end_ = false;
- void rewind() noexcept override;
- bool measure(std::size_t&) noexcept override;
- void copy(char*&, char const*) noexcept override;
- };
- //------------------------------------------------
- //
- // param_encoded_value_iter
- //
- //------------------------------------------------
- // An iterator which outputs one
- // encoded value on an existing key
- struct param_encoded_value_iter
- : any_params_iter
- {
- param_encoded_value_iter(
- std::size_t nk,
- pct_string_view const& value,
- bool has_value) noexcept
- : any_params_iter(
- false,
- value)
- , nk_(nk)
- , has_value_(has_value)
- {
- }
- private:
- std::size_t nk_ = 0;
- bool has_value_ = false;
- bool at_end_ = false;
- void rewind() noexcept override;
- bool measure(std::size_t&) noexcept override;
- void copy(char*&, char const*) noexcept override;
- };
- //------------------------------------------------
- template<class FwdIt>
- params_iter<FwdIt>
- make_params_iter(
- FwdIt first, FwdIt last)
- {
- return params_iter<
- FwdIt>(first, last);
- }
- template<class FwdIt>
- params_encoded_iter<FwdIt>
- make_params_encoded_iter(
- FwdIt first, FwdIt last)
- {
- return params_encoded_iter<
- FwdIt>(first, last);
- }
- } // detail
- } // urls
- } // boost
- #endif
|