LCOV - code coverage report
Current view: top level - libs/url/src/url_view_base.cpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 96.9 % 326 316
Test Date: 2024-08-19 20:08:54 Functions: 95.2 % 42 40

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

Generated by: LCOV version 2.1