LCOV - code coverage report
Current view: top level - libs/url/src - params_ref.cpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 68 98 69.4 %
Date: 2024-02-29 20:02:55 Functions: 13 15 86.7 %

          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_REF_IPP
      12             : #define BOOST_URL_IMPL_PARAMS_REF_IPP
      13             : 
      14             : #include <boost/url/detail/config.hpp>
      15             : #include <boost/url/decode_view.hpp>
      16             : #include <boost/url/params_ref.hpp>
      17             : #include <boost/url/params_view.hpp>
      18             : #include <boost/url/url_base.hpp>
      19             : #include <boost/url/grammar/ci_string.hpp>
      20             : #include <boost/assert.hpp>
      21             : #include <utility>
      22             : 
      23             : namespace boost {
      24             : namespace urls {
      25             : 
      26             : //------------------------------------------------
      27             : //
      28             : // Special Members
      29             : //
      30             : //------------------------------------------------
      31             : 
      32             : auto
      33           1 : params_ref::
      34             : operator=(params_ref const& other) ->
      35             :     params_ref&
      36             : {
      37           1 :     if (!ref_.alias_of(other.ref_))
      38           1 :         assign(other.begin(), other.end());
      39           1 :     return *this;
      40             : }
      41             : 
      42          63 : params_ref::
      43             : operator
      44             : params_view() const noexcept
      45             : {
      46          63 :     return { ref_, opt_ };
      47             : }
      48             : 
      49             : //------------------------------------------------
      50             : //
      51             : // Modifiers
      52             : //
      53             : //------------------------------------------------
      54             : 
      55             : void
      56           5 : params_ref::
      57             : assign(
      58             :     std::initializer_list<
      59             :         param_view> init)
      60             : {
      61           5 :     assign(init.begin(), init.end());
      62           5 : }
      63             : 
      64             : auto
      65          11 : params_ref::
      66             : insert(
      67             :     iterator before,
      68             :     param_view const& p) ->
      69             :         iterator
      70             : {
      71             :     return iterator(
      72          22 :         u_->edit_params(
      73             :             before.it_,
      74             :             before.it_,
      75          22 :             detail::param_iter(p)),
      76          22 :         opt_);
      77             : }
      78             : 
      79             : auto
      80          15 : params_ref::
      81             : insert(
      82             :     iterator before,
      83             :     std::initializer_list<
      84             :         param_view> init) ->
      85             :     iterator
      86             : {
      87             :     return insert(
      88             :         before,
      89             :         init.begin(),
      90          15 :         init.end());
      91             : }
      92             : 
      93             : std::size_t
      94           2 : params_ref::
      95             : erase(
      96             :     core::string_view key,
      97             :     ignore_case_param ic) noexcept
      98             : {
      99             :     // end() can't be fully cached,
     100             :     // since erase invalidates it.
     101           2 :     iterator it;
     102             :     {
     103           2 :         auto const end_ = end();
     104           2 :         it = find_last(end_, key, ic);
     105           2 :         if(it == end_)
     106           0 :             return 0;
     107             :     }
     108           2 :     std::size_t n = 0;
     109             :     for(;;)
     110             :     {
     111           5 :         ++n;
     112             :         // Use it->key instead of key,
     113             :         // to handle self-intersection
     114           5 :         auto prev = find_last(it, (*it).key, ic);
     115           5 :         if(prev == end())
     116           2 :             break;
     117           3 :         erase(it);
     118           3 :         it = prev;
     119           3 :     }
     120           2 :     erase(it);
     121           2 :     return n;
     122             : }
     123             : 
     124             : auto
     125           6 : params_ref::
     126             : replace(
     127             :     iterator pos,
     128             :     param_view const& p) ->
     129             :         iterator
     130             : {
     131             :     return iterator(
     132          12 :         u_->edit_params(
     133             :             pos.it_,
     134           6 :             std::next(pos).it_,
     135          18 :             detail::param_iter(p)),
     136          12 :         opt_);
     137             : }
     138             : 
     139             : auto
     140           2 : params_ref::
     141             : replace(
     142             :     iterator from,
     143             :     iterator to,
     144             :     std::initializer_list<
     145             :         param_view> init) ->
     146             :     iterator
     147             : {
     148             :     return replace(
     149             :         from,
     150             :         to,
     151             :         init.begin(),
     152           2 :         init.end());
     153             : }
     154             : 
     155             : auto
     156           4 : params_ref::
     157             : unset(
     158             :     iterator pos) noexcept ->
     159             :         iterator
     160             : {
     161           4 :     BOOST_ASSERT(pos.it_.nk > 0);
     162           4 :     core::string_view s;
     163             :     return iterator(
     164           8 :         u_->edit_params(
     165             :             pos.it_,
     166           4 :             pos.it_.next(),
     167           4 :             detail::param_value_iter(
     168           8 :                 pos.it_.nk - 1, s, false)),
     169           4 :         opt_);
     170             : }
     171             : 
     172             : auto
     173           5 : params_ref::
     174             : set(
     175             :     iterator pos,
     176             :     core::string_view value) ->
     177             :         iterator
     178             : {
     179           5 :     BOOST_ASSERT(pos.it_.nk > 0);
     180             :     return iterator(
     181          10 :         u_->edit_params(
     182             :             pos.it_,
     183           5 :             pos.it_.next(),
     184           5 :             detail::param_value_iter(
     185          10 :                 pos.it_.nk - 1, value, true)),
     186          10 :         opt_);
     187             : }
     188             : 
     189             : auto
     190           1 : params_ref::
     191             : set(
     192             :     core::string_view key,
     193             :     core::string_view value,
     194             :     ignore_case_param ic) ->
     195             :         iterator
     196             : {
     197             :     // VFALCO we can't cache end() here
     198             :     // because it is invalidated
     199             :     // every time we set or erase.
     200           1 :     auto it0 = find(key, ic);
     201           1 :     if(it0 == end())
     202           0 :         return append({key, value});
     203           1 :     it0 = set(it0, value);
     204           1 :     auto it = end();
     205             :     for(;;)
     206             :     {
     207           2 :         it = find_last(it, key, ic);
     208           2 :         if(it == it0)
     209           1 :             return it0;
     210           1 :         it = erase(it);
     211             :     }
     212             : }
     213             : 
     214             : auto
     215           9 : params_ref::
     216             : erase(
     217             :     iterator pos) noexcept ->
     218             :     iterator
     219             : {
     220             :     return erase(
     221             :         pos,
     222           9 :         std::next(pos));
     223             : }
     224             : 
     225             : auto
     226          11 : params_ref::
     227             : erase(
     228             :     iterator first,
     229             :     iterator last) noexcept ->
     230             :         iterator
     231             : {
     232          11 :     core::string_view s("", 0);
     233             :     return iterator(
     234          22 :         u_->edit_params(
     235             :             first.it_,
     236             :             last.it_,
     237          22 :             detail::query_iter(s)),
     238          11 :         opt_);
     239             : }
     240             : 
     241             : //------------------------------------------------
     242             : //
     243             : // (implementation)
     244             : //
     245             : //------------------------------------------------
     246             : 
     247             : detail::params_iter_impl
     248           0 : params_ref::
     249             : find_impl(
     250             :     detail::params_iter_impl it,
     251             :     core::string_view key,
     252             :     ignore_case_param ic) const noexcept
     253             : {
     254           0 :     detail::params_iter_impl end_(u_->impl_, 0);
     255           0 :     if(! ic)
     256             :     {
     257             :         for(;;)
     258             :         {
     259           0 :             if(it.equal(end_))
     260           0 :                 return it;
     261           0 :             if(*it.key() == key)
     262           0 :                 return it;
     263           0 :             it.increment();
     264             :         }
     265             :     }
     266             :     for(;;)
     267             :     {
     268           0 :         if(it.equal(end_))
     269           0 :             return it;
     270           0 :         if( grammar::ci_is_equal(
     271           0 :                 *it.key(), key))
     272           0 :             return it;
     273           0 :         it.increment();
     274             :     }
     275             : }
     276             : 
     277             : detail::params_iter_impl
     278           0 : params_ref::
     279             : find_last_impl(
     280             :     detail::params_iter_impl it,
     281             :     core::string_view key,
     282             :     ignore_case_param ic) const noexcept
     283             : {
     284           0 :     detail::params_iter_impl begin_(u_->impl_);
     285           0 :     if(! ic)
     286             :     {
     287             :         for(;;)
     288             :         {
     289           0 :             if(it.equal(begin_))
     290           0 :                 return { u_->impl_, 0 };
     291           0 :             it.decrement();
     292           0 :             if(*it.key() == key)
     293           0 :                 return it;
     294             :         }
     295             :     }
     296             :     for(;;)
     297             :     {
     298           0 :         if(it.equal(begin_))
     299           0 :             return { u_->impl_, 0 };
     300           0 :         it.decrement();
     301           0 :         if(grammar::ci_is_equal(
     302           0 :                 *it.key(), key))
     303           0 :             return it;
     304             :     }
     305             : }
     306             : 
     307             : } // urls
     308             : } // boost
     309             : 
     310             : #endif

Generated by: LCOV version 1.15