LCOV - code coverage report
Current view: top level - /jenkins/workspace/boost-root/libs/url/src/detail - pct_format.cpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 80 80
Test Date: 2026-02-25 21:00:01 Functions: 100.0 % 2 2

           TLA  Line data    Source code
       1                 : //
       2                 : // Copyright (c) 2022 Alan de Freitas (alandefreitas@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                 : 
      11                 : #include <boost/url/detail/config.hpp>
      12                 : #include "pct_format.hpp"
      13                 : #include <boost/url/grammar/parse.hpp>
      14                 : #include <boost/url/grammar/unsigned_rule.hpp>
      15                 : 
      16                 : namespace boost {
      17                 : namespace urls {
      18                 : namespace detail {
      19                 : 
      20                 : std::size_t
      21 HIT         297 : pct_vmeasure(
      22                 :     grammar::lut_chars const& cs,
      23                 :     format_parse_context& pctx,
      24                 :     measure_context& mctx)
      25                 : {
      26             297 :     auto it0 = pctx.begin();
      27             297 :     auto end = pctx.end();
      28             581 :     while( it0 != end )
      29                 :     {
      30                 :         // look for replacement id
      31             348 :         char const* it1 = it0;
      32             348 :         while(
      33             902 :             it1 != end &&
      34             840 :             *it1 != '{' )
      35                 :         {
      36             554 :             ++it1;
      37                 :         }
      38                 : 
      39                 :         // output literal prefix
      40             348 :         if( it0 != it1 )
      41                 :         {
      42             693 :             for (char const* i = it0; i != it1; ++i)
      43             554 :                 mctx.advance_to( mctx.out() + measure_one(*i, cs));
      44                 :         }
      45                 : 
      46                 :         // over
      47             348 :         if( it1 == end )
      48                 :         {
      49              62 :             break;
      50                 :         }
      51                 : 
      52                 :         // enter replacement id
      53             286 :         ++it1;
      54             286 :         BOOST_ASSERT(it1 != end);
      55                 : 
      56                 :         // handle escaped replacement (second '{')
      57                 :         // there's no "{{" in URL templates because
      58                 :         // '{'s are not allowed in URLs
      59             286 :         BOOST_ASSERT(*it1 != '{');
      60                 :         /*
      61                 :         if( *it1 == '{' )
      62                 :         {
      63                 :             mctx.advance_to( mctx.out() + measure_one('{', cs));
      64                 :             ++it1;
      65                 :             // this was not a real replacement,
      66                 :             // so we just keep moving
      67                 :             continue;
      68                 :         }
      69                 :         */
      70                 : 
      71                 : 
      72                 :         // parse {id} or {id:specs}
      73             286 :         char const* id_start = it1;
      74             286 :         while (it1 != end &&
      75             536 :                *it1 != ':' &&
      76             495 :                *it1 != '}')
      77                 :         {
      78             250 :             ++it1;
      79                 :         }
      80             286 :         core::string_view id(id_start, it1);
      81                 : 
      82                 :         // move to specs start
      83             286 :         if (it1 != end &&
      84             286 :             *it1 == ':')
      85              41 :             ++it1;
      86             286 :         pctx.advance_to( it1 );
      87                 : 
      88                 :         // get format_arg to use
      89             286 :         auto idv = grammar::parse(
      90             286 :             id, grammar::unsigned_rule<std::size_t>{});
      91             286 :         if (idv)
      92                 :         {
      93              33 :             mctx.arg( *idv ).measure( pctx, mctx, cs );
      94                 :         }
      95             253 :         else if (!id.empty())
      96                 :         {
      97              43 :             mctx.arg( id ).measure( pctx, mctx, cs );
      98                 :         }
      99                 :         else
     100                 :         {
     101             210 :             std::size_t arg_id = pctx.next_arg_id();
     102             210 :             mctx.arg( arg_id ).measure( pctx, mctx, cs );
     103                 :         }
     104                 : 
     105                 : 
     106             284 :         it1 = pctx.begin();
     107             284 :         BOOST_ASSERT(*it1 == '}');
     108             284 :         it0 = it1 + 1;
     109                 :     }
     110                 : 
     111             295 :     return mctx.out();
     112                 : }
     113                 : 
     114                 : char*
     115             292 : pct_vformat(
     116                 :     grammar::lut_chars const& cs,
     117                 :     format_parse_context& pctx,
     118                 :     format_context& fctx)
     119                 : {
     120             292 :     auto it0 = pctx.begin();
     121             292 :     auto end = pctx.end();
     122             574 :     while( it0 != end )
     123                 :     {
     124                 :         // look for replacement id
     125             343 :         char const* it1 = it0;
     126             343 :         while(
     127             888 :             it1 != end &&
     128             827 :             *it1 != '{' )
     129                 :         {
     130             545 :             ++it1;
     131                 :         }
     132                 : 
     133                 :         // output literal prefix
     134             343 :         if( it0 != it1 )
     135                 :         {
     136             683 :             for (char const* i = it0; i != it1; ++i)
     137                 :             {
     138             545 :                 char* o = fctx.out();
     139             545 :                 encode_one(o, *i, cs);
     140             545 :                 fctx.advance_to(o);
     141                 :             }
     142                 :         }
     143                 : 
     144                 :         // over
     145             343 :         if( it1 == end )
     146                 :         {
     147              61 :             break;
     148                 :         }
     149                 : 
     150                 :         // enter replacement id
     151             282 :         ++it1;
     152             282 :         BOOST_ASSERT(it1 != end);
     153                 : 
     154                 :         // handle escaped replacement (second '{')
     155                 :         // there's no "{{" in URL templates because
     156                 :         // '{'s are not allowed in URLs
     157             282 :         BOOST_ASSERT(*it1 != '{');
     158                 :         /*
     159                 :         if( *it1 == '{' )
     160                 :         {
     161                 :             char* o = fctx.out();
     162                 :             encode_one(o, '{', cs);
     163                 :             fctx.advance_to(o);
     164                 :             ++it1;
     165                 :             // this was not a real replacement,
     166                 :             // so we just keep moving
     167                 :             continue;
     168                 :         }
     169                 :         */
     170                 : 
     171                 :         // parse {id} or {id:specs}
     172             282 :         char const* id_start = it1;
     173             282 :         while (it1 != end &&
     174             532 :                *it1 != ':' &&
     175             493 :                *it1 != '}')
     176                 :         {
     177             250 :             ++it1;
     178                 :         }
     179             282 :         core::string_view id(id_start, it1);
     180                 : 
     181                 :         // move to specs part
     182             282 :         if (it1 != end &&
     183             282 :             *it1 == ':')
     184              39 :             ++it1;
     185             282 :         pctx.advance_to( it1 );
     186                 : 
     187                 :         // get format_arg to use
     188             282 :         auto idv = grammar::parse(
     189             282 :             id, grammar::unsigned_rule<std::size_t>{});
     190             282 :         if (idv)
     191                 :         {
     192              33 :             fctx.arg( *idv ).format( pctx, fctx, cs );
     193                 :         }
     194             249 :         else if (!id.empty())
     195                 :         {
     196              43 :             fctx.arg( id ).format( pctx, fctx, cs );
     197                 :         }
     198                 :         else
     199                 :         {
     200             206 :             std::size_t arg_id = pctx.next_arg_id();
     201             206 :             fctx.arg( arg_id ).format( pctx, fctx, cs );
     202                 :         }
     203                 : 
     204             282 :         it1 = pctx.begin();
     205             282 :         BOOST_ASSERT(*it1 == '}');
     206             282 :         it0 = it1 + 1;
     207                 :     }
     208                 : 
     209             292 :     return fctx.out();
     210                 : }
     211                 : 
     212                 : } // detail
     213                 : } // urls
     214                 : } // boost
     215                 : 
        

Generated by: LCOV version 2.3