LCOV - code coverage report
Current view: top level - libs/http_proto/src/fields_view_base.cpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 95.0 % 160 152
Test Date: 2025-09-21 18:08:14 Functions: 91.7 % 24 22

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
       3              : // Copyright (c) 2025 Mohammad Nejati
       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/cppalliance/http_proto
       9              : //
      10              : 
      11              : #include <boost/http_proto/fields_view_base.hpp>
      12              : #include <boost/http_proto/field.hpp>
      13              : #include <boost/http_proto/detail/except.hpp>
      14              : #include <boost/url/grammar/ci_string.hpp>
      15              : #include <boost/url/grammar/parse.hpp>
      16              : #include <boost/assert.hpp>
      17              : #include <boost/assert/source_location.hpp>
      18              : 
      19              : namespace boost {
      20              : namespace http_proto {
      21              : 
      22            0 : fields_view_base::
      23              : value_type::
      24              : value_type(
      25            0 :     reference const& other)
      26            0 :     : id(other.id)
      27            0 :     , name(other.name)
      28            0 :     , value(other.value)
      29              : {
      30            0 : }
      31              : 
      32              : //------------------------------------------------
      33              : 
      34              : auto
      35         2164 : fields_view_base::
      36              : iterator::
      37              : operator*() const noexcept ->
      38              :     reference
      39              : {
      40         2164 :     BOOST_ASSERT(i_ < ph_->count);
      41              :     auto tab =
      42         2164 :         ph_->tab();
      43              :     auto const& e =
      44         2164 :         tab[i_];
      45         2164 :     auto const* p =
      46         2164 :         ph_->cbuf + ph_->prefix;
      47              :     return {
      48         2164 :         (e.id == detail::header::unknown_field)
      49         2164 :             ? optional<field>{} : e.id,
      50              :         core::string_view(
      51         2164 :             p + e.np, e.nn),
      52              :         core::string_view(
      53         2164 :             p + e.vp, e.vn) };
      54              : }
      55              : 
      56              : //------------------------------------------------
      57              : 
      58              : auto
      59           24 : fields_view_base::
      60              : reverse_iterator::
      61              : operator*() const noexcept ->
      62              :     reference
      63              : {
      64           24 :     BOOST_ASSERT(i_ > 0);
      65              :     auto tab =
      66           24 :       ph_->tab();
      67              :     auto const& e =
      68           24 :         tab[i_-1];
      69           24 :     auto const* p =
      70           24 :         ph_->cbuf + ph_->prefix;
      71              :     return {
      72           24 :         (e.id == detail::header::unknown_field)
      73           24 :             ? optional<field>{} : e.id,
      74              :         core::string_view(
      75           24 :             p + e.np, e.nn),
      76              :         core::string_view(
      77           24 :             p + e.vp, e.vn) };
      78              : }
      79              : 
      80              : //------------------------------------------------
      81              : 
      82           21 : fields_view_base::
      83              : subrange::
      84              : iterator::
      85              : iterator(
      86              :     detail::header const* ph,
      87           21 :     std::size_t i) noexcept
      88           21 :     : ph_(ph)
      89           21 :     , i_(i)
      90              : {
      91           21 :     BOOST_ASSERT(i <= ph_->count);
      92           21 : }
      93              : 
      94           21 : fields_view_base::
      95              : subrange::
      96              : iterator::
      97              : iterator(
      98           21 :     detail::header const* ph) noexcept
      99           21 :     : ph_(ph)
     100           21 :     , i_(ph->count)
     101              : {
     102           21 : }
     103              : 
     104              : auto
     105           11 : fields_view_base::
     106              : subrange::
     107              : iterator::
     108              : operator*() const noexcept ->
     109              :     reference const
     110              : {
     111              :     auto tab =
     112           11 :         ph_->tab();
     113              :     auto const& e =
     114           11 :         tab[i_];
     115           11 :     auto const p =
     116           11 :         ph_->cbuf + ph_->prefix;
     117           22 :     return core::string_view(
     118           11 :         p + e.vp, e.vn);
     119              : }
     120              : 
     121              : auto
     122           27 : fields_view_base::
     123              : subrange::
     124              : iterator::
     125              : operator++() noexcept ->
     126              :     iterator&
     127              : {
     128           27 :     BOOST_ASSERT(i_ < ph_->count);
     129           27 :     auto const* e = &ph_->tab()[i_];
     130           27 :     auto const id = e->id;
     131           27 :     if(id != detail::header::unknown_field)
     132              :     {
     133           20 :         ++i_;
     134           20 :         --e;
     135           38 :         while(i_ != ph_->count)
     136              :         {
     137           26 :             if(e->id == id)
     138            8 :                 break;
     139           18 :             ++i_;
     140           18 :             --e;
     141              :         }
     142           20 :         return *this;
     143              :     }
     144            7 :     auto const p =
     145            7 :         ph_->cbuf + ph_->prefix;
     146              :     auto name = core::string_view(
     147            7 :         p + e->np, e->nn);
     148            7 :     ++i_;
     149            7 :     --e;
     150           24 :     while(i_ != ph_->count)
     151              :     {
     152           20 :         if(grammar::ci_is_equal(
     153              :             name, core::string_view(
     154           20 :                 p + e->np, e->nn)))
     155            3 :             break;
     156           17 :         ++i_;
     157           17 :         --e;
     158              :     }
     159            7 :     return *this;
     160              : }
     161              : 
     162              : //------------------------------------------------
     163              : //
     164              : // fields_view_base
     165              : //
     166              : //------------------------------------------------
     167              : 
     168              : core::string_view
     169            2 : fields_view_base::
     170              : at(
     171              :     field id) const
     172              : {
     173            2 :     auto const it = find(id);
     174            2 :     if(it == end())
     175            2 :         BOOST_THROW_EXCEPTION(
     176              :             std::out_of_range{ "field not found" });
     177            1 :     return it->value;
     178              : }
     179              : 
     180              : core::string_view
     181            2 : fields_view_base::
     182              : at(
     183              :     core::string_view name) const
     184              : {
     185            2 :     auto const it = find(name);
     186            2 :     if(it == end())
     187            2 :         BOOST_THROW_EXCEPTION(
     188              :             std::out_of_range{ "field not found" });
     189            1 :     return it->value;
     190              : }
     191              : 
     192              : bool
     193            4 : fields_view_base::
     194              : exists(
     195              :     field id) const noexcept
     196              : {
     197            4 :     return find(id) != end();
     198              : }
     199              : 
     200              : bool
     201            7 : fields_view_base::
     202              : exists(
     203              :     core::string_view name) const noexcept
     204              : {
     205            7 :     return find(name) != end();
     206              : }
     207              : 
     208              : std::size_t
     209           12 : fields_view_base::
     210              : count(field id) const noexcept
     211              : {
     212           12 :     std::size_t n = 0;
     213           57 :     for(auto v : *this)
     214           45 :         if(v.id == id)
     215           11 :             ++n;
     216           12 :     return n;
     217              : }
     218              : 
     219              : std::size_t
     220           23 : fields_view_base::
     221              : count(
     222              :     core::string_view name) const noexcept
     223              : {
     224           23 :     std::size_t n = 0;
     225          103 :     for(auto v : *this)
     226           80 :         if(grammar::ci_is_equal(
     227              :                 v.name, name))
     228           31 :             ++n;
     229           23 :     return n;
     230              : }
     231              : 
     232              : auto
     233           99 : fields_view_base::
     234              : find(field id) const noexcept ->
     235              :     iterator
     236              : {
     237           99 :     auto it = begin();
     238           99 :     auto const last = end();
     239          213 :     while(it != last)
     240              :     {
     241          204 :         if(it->id == id)
     242           90 :             break;
     243          114 :         ++it;
     244              :     }
     245           99 :     return it;
     246              : }
     247              : 
     248              : auto
     249           93 : fields_view_base::
     250              : find(
     251              :     core::string_view name) const noexcept ->
     252              :     iterator
     253              : {
     254           93 :     auto it = begin();
     255           93 :     auto const last = end();
     256          206 :     while(it != last)
     257              :     {
     258          200 :         if(grammar::ci_is_equal(
     259          400 :                 it->name, name))
     260           87 :             break;
     261          113 :         ++it;
     262              :     }
     263           93 :     return it;
     264              : }
     265              : 
     266              : auto
     267            2 : fields_view_base::
     268              : find(
     269              :     iterator from,
     270              :     field id) const noexcept ->
     271              :         iterator
     272              : {
     273            2 :     auto const last = end();
     274           11 :     while(from != last)
     275              :     {
     276           10 :         if(from->id == id)
     277            1 :             break;
     278            9 :         ++from;
     279              :     }
     280            2 :     return from;
     281              : }
     282              : 
     283              : auto
     284            2 : fields_view_base::
     285              : find(
     286              :     iterator from,
     287              :     core::string_view name) const noexcept ->
     288              :         iterator
     289              : {
     290            2 :     auto const last = end();
     291           12 :     while(from != last)
     292              :     {
     293           11 :         if(grammar::ci_is_equal(
     294           22 :                 name, from->name))
     295            1 :             break;
     296           10 :         ++from;
     297              :     }
     298            2 :     return from;
     299              : }
     300              : 
     301              : auto
     302            3 : fields_view_base::
     303              : find_last(
     304              :     iterator it,
     305              :     field id) const noexcept ->
     306              :         iterator
     307              : {
     308            3 :     auto const it0 = begin();
     309              :     for(;;)
     310              :     {
     311           10 :         if(it == it0)
     312            1 :             return end();
     313            9 :         --it;
     314            9 :         if(it->id == id)
     315            2 :             return it;
     316              :     }
     317              : }
     318              : 
     319              : auto
     320            3 : fields_view_base::
     321              : find_last(
     322              :     iterator it,
     323              :     core::string_view name) const noexcept ->
     324              :         iterator
     325              : {
     326            3 :     auto const it0 = begin();
     327              :     for(;;)
     328              :     {
     329           14 :         if(it == it0)
     330            1 :             return end();
     331           13 :         --it;
     332           13 :         if(grammar::ci_is_equal(
     333           26 :                 it->name, name))
     334            2 :             return it;
     335              :     }
     336              : }
     337              : 
     338              : core::string_view
     339            2 : fields_view_base::
     340              : value_or(
     341              :     field id,
     342              :     core::string_view s) const noexcept
     343              : {
     344            2 :     auto it = find(id);
     345            2 :     if(it != end())
     346            1 :         return it->value;
     347            1 :     return s;
     348              : }
     349              : 
     350              : core::string_view
     351            2 : fields_view_base::
     352              : value_or(
     353              :     core::string_view name,
     354              :     core::string_view s) const noexcept
     355              : {
     356            2 :     auto it = find(name);
     357            2 :     if(it != end())
     358            1 :         return it->value;
     359            1 :     return s;
     360              : }
     361              : 
     362              : //------------------------------------------------
     363              : 
     364              : auto
     365           16 : fields_view_base::
     366              : find_all(
     367              :     field id) const noexcept ->
     368              :         subrange
     369              : {
     370           32 :     return subrange(
     371           16 :         ph_, find(id).i_);
     372              : }
     373              : 
     374              : auto
     375            5 : fields_view_base::
     376              : find_all(
     377              :     core::string_view name) const noexcept ->
     378              :         subrange
     379              : {
     380           10 :     return subrange(
     381            5 :         ph_, find(name).i_);
     382              : }
     383              : 
     384              : //------------------------------------------------
     385              : 
     386              : std::ostream&
     387            0 : operator<<(
     388              :     std::ostream& os,
     389              :     const fields_view_base& f)
     390              : {
     391            0 :     return os << f.buffer();
     392              : }
     393              : 
     394              : } // http_proto
     395              : } // boost
        

Generated by: LCOV version 2.1