From 559dc25102c1bd515e95da15ec459701a5fff047 Mon Sep 17 00:00:00 2001 From: alandefreitas Date: Wed, 14 Sep 2022 19:06:17 -0300 Subject: [PATCH] [FOLD] rebase and adjust to new containers --- include/boost/url/impl/url.ipp | 12 ----- include/boost/url/impl/url_base.ipp | 42 ++++++++------- include/boost/url/url.hpp | 67 ------------------------ include/boost/url/url_base.hpp | 80 +++++++++++++++++++++++++++++ test/unit/url.cpp | 4 +- 5 files changed, 105 insertions(+), 100 deletions(-) diff --git a/include/boost/url/impl/url.ipp b/include/boost/url/impl/url.ipp index 91e3f7d40..36ee042f2 100644 --- a/include/boost/url/impl/url.ipp +++ b/include/boost/url/impl/url.ipp @@ -139,18 +139,6 @@ reserve_impl( impl_.cs_ = s_; } -result -relative( - url_view_base const& base, - url_view_base const& href, - url_base& dest) -{ - BOOST_ASSERT(&dest != &base); - BOOST_ASSERT(&dest != &href); - dest.copy(base); - return dest.relative(href); -} - void url:: cleanup( diff --git a/include/boost/url/impl/url_base.ipp b/include/boost/url/impl/url_base.ipp index 4ddea917a..39ad11158 100644 --- a/include/boost/url/impl/url_base.ipp +++ b/include/boost/url/impl/url_base.ipp @@ -1403,28 +1403,32 @@ relative( // Resolve new path // 0. Get segments - auto segs0 = dynamic_cast(this)->segments(); - auto segs1 = href.segments(); + auto segs0 = dynamic_cast(this)->encoded_segments(); + auto segs1 = href.encoded_segments(); // Reference iterators auto const begin0 = segs0.begin(); auto it0 = begin0; auto const end0 = segs0.end(); auto const last0 = begin0 != end0 ? std::prev(end0) : end0; + auto const begin1 = segs1.begin(); auto it1 = begin1; auto const end1 = segs1.end(); auto const last1 = begin1 != end1 ? std::prev(end1) : end1; // Function to advance the dotdot segments - decode_view dotdot(".."); - decode_view dot("."); + pct_string_view dotdot_str(".."); + pct_string_view dot_str("."); + decode_view dotdot(dotdot_str); + decode_view dot(dot_str); + auto consume_dots = [dotdot, dot]( - segments_view::iterator& first, - segments_view::iterator last) + segments_encoded_view::iterator& first, + segments_encoded_view::iterator last) { - if (*first == dotdot || - *first == dot) + if (decode_view(*first) == dotdot || + decode_view(*first) == dot) { ++first; return true; @@ -1433,7 +1437,7 @@ relative( std::size_t l = 1; while (it != last) { - if (*it == dotdot) + if (decode_view(*it) == dotdot) { if (--l == 0) { @@ -1442,7 +1446,7 @@ relative( break; } } - else if (*it != dot) + else if (decode_view(*it) != dot) { ++l; } @@ -1460,7 +1464,7 @@ relative( continue; if (consume_dots(it1, last1)) continue; - if (*it0 == *it1) + if (decode_view(*it0) == decode_view(*it1)) { ++it0; ++it1; @@ -1476,7 +1480,7 @@ relative( it1 == last1 && it0 != end0 && it1 != end1 && - *it0 == *it1) + decode_view(*it0) == decode_view(*it1)) { // Return empty path if (href.has_query()) @@ -1497,12 +1501,12 @@ relative( { while (it0 != last0) { - if (*it0 == dotdot) + if (decode_view(*it0) == dotdot) { if (n != 0) --n; } - else if (*it0 != dot) + else if (decode_view(*it0) != dot) { ++n; } @@ -1511,23 +1515,23 @@ relative( } set_encoded_path({}); set_path_absolute(false); - segments_encoded segs = encoded_segments(); + segments_encoded_ref segs = encoded_segments(); while (n--) { - segs.push_back(dotdot.encoded()); + segs.push_back(dotdot_str); } // 3. Append segments left from the reference while (it1 != end1) { - if (*it1 == dotdot) + if (decode_view(*it1) == dotdot) { if (!segs.empty()) segs.pop_back(); } - else if (*it1 != dot) + else if (decode_view(*it1) != dot) { - segs.push_back((*it1).encoded()); + segs.push_back(*it1); } ++it1; } diff --git a/include/boost/url/url.hpp b/include/boost/url/url.hpp index a4d09e02a..f7802bcfb 100644 --- a/include/boost/url/url.hpp +++ b/include/boost/url/url.hpp @@ -410,73 +410,6 @@ class BOOST_SYMBOL_VISIBLE url //---------------------------------------------------------- -/** Compares two absolute paths and make one relative to the other - - This function compares the absolute paths in - two urls. It returns a new url with a relative - path that references the target path relative - to the base path. - - Unlike @ref resolve, this function takes - two absolute paths to create a relative - path. - - If the input URLs contain schemes and - authorities, these are resolved. If the - schemes and authorities are the same, they - are removed before the relative path is - calculated. If they are different, only - the relative path of the reference URL - is returned. - - Given the input base URL, this function - resolves the reference URL as if performing - the following steps: - - @li Normalize both URLs - @li Remove the longest common path from both paths - @li Replace each segment in the base path with ".." - @li Append the reference path - - This function places the result of the - resolution into `dest`, which can be - any of the url containers that inherit - from @ref url_base. - - If the function fails, an error is returned. - - @par Example - @code - url dest; - error_code ec; - relative("/relative/sub/foo/sub/file", "/relative/path", dest, ec); - assert( dest.str() == "../../../path" ); - @endcode - - @par Exception Safety - Basic guarantee. - Calls to allocate may throw. - - @param base The base URL to resolve against. - - @param href The target URL the relative URL should point to - - @param dest The container where the relative result - is written, upon success. - - @param ec Set to the error if any occurred. - - @see - @ref url, - @ref url_view. -*/ -BOOST_URL_DECL -result -relative( - url_view_base const& base, - url_view_base const& href, - url_base& dest); - } // urls } // boost diff --git a/include/boost/url/url_base.hpp b/include/boost/url/url_base.hpp index b64a7661d..578b23f3c 100644 --- a/include/boost/url/url_base.hpp +++ b/include/boost/url/url_base.hpp @@ -2616,6 +2616,13 @@ class BOOST_SYMBOL_VISIBLE url_view_base const& ref, url_base& dest); + friend + result + relative( + url_view_base const& base, + url_view_base const& href, + url_base& dest); + private: //-------------------------------------------- // @@ -2768,6 +2775,79 @@ resolve( return dest.resolve(ref); } +/** Compares two absolute paths and make one relative to the other + + This function compares the absolute paths in + two urls. It returns a new url with a relative + path that references the target path relative + to the base path. + + Unlike @ref resolve, this function takes + two absolute paths to create a relative + path. + + If the input URLs contain schemes and + authorities, these are resolved. If the + schemes and authorities are the same, they + are removed before the relative path is + calculated. If they are different, only + the relative path of the reference URL + is returned. + + Given the input base URL, this function + resolves the reference URL as if performing + the following steps: + + @li Normalize both URLs + @li Remove the longest common path from both paths + @li Replace each segment in the base path with ".." + @li Append the reference path + + This function places the result of the + resolution into `dest`, which can be + any of the url containers that inherit + from @ref url_base. + + If the function fails, an error is returned. + + @par Example + @code + url dest; + error_code ec; + relative("/relative/sub/foo/sub/file", "/relative/path", dest, ec); + assert( dest.str() == "../../../path" ); + @endcode + + @par Exception Safety + Basic guarantee. + Calls to allocate may throw. + + @param base The base URL to resolve against. + + @param href The target URL the relative URL should point to + + @param dest The container where the relative result + is written, upon success. + + @param ec Set to the error if any occurred. + + @see + @ref url, + @ref url_view. +*/ +inline +result +relative( + url_view_base const& base, + url_view_base const& href, + url_base& dest) +{ + BOOST_ASSERT(&dest != &href); + if (&dest != &base) + dest.copy(base); + return dest.relative(href); +} + } // urls } // boost diff --git a/test/unit/url.cpp b/test/unit/url.cpp index 0d8f8a56e..c8025020d 100644 --- a/test/unit/url.cpp +++ b/test/unit/url.cpp @@ -877,13 +877,13 @@ struct url_test url dest = parse_uri_reference("x/y" ).value(); auto rv = relative(ub, ur, dest); BOOST_TEST(!rv.has_error()); - BOOST_TEST_EQ(dest.string(), e); + BOOST_TEST_EQ(dest.buffer(), e); // in place url base( ub ); rv = base.relative( ur ); BOOST_TEST(!rv.has_error()); - BOOST_TEST_EQ(base.string(), e); + BOOST_TEST_EQ(base.buffer(), e); }; // relative URL / absolute paths