LCOV - code coverage report
Current view: top level - boost/http_proto/rfc/impl/list_rule.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 98.2 % 57 56
Test Date: 2025-09-21 18:08:14 Functions: 100.0 % 16 16

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2021 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/cppalliance/http_proto
       8              : //
       9              : 
      10              : #ifndef BOOST_HTTP_PROTO_RFC_IMPL_LIST_RULE_HPP
      11              : #define BOOST_HTTP_PROTO_RFC_IMPL_LIST_RULE_HPP
      12              : 
      13              : #include <boost/http_proto/rfc/detail/ws.hpp>
      14              : 
      15              : #include <boost/url/grammar/parse.hpp>
      16              : #include <boost/url/grammar/charset.hpp>
      17              : #include <boost/url/grammar/range_rule.hpp>
      18              : #include <boost/core/empty_value.hpp>
      19              : 
      20              : namespace boost {
      21              : namespace http_proto {
      22              : 
      23              : namespace detail {
      24              : 
      25              : /*  Peter:
      26              : 
      27              :     So, to put everything together, this is what I propose
      28              : 
      29              :     - make range2_rule that takes first and next with
      30              :       value types of optional<E> rather than E like the current rule
      31              :     - make variant_rule produce an optional<X> when otherwise
      32              :       the value type would have been variant<void, void, X, void>
      33              :     - add operators for combining the rules so that one can
      34              :       write *( OWS >> !literal(",") >> -( OWS >> element ) )
      35              :     - profit
      36              : */
      37              : 
      38              : // *( OWS "," )
      39              : struct ows_comma_t
      40              : {
      41              :     using value_type = void;
      42              : 
      43              :     auto
      44           81 :     parse(
      45              :         char const*& it,
      46              :         char const* end) const noexcept ->
      47              :             system::result<value_type>
      48              :     {
      49           81 :         auto it1 = it;
      50          202 :         while(it != end)
      51              :         {
      52              :             // SP / HT
      53          191 :             if( *it == ' ' ||
      54          143 :                 *it == '\t')
      55              :             {
      56           50 :                 ++it;
      57           50 :                 continue;
      58              :             }
      59          141 :             if(*it != ',')
      60           70 :                 break;
      61              :             // ","
      62           71 :             it1 = ++it;
      63              :         }
      64           81 :         it = it1;
      65           81 :         return {};
      66              :     }
      67              : };
      68              : 
      69              : constexpr ows_comma_t ows_comma{};
      70              : 
      71              : } // detail
      72              : 
      73              : /*
      74              :     #element    => [ ( "," / element ) *( OWS "," [ OWS element ] ) ]
      75              : 
      76              :     #element    => first *next
      77              :     first       => [ element / ( "," *( OWS "," ) [ OWS element ] ) ]
      78              :     next        => "" / ( 1*( OWS "," ) [ OWS element ] )
      79              : */
      80              : 
      81              : namespace implementation_defined {
      82              : template<class Rule>
      83              : struct list_rule_t<Rule>::
      84              :     first_rule : empty_value<Rule>
      85              : {
      86              :     using value_type =
      87              :         typename Rule::value_type;
      88              : 
      89              :     constexpr
      90              :     explicit
      91         4554 :     first_rule(
      92              :         Rule const& r) noexcept
      93              :         : empty_value<Rule>(
      94         4554 :             empty_init, r)
      95              :     {
      96         4554 :     }
      97              : 
      98              :     auto
      99         9148 :     parse(
     100              :         char const*& it,
     101              :         char const* end) const ->
     102              :             system::result<value_type>
     103              :     {
     104              :     //  first       => [ element / ( "," *( OWS "," ) [ OWS element ] ) ]
     105              : 
     106         9148 :         if(it == end)
     107            4 :             return grammar::error::end_of_range;
     108              :         {
     109              :             // element
     110         9144 :             auto it0 = it;
     111         9144 :             auto rv = this->get().parse(it, end);
     112         9144 :             if(rv)
     113         9120 :                 return std::move(*rv);
     114           24 :             it = it0;
     115         8456 :         }
     116              :         // ","
     117           24 :         if(*it != ',')
     118           11 :             return grammar::error::end_of_range;
     119           13 :         ++it;
     120              :         // *( OWS "," )
     121           13 :         detail::ows_comma.parse(it, end);
     122           13 :         auto it1 = it;
     123              :         // OWS
     124           13 :         it = grammar::find_if_not(
     125              :             it, end, detail::ws);
     126              :         // element
     127           13 :         auto rv = this->get().parse(it, end);
     128           13 :         if(rv)
     129            6 :             return std::move(*rv);
     130            7 :         it = it1;
     131            7 :         return grammar::error::end_of_range;
     132            0 :     }
     133              : };
     134              : 
     135              : template<class Rule>
     136              : struct list_rule_t<Rule>::
     137              :     next_rule : empty_value<Rule>
     138              : {
     139              :     using value_type =
     140              :         typename Rule::value_type;
     141              : 
     142              :     constexpr
     143              :     explicit
     144         4554 :     next_rule(
     145              :         Rule const& r) noexcept
     146              :         : empty_value<Rule>(
     147         4554 :             empty_init, r)
     148              :     {
     149         4554 :     }
     150              : 
     151              :     auto
     152         8978 :     parse(
     153              :         char const*& it,
     154              :         char const* end) const ->
     155              :             system::result<value_type>
     156              :     {
     157              :     //  next        => "" / ( 1*( OWS "," ) [ OWS element ] )
     158              : 
     159              :         // ""
     160         8978 :         if(it == end)
     161         8910 :             return grammar::error::end_of_range;
     162              : 
     163              :         // 1*( OWS "," )
     164              :         {
     165           68 :             auto it0 = it;
     166           68 :             detail::ows_comma.parse(it, end);
     167           68 :             if(it == it0)
     168            3 :                 return grammar::error::end_of_range;
     169              :         }
     170           65 :         auto it1 = it;
     171              :         // OWS
     172           65 :         it = grammar::find_if_not(
     173              :             it, end, detail::ws);
     174           65 :         auto rv = this->get().parse(it, end);
     175           65 :         if(rv)
     176           59 :             return std::move(*rv);
     177            6 :         it = it1;
     178            6 :         return grammar::error::end_of_range;
     179           14 :     }
     180              : };
     181              : 
     182              : template<class Rule>
     183              : auto
     184         4554 : list_rule_t<Rule>::
     185              : parse(
     186              :     char const*& it,
     187              :     char const* end) const ->
     188              :         system::result<value_type>
     189              : {
     190              :     return grammar::parse(it, end,
     191         9108 :         grammar::range_rule(
     192              :             first_rule{this->get()},
     193              :             next_rule{this->get()},
     194        13662 :                 n_, m_));
     195              : }
     196              : } // implementation_defined
     197              : 
     198              : } // http_proto
     199              : } // boost
     200              : 
     201              : #endif
        

Generated by: LCOV version 2.1