LCOV - code coverage report
Current view: top level - boost/url/detail/any_segments_iter.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 98.5 % 67 66
Test Date: 2024-09-08 09:46:47 Functions: 89.2 % 37 33

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2019 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/boostorg/url
       8              : //
       9              : 
      10              : #ifndef BOOST_URL_DETAIL_ANY_SEGMENTS_ITER_HPP
      11              : #define BOOST_URL_DETAIL_ANY_SEGMENTS_ITER_HPP
      12              : 
      13              : #include <boost/url/pct_string_view.hpp>
      14              : #include <boost/static_assert.hpp>
      15              : #include <cstddef>
      16              : #include <iterator>
      17              : #include <type_traits>
      18              : 
      19              : namespace boost {
      20              : namespace urls {
      21              : namespace detail {
      22              : 
      23              : struct BOOST_SYMBOL_VISIBLE
      24              :     any_segments_iter
      25              : {
      26              : protected:
      27              :     explicit
      28          610 :     any_segments_iter(
      29              :         core::string_view s_ = {}) noexcept
      30          610 :         : s(s_)
      31              :     {
      32          610 :     }
      33              : 
      34          610 :     virtual ~any_segments_iter() = default;
      35              : 
      36              : public:
      37              :     // this is adjusted
      38              :     // when self-intersecting
      39              :     core::string_view s;
      40              : 
      41              :     // the first segment,
      42              :     // to handle special cases
      43              :     core::string_view front;
      44              : 
      45              :     // quick number of segments
      46              :     // 0 = zero
      47              :     // 1 = one
      48              :     // 2 = two, or more
      49              :     int fast_nseg = 0;
      50              : 
      51              :     // whether the segments should encode colons
      52              :     // when we measure and copy. the calling
      53              :     // function uses this for the first
      54              :     // segment in some cases, such as:
      55              :     // "x:y:z" -> remove_scheme -> "y%3Az"
      56              :     // as "y:z" would no longer represent a path
      57              :     bool encode_colons = false;
      58              : 
      59              :     // Rewind the iterator to the beginning
      60              :     virtual void rewind() noexcept = 0;
      61              : 
      62              :     // Measure and increment the current
      63              :     // element. n is increased by the
      64              :     // encoded size. Returns false on
      65              :     // end of range. 
      66              :     virtual bool measure(std::size_t& n) = 0;
      67              : 
      68              :     // Copy and increment the current
      69              :     // element, encoding as needed.
      70              :     virtual void copy(char*& dest,
      71              :         char const* end) noexcept = 0;
      72              : };
      73              : 
      74              : //------------------------------------------------
      75              : //
      76              : // segment_iter
      77              : //
      78              : //------------------------------------------------
      79              : 
      80              : // A 1-segment range
      81              : // allowing self-intersection
      82              : struct BOOST_SYMBOL_VISIBLE
      83              :     segment_iter
      84              :     : any_segments_iter
      85              : {
      86           74 :     virtual ~segment_iter() = default;
      87              : 
      88              :     explicit
      89              :     segment_iter(
      90              :         core::string_view s) noexcept;
      91              : 
      92              : private:
      93              :     bool at_end_ = false;
      94              :     void rewind() noexcept override;
      95              :     bool measure(std::size_t&) noexcept override;
      96              :     void copy(char*&, char const*) noexcept override;
      97              : };
      98              : 
      99              : //------------------------------------------------
     100              : //
     101              : // segments_iter
     102              : //
     103              : //------------------------------------------------
     104              : 
     105              : struct segments_iter_base
     106              : {
     107              : protected:
     108              :     BOOST_URL_DECL static void
     109              :     measure_impl(std::size_t&,
     110              :         core::string_view, bool) noexcept;
     111              :     BOOST_URL_DECL static void
     112              :     copy_impl(char*&, char const*,
     113              :         core::string_view, bool) noexcept;
     114              : };
     115              : 
     116              : // iterates segments in a
     117              : // plain segment range
     118              : template<class FwdIt>
     119              : struct segments_iter
     120              :     : any_segments_iter
     121              :     , segments_iter_base
     122              : {
     123              :     BOOST_STATIC_ASSERT(
     124              :         std::is_convertible<
     125              :             typename std::iterator_traits<
     126              :                 FwdIt>::reference,
     127              :             core::string_view>::value);
     128              : 
     129           79 :     segments_iter(
     130              :         FwdIt first,
     131              :         FwdIt last) noexcept
     132           79 :         : it_(first)
     133           79 :         , it0_(first)
     134           79 :         , end_(last)
     135              :     {
     136           79 :         if(first != last)
     137              :         {
     138           79 :             front = *first;
     139           79 :             auto it = first;
     140           79 :             if(++it == last)
     141            8 :                 fast_nseg = 1;
     142              :             else
     143           71 :                 fast_nseg = 2;
     144              :         }
     145              :         else
     146              :         {
     147            0 :             fast_nseg = 0;
     148              :         }
     149           79 :     }
     150              : 
     151              : private:
     152              :     FwdIt it_;
     153              :     FwdIt it0_;
     154              :     FwdIt end_;
     155              : 
     156              :     void
     157           79 :     rewind() noexcept override
     158              :     {
     159           79 :         it_ = it0_;
     160           79 :     }
     161              : 
     162              :     bool
     163          267 :     measure(
     164              :         std::size_t& n) noexcept override
     165              :     {
     166          267 :         if(it_ == end_)
     167           79 :             return false;
     168          188 :         measure_impl(n,
     169          182 :             detail::to_sv(*it_),
     170          188 :             encode_colons);
     171          188 :         ++it_;
     172          188 :         return true;
     173              :     }
     174              : 
     175              :     void
     176          188 :     copy(
     177              :         char*& dest,
     178              :         char const* end) noexcept override
     179              :     {
     180          188 :         copy_impl(dest, end,
     181          194 :             detail::to_sv(*it_++),
     182          188 :             encode_colons);
     183          188 :     }
     184              : };
     185              : 
     186              : //------------------------------------------------
     187              : //
     188              : // segment_encoded_iter
     189              : //
     190              : //------------------------------------------------
     191              : 
     192              : // A 1-segment range
     193              : // allowing self-intersection
     194              : struct BOOST_SYMBOL_VISIBLE
     195              :     segment_encoded_iter
     196              :     : any_segments_iter
     197              : {
     198           72 :     virtual ~segment_encoded_iter() = default;
     199              : 
     200              :     explicit
     201              :     segment_encoded_iter(
     202              :         pct_string_view const& s) noexcept;
     203              : 
     204              : private:
     205              :     bool at_end_ = false;
     206              :     void rewind() noexcept override;
     207              :     bool measure(std::size_t&) noexcept override;
     208              :     void copy(char*&, char const*) noexcept override;
     209              : };
     210              : 
     211              : //------------------------------------------------
     212              : //
     213              : // segments_encoded_iter
     214              : //
     215              : //------------------------------------------------
     216              : 
     217              : // Validating and copying from
     218              : // a string of encoded segments
     219              : struct segments_encoded_iter_base
     220              : {
     221              : protected:
     222              :     BOOST_URL_DECL static void
     223              :     measure_impl(std::size_t&,
     224              :         core::string_view, bool) noexcept;
     225              :     BOOST_URL_DECL static void
     226              :     copy_impl(char*&, char const*,
     227              :         core::string_view, bool) noexcept;
     228              : };
     229              : 
     230              : // iterates segments in an
     231              : // encoded segment range
     232              : template<class FwdIt>
     233              : struct segments_encoded_iter
     234              :     : public any_segments_iter
     235              :     , public segments_encoded_iter_base
     236              : {
     237              :     BOOST_STATIC_ASSERT(
     238              :         std::is_convertible<
     239              :             typename std::iterator_traits<
     240              :                 FwdIt>::reference,
     241              :             core::string_view>::value);
     242              : 
     243          385 :     segments_encoded_iter(
     244              :         FwdIt first,
     245              :         FwdIt last)
     246          385 :         : it_(first)
     247          385 :         , it0_(first)
     248          385 :         , end_(last)
     249              :     {
     250          385 :         if(it_ != end_)
     251              :         {
     252              :             // throw on invalid input
     253          196 :             front = pct_string_view(
     254          125 :                 detail::to_sv(*first));
     255          183 :             auto it = first;
     256          183 :             if(++it == last)
     257           65 :                 fast_nseg = 1;
     258              :             else
     259          118 :                 fast_nseg = 2;
     260              :         }
     261              :         else
     262              :         {
     263          189 :             fast_nseg = 0;
     264              :         }
     265          385 :     }
     266              : 
     267              : private:
     268              :     FwdIt it_;
     269              :     FwdIt it0_;
     270              :     FwdIt end_;
     271              : 
     272              :     void
     273          370 :     rewind() noexcept override
     274              :     {
     275          370 :         it_ = it0_;
     276          370 :     }
     277              : 
     278              :     bool
     279          771 :     measure(
     280              :         std::size_t& n) override
     281              :     {
     282          771 :         if(it_ == end_)
     283          370 :             return false;
     284              :         // throw on invalid input
     285          399 :         measure_impl(n,
     286          401 :             pct_string_view(
     287          401 :                 detail::to_sv(*it_++)),
     288          401 :             encode_colons);
     289          399 :         return true;
     290              :     }
     291              : 
     292              :     void
     293          397 :     copy(
     294              :         char*& dest,
     295              :         char const* end) noexcept override
     296              :     {
     297          397 :         copy_impl(dest, end,
     298          397 :             detail::to_sv(*it_++),
     299          397 :             encode_colons);
     300          397 :     }
     301              : };
     302              : 
     303              : //------------------------------------------------
     304              : 
     305              : template<class FwdIt>
     306              : segments_iter<FwdIt>
     307           79 : make_segments_iter(
     308              :     FwdIt first, FwdIt last)
     309              : {
     310              :     return segments_iter<
     311           79 :         FwdIt>(first, last);
     312              : }
     313              : 
     314              : template<class FwdIt>
     315              : segments_encoded_iter<FwdIt>
     316          385 : make_segments_encoded_iter(
     317              :     FwdIt first, FwdIt last)
     318              : {
     319              :     return segments_encoded_iter<
     320          385 :         FwdIt>(first, last);
     321              : }
     322              : 
     323              : } // detail
     324              : } // urls
     325              : } // boost
     326              : 
     327              : #endif
        

Generated by: LCOV version 2.1