LCOV - code coverage report
Current view: top level - url/impl - params_base.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 128 128
Test Date: 2026-02-25 21:00:01 Functions: 100.0 % 28 28

           TLA  Line data    Source code
       1                 : //
       2                 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
       3                 : // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
       4                 : //
       5                 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       6                 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       7                 : //
       8                 : // Official repository: https://github.com/boostorg/url
       9                 : //
      10                 : 
      11                 : #ifndef BOOST_URL_IMPL_PARAMS_BASE_HPP
      12                 : #define BOOST_URL_IMPL_PARAMS_BASE_HPP
      13                 : 
      14                 : #include <boost/url/detail/params_iter_impl.hpp>
      15                 : #include <boost/url/decode_view.hpp>
      16                 : #include <boost/url/grammar/ci_string.hpp>
      17                 : #include <iterator>
      18                 : #include <ostream>
      19                 : #include <string>
      20                 : 
      21                 : namespace boost {
      22                 : namespace urls {
      23                 : 
      24                 : //------------------------------------------------
      25                 : 
      26                 : class BOOST_SYMBOL_VISIBLE params_base::iterator
      27                 : {
      28                 :     detail::params_iter_impl it_;
      29                 :     bool space_as_plus_ = true;
      30                 : 
      31                 :     friend class params_base;
      32                 :     friend class params_ref;
      33                 : 
      34                 :     iterator(
      35                 :         detail::query_ref const& ref,
      36                 :         encoding_opts opt) noexcept;
      37                 : 
      38                 :     iterator(
      39                 :         detail::query_ref const& impl,
      40                 :         encoding_opts opt,
      41                 :         int) noexcept;
      42                 : 
      43 HIT         183 :     iterator(
      44                 :         detail::params_iter_impl const& it,
      45                 :         encoding_opts opt) noexcept
      46             183 :         : it_(it)
      47             183 :         , space_as_plus_(opt.space_as_plus)
      48                 :     {
      49             183 :     }
      50                 : 
      51                 : public:
      52                 :     using value_type = params_base::value_type;
      53                 :     using reference = params_base::reference;
      54                 :     using pointer = reference;
      55                 :     using difference_type =
      56                 :         params_base::difference_type;
      57                 :     using iterator_category =
      58                 :         std::bidirectional_iterator_tag;
      59                 : 
      60               4 :     iterator() = default;
      61                 :     iterator(iterator const&) = default;
      62                 :     iterator& operator=(
      63                 :         iterator const&) noexcept = default;
      64                 : 
      65                 :     iterator&
      66             861 :     operator++() noexcept
      67                 :     {
      68             861 :         it_.increment();
      69             861 :         return *this;
      70                 :     }
      71                 : 
      72                 :     iterator
      73             367 :     operator++(int) noexcept
      74                 :     {
      75             367 :         auto tmp = *this;
      76             367 :         ++*this;
      77             367 :         return tmp;
      78                 :     }
      79                 : 
      80                 :     iterator&
      81             730 :     operator--() noexcept
      82                 :     {
      83             730 :         it_.decrement();
      84             730 :         return *this;
      85                 :     }
      86                 : 
      87                 :     iterator
      88             365 :     operator--(int) noexcept
      89                 :     {
      90             365 :         auto tmp = *this;
      91             365 :         --*this;
      92             365 :         return tmp;
      93                 :     }
      94                 : 
      95                 :     reference
      96                 :     operator*() const;
      97                 : 
      98                 :     // the return value is too expensive
      99                 :     pointer operator->() const = delete;
     100                 : 
     101                 :     bool
     102             768 :     operator==(
     103                 :         iterator const& other) const noexcept
     104                 :     {
     105             768 :         return it_.equal(other.it_);
     106                 :     }
     107                 : 
     108                 :     bool
     109             106 :     operator!=(
     110                 :         iterator const& other) const noexcept
     111                 :     {
     112             106 :         return ! it_.equal(other.it_);
     113                 :     }
     114                 : };
     115                 : 
     116                 : 
     117                 : //------------------------------------------------
     118                 : 
     119                 : inline
     120             326 : params_base::
     121                 : iterator::
     122                 : iterator(
     123                 :     detail::query_ref const& ref,
     124             326 :     encoding_opts opt) noexcept
     125             326 :     : it_(ref)
     126             326 :     , space_as_plus_(opt.space_as_plus)
     127                 : {
     128             326 : }
     129                 : 
     130                 : inline
     131             247 : params_base::
     132                 : iterator::
     133                 : iterator(
     134                 :     detail::query_ref const& ref,
     135                 :     encoding_opts opt,
     136             247 :     int) noexcept
     137             247 :     : it_(ref, 0)
     138             247 :     , space_as_plus_(opt.space_as_plus)
     139                 : {
     140             247 : }
     141                 : 
     142                 : 
     143                 : inline
     144                 : auto
     145             826 : params_base::
     146                 : iterator::
     147                 : operator*() const ->
     148                 :     reference
     149                 : 
     150                 : {
     151             826 :     encoding_opts opt;
     152             826 :     opt.space_as_plus =
     153             826 :         space_as_plus_;
     154                 :     param_pct_view p =
     155             826 :         it_.dereference();
     156                 :     return reference(
     157            1652 :         p.key.decode(opt),
     158            1652 :         p.value.decode(opt),
     159            4130 :         p.has_value);
     160                 : }
     161                 : 
     162                 : //------------------------------------------------
     163                 : //
     164                 : // params_base
     165                 : //
     166                 : //------------------------------------------------
     167                 : 
     168                 : inline
     169               1 : params_base::
     170               1 : params_base() noexcept
     171                 :     // space_as_plus = true
     172               1 :     : opt_(true, false, false)
     173                 : {
     174               1 : }
     175                 : 
     176                 : inline
     177                 : bool
     178              28 : params_base::
     179                 : contains(
     180                 :     core::string_view key,
     181                 :     ignore_case_param ic) const noexcept
     182                 : {
     183              28 :     return find(
     184              56 :         begin(),key, ic) != end();
     185                 : }
     186                 : 
     187                 : inline
     188                 : auto
     189              42 : params_base::
     190                 : find(
     191                 :     core::string_view key,
     192                 :     ignore_case_param ic) const noexcept ->
     193                 :         iterator
     194                 : {
     195                 :     return iterator(
     196              42 :         find_impl(
     197              84 :             begin().it_, key, ic),
     198              42 :         opt_);
     199                 : }
     200                 : 
     201                 : inline
     202                 : auto
     203              60 : params_base::
     204                 : find(
     205                 :     iterator it,
     206                 :     core::string_view key,
     207                 :     ignore_case_param ic) const noexcept ->
     208                 :         iterator
     209                 : {
     210                 :     return iterator(
     211             120 :         find_impl(
     212                 :             it.it_, key, ic),
     213              60 :         opt_);
     214                 : }
     215                 : 
     216                 : inline
     217                 : auto
     218               4 : params_base::
     219                 : find_last(
     220                 :     core::string_view key,
     221                 :     ignore_case_param ic) const noexcept ->
     222                 :         iterator
     223                 : {
     224                 :     return iterator(
     225               4 :         find_last_impl(
     226               8 :             end().it_, key, ic),
     227               4 :         opt_);
     228                 : }
     229                 : 
     230                 : inline
     231                 : auto
     232               9 : params_base::
     233                 : find_last(
     234                 :     iterator it,
     235                 :     core::string_view key,
     236                 :     ignore_case_param ic) const noexcept ->
     237                 :         iterator
     238                 : {
     239                 :     return iterator(
     240              18 :         find_last_impl(
     241                 :             it.it_, key, ic),
     242               9 :         opt_);
     243                 : }
     244                 : 
     245                 : inline
     246             312 : params_base::
     247                 : params_base(
     248                 :     detail::query_ref const& ref,
     249             312 :     encoding_opts opt) noexcept
     250             312 :     : ref_(ref)
     251             312 :     , opt_(opt)
     252                 : {
     253             312 : }
     254                 : 
     255                 : inline
     256                 : pct_string_view
     257              13 : params_base::
     258                 : buffer() const noexcept
     259                 : {
     260              13 :     return ref_.buffer();
     261                 : }
     262                 : 
     263                 : inline
     264                 : bool
     265               5 : params_base::
     266                 : empty() const noexcept
     267                 : {
     268               5 :     return ref_.nparam() == 0;
     269                 : }
     270                 : 
     271                 : inline
     272                 : std::size_t
     273             222 : params_base::
     274                 : size() const noexcept
     275                 : {
     276             222 :     return ref_.nparam();
     277                 : }
     278                 : 
     279                 : inline
     280                 : auto
     281             326 : params_base::
     282                 : begin() const noexcept ->
     283                 :     iterator
     284                 : {
     285             326 :     return iterator(ref_, opt_);
     286                 : }
     287                 : 
     288                 : inline
     289                 : auto
     290             247 : params_base::
     291                 : end() const noexcept ->
     292                 :     iterator
     293                 : {
     294             247 :     return {ref_, opt_, 0};
     295                 : }
     296                 : 
     297                 : //------------------------------------------------
     298                 : 
     299                 : inline
     300                 : std::size_t
     301              29 : params_base::
     302                 : count(
     303                 :     core::string_view key,
     304                 :     ignore_case_param ic) const noexcept
     305                 : {
     306              29 :     std::size_t n = 0;
     307              29 :     auto it = find(key, ic);
     308              29 :     auto const end_ = end();
     309              57 :     while(it != end_)
     310                 :     {
     311              28 :         ++n;
     312              28 :         ++it;
     313              28 :         it = find(it, key, ic);
     314                 :     }
     315              29 :     return n;
     316                 : }
     317                 : 
     318                 : inline
     319                 : std::string
     320               8 : params_base::
     321                 : get_or(
     322                 :     core::string_view key,
     323                 :     core::string_view value,
     324                 :     ignore_case_param ic) const
     325                 : {
     326               8 :     auto it = find_impl(
     327               8 :         begin().it_, key, ic);
     328               8 :     detail::params_iter_impl end_(ref_, 0);
     329               8 :     if(it.equal(end_))
     330               2 :         return std::string(value);
     331                 : 
     332               6 :     param_pct_view const p = it.dereference();
     333               6 :     if(! p.has_value)
     334               1 :         return std::string();
     335                 : 
     336               5 :     auto opt = opt_;
     337               5 :     return p.value.decode(opt);
     338                 : }
     339                 : 
     340                 : //------------------------------------------------
     341                 : //
     342                 : // (implementation)
     343                 : //
     344                 : //------------------------------------------------
     345                 : 
     346                 : inline
     347                 : detail::params_iter_impl
     348             110 : params_base::
     349                 : find_impl(
     350                 :     detail::params_iter_impl it,
     351                 :     core::string_view key,
     352                 :     ignore_case_param ic) const noexcept
     353                 : {
     354             110 :     detail::params_iter_impl end_(ref_, 0);
     355             110 :     if(! ic)
     356                 :     {
     357                 :         for(;;)
     358                 :         {
     359             323 :             if(it.equal(end_))
     360              33 :                 return it;
     361             290 :             if(*it.key() == key)
     362              39 :                 return it;
     363             251 :             it.increment();
     364                 :         }
     365                 :     }
     366                 :     for(;;)
     367                 :     {
     368             129 :         if(it.equal(end_))
     369              10 :             return it;
     370             119 :         if( grammar::ci_is_equal(
     371             238 :                 *it.key(), key))
     372              28 :             return it;
     373              91 :         it.increment();
     374                 :     }
     375                 : }
     376                 : 
     377                 : inline
     378                 : detail::params_iter_impl
     379              13 : params_base::
     380                 : find_last_impl(
     381                 :     detail::params_iter_impl it,
     382                 :     core::string_view key,
     383                 :     ignore_case_param ic) const noexcept
     384                 : {
     385              13 :     detail::params_iter_impl begin_(ref_);
     386              13 :     if(! ic)
     387                 :     {
     388                 :         for(;;)
     389                 :         {
     390              13 :             if(it.equal(begin_))
     391               2 :                 return { ref_, 0 };
     392              11 :             it.decrement();
     393              11 :             if(*it.key() == key)
     394               5 :                 return it;
     395                 :         }
     396                 :     }
     397                 :     for(;;)
     398                 :     {
     399               9 :         if(it.equal(begin_))
     400               1 :             return { ref_, 0 };
     401               8 :         it.decrement();
     402               8 :         if(grammar::ci_is_equal(
     403              16 :                 *it.key(), key))
     404               5 :             return it;
     405                 :     }
     406                 : }
     407                 : 
     408                 : //------------------------------------------------
     409                 : 
     410                 : inline
     411                 : std::ostream&
     412               1 : operator<<(
     413                 :     std::ostream& os,
     414                 :     params_base const& qp)
     415                 : {
     416               1 :     os << qp.buffer();
     417               1 :     return os;
     418                 : }
     419                 : 
     420                 : } // urls
     421                 : } // boost
     422                 : 
     423                 : #endif
        

Generated by: LCOV version 2.3