LCOV - code coverage report
Current view: top level - libs/url/src/detail/pct_format.cpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 80 80
Test Date: 2024-09-08 09:46:47 Functions: 100.0 % 2 2

            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          250 : pct_vmeasure(
      22              :     grammar::lut_chars const& cs,
      23              :     format_parse_context& pctx,
      24              :     measure_context& mctx)
      25              : {
      26          250 :     auto it0 = pctx.begin();
      27          250 :     auto end = pctx.end();
      28          488 :     while( it0 != end )
      29              :     {
      30              :         // look for replacement id
      31          295 :         char const* it1 = it0;
      32          295 :         while(
      33          762 :             it1 != end &&
      34          707 :             *it1 != '{' )
      35              :         {
      36          467 :             ++it1;
      37              :         }
      38              : 
      39              :         // output literal prefix
      40          295 :         if( it0 != it1 )
      41              :         {
      42          584 :             for (char const* i = it0; i != it1; ++i)
      43          467 :                 mctx.advance_to( mctx.out() + measure_one(*i, cs));
      44              :         }
      45              : 
      46              :         // over
      47          295 :         if( it1 == end )
      48              :         {
      49           55 :             break;
      50              :         }
      51              : 
      52              :         // enter replacement id
      53          240 :         ++it1;
      54          240 :         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          240 :         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          240 :         char const* id_start = it1;
      74          240 :         while (it1 != end &&
      75          405 :                *it1 != ':' &&
      76          364 :                *it1 != '}')
      77              :         {
      78          165 :             ++it1;
      79              :         }
      80          240 :         core::string_view id(id_start, it1);
      81              : 
      82              :         // move to specs start
      83          240 :         if (it1 != end &&
      84          240 :             *it1 == ':')
      85           41 :             ++it1;
      86          240 :         pctx.advance_to( it1 );
      87              : 
      88              :         // get format_arg to use
      89          240 :         auto idv = grammar::parse(
      90          240 :             id, grammar::unsigned_rule<std::size_t>{});
      91          240 :         if (idv)
      92              :         {
      93           27 :             mctx.arg( *idv ).measure( pctx, mctx, cs );
      94              :         }
      95          213 :         else if (!id.empty())
      96              :         {
      97           26 :             mctx.arg( id ).measure( pctx, mctx, cs );
      98              :         }
      99              :         else
     100              :         {
     101          187 :             std::size_t arg_id = pctx.next_arg_id();
     102          187 :             mctx.arg( arg_id ).measure( pctx, mctx, cs );
     103              :         }
     104              : 
     105              : 
     106          238 :         it1 = pctx.begin();
     107          238 :         BOOST_ASSERT(*it1 == '}');
     108          238 :         it0 = it1 + 1;
     109              :     }
     110              : 
     111          248 :     return mctx.out();
     112              : }
     113              : 
     114              : char*
     115          245 : pct_vformat(
     116              :     grammar::lut_chars const& cs,
     117              :     format_parse_context& pctx,
     118              :     format_context& fctx)
     119              : {
     120          245 :     auto it0 = pctx.begin();
     121          245 :     auto end = pctx.end();
     122          481 :     while( it0 != end )
     123              :     {
     124              :         // look for replacement id
     125          290 :         char const* it1 = it0;
     126          290 :         while(
     127          748 :             it1 != end &&
     128          694 :             *it1 != '{' )
     129              :         {
     130          458 :             ++it1;
     131              :         }
     132              : 
     133              :         // output literal prefix
     134          290 :         if( it0 != it1 )
     135              :         {
     136          574 :             for (char const* i = it0; i != it1; ++i)
     137              :             {
     138          458 :                 char* o = fctx.out();
     139          458 :                 encode_one(o, *i, cs);
     140          458 :                 fctx.advance_to(o);
     141              :             }
     142              :         }
     143              : 
     144              :         // over
     145          290 :         if( it1 == end )
     146              :         {
     147           54 :             break;
     148              :         }
     149              : 
     150              :         // enter replacement id
     151          236 :         ++it1;
     152          236 :         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          236 :         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          236 :         char const* id_start = it1;
     173          236 :         while (it1 != end &&
     174          401 :                *it1 != ':' &&
     175          362 :                *it1 != '}')
     176              :         {
     177          165 :             ++it1;
     178              :         }
     179          236 :         core::string_view id(id_start, it1);
     180              : 
     181              :         // move to specs part
     182          236 :         if (it1 != end &&
     183          236 :             *it1 == ':')
     184           39 :             ++it1;
     185          236 :         pctx.advance_to( it1 );
     186              : 
     187              :         // get format_arg to use
     188          236 :         auto idv = grammar::parse(
     189          236 :             id, grammar::unsigned_rule<std::size_t>{});
     190          236 :         if (idv)
     191              :         {
     192           27 :             fctx.arg( *idv ).format( pctx, fctx, cs );
     193              :         }
     194          209 :         else if (!id.empty())
     195              :         {
     196           26 :             fctx.arg( id ).format( pctx, fctx, cs );
     197              :         }
     198              :         else
     199              :         {
     200          183 :             std::size_t arg_id = pctx.next_arg_id();
     201          183 :             fctx.arg( arg_id ).format( pctx, fctx, cs );
     202              :         }
     203              : 
     204          236 :         it1 = pctx.begin();
     205          236 :         BOOST_ASSERT(*it1 == '}');
     206          236 :         it0 = it1 + 1;
     207              :     }
     208              : 
     209          245 :     return fctx.out();
     210              : }
     211              : 
     212              : } // detail
     213              : } // urls
     214              : } // boost
     215              : 
        

Generated by: LCOV version 2.1