Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //
0002 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/url
0008 //
0009 
0010 #ifndef BOOST_URL_DETAIL_ANY_PARAMS_ITER_HPP
0011 #define BOOST_URL_DETAIL_ANY_PARAMS_ITER_HPP
0012 
0013 #include <boost/url/param.hpp>
0014 #include <boost/url/pct_string_view.hpp>
0015 #include <boost/static_assert.hpp>
0016 #include <cstddef>
0017 #include <iterator>
0018 #include <type_traits>
0019 
0020 namespace boost {
0021 namespace urls {
0022 namespace detail {
0023 
0024 //------------------------------------------------
0025 //
0026 // any_params_iter
0027 //
0028 //------------------------------------------------
0029 
0030 /*  An iterator to a type-erased,
0031     possibly encoded sequence of
0032     query params_ref.
0033 */  
0034 struct BOOST_SYMBOL_VISIBLE
0035     any_params_iter
0036 {
0037 protected:
0038     any_params_iter(
0039         bool empty_,
0040         core::string_view s0_ = {},
0041         core::string_view s1_ = {}) noexcept
0042         : s0(s0_)
0043         , s1(s1_)
0044         , empty(empty_)
0045     {
0046     }
0047 
0048 public:
0049     // these are adjusted
0050     // when self-intersecting
0051     core::string_view s0;
0052     core::string_view s1;
0053 
0054     // True if the sequence is empty
0055     bool empty = false;
0056 
0057     BOOST_URL_DECL
0058     virtual
0059     ~any_params_iter() noexcept = 0;
0060 
0061     // Rewind the iterator to the beginning
0062     virtual
0063     void
0064     rewind() noexcept = 0;
0065 
0066     // Measure and increment current element
0067     // element.
0068     // Returns false on end of range.
0069     // n is increased by encoded size.
0070     // Can throw on bad percent-escape
0071     virtual
0072     bool
0073     measure(std::size_t& n) = 0;
0074 
0075     // Copy and increment the current
0076     // element. encoding is performed
0077     // if needed.
0078     virtual
0079     void
0080     copy(
0081         char*& dest,
0082         char const* end) noexcept = 0;
0083 };
0084 
0085 //------------------------------------------------
0086 //
0087 // query_iter
0088 //
0089 //------------------------------------------------
0090 
0091 // A string of plain query params
0092 struct BOOST_SYMBOL_VISIBLE
0093     query_iter
0094     : any_params_iter
0095 {
0096     // ne = never empty
0097     BOOST_URL_DECL
0098     explicit
0099     query_iter(
0100         core::string_view s,
0101         bool ne = false) noexcept;
0102 
0103 private:
0104     core::string_view s_;
0105     std::size_t n_;
0106     char const* p_;
0107     bool at_end_;
0108 
0109     void rewind() noexcept override;
0110     bool measure(std::size_t&) noexcept override;
0111     void copy(char*&, char const*) noexcept override;
0112     void increment() noexcept;
0113 };
0114 
0115 //------------------------------------------------
0116 //
0117 // param_iter
0118 //
0119 //------------------------------------------------
0120 
0121 // A 1-param range allowing
0122 // self-intersection
0123 struct BOOST_SYMBOL_VISIBLE
0124     param_iter
0125     : any_params_iter
0126 {
0127     explicit
0128     param_iter(
0129         param_view const&) noexcept;
0130 
0131 private:
0132     bool has_value_;
0133     bool at_end_ = false;
0134 
0135     void rewind() noexcept override;
0136     bool measure(std::size_t&) noexcept override;
0137     void copy(char*&, char const*) noexcept override;
0138 };
0139 
0140 //------------------------------------------------
0141 //
0142 // params_iter_base
0143 //
0144 //------------------------------------------------
0145 
0146 struct params_iter_base
0147 {
0148 protected:
0149     // return encoded size
0150     BOOST_URL_DECL
0151     static
0152     void
0153     measure_impl(
0154         std::size_t& n,
0155         param_view const& p) noexcept;
0156 
0157     // encode to dest
0158     BOOST_URL_DECL
0159     static
0160     void
0161     copy_impl(
0162         char*& dest,
0163         char const* end,
0164         param_view const& v) noexcept;
0165 };
0166 
0167 //------------------------------------------------
0168 
0169 // A range of plain query params_ref
0170 template<class FwdIt>
0171 struct params_iter
0172     : any_params_iter
0173     , private params_iter_base
0174 {
0175     BOOST_STATIC_ASSERT(
0176         std::is_convertible<
0177             typename std::iterator_traits<
0178                 FwdIt>::reference,
0179             param_view>::value);
0180 
0181     params_iter(
0182         FwdIt first,
0183         FwdIt last) noexcept
0184         : any_params_iter(
0185             first == last)
0186         , it0_(first)
0187         , it_(first)
0188         , end_(last)
0189     {
0190     }
0191 
0192 private:
0193     FwdIt it0_;
0194     FwdIt it_;
0195     FwdIt end_;
0196 
0197     void
0198     rewind() noexcept override
0199     {
0200         it_ = it0_;
0201     }
0202 
0203     bool
0204     measure(
0205         std::size_t& n) noexcept override
0206     {
0207         if(it_ == end_)
0208             return false;
0209        measure_impl(n,
0210            param_view(*it_++));
0211         return true;
0212     }
0213 
0214     void
0215     copy(
0216         char*& dest,
0217         char const* end) noexcept override
0218     {
0219         copy_impl(dest, end,
0220             param_view(*it_++));
0221     }
0222 };
0223 
0224 //------------------------------------------------
0225 //
0226 // param_encoded_iter
0227 //
0228 //------------------------------------------------
0229 
0230 // A 1-param encoded range
0231 // allowing self-intersection
0232 struct BOOST_SYMBOL_VISIBLE
0233     param_encoded_iter
0234     : any_params_iter
0235 {
0236     explicit
0237     param_encoded_iter(
0238         param_pct_view const&) noexcept;
0239 
0240 private:
0241     bool has_value_;
0242     bool at_end_ = false;
0243 
0244     void rewind() noexcept override;
0245     bool measure(std::size_t&) noexcept override;
0246     void copy(char*&, char const*) noexcept override;
0247 };
0248 
0249 //------------------------------------------------
0250 //
0251 // params_encoded_iter
0252 //
0253 //------------------------------------------------
0254 
0255 // Validating and copying from
0256 // a string of encoded params
0257 struct params_encoded_iter_base
0258 {
0259 protected:
0260     BOOST_URL_DECL
0261     static
0262     void
0263     measure_impl(
0264         std::size_t& n,
0265         param_view const& v) noexcept;
0266 
0267     BOOST_URL_DECL
0268     static
0269     void
0270     copy_impl(
0271         char*& dest,
0272         char const* end,
0273         param_view const& v) noexcept;
0274 };
0275 
0276 //------------------------------------------------
0277 
0278 // A range of encoded query params_ref
0279 template<class FwdIt>
0280 struct params_encoded_iter
0281     : any_params_iter
0282     , private params_encoded_iter_base
0283 {
0284     BOOST_STATIC_ASSERT(
0285         std::is_convertible<
0286             typename std::iterator_traits<
0287                 FwdIt>::reference,
0288             param_view>::value);
0289 
0290     params_encoded_iter(
0291         FwdIt first,
0292         FwdIt last) noexcept
0293         : any_params_iter(
0294             first == last)
0295         , it0_(first)
0296         , it_(first)
0297         , end_(last)
0298     {
0299     }
0300 
0301 private:
0302     FwdIt it0_;
0303     FwdIt it_;
0304     FwdIt end_;
0305 
0306     void
0307     rewind() noexcept override
0308     {
0309         it_ = it0_;
0310     }
0311 
0312     bool
0313     measure(
0314         std::size_t& n) override
0315     {
0316         if(it_ == end_)
0317             return false;
0318         // throw on invalid input
0319         measure_impl(n,
0320             param_pct_view(
0321                 param_view(*it_++)));
0322         return true;
0323     }
0324 
0325     void
0326     copy(
0327         char*& dest,
0328         char const* end
0329             ) noexcept override
0330     {
0331         copy_impl(dest, end,
0332             param_view(*it_++));
0333     }
0334 };
0335 
0336 //------------------------------------------------
0337 //
0338 // param_value_iter
0339 //
0340 //------------------------------------------------
0341 
0342 // An iterator which outputs
0343 // one value on an existing key
0344 struct param_value_iter
0345     : any_params_iter
0346 {
0347     param_value_iter(
0348         std::size_t nk,
0349         core::string_view const& value,
0350         bool has_value) noexcept
0351         : any_params_iter(
0352             false,
0353             value)
0354         , nk_(nk)
0355         , has_value_(has_value)
0356     {
0357     }
0358 
0359 private:
0360     std::size_t nk_ = 0;
0361     bool has_value_ = false;
0362     bool at_end_ = false;
0363 
0364     void rewind() noexcept override;
0365     bool measure(std::size_t&) noexcept override;
0366     void copy(char*&, char const*) noexcept override;
0367 };
0368 
0369 //------------------------------------------------
0370 //
0371 // param_encoded_value_iter
0372 //
0373 //------------------------------------------------
0374 
0375 // An iterator which outputs one
0376 // encoded value on an existing key
0377 struct param_encoded_value_iter
0378     : any_params_iter
0379 {
0380     param_encoded_value_iter(
0381         std::size_t nk,
0382         pct_string_view const& value,
0383         bool has_value) noexcept
0384         : any_params_iter(
0385             false,
0386             value)
0387         , nk_(nk)
0388         , has_value_(has_value)
0389     {
0390     }
0391 
0392 private:
0393     std::size_t nk_ = 0;
0394     bool has_value_ = false;
0395     bool at_end_ = false;
0396 
0397     void rewind() noexcept override;
0398     bool measure(std::size_t&) noexcept override;
0399     void copy(char*&, char const*) noexcept override;
0400 };
0401 
0402 //------------------------------------------------
0403 
0404 template<class FwdIt>
0405 params_iter<FwdIt>
0406 make_params_iter(
0407     FwdIt first, FwdIt last)
0408 {
0409     return params_iter<
0410         FwdIt>(first, last);
0411 }
0412 
0413 template<class FwdIt>
0414 params_encoded_iter<FwdIt>
0415 make_params_encoded_iter(
0416     FwdIt first, FwdIt last)
0417 {
0418     return params_encoded_iter<
0419         FwdIt>(first, last);
0420 }
0421 
0422 } // detail
0423 } // urls
0424 } // boost
0425 
0426 #endif