LCOV - code coverage report
Current view: top level - libs/url/src/detail/url_impl.cpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 97.7 % 216 211
Test Date: 2024-08-19 20:08:54 Functions: 100.0 % 34 34

            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         2269 : url_impl::
      35              : apply_scheme(
      36              :     core::string_view s) noexcept
      37              : {
      38         2269 :     scheme_ = string_to_scheme(s);
      39         2269 :     set_size(id_scheme, s.size() + 1);
      40         2269 : }
      41              : 
      42              : void
      43          381 : 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          381 :     BOOST_ASSERT(from_ == from::authority);
      51              : 
      52              :     // userinfo
      53          381 :     set_size(id_user, user.size());
      54          381 :     decoded_[id_user] =
      55          381 :         user.decoded_size();
      56          381 :     if(pass)
      57              :     {
      58          252 :         set_size(id_pass,
      59          252 :             pass->size() + 2);
      60          252 :         decoded_[id_pass] =
      61          252 :             pass->decoded_size();
      62              :     }
      63              :     else
      64              :     {
      65              :         // trailing '@'
      66          129 :         set_size(id_pass, 1 );
      67              :     }
      68          381 : }
      69              : 
      70              : void
      71         1870 : 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         1870 :     BOOST_ASSERT(from_ == from::authority);
      80              : 
      81              :     // host, port
      82         1870 :     host_type_ = ht;
      83         1870 :     set_size(id_host, s.size());
      84         1870 :     decoded_[id_host] =
      85         1870 :         s.decoded_size();
      86         1870 :     std::memcpy(
      87         1870 :         ip_addr_,
      88              :         addr,
      89              :         sizeof(ip_addr_));
      90         1870 : }
      91              : 
      92              : void
      93          260 : 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          260 :     BOOST_ASSERT(from_ == from::authority);
     101              : 
     102          260 :     port_number_ = pn;
     103          260 :     set_size(id_port, 1 + s.size());
     104          260 : }
     105              : 
     106              : void
     107         1812 : url_impl::
     108              : apply_authority(
     109              :     authority_view const& a) noexcept
     110              : {
     111         1812 :     BOOST_ASSERT(from_ != from::authority);
     112              : 
     113              :     // userinfo
     114         1812 :     set_size(id_user,
     115         1812 :         a.u_.len(id_user) +
     116         1812 :         (from_ == from::authority ? 0 : 2));
     117         1812 :     set_size(id_pass, a.u_.len(id_pass));
     118         1812 :     decoded_[id_user] = a.u_.decoded_[id_user];
     119         1812 :     decoded_[id_pass] = a.u_.decoded_[id_pass];
     120              : 
     121              :     // host, port
     122         1812 :     host_type_ = a.u_.host_type_;
     123         1812 :     port_number_ = a.u_.port_number_;
     124         1812 :     set_size(id_host, a.u_.len(id_host));
     125         1812 :     set_size(id_port, a.u_.len(id_port));
     126         1812 :     std::memcpy(
     127         1812 :         ip_addr_,
     128         1812 :         a.u_.ip_addr_,
     129              :         sizeof(ip_addr_));
     130         1812 :     decoded_[id_host] = a.u_.decoded_[id_host];
     131         1812 : }
     132              : 
     133              : void
     134         3544 : url_impl::
     135              : apply_path(
     136              :     pct_string_view s,
     137              :     std::size_t nseg) noexcept
     138              : {
     139         3544 :     set_size(id_path, s.size());
     140         3544 :     decoded_[id_path] = s.decoded_size();
     141         3544 :     nseg_ = detail::path_segments(s, nseg);
     142         3544 : }
     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        20207 : url_impl::
     167              : len(
     168              :     int first,
     169              :     int last) const noexcept ->
     170              :         std::size_t
     171              : {
     172        20207 :     BOOST_ASSERT(first <= last);
     173        20207 :     BOOST_ASSERT(last <= id_end);
     174        20207 :     return offset(last) - offset(first);
     175              : }
     176              : 
     177              : // return length of part
     178              : auto
     179       265516 : url_impl::
     180              : len(int id) const noexcept ->
     181              :     std::size_t
     182              : {
     183              :     return id == id_end
     184       531032 :         ? zero_
     185       265516 :         : ( offset(id + 1) -
     186       531032 :             offset(id) );
     187              : }
     188              : 
     189              : // return offset of id
     190              : auto
     191       695451 : url_impl::
     192              : offset(int id) const noexcept ->
     193              :     std::size_t
     194              : {
     195              :     return
     196              :         id == id_scheme
     197       695451 :         ? zero_
     198       695451 :         : offset_[id];
     199              : }
     200              : 
     201              : // return id as string
     202              : core::string_view
     203        47265 : url_impl::
     204              : get(int id) const noexcept
     205              : {
     206              :     return {
     207        47265 :         cs_ + offset(id), len(id) };
     208              : }
     209              : 
     210              : // return [first, last) as string
     211              : core::string_view
     212          873 : url_impl::
     213              : get(int first,
     214              :     int last) const noexcept
     215              : {
     216          873 :     return { cs_ + offset(first),
     217          873 :         offset(last) - offset(first) };
     218              : }
     219              : 
     220              : // return id as pct-string
     221              : pct_string_view
     222         2172 : url_impl::
     223              : pct_get(
     224              :     int id) const noexcept
     225              : {
     226         2172 :     return make_pct_string_view_unsafe(
     227         2172 :         cs_ + offset(id),
     228              :         len(id),
     229         4344 :         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          120 :     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        19240 : url_impl::
     254              : set_size(
     255              :     int id,
     256              :     std::size_t n) noexcept
     257              : {
     258        19240 :     auto d = n - len(id);
     259        19240 :     for(auto i = id + 1;
     260       116899 :         i <= id_end; ++i)
     261        97659 :         offset_[i] += d;
     262        19240 : }
     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         2027 : path_ref::
     324              : path_ref(
     325         2027 :     url_impl const& impl) noexcept
     326              : {
     327         2027 :     if(impl.from_ == url_impl::from::url)
     328              :     {
     329         1571 :         impl_ = &impl;
     330              :     }
     331              :     else
     332              :     {
     333          456 :         core::string_view s = impl.get(id_path);
     334          456 :         data_ = s.data();
     335          456 :         size_ = s.size();
     336          456 :         nseg_ = impl.nseg_;
     337          456 :         dn_ = impl.decoded_[id_path];
     338              :     }
     339         2027 : }
     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          282 :     : data_(s.data())
     347          141 :     , size_(s.size())
     348          141 :     , nseg_(nseg)
     349          141 :     , dn_(dn)
     350              : {
     351          141 : }
     352              : 
     353              : pct_string_view
     354         4517 : path_ref::
     355              : buffer() const noexcept
     356              : {
     357         4517 :     if(impl_)
     358         2333 :         return make_pct_string_view_unsafe(
     359         2333 :             impl_->cs_ +
     360         2333 :                 impl_->offset(id_path),
     361         2333 :             impl_->len(id_path),
     362         4666 :             impl_->decoded_[id_path]);
     363         2184 :     return make_pct_string_view_unsafe(
     364         2184 :         data_, size_, dn_);
     365              : }
     366              : 
     367              : std::size_t
     368         3927 : path_ref::
     369              : size() const noexcept
     370              : {
     371         3927 :     if(impl_)
     372         2665 :         return impl_->len(id_path);
     373         1262 :     return size_;
     374              : }
     375              : 
     376              : char const*
     377        12658 : path_ref::
     378              : data() const noexcept
     379              : {
     380        12658 :     if(impl_)
     381         7463 :         return impl_->cs_ +
     382         7463 :             impl_->offset(id_path);
     383         5195 :     return data_;
     384              : }
     385              : 
     386              : char const*
     387         4421 : path_ref::
     388              : end() const noexcept
     389              : {
     390         4421 :     if(impl_)
     391         2951 :         return impl_->cs_ +
     392         2951 :             impl_->offset(id_query);
     393         1470 :     return data_ + size_;
     394              : }
     395              : 
     396              : std::size_t
     397         8654 : path_ref::
     398              : nseg() const noexcept
     399              : {
     400         8654 :     if(impl_)
     401         5514 :         return impl_->nseg_;
     402         3140 :     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         1348 :     : data_(s.data())
     417          674 :     , size_(s.size())
     418          674 :     , 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            0 :             return make_pct_string_view_unsafe(
     458            0 :                 impl_->cs_ + pos,
     459              :                 pos1 - pos,
     460            0 :                 impl_->decoded_[id_query]);
     461              :         }
     462              :         // empty
     463            2 :         return make_pct_string_view_unsafe(
     464            2 :             impl_->cs_ + pos,
     465              :             0,
     466            2 :             0);
     467              :     }
     468              :     // no '?'
     469          452 :     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 2.1