LCOV - code coverage report
Current view: top level - libs/url/src - url_view_base.cpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 304 314 96.8 %
Date: 2023-12-15 15:31:48 Functions: 40 42 95.2 %

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
       3             : // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
       4             : //
       5             : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       6             : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       7             : //
       8             : // Official repository: https://github.com/boostorg/url
       9             : //
      10             : 
      11             : #ifndef BOOST_URL_IMPL_URL_VIEW_BASE_IPP
      12             : #define BOOST_URL_IMPL_URL_VIEW_BASE_IPP
      13             : 
      14             : #include <boost/url/detail/config.hpp>
      15             : #include <boost/url/url_view_base.hpp>
      16             : #include <boost/url/url_view.hpp>
      17             : #include <boost/url/detail/except.hpp>
      18             : #include <boost/url/detail/normalize.hpp>
      19             : #include <boost/url/detail/over_allocator.hpp>
      20             : 
      21             : namespace boost {
      22             : namespace urls {
      23             : 
      24             : // construct empty view
      25        4069 : url_view_base::
      26        4069 : url_view_base() noexcept
      27             :     : impl_(from::url)
      28        4069 :     , pi_(&impl_)
      29             : {
      30        4069 : }
      31             : 
      32             : // construct reference
      33       20556 : url_view_base::
      34             : url_view_base(
      35       20556 :     detail::url_impl const& impl) noexcept
      36             :     : impl_(impl)
      37       20556 :     , pi_(&impl_)
      38             : {
      39       20556 : }
      40             : 
      41             : //------------------------------------------------
      42             : 
      43             : std::size_t
      44         276 : url_view_base::
      45             : digest(std::size_t salt) const noexcept
      46             : {
      47         276 :     detail::fnv_1a h(salt);
      48         276 :     detail::ci_digest(pi_->get(id_scheme), h);
      49         276 :     detail::digest_encoded(pi_->get(id_user), h);
      50         276 :     detail::digest_encoded(pi_->get(id_pass), h);
      51         276 :     detail::ci_digest_encoded(pi_->get(id_host), h);
      52         276 :     h.put(pi_->get(id_port));
      53         276 :     detail::normalized_path_digest(
      54         276 :         pi_->get(id_path), is_path_absolute(), h);
      55         276 :     detail::digest_encoded(pi_->get(id_query), h);
      56         276 :     detail::digest_encoded(pi_->get(id_frag), h);
      57         276 :     return h.digest();
      58             : }
      59             : 
      60             : //------------------------------------------------
      61             : //
      62             : // Observers
      63             : //
      64             : //------------------------------------------------
      65             : 
      66             : struct url_view_base::shared_impl
      67             :     : url_view
      68             : {
      69             :     virtual
      70           2 :     ~shared_impl()
      71           2 :     {
      72           2 :     }
      73             : 
      74           2 :     shared_impl(
      75             :         url_view const& u) noexcept
      76           2 :         : url_view(u)
      77             :     {
      78           2 :         impl_.cs_ = reinterpret_cast<
      79             :             char const*>(this + 1);
      80           2 :     }
      81             : };
      82             : 
      83             : std::shared_ptr<url_view const>
      84           2 : url_view_base::
      85             : persist() const
      86             : {
      87             :     using T = shared_impl;
      88             :     using Alloc = std::allocator<char>;
      89           4 :     Alloc a;
      90             :     auto p = std::allocate_shared<T>(
      91           2 :         detail::over_allocator<T, Alloc>(
      92           6 :             size(), a), url_view(*pi_));
      93           2 :     std::memcpy(
      94             :         reinterpret_cast<char*>(
      95           2 :             p.get() + 1), data(), size());
      96           4 :     return p;
      97             : }
      98             : 
      99             : //------------------------------------------------
     100             : //
     101             : // Scheme
     102             : //
     103             : //------------------------------------------------
     104             : 
     105             : bool
     106        2667 : url_view_base::
     107             : has_scheme() const noexcept
     108             : {
     109        2667 :     auto const n = pi_->len(
     110             :         id_scheme);
     111        2667 :     if(n == 0)
     112         563 :         return false;
     113        2104 :     BOOST_ASSERT(n > 1);
     114        2104 :     BOOST_ASSERT(
     115             :         pi_->get(id_scheme
     116             :             ).ends_with(':'));
     117        2104 :     return true;
     118             : }
     119             : 
     120             : core::string_view
     121        1352 : url_view_base::
     122             : scheme() const noexcept
     123             : {
     124        1352 :     auto s = pi_->get(id_scheme);
     125        1352 :     if(! s.empty())
     126             :     {
     127        1256 :         BOOST_ASSERT(s.size() > 1);
     128        1256 :         BOOST_ASSERT(s.ends_with(':'));
     129        1256 :         s.remove_suffix(1);
     130             :     }
     131        1352 :     return s;
     132             : }
     133             : 
     134             : urls::scheme
     135          44 : url_view_base::
     136             : scheme_id() const noexcept
     137             : {
     138          44 :     return pi_->scheme_;
     139             : }
     140             : 
     141             : //------------------------------------------------
     142             : //
     143             : // Authority
     144             : //
     145             : //------------------------------------------------
     146             : 
     147             : authority_view
     148         399 : url_view_base::
     149             : authority() const noexcept
     150             : {
     151         399 :     detail::url_impl u(from::authority);
     152         399 :     u.cs_ = encoded_authority().data();
     153         399 :     if(has_authority())
     154             :     {
     155         399 :         u.set_size(id_user, pi_->len(id_user) - 2);
     156         399 :         u.set_size(id_pass, pi_->len(id_pass));
     157         399 :         u.set_size(id_host, pi_->len(id_host));
     158         399 :         u.set_size(id_port, pi_->len(id_port));
     159             :     }
     160             :     else
     161             :     {
     162           0 :         u.set_size(id_user, pi_->len(id_user));
     163           0 :         BOOST_ASSERT(pi_->len(id_pass) == 0);
     164           0 :         BOOST_ASSERT(pi_->len(id_host) == 0);
     165           0 :         BOOST_ASSERT(pi_->len(id_port) == 0);
     166             :     }
     167         399 :     u.decoded_[id_user] = pi_->decoded_[id_user];
     168         399 :     u.decoded_[id_pass] = pi_->decoded_[id_pass];
     169         399 :     u.decoded_[id_host] = pi_->decoded_[id_host];
     170        6783 :     for (int i = 0; i < 16; ++i)
     171        6384 :         u.ip_addr_[i] = pi_->ip_addr_[i];
     172         399 :     u.port_number_ = pi_->port_number_;
     173         399 :     u.host_type_ = pi_->host_type_;
     174         399 :     return u.construct_authority();
     175             : }
     176             : 
     177             : pct_string_view
     178         557 : url_view_base::
     179             : encoded_authority() const noexcept
     180             : {
     181         557 :     auto s = pi_->get(id_user, id_path);
     182         557 :     if(! s.empty())
     183             :     {
     184         517 :         BOOST_ASSERT(has_authority());
     185         517 :         s.remove_prefix(2);
     186             :     }
     187             :     return make_pct_string_view_unsafe(
     188             :         s.data(),
     189             :         s.size(),
     190         557 :         pi_->decoded_[id_user] +
     191         557 :             pi_->decoded_[id_pass] +
     192         557 :             pi_->decoded_[id_host] +
     193         557 :             pi_->decoded_[id_port] +
     194         557 :             has_password());
     195             : }
     196             : 
     197             : //------------------------------------------------
     198             : //
     199             : // Userinfo
     200             : //
     201             : //------------------------------------------------
     202             : 
     203             : bool
     204         261 : url_view_base::
     205             : has_userinfo() const noexcept
     206             : {
     207         261 :     auto n = pi_->len(id_pass);
     208         261 :     if(n == 0)
     209          97 :         return false;
     210         164 :     BOOST_ASSERT(has_authority());
     211         164 :     BOOST_ASSERT(pi_->get(
     212             :         id_pass).ends_with('@'));
     213         164 :     return true;
     214             : }
     215             : 
     216             : bool
     217         692 : url_view_base::
     218             : has_password() const noexcept
     219             : {
     220         692 :     auto const n = pi_->len(id_pass);
     221         692 :     if(n > 1)
     222             :     {
     223         114 :         BOOST_ASSERT(pi_->get(id_pass
     224             :             ).starts_with(':'));
     225         114 :         BOOST_ASSERT(pi_->get(id_pass
     226             :             ).ends_with('@'));
     227         114 :         return true;
     228             :     }
     229         578 :     BOOST_ASSERT(n == 0 || pi_->get(
     230             :         id_pass).ends_with('@'));
     231         578 :     return false;
     232             : }
     233             : 
     234             : pct_string_view
     235         119 : url_view_base::
     236             : encoded_userinfo() const noexcept
     237             : {
     238         119 :     auto s = pi_->get(
     239         119 :         id_user, id_host);
     240         119 :     if(s.empty())
     241           8 :         return s;
     242         111 :     BOOST_ASSERT(
     243             :         has_authority());
     244         111 :     s.remove_prefix(2);
     245         111 :     if(s.empty())
     246          34 :         return s;
     247          77 :     BOOST_ASSERT(
     248             :         s.ends_with('@'));
     249          77 :     s.remove_suffix(1);
     250             :     return make_pct_string_view_unsafe(
     251             :         s.data(),
     252             :         s.size(),
     253          77 :         pi_->decoded_[id_user] +
     254          77 :             pi_->decoded_[id_pass] +
     255          77 :             has_password());
     256             : }
     257             : 
     258             : pct_string_view
     259         131 : url_view_base::
     260             : encoded_user() const noexcept
     261             : {
     262         131 :     auto s = pi_->get(id_user);
     263         131 :     if(! s.empty())
     264             :     {
     265         130 :         BOOST_ASSERT(
     266             :             has_authority());
     267         130 :         s.remove_prefix(2);
     268             :     }
     269             :     return make_pct_string_view_unsafe(
     270             :         s.data(),
     271             :         s.size(),
     272         131 :         pi_->decoded_[id_user]);
     273             : }
     274             : 
     275             : pct_string_view
     276          94 : url_view_base::
     277             : encoded_password() const noexcept
     278             : {
     279          94 :     auto s = pi_->get(id_pass);
     280          94 :     switch(s.size())
     281             :     {
     282          24 :     case 1:
     283          24 :         BOOST_ASSERT(
     284             :             s.starts_with('@'));
     285          24 :         s.remove_prefix(1);
     286             :         BOOST_FALLTHROUGH;
     287          42 :     case 0:
     288             :         return make_pct_string_view_unsafe(
     289          42 :             s.data(), s.size(), 0);
     290          52 :     default:
     291          52 :         break;
     292             :     }
     293          52 :     BOOST_ASSERT(s.ends_with('@'));
     294          52 :     BOOST_ASSERT(s.starts_with(':'));
     295             :     return make_pct_string_view_unsafe(
     296          52 :         s.data() + 1,
     297          52 :         s.size() - 2,
     298          52 :         pi_->decoded_[id_pass]);
     299             : }
     300             : 
     301             : //------------------------------------------------
     302             : //
     303             : // Host
     304             : //
     305             : //------------------------------------------------
     306             : /*
     307             : host_type       host_type()                 // ipv4, ipv6, ipvfuture, name
     308             : 
     309             : std::string     host()                      // return encoded_host().decode()
     310             : pct_string_view encoded_host()              // return host part, as-is
     311             : std::string     host_address()              // return encoded_host_address().decode()
     312             : pct_string_view encoded_host_address()      // ipv4, ipv6, ipvfut, or encoded name, no brackets
     313             : 
     314             : ipv4_address    host_ipv4_address()         // return ipv4_address or {}
     315             : ipv6_address    host_ipv6_address()         // return ipv6_address or {}
     316             : core::string_view     host_ipvfuture()            // return ipvfuture or {}
     317             : std::string     host_name()                 // return decoded name or ""
     318             : pct_string_view encoded_host_name()         // return encoded host name or ""
     319             : */
     320             : 
     321             : pct_string_view
     322         521 : url_view_base::
     323             : encoded_host() const noexcept
     324             : {
     325         521 :     return pi_->pct_get(id_host);
     326             : }
     327             : 
     328             : pct_string_view
     329         117 : url_view_base::
     330             : encoded_host_address() const noexcept
     331             : {
     332         117 :     core::string_view s = pi_->get(id_host);
     333             :     std::size_t n;
     334         117 :     switch(pi_->host_type_)
     335             :     {
     336          41 :     default:
     337             :     case urls::host_type::none:
     338          41 :         BOOST_ASSERT(s.empty());
     339          41 :         n = 0;
     340          41 :         break;
     341             : 
     342          53 :     case urls::host_type::name:
     343             :     case urls::host_type::ipv4:
     344          53 :         n = pi_->decoded_[id_host];
     345          53 :         break;
     346             : 
     347          23 :     case urls::host_type::ipv6:
     348             :     case urls::host_type::ipvfuture:
     349             :     {
     350          23 :         BOOST_ASSERT(
     351             :             pi_->decoded_[id_host] ==
     352             :                 s.size());
     353          23 :         BOOST_ASSERT(s.size() >= 2);
     354          23 :         BOOST_ASSERT(s.front() == '[');
     355          23 :         BOOST_ASSERT(s.back() == ']');
     356          23 :         s = s.substr(1, s.size() - 2);
     357          23 :         n = pi_->decoded_[id_host] - 2;
     358          23 :         break;
     359             :     }
     360             :     }
     361             :     return make_pct_string_view_unsafe(
     362             :         s.data(),
     363             :         s.size(),
     364         117 :         n);
     365             : }
     366             : 
     367             : urls::ipv4_address
     368          51 : url_view_base::
     369             : host_ipv4_address() const noexcept
     370             : {
     371          51 :     if(pi_->host_type_ !=
     372             :             urls::host_type::ipv4)
     373          35 :         return {};
     374          16 :     ipv4_address::bytes_type b{{}};
     375          16 :     std::memcpy(
     376          16 :         &b[0], &pi_->ip_addr_[0], b.size());
     377          16 :     return urls::ipv4_address(b);
     378             : }
     379             : 
     380             : urls::ipv6_address
     381          51 : url_view_base::
     382             : host_ipv6_address() const noexcept
     383             : {
     384          51 :     if(pi_->host_type_ !=
     385             :             urls::host_type::ipv6)
     386          43 :         return {};
     387           8 :     ipv6_address::bytes_type b{{}};
     388           8 :     std::memcpy(
     389           8 :         &b[0], &pi_->ip_addr_[0], b.size());
     390           8 :     return urls::ipv6_address(b);
     391             : }
     392             : 
     393             : core::string_view
     394          51 : url_view_base::
     395             : host_ipvfuture() const noexcept
     396             : {
     397          51 :     if(pi_->host_type_ !=
     398             :             urls::host_type::ipvfuture)
     399          44 :         return {};
     400           7 :     core::string_view s = pi_->get(id_host);
     401           7 :     BOOST_ASSERT(s.size() >= 6);
     402           7 :     BOOST_ASSERT(s.front() == '[');
     403           7 :     BOOST_ASSERT(s.back() == ']');
     404           7 :     s = s.substr(1, s.size() - 2);
     405           7 :     return s;
     406             : }
     407             : 
     408             : pct_string_view
     409         146 : url_view_base::
     410             : encoded_host_name() const noexcept
     411             : {
     412         146 :     if(pi_->host_type_ !=
     413             :             urls::host_type::name)
     414          78 :         return {};
     415          68 :     core::string_view s = pi_->get(id_host);
     416             :     return make_pct_string_view_unsafe(
     417             :         s.data(),
     418             :         s.size(),
     419          68 :         pi_->decoded_[id_host]);
     420             : }
     421             : 
     422             : pct_string_view
     423          10 : url_view_base::
     424             : encoded_zone_id() const noexcept
     425             : {
     426          10 :     if(pi_->host_type_ !=
     427             :         urls::host_type::ipv6)
     428           2 :         return {};
     429           8 :     core::string_view s = pi_->get(id_host);
     430           8 :     BOOST_ASSERT(s.front() == '[');
     431           8 :     BOOST_ASSERT(s.back() == ']');
     432           8 :     s = s.substr(1, s.size() - 2);
     433           8 :     auto pos = s.find("%25");
     434           8 :     if (pos == core::string_view::npos)
     435           2 :         return {};
     436           6 :     s.remove_prefix(pos + 3);
     437           6 :     return *make_pct_string_view(s);
     438             : }
     439             : 
     440             : //------------------------------------------------
     441             : 
     442             : bool
     443         364 : url_view_base::
     444             : has_port() const noexcept
     445             : {
     446         364 :     auto const n = pi_->len(id_port);
     447         364 :     if(n == 0)
     448          87 :         return false;
     449         277 :     BOOST_ASSERT(
     450             :         pi_->get(id_port).starts_with(':'));
     451         277 :     return true;
     452             : }
     453             : 
     454             : core::string_view
     455         179 : url_view_base::
     456             : port() const noexcept
     457             : {
     458         179 :     auto s = pi_->get(id_port);
     459         179 :     if(s.empty())
     460          58 :         return s;
     461         121 :     BOOST_ASSERT(has_port());
     462         121 :     return s.substr(1);
     463             : }
     464             : 
     465             : std::uint16_t
     466         101 : url_view_base::
     467             : port_number() const noexcept
     468             : {
     469         101 :     BOOST_ASSERT(
     470             :         has_port() ||
     471             :         pi_->port_number_ == 0);
     472         101 :     return pi_->port_number_;
     473             : }
     474             : 
     475             : //------------------------------------------------
     476             : //
     477             : // Path
     478             : //
     479             : //------------------------------------------------
     480             : 
     481             : pct_string_view
     482        1282 : url_view_base::
     483             : encoded_path() const noexcept
     484             : {
     485        1282 :     return pi_->pct_get(id_path);
     486             : }
     487             : 
     488             : segments_view
     489          45 : url_view_base::
     490             : segments() const noexcept
     491             : {
     492          45 :     return {detail::path_ref(*pi_)};
     493             : }
     494             : 
     495             : segments_encoded_view
     496         617 : url_view_base::
     497             : encoded_segments() const noexcept
     498             : {
     499             :     return segments_encoded_view(
     500         617 :         detail::path_ref(*pi_));
     501             : }
     502             : 
     503             : //------------------------------------------------
     504             : //
     505             : // Query
     506             : //
     507             : //------------------------------------------------
     508             : 
     509             : bool
     510         700 : url_view_base::
     511             : has_query() const noexcept
     512             : {
     513         700 :     auto const n = pi_->len(
     514             :         id_query);
     515         700 :     if(n == 0)
     516         582 :         return false;
     517         118 :     BOOST_ASSERT(
     518             :         pi_->get(id_query).
     519             :             starts_with('?'));
     520         118 :     return true;
     521             : }
     522             : 
     523             : pct_string_view
     524         274 : url_view_base::
     525             : encoded_query() const noexcept
     526             : {
     527         274 :     auto s = pi_->get(id_query);
     528         274 :     if(s.empty())
     529          10 :         return s;
     530         264 :     BOOST_ASSERT(
     531             :         s.starts_with('?'));
     532         264 :     return s.substr(1);
     533             : }
     534             : 
     535             : params_encoded_view
     536          55 : url_view_base::
     537             : encoded_params() const noexcept
     538             : {
     539          55 :     return params_encoded_view(*pi_);
     540             : }
     541             : 
     542             : params_view
     543          46 : url_view_base::
     544             : params() const noexcept
     545             : {
     546             :     return params_view(
     547          46 :         *pi_,
     548             :         encoding_opts{
     549          46 :             true,false,false});
     550             : }
     551             : 
     552             : params_view
     553           0 : url_view_base::
     554             : params(encoding_opts opt) const noexcept
     555             : {
     556           0 :     return params_view(*pi_, opt);
     557             : }
     558             : 
     559             : //------------------------------------------------
     560             : //
     561             : // Fragment
     562             : //
     563             : //------------------------------------------------
     564             : 
     565             : bool
     566         608 : url_view_base::
     567             : has_fragment() const noexcept
     568             : {
     569         608 :     auto const n = pi_->len(id_frag);
     570         608 :     if(n == 0)
     571         483 :         return false;
     572         125 :     BOOST_ASSERT(
     573             :         pi_->get(id_frag).
     574             :             starts_with('#'));
     575         125 :     return true;
     576             : }
     577             : 
     578             : pct_string_view
     579         155 : url_view_base::
     580             : encoded_fragment() const noexcept
     581             : {
     582         155 :     auto s = pi_->get(id_frag);
     583         155 :     if(! s.empty())
     584             :     {
     585         153 :         BOOST_ASSERT(
     586             :             s.starts_with('#'));
     587         153 :         s.remove_prefix(1);
     588             :     }
     589             :     return make_pct_string_view_unsafe(
     590             :         s.data(),
     591             :         s.size(),
     592         155 :         pi_->decoded_[id_frag]);
     593             : }
     594             : 
     595             : //------------------------------------------------
     596             : //
     597             : // Compound Fields
     598             : //
     599             : //------------------------------------------------
     600             : 
     601             : pct_string_view
     602         120 : url_view_base::
     603             : encoded_host_and_port() const noexcept
     604             : {
     605         120 :     return pi_->pct_get(id_host, id_path);
     606             : }
     607             : 
     608             : pct_string_view
     609          16 : url_view_base::
     610             : encoded_origin() const noexcept
     611             : {
     612          16 :     if(pi_->len(id_user) < 2)
     613          14 :         return {};
     614           2 :     return pi_->get(id_scheme, id_path);
     615             : }
     616             : 
     617             : pct_string_view
     618           1 : url_view_base::
     619             : encoded_resource() const noexcept
     620             : {
     621           1 :     auto n =
     622           1 :         pi_->decoded_[id_path] +
     623           1 :         pi_->decoded_[id_query] +
     624           1 :         pi_->decoded_[id_frag];
     625           1 :     if(has_query())
     626           1 :         ++n;
     627           1 :     if(has_fragment())
     628           1 :         ++n;
     629           1 :     BOOST_ASSERT(pct_string_view(
     630             :         pi_->get(id_path, id_end)
     631             :             ).decoded_size() == n);
     632           1 :     auto s = pi_->get(id_path, id_end);
     633             :     return make_pct_string_view_unsafe(
     634           1 :         s.data(), s.size(), n);
     635             : }
     636             : 
     637             : pct_string_view
     638           2 : url_view_base::
     639             : encoded_target() const noexcept
     640             : {
     641           2 :     auto n =
     642           2 :         pi_->decoded_[id_path] +
     643           2 :         pi_->decoded_[id_query];
     644           2 :     if(has_query())
     645           1 :         ++n;
     646           2 :     BOOST_ASSERT(pct_string_view(
     647             :         pi_->get(id_path, id_frag)
     648             :             ).decoded_size() == n);
     649           2 :     auto s = pi_->get(id_path, id_frag);
     650             :     return make_pct_string_view_unsafe(
     651           2 :         s.data(), s.size(), n);
     652             : }
     653             : 
     654             : //------------------------------------------------
     655             : //
     656             : // Comparisons
     657             : //
     658             : //------------------------------------------------
     659             : 
     660             : int
     661         236 : url_view_base::
     662             : compare(const url_view_base& other) const noexcept
     663             : {
     664             :     int comp =
     665         236 :         static_cast<int>(has_scheme()) -
     666         236 :         static_cast<int>(other.has_scheme());
     667         236 :     if ( comp != 0 )
     668           0 :         return comp;
     669             : 
     670         236 :     if (has_scheme())
     671             :     {
     672         156 :         comp = detail::ci_compare(
     673             :             scheme(),
     674             :             other.scheme());
     675         156 :         if ( comp != 0 )
     676          14 :             return comp;
     677             :     }
     678             : 
     679         222 :     comp =
     680         222 :         static_cast<int>(has_authority()) -
     681         222 :         static_cast<int>(other.has_authority());
     682         222 :     if ( comp != 0 )
     683           0 :         return comp;
     684             : 
     685         222 :     if (has_authority())
     686             :     {
     687         142 :         comp = authority().compare(other.authority());
     688         142 :         if ( comp != 0 )
     689          54 :             return comp;
     690             :     }
     691             : 
     692         168 :     comp = detail::segments_compare(
     693             :         encoded_segments(),
     694             :         other.encoded_segments());
     695         168 :     if ( comp != 0 )
     696          43 :         return comp;
     697             : 
     698         125 :     comp =
     699         125 :         static_cast<int>(has_query()) -
     700         125 :         static_cast<int>(other.has_query());
     701         125 :     if ( comp != 0 )
     702           0 :         return comp;
     703             : 
     704         125 :     if (has_query())
     705             :     {
     706          34 :         comp = detail::compare_encoded(
     707          17 :             encoded_query(),
     708          17 :             other.encoded_query());
     709          17 :         if ( comp != 0 )
     710          14 :             return comp;
     711             :     }
     712             : 
     713         111 :     comp =
     714         111 :         static_cast<int>(has_fragment()) -
     715         111 :         static_cast<int>(other.has_fragment());
     716         111 :     if ( comp != 0 )
     717           0 :         return comp;
     718             : 
     719         111 :     if (has_fragment())
     720             :     {
     721          44 :         comp = detail::compare_encoded(
     722          22 :             encoded_fragment(),
     723          22 :             other.encoded_fragment());
     724          22 :         if ( comp != 0 )
     725          21 :             return comp;
     726             :     }
     727             : 
     728          90 :     return 0;
     729             : }
     730             : 
     731             : } // urls
     732             : } // boost
     733             : 
     734             : #endif

Generated by: LCOV version 1.15