LCOV - code coverage report
Current view: top level - libs/url/src/detail - url_impl.cpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 203 207 98.1 %
Date: 2024-03-05 20:06:56 Functions: 34 34 100.0 %

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2022 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             : 
      11             : #include <boost/url/detail/config.hpp>
      12             : #include "path.hpp"
      13             : #include <boost/url/detail/url_impl.hpp>
      14             : #include <boost/url/authority_view.hpp>
      15             : #include <boost/assert.hpp>
      16             : #include <cstring>
      17             : 
      18             : namespace boost {
      19             : namespace urls {
      20             : namespace detail {
      21             : 
      22             : #if defined(__GNUC__) && ! defined(__clang__) && defined(__MINGW32__)
      23             : #pragma GCC diagnostic push
      24             : #pragma GCC diagnostic ignored "-Warray-bounds"
      25             : #endif
      26             : 
      27             : //------------------------------------------------
      28             : //
      29             : // url_impl
      30             : //
      31             : //------------------------------------------------
      32             : 
      33             : void
      34        2249 : url_impl::
      35             : apply_scheme(
      36             :     core::string_view s) noexcept
      37             : {
      38        2249 :     scheme_ = string_to_scheme(s);
      39        2249 :     set_size(id_scheme, s.size() + 1);
      40        2249 : }
      41             : 
      42             : void
      43         380 : url_impl::
      44             : apply_userinfo(
      45             :     pct_string_view const& user,
      46             :     pct_string_view const* pass) noexcept
      47             : {
      48             :     // this function is for
      49             :     // authority_view_rule only
      50         380 :     BOOST_ASSERT(from_ == from::authority);
      51             : 
      52             :     // userinfo
      53         380 :     set_size(id_user, user.size());
      54         380 :     decoded_[id_user] =
      55         380 :         user.decoded_size();
      56         380 :     if(pass)
      57             :     {
      58         251 :         set_size(id_pass,
      59         251 :             pass->size() + 2);
      60         251 :         decoded_[id_pass] =
      61         251 :             pass->decoded_size();
      62             :     }
      63             :     else
      64             :     {
      65             :         // trailing '@'
      66         129 :         set_size(id_pass, 1 );
      67             :     }
      68         380 : }
      69             : 
      70             : void
      71        1848 : url_impl::
      72             : apply_host(
      73             :     host_type ht,
      74             :     pct_string_view s,
      75             :     unsigned char const* addr) noexcept
      76             : {
      77             :     // this function is for
      78             :     // authority_view_rule only
      79        1848 :     BOOST_ASSERT(from_ == from::authority);
      80             : 
      81             :     // host, port
      82        1848 :     host_type_ = ht;
      83        1848 :     set_size(id_host, s.size());
      84        1848 :     decoded_[id_host] =
      85        1848 :         s.decoded_size();
      86        1848 :     std::memcpy(
      87        1848 :         ip_addr_,
      88             :         addr,
      89             :         sizeof(ip_addr_));
      90        1848 : }
      91             : 
      92             : void
      93         247 : url_impl::
      94             : apply_port(
      95             :     core::string_view s,
      96             :     unsigned short pn) noexcept
      97             : {
      98             :     // this function is for
      99             :     // authority_view_rule only
     100         247 :     BOOST_ASSERT(from_ == from::authority);
     101             : 
     102         247 :     port_number_ = pn;
     103         247 :     set_size(id_port, 1 + s.size());
     104         247 : }
     105             : 
     106             : void
     107        1792 : url_impl::
     108             : apply_authority(
     109             :     authority_view const& a) noexcept
     110             : {
     111        1792 :     BOOST_ASSERT(from_ != from::authority);
     112             : 
     113             :     // userinfo
     114        1792 :     set_size(id_user,
     115        1792 :         a.u_.len(id_user) +
     116        1792 :         (from_ == from::authority ? 0 : 2));
     117        1792 :     set_size(id_pass, a.u_.len(id_pass));
     118        1792 :     decoded_[id_user] = a.u_.decoded_[id_user];
     119        1792 :     decoded_[id_pass] = a.u_.decoded_[id_pass];
     120             : 
     121             :     // host, port
     122        1792 :     host_type_ = a.u_.host_type_;
     123        1792 :     port_number_ = a.u_.port_number_;
     124        1792 :     set_size(id_host, a.u_.len(id_host));
     125        1792 :     set_size(id_port, a.u_.len(id_port));
     126        1792 :     std::memcpy(
     127        1792 :         ip_addr_,
     128        1792 :         a.u_.ip_addr_,
     129             :         sizeof(ip_addr_));
     130        1792 :     decoded_[id_host] = a.u_.decoded_[id_host];
     131        1792 : }
     132             : 
     133             : void
     134        3523 : url_impl::
     135             : apply_path(
     136             :     pct_string_view s,
     137             :     std::size_t nseg) noexcept
     138             : {
     139        3523 :     set_size(id_path, s.size());
     140        3523 :     decoded_[id_path] = s.decoded_size();
     141        3523 :     nseg_ = detail::path_segments(s, nseg);
     142        3523 : }
     143             : 
     144             : void
     145         430 : url_impl::
     146             : apply_query(
     147             :     pct_string_view s,
     148             :     std::size_t n) noexcept
     149             : {
     150         430 :     nparam_ = n;
     151         430 :     set_size(id_query, 1 + s.size());
     152         430 :     decoded_[id_query] = s.decoded_size();
     153         430 : }
     154             : 
     155             : void
     156         210 : url_impl::
     157             : apply_frag(
     158             :     pct_string_view s) noexcept
     159             : {
     160         210 :     set_size(id_frag, s.size() + 1);
     161         210 :     decoded_[id_frag] = s.decoded_size();
     162         210 : }
     163             : 
     164             : // return length of [first, last)
     165             : auto
     166       20187 : url_impl::
     167             : len(
     168             :     int first,
     169             :     int last) const noexcept ->
     170             :         std::size_t
     171             : {
     172       20187 :     BOOST_ASSERT(first <= last);
     173       20187 :     BOOST_ASSERT(last <= id_end);
     174       20187 :     return offset(last) - offset(first);
     175             : }
     176             : 
     177             : // return length of part
     178             : auto
     179      262748 : url_impl::
     180             : len(int id) const noexcept ->
     181             :     std::size_t
     182             : {
     183             :     return id == id_end
     184      525496 :         ? zero_
     185      262748 :         : ( offset(id + 1) -
     186      525496 :             offset(id) );
     187             : }
     188             : 
     189             : // return offset of id
     190             : auto
     191      688690 : url_impl::
     192             : offset(int id) const noexcept ->
     193             :     std::size_t
     194             : {
     195             :     return
     196             :         id == id_scheme
     197      688690 :         ? zero_
     198      688690 :         : offset_[id];
     199             : }
     200             : 
     201             : // return id as string
     202             : core::string_view
     203       46519 : url_impl::
     204             : get(int id) const noexcept
     205             : {
     206             :     return {
     207       46519 :         cs_ + offset(id), len(id) };
     208             : }
     209             : 
     210             : // return [first, last) as string
     211             : core::string_view
     212         791 : url_impl::
     213             : get(int first,
     214             :     int last) const noexcept
     215             : {
     216         791 :     return { cs_ + offset(first),
     217         791 :         offset(last) - offset(first) };
     218             : }
     219             : 
     220             : // return id as pct-string
     221             : pct_string_view
     222        2085 : url_impl::
     223             : pct_get(
     224             :     int id) const noexcept
     225             : {
     226             :     return make_pct_string_view_unsafe(
     227        2085 :         cs_ + offset(id),
     228             :         len(id),
     229        4170 :         decoded_[id]);
     230             : }
     231             : 
     232             : // return [first, last) as pct-string
     233             : pct_string_view
     234         120 : url_impl::
     235             : pct_get(
     236             :     int first,
     237             :     int last) const noexcept
     238             : {
     239         120 :     auto const pos = offset(first);
     240         120 :     std::size_t n = 0;
     241         360 :     for(auto i = first; i < last;)
     242         240 :         n += decoded_[i++];
     243             :     return make_pct_string_view_unsafe(
     244         120 :         cs_ + pos,
     245         120 :         offset(last) - pos,
     246         120 :         n);
     247             : }
     248             : 
     249             : //------------------------------------------------
     250             : 
     251             : // change id to size n
     252             : void
     253       18762 : url_impl::
     254             : set_size(
     255             :     int id,
     256             :     std::size_t n) noexcept
     257             : {
     258       18762 :     auto d = n - len(id);
     259       18762 :     for(auto i = id + 1;
     260      113823 :         i <= id_end; ++i)
     261       95061 :         offset_[i] += d;
     262       18762 : }
     263             : 
     264             : // trim id to size n,
     265             : // moving excess into id+1
     266             : void
     267         811 : url_impl::
     268             : split(
     269             :     int id,
     270             :     std::size_t n) noexcept
     271             : {
     272         811 :     BOOST_ASSERT(id < id_end - 1);
     273             :     //BOOST_ASSERT(n <= len(id));
     274         811 :     offset_[id + 1] = offset(id) + n;
     275         811 : }
     276             : 
     277             : // add n to [first, last]
     278             : void
     279         911 : url_impl::
     280             : adjust_right(
     281             :     int first,
     282             :     int last,
     283             :     std::size_t n) noexcept
     284             : {
     285         911 :     for(int i = first;
     286        5305 :             i <= last; ++i)
     287        4394 :         offset_[i] += n;
     288         911 : }
     289             : 
     290             : // remove n from [first, last]
     291             : void
     292         676 : url_impl::
     293             : adjust_left(
     294             :     int first,
     295             :     int last,
     296             :     std::size_t n) noexcept
     297             : {
     298         676 :     for(int i = first;
     299        3333 :             i <= last; ++i)
     300        2657 :         offset_[i] -= n;
     301         676 : }
     302             : 
     303             : // set [first, last) offset
     304             : void
     305        1568 : url_impl::
     306             : collapse(
     307             :     int first,
     308             :     int last,
     309             :     std::size_t n) noexcept
     310             : {
     311        1568 :     for(int i = first + 1;
     312        2113 :             i < last; ++i)
     313         545 :         offset_[i] = n;
     314        1568 : }
     315             : 
     316             : 
     317             : //------------------------------------------------
     318             : //
     319             : // path_ref
     320             : //
     321             : //------------------------------------------------
     322             : 
     323        2017 : path_ref::
     324             : path_ref(
     325        2017 :     url_impl const& impl) noexcept
     326             : {
     327        2017 :     if(impl.from_ == url_impl::from::url)
     328             :     {
     329        1569 :         impl_ = &impl;
     330             :     }
     331             :     else
     332             :     {
     333         448 :         core::string_view s = impl.get(id_path);
     334         448 :         data_ = s.data();
     335         448 :         size_ = s.size();
     336         448 :         nseg_ = impl.nseg_;
     337         448 :         dn_ = impl.decoded_[id_path];
     338             :     }
     339        2017 : }
     340             : 
     341         141 : path_ref::
     342             : path_ref(
     343             :     core::string_view s,
     344             :     std::size_t dn,
     345         141 :     std::size_t nseg) noexcept
     346         141 :     : data_(s.data())
     347         141 :     , size_(s.size())
     348             :     , nseg_(nseg)
     349         141 :     , dn_(dn)
     350             : {
     351         141 : }
     352             : 
     353             : pct_string_view
     354        4475 : path_ref::
     355             : buffer() const noexcept
     356             : {
     357        4475 :     if(impl_)
     358             :         return make_pct_string_view_unsafe(
     359        2321 :             impl_->cs_ +
     360        2321 :                 impl_->offset(id_path),
     361        2321 :             impl_->len(id_path),
     362        4642 :             impl_->decoded_[id_path]);
     363             :     return make_pct_string_view_unsafe(
     364        2154 :         data_, size_, dn_);
     365             : }
     366             : 
     367             : std::size_t
     368        3899 : path_ref::
     369             : size() const noexcept
     370             : {
     371        3899 :     if(impl_)
     372        2657 :         return impl_->len(id_path);
     373        1242 :     return size_;
     374             : }
     375             : 
     376             : char const*
     377       12602 : path_ref::
     378             : data() const noexcept
     379             : {
     380       12602 :     if(impl_)
     381        7447 :         return impl_->cs_ +
     382        7447 :             impl_->offset(id_path);
     383        5155 :     return data_;
     384             : }
     385             : 
     386             : char const*
     387        4397 : path_ref::
     388             : end() const noexcept
     389             : {
     390        4397 :     if(impl_)
     391        2945 :         return impl_->cs_ +
     392        2945 :             impl_->offset(id_query);
     393        1452 :     return data_ + size_;
     394             : }
     395             : 
     396             : std::size_t
     397        8630 : path_ref::
     398             : nseg() const noexcept
     399             : {
     400        8630 :     if(impl_)
     401        5508 :         return impl_->nseg_;
     402        3122 :     return nseg_;
     403             : }
     404             : 
     405             : //------------------------------------------------
     406             : //
     407             : // query_ref
     408             : //
     409             : //------------------------------------------------
     410             : 
     411         674 : query_ref::
     412             : query_ref(
     413             :     core::string_view s,
     414             :     std::size_t dn,
     415         674 :     std::size_t nparam) noexcept
     416         674 :     : data_(s.data())
     417         674 :     , size_(s.size())
     418             :     , nparam_(nparam)
     419         674 :     , dn_(dn)
     420             : {
     421         674 : }
     422             : 
     423         425 : query_ref::
     424             : query_ref(
     425         425 :     url_impl const& impl) noexcept
     426             : {
     427         425 :     if(impl.from_ == url_impl::from::url)
     428             :     {
     429         344 :         impl_ = &impl;
     430             :     }
     431             :     else
     432             :     {
     433          81 :         core::string_view s = impl.get(id_query);
     434          81 :         if (!s.empty())
     435             :         {
     436          79 :             s.remove_prefix(1);
     437          79 :             question_mark_ = true;
     438             :         }
     439          81 :         data_ = s.data();
     440          81 :         size_ = s.size();
     441          81 :         nparam_ = impl.nparam_;
     442          81 :         dn_ = impl.decoded_[id_query];
     443             :     }
     444         425 : }
     445             : 
     446             : pct_string_view
     447         454 : query_ref::
     448             : buffer() const noexcept
     449             : {
     450         454 :     if(impl_)
     451             :     {
     452           2 :         auto pos = impl_->offset_[id_query];
     453           2 :         auto pos1 = impl_->offset_[id_frag];
     454           2 :         if(pos < pos1)
     455             :         {
     456           0 :             ++pos; // no '?'
     457             :             return make_pct_string_view_unsafe(
     458           0 :                 impl_->cs_ + pos,
     459             :                 pos1 - pos,
     460           0 :                 impl_->decoded_[id_query]);
     461             :         }
     462             :         // empty
     463             :         return make_pct_string_view_unsafe(
     464           2 :             impl_->cs_ + pos,
     465             :             0,
     466           2 :             0);
     467             :     }
     468             :     // no '?'
     469             :     return make_pct_string_view_unsafe(
     470         452 :         data_, size_, dn_);
     471             : }
     472             : 
     473             : // with '?'
     474             : std::size_t
     475        5282 : query_ref::
     476             : size() const noexcept
     477             : {
     478        5282 :     if(impl_)
     479        1990 :         return impl_->len(id_query);
     480        3292 :     if(size_ > 0)
     481        3264 :         return size_ + 1;
     482          28 :     return question_mark_;
     483             : }
     484             : 
     485             : // no '?'
     486             : char const*
     487        5807 : query_ref::
     488             : begin() const noexcept
     489             : {
     490        5807 :     if(impl_)
     491             :     {
     492             :         // using the offset array here
     493        2267 :         auto pos = impl_->offset_[id_query];
     494        2267 :         auto pos1 = impl_->offset_[id_frag];
     495        2267 :         if(pos < pos1)
     496        2267 :             return impl_->cs_ + pos + 1; // no '?'
     497             :         // empty
     498           0 :         return impl_->cs_ + pos;
     499             :     }
     500        3540 :     return data_;
     501             : 
     502             : }
     503             : 
     504             : char const*
     505        2282 : query_ref::
     506             : end() const noexcept
     507             : {
     508        2282 :     if(impl_)
     509         902 :         return impl_->cs_ +
     510         902 :             impl_->offset(id_frag);
     511        1380 :     return data_ + size_;
     512             : }
     513             : 
     514             : std::size_t
     515        8886 : query_ref::
     516             : nparam() const noexcept
     517             : {
     518        8886 :     if(impl_)
     519        3134 :         return impl_->nparam_;
     520        5752 :     return nparam_;
     521             : }
     522             : 
     523             : #if defined(__GNUC__) && ! defined(__clang__) && defined(__MINGW32__)
     524             : #pragma GCC diagnostic pop
     525             : #endif
     526             : 
     527             : } // detail
     528             : } // urls
     529             : } // boost
     530             : 

Generated by: LCOV version 1.15