Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:26

0001 //
0002 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/url
0008 //
0009 
0010 #ifndef BOOST_URL_DETAIL_ANY_SEGMENTS_ITER_HPP
0011 #define BOOST_URL_DETAIL_ANY_SEGMENTS_ITER_HPP
0012 
0013 #include <boost/url/pct_string_view.hpp>
0014 #include <boost/static_assert.hpp>
0015 #include <cstddef>
0016 #include <iterator>
0017 #include <type_traits>
0018 
0019 namespace boost {
0020 namespace urls {
0021 namespace detail {
0022 
0023 struct BOOST_SYMBOL_VISIBLE
0024     any_segments_iter
0025 {
0026 protected:
0027     explicit
0028     any_segments_iter(
0029         core::string_view s_ = {}) noexcept
0030         : s(s_)
0031     {
0032     }
0033 
0034     virtual ~any_segments_iter() = default;
0035 
0036 public:
0037     // this is adjusted
0038     // when self-intersecting
0039     core::string_view s;
0040 
0041     // the first segment,
0042     // to handle special cases
0043     core::string_view front;
0044 
0045     // quick number of segments
0046     // 0 = zero
0047     // 1 = one
0048     // 2 = two, or more
0049     int fast_nseg = 0;
0050 
0051     // whether the segments should encode colons
0052     // when we measure and copy. the calling
0053     // function uses this for the first
0054     // segment in some cases, such as:
0055     // "x:y:z" -> remove_scheme -> "y%3Az"
0056     // as "y:z" would no longer represent a path
0057     bool encode_colons = false;
0058 
0059     // Rewind the iterator to the beginning
0060     virtual void rewind() noexcept = 0;
0061 
0062     // Measure and increment the current
0063     // element. n is increased by the
0064     // encoded size. Returns false on
0065     // end of range. 
0066     virtual bool measure(std::size_t& n) = 0;
0067 
0068     // Copy and increment the current
0069     // element, encoding as needed.
0070     virtual void copy(char*& dest,
0071         char const* end) noexcept = 0;
0072 };
0073 
0074 //------------------------------------------------
0075 //
0076 // segment_iter
0077 //
0078 //------------------------------------------------
0079 
0080 // A 1-segment range
0081 // allowing self-intersection
0082 struct BOOST_SYMBOL_VISIBLE
0083     segment_iter
0084     : any_segments_iter
0085 {
0086     virtual ~segment_iter() = default;
0087 
0088     explicit
0089     segment_iter(
0090         core::string_view s) noexcept;
0091 
0092 private:
0093     bool at_end_ = false;
0094     void rewind() noexcept override;
0095     bool measure(std::size_t&) noexcept override;
0096     void copy(char*&, char const*) noexcept override;
0097 };
0098 
0099 //------------------------------------------------
0100 //
0101 // segments_iter
0102 //
0103 //------------------------------------------------
0104 
0105 struct segments_iter_base
0106 {
0107 protected:
0108     BOOST_URL_DECL static void
0109     measure_impl(std::size_t&,
0110         core::string_view, bool) noexcept;
0111     BOOST_URL_DECL static void
0112     copy_impl(char*&, char const*,
0113         core::string_view, bool) noexcept;
0114 };
0115 
0116 // iterates segments in a
0117 // plain segment range
0118 template<class FwdIt>
0119 struct segments_iter
0120     : any_segments_iter
0121     , segments_iter_base
0122 {
0123     BOOST_STATIC_ASSERT(
0124         std::is_convertible<
0125             typename std::iterator_traits<
0126                 FwdIt>::reference,
0127             core::string_view>::value);
0128 
0129     segments_iter(
0130         FwdIt first,
0131         FwdIt last) noexcept
0132         : it_(first)
0133         , it0_(first)
0134         , end_(last)
0135     {
0136         if(first != last)
0137         {
0138             front = *first;
0139             auto it = first;
0140             if(++it == last)
0141                 fast_nseg = 1;
0142             else
0143                 fast_nseg = 2;
0144         }
0145         else
0146         {
0147             fast_nseg = 0;
0148         }
0149     }
0150 
0151 private:
0152     FwdIt it_;
0153     FwdIt it0_;
0154     FwdIt end_;
0155 
0156     void
0157     rewind() noexcept override
0158     {
0159         it_ = it0_;
0160     }
0161 
0162     bool
0163     measure(
0164         std::size_t& n) noexcept override
0165     {
0166         if(it_ == end_)
0167             return false;
0168         measure_impl(n,
0169             detail::to_sv(*it_),
0170             encode_colons);
0171         ++it_;
0172         return true;
0173     }
0174 
0175     void
0176     copy(
0177         char*& dest,
0178         char const* end) noexcept override
0179     {
0180         copy_impl(dest, end,
0181             detail::to_sv(*it_++),
0182             encode_colons);
0183     }
0184 };
0185 
0186 //------------------------------------------------
0187 //
0188 // segment_encoded_iter
0189 //
0190 //------------------------------------------------
0191 
0192 // A 1-segment range
0193 // allowing self-intersection
0194 struct BOOST_SYMBOL_VISIBLE
0195     segment_encoded_iter
0196     : any_segments_iter
0197 {
0198     virtual ~segment_encoded_iter() = default;
0199 
0200     explicit
0201     segment_encoded_iter(
0202         pct_string_view const& s) noexcept;
0203 
0204 private:
0205     bool at_end_ = false;
0206     void rewind() noexcept override;
0207     bool measure(std::size_t&) noexcept override;
0208     void copy(char*&, char const*) noexcept override;
0209 };
0210 
0211 //------------------------------------------------
0212 //
0213 // segments_encoded_iter
0214 //
0215 //------------------------------------------------
0216 
0217 // Validating and copying from
0218 // a string of encoded segments
0219 struct segments_encoded_iter_base
0220 {
0221 protected:
0222     BOOST_URL_DECL static void
0223     measure_impl(std::size_t&,
0224         core::string_view, bool) noexcept;
0225     BOOST_URL_DECL static void
0226     copy_impl(char*&, char const*,
0227         core::string_view, bool) noexcept;
0228 };
0229 
0230 // iterates segments in an
0231 // encoded segment range
0232 template<class FwdIt>
0233 struct segments_encoded_iter
0234     : public any_segments_iter
0235     , public segments_encoded_iter_base
0236 {
0237     BOOST_STATIC_ASSERT(
0238         std::is_convertible<
0239             typename std::iterator_traits<
0240                 FwdIt>::reference,
0241             core::string_view>::value);
0242 
0243     segments_encoded_iter(
0244         FwdIt first,
0245         FwdIt last)
0246         : it_(first)
0247         , it0_(first)
0248         , end_(last)
0249     {
0250         if(it_ != end_)
0251         {
0252             // throw on invalid input
0253             front = pct_string_view(
0254                 detail::to_sv(*first));
0255             auto it = first;
0256             if(++it == last)
0257                 fast_nseg = 1;
0258             else
0259                 fast_nseg = 2;
0260         }
0261         else
0262         {
0263             fast_nseg = 0;
0264         }
0265     }
0266 
0267 private:
0268     FwdIt it_;
0269     FwdIt it0_;
0270     FwdIt end_;
0271 
0272     void
0273     rewind() noexcept override
0274     {
0275         it_ = it0_;
0276     }
0277 
0278     bool
0279     measure(
0280         std::size_t& n) override
0281     {
0282         if(it_ == end_)
0283             return false;
0284         // throw on invalid input
0285         measure_impl(n,
0286             pct_string_view(
0287                 detail::to_sv(*it_++)),
0288             encode_colons);
0289         return true;
0290     }
0291 
0292     void
0293     copy(
0294         char*& dest,
0295         char const* end) noexcept override
0296     {
0297         copy_impl(dest, end,
0298             detail::to_sv(*it_++),
0299             encode_colons);
0300     }
0301 };
0302 
0303 //------------------------------------------------
0304 
0305 template<class FwdIt>
0306 segments_iter<FwdIt>
0307 make_segments_iter(
0308     FwdIt first, FwdIt last)
0309 {
0310     return segments_iter<
0311         FwdIt>(first, last);
0312 }
0313 
0314 template<class FwdIt>
0315 segments_encoded_iter<FwdIt>
0316 make_segments_encoded_iter(
0317     FwdIt first, FwdIt last)
0318 {
0319     return segments_encoded_iter<
0320         FwdIt>(first, last);
0321 }
0322 
0323 } // detail
0324 } // urls
0325 } // boost
0326 
0327 #endif