LCOV - code coverage report
Current view: top level - boost/url/detail - any_params_iter.hpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 51 51 100.0 %
Date: 2024-04-08 19:38:36 Functions: 29 30 96.7 %

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
       3             : //
       4             : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       5             : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       6             : //
       7             : // Official repository: https://github.com/boostorg/url
       8             : //
       9             : 
      10             : #ifndef BOOST_URL_DETAIL_ANY_PARAMS_ITER_HPP
      11             : #define BOOST_URL_DETAIL_ANY_PARAMS_ITER_HPP
      12             : 
      13             : #include <boost/url/param.hpp>
      14             : #include <boost/url/pct_string_view.hpp>
      15             : #include <boost/static_assert.hpp>
      16             : #include <cstddef>
      17             : #include <iterator>
      18             : #include <type_traits>
      19             : 
      20             : namespace boost {
      21             : namespace urls {
      22             : namespace detail {
      23             : 
      24             : //------------------------------------------------
      25             : //
      26             : // any_params_iter
      27             : //
      28             : //------------------------------------------------
      29             : 
      30             : /*  An iterator to a type-erased,
      31             :     possibly encoded sequence of
      32             :     query params_ref.
      33             : */  
      34             : struct BOOST_SYMBOL_VISIBLE
      35         138 :     any_params_iter
      36             : {
      37             : protected:
      38         138 :     any_params_iter(
      39             :         bool empty_,
      40             :         core::string_view s0_ = {},
      41             :         core::string_view s1_ = {}) noexcept
      42         138 :         : s0(s0_)
      43             :         , s1(s1_)
      44         138 :         , empty(empty_)
      45             :     {
      46         138 :     }
      47             : 
      48             : public:
      49             :     // these are adjusted
      50             :     // when self-intersecting
      51             :     core::string_view s0;
      52             :     core::string_view s1;
      53             : 
      54             :     // True if the sequence is empty
      55             :     bool empty = false;
      56             : 
      57             :     BOOST_URL_DECL
      58             :     virtual
      59             :     ~any_params_iter() noexcept = 0;
      60             : 
      61             :     // Rewind the iterator to the beginning
      62             :     virtual
      63             :     void
      64             :     rewind() noexcept = 0;
      65             : 
      66             :     // Measure and increment current element
      67             :     // element.
      68             :     // Returns false on end of range.
      69             :     // n is increased by encoded size.
      70             :     // Can throw on bad percent-escape
      71             :     virtual
      72             :     bool
      73             :     measure(std::size_t& n) = 0;
      74             : 
      75             :     // Copy and increment the current
      76             :     // element. encoding is performed
      77             :     // if needed.
      78             :     virtual
      79             :     void
      80             :     copy(
      81             :         char*& dest,
      82             :         char const* end) noexcept = 0;
      83             : };
      84             : 
      85             : //------------------------------------------------
      86             : //
      87             : // query_iter
      88             : //
      89             : //------------------------------------------------
      90             : 
      91             : // A string of plain query params
      92             : struct BOOST_SYMBOL_VISIBLE
      93             :     query_iter
      94             :     : any_params_iter
      95             : {
      96             :     // ne = never empty
      97             :     BOOST_URL_DECL
      98             :     explicit
      99             :     query_iter(
     100             :         core::string_view s,
     101             :         bool ne = false) noexcept;
     102             : 
     103             : private:
     104             :     core::string_view s_;
     105             :     std::size_t n_;
     106             :     char const* p_;
     107             :     bool at_end_;
     108             : 
     109             :     void rewind() noexcept override;
     110             :     bool measure(std::size_t&) noexcept override;
     111             :     void copy(char*&, char const*) noexcept override;
     112             :     void increment() noexcept;
     113             : };
     114             : 
     115             : //------------------------------------------------
     116             : //
     117             : // param_iter
     118             : //
     119             : //------------------------------------------------
     120             : 
     121             : // A 1-param range allowing
     122             : // self-intersection
     123             : struct BOOST_SYMBOL_VISIBLE
     124             :     param_iter
     125             :     : any_params_iter
     126             : {
     127             :     explicit
     128             :     param_iter(
     129             :         param_view const&) noexcept;
     130             : 
     131             : private:
     132             :     bool has_value_;
     133             :     bool at_end_ = false;
     134             : 
     135             :     void rewind() noexcept override;
     136             :     bool measure(std::size_t&) noexcept override;
     137             :     void copy(char*&, char const*) noexcept override;
     138             : };
     139             : 
     140             : //------------------------------------------------
     141             : //
     142             : // params_iter_base
     143             : //
     144             : //------------------------------------------------
     145             : 
     146             : struct params_iter_base
     147             : {
     148             : protected:
     149             :     // return encoded size
     150             :     BOOST_URL_DECL
     151             :     static
     152             :     void
     153             :     measure_impl(
     154             :         std::size_t& n,
     155             :         param_view const& p) noexcept;
     156             : 
     157             :     // encode to dest
     158             :     BOOST_URL_DECL
     159             :     static
     160             :     void
     161             :     copy_impl(
     162             :         char*& dest,
     163             :         char const* end,
     164             :         param_view const& v) noexcept;
     165             : };
     166             : 
     167             : //------------------------------------------------
     168             : 
     169             : // A range of plain query params_ref
     170             : template<class FwdIt>
     171             : struct params_iter
     172             :     : any_params_iter
     173             :     , private params_iter_base
     174             : {
     175             :     BOOST_STATIC_ASSERT(
     176             :         std::is_convertible<
     177             :             typename std::iterator_traits<
     178             :                 FwdIt>::reference,
     179             :             param_view>::value);
     180             : 
     181          31 :     params_iter(
     182             :         FwdIt first,
     183             :         FwdIt last) noexcept
     184             :         : any_params_iter(
     185           1 :             first == last)
     186             :         , it0_(first)
     187             :         , it_(first)
     188          32 :         , end_(last)
     189             :     {
     190          31 :     }
     191             : 
     192             : private:
     193             :     FwdIt it0_;
     194             :     FwdIt it_;
     195             :     FwdIt end_;
     196             : 
     197             :     void
     198          31 :     rewind() noexcept override
     199             :     {
     200          31 :         it_ = it0_;
     201          31 :     }
     202             : 
     203             :     bool
     204          99 :     measure(
     205             :         std::size_t& n) noexcept override
     206             :     {
     207          99 :         if(it_ == end_)
     208          31 :             return false;
     209         135 :        measure_impl(n,
     210          68 :            param_view(*it_++));
     211          68 :         return true;
     212             :     }
     213             : 
     214             :     void
     215          68 :     copy(
     216             :         char*& dest,
     217             :         char const* end) noexcept override
     218             :     {
     219         135 :         copy_impl(dest, end,
     220          68 :             param_view(*it_++));
     221          68 :     }
     222             : };
     223             : 
     224             : //------------------------------------------------
     225             : //
     226             : // param_encoded_iter
     227             : //
     228             : //------------------------------------------------
     229             : 
     230             : // A 1-param encoded range
     231             : // allowing self-intersection
     232             : struct BOOST_SYMBOL_VISIBLE
     233             :     param_encoded_iter
     234             :     : any_params_iter
     235             : {
     236             :     explicit
     237             :     param_encoded_iter(
     238             :         param_pct_view const&) noexcept;
     239             : 
     240             : private:
     241             :     bool has_value_;
     242             :     bool at_end_ = false;
     243             : 
     244             :     void rewind() noexcept override;
     245             :     bool measure(std::size_t&) noexcept override;
     246             :     void copy(char*&, char const*) noexcept override;
     247             : };
     248             : 
     249             : //------------------------------------------------
     250             : //
     251             : // params_encoded_iter
     252             : //
     253             : //------------------------------------------------
     254             : 
     255             : // Validating and copying from
     256             : // a string of encoded params
     257             : struct params_encoded_iter_base
     258             : {
     259             : protected:
     260             :     BOOST_URL_DECL
     261             :     static
     262             :     void
     263             :     measure_impl(
     264             :         std::size_t& n,
     265             :         param_view const& v) noexcept;
     266             : 
     267             :     BOOST_URL_DECL
     268             :     static
     269             :     void
     270             :     copy_impl(
     271             :         char*& dest,
     272             :         char const* end,
     273             :         param_view const& v) noexcept;
     274             : };
     275             : 
     276             : //------------------------------------------------
     277             : 
     278             : // A range of encoded query params_ref
     279             : template<class FwdIt>
     280             : struct params_encoded_iter
     281             :     : any_params_iter
     282             :     , private params_encoded_iter_base
     283             : {
     284             :     BOOST_STATIC_ASSERT(
     285             :         std::is_convertible<
     286             :             typename std::iterator_traits<
     287             :                 FwdIt>::reference,
     288             :             param_view>::value);
     289             : 
     290          29 :     params_encoded_iter(
     291             :         FwdIt first,
     292             :         FwdIt last) noexcept
     293             :         : any_params_iter(
     294           1 :             first == last)
     295             :         , it0_(first)
     296             :         , it_(first)
     297          30 :         , end_(last)
     298             :     {
     299          29 :     }
     300             : 
     301             : private:
     302             :     FwdIt it0_;
     303             :     FwdIt it_;
     304             :     FwdIt end_;
     305             : 
     306             :     void
     307          24 :     rewind() noexcept override
     308             :     {
     309          24 :         it_ = it0_;
     310          24 :     }
     311             : 
     312             :     bool
     313          80 :     measure(
     314             :         std::size_t& n) override
     315             :     {
     316          80 :         if(it_ == end_)
     317          24 :             return false;
     318             :         // throw on invalid input
     319          51 :         measure_impl(n,
     320             :             param_pct_view(
     321          56 :                 param_view(*it_++)));
     322          51 :         return true;
     323             :     }
     324             : 
     325             :     void
     326          51 :     copy(
     327             :         char*& dest,
     328             :         char const* end
     329             :             ) noexcept override
     330             :     {
     331          64 :         copy_impl(dest, end,
     332          51 :             param_view(*it_++));
     333          51 :     }
     334             : };
     335             : 
     336             : //------------------------------------------------
     337             : //
     338             : // param_value_iter
     339             : //
     340             : //------------------------------------------------
     341             : 
     342             : // An iterator which outputs
     343             : // one value on an existing key
     344             : struct param_value_iter
     345             :     : any_params_iter
     346             : {
     347           9 :     param_value_iter(
     348             :         std::size_t nk,
     349             :         core::string_view const& value,
     350             :         bool has_value) noexcept
     351           9 :         : any_params_iter(
     352             :             false,
     353             :             value)
     354             :         , nk_(nk)
     355           9 :         , has_value_(has_value)
     356             :     {
     357           9 :     }
     358             : 
     359             : private:
     360             :     std::size_t nk_ = 0;
     361             :     bool has_value_ = false;
     362             :     bool at_end_ = false;
     363             : 
     364             :     void rewind() noexcept override;
     365             :     bool measure(std::size_t&) noexcept override;
     366             :     void copy(char*&, char const*) noexcept override;
     367             : };
     368             : 
     369             : //------------------------------------------------
     370             : //
     371             : // param_encoded_value_iter
     372             : //
     373             : //------------------------------------------------
     374             : 
     375             : // An iterator which outputs one
     376             : // encoded value on an existing key
     377             : struct param_encoded_value_iter
     378             :     : any_params_iter
     379             : {
     380           8 :     param_encoded_value_iter(
     381             :         std::size_t nk,
     382             :         pct_string_view const& value,
     383             :         bool has_value) noexcept
     384           8 :         : any_params_iter(
     385             :             false,
     386             :             value)
     387             :         , nk_(nk)
     388           8 :         , has_value_(has_value)
     389             :     {
     390           8 :     }
     391             : 
     392             : private:
     393             :     std::size_t nk_ = 0;
     394             :     bool has_value_ = false;
     395             :     bool at_end_ = false;
     396             : 
     397             :     void rewind() noexcept override;
     398             :     bool measure(std::size_t&) noexcept override;
     399             :     void copy(char*&, char const*) noexcept override;
     400             : };
     401             : 
     402             : //------------------------------------------------
     403             : 
     404             : template<class FwdIt>
     405             : params_iter<FwdIt>
     406          31 : make_params_iter(
     407             :     FwdIt first, FwdIt last)
     408             : {
     409             :     return params_iter<
     410          31 :         FwdIt>(first, last);
     411             : }
     412             : 
     413             : template<class FwdIt>
     414             : params_encoded_iter<FwdIt>
     415          29 : make_params_encoded_iter(
     416             :     FwdIt first, FwdIt last)
     417             : {
     418             :     return params_encoded_iter<
     419          29 :         FwdIt>(first, last);
     420             : }
     421             : 
     422             : } // detail
     423             : } // urls
     424             : } // boost
     425             : 
     426             : #endif

Generated by: LCOV version 1.15