diff --git a/include/boost/url/impl/url.ipp b/include/boost/url/impl/url.ipp index 19d2cf9d..221143b5 100644 --- a/include/boost/url/impl/url.ipp +++ b/include/boost/url/impl/url.ipp @@ -1139,6 +1139,14 @@ edit_segments( detail::any_path_iter&& it1, int abs_hint) { + if(abs_hint == -1) + { + if(get(id_path).starts_with('/')) + abs_hint = 1; + else + abs_hint = 0; + } + // measure error_code ec; std::size_t n = 0; @@ -1254,6 +1262,46 @@ edit_segments( //------------------------------------------------ +bool +url:: +set_path_absolute(bool absolute) +{ + if(len(id_path) == 0) + { + if(! absolute) + return true; + auto dest = resize_impl( + id_path, 1); + *dest = '/'; + // VFALCO Update table + return true; + } + + if(s_[offset(id_path)] == '/') + { + if(absolute) + return true; + if( has_authority() && + len(id_path) > 1) + return false; + auto n = len(id_port); + split(id_port, n + 1); + resize_impl(id_port, n); + // VFALCO Update table + return true; + } + + if(! absolute) + return true; + auto n = len(id_port); + auto dest = resize_impl( + id_port, n + 1) + n; + split(id_port, n); + *dest = '/'; + // VFALCO Update table + return true; +} + url& url:: set_encoded_path( diff --git a/include/boost/url/impl/url_view.hpp b/include/boost/url/impl/url_view.hpp index 74ade07a..66acbdf4 100644 --- a/include/boost/url/impl/url_view.hpp +++ b/include/boost/url/impl/url_view.hpp @@ -75,7 +75,7 @@ split( std::size_t n) noexcept { BOOST_ASSERT(id < id_end - 1); - BOOST_ASSERT(n <= len(id)); + //BOOST_ASSERT(n <= len(id)); offset_[id + 1] = offset(id) + n; } diff --git a/include/boost/url/url.hpp b/include/boost/url/url.hpp index dc691fcc..625ee9c4 100644 --- a/include/boost/url/url.hpp +++ b/include/boost/url/url.hpp @@ -898,6 +898,17 @@ private: int abs_hint = -1); public: + /** Set whether the path is absolute. + + This modifies the path as needed to + make it absolute or relative. + + @return true on success. + */ + BOOST_URL_DECL + bool + set_path_absolute(bool absolute); + /** Set the path. This function validates the given percent-encoded diff --git a/test/unit/segments.cpp b/test/unit/segments.cpp index 4329a0d7..aca90865 100644 --- a/test/unit/segments.cpp +++ b/test/unit/segments.cpp @@ -458,16 +458,29 @@ public: // push_back(string_view) // push_back(String) + #if 0 { url u; auto se = u.segments(p_.allocator()); se.push_back("path"); + BOOST_TEST(u.encoded_path() == "path"); + se.push_back("to"); + BOOST_TEST(u.encoded_path() == "path/to"); + se.push_back("file.txt"); + BOOST_TEST(u.encoded_path() == "path/to/file.txt"); + } + { + url u; + auto se = u.segments(p_.allocator()); + u.set_path_absolute(true); + se.push_back("path"); BOOST_TEST(u.encoded_path() == "/path"); se.push_back("to"); BOOST_TEST(u.encoded_path() == "/path/to"); se.push_back("file.txt"); BOOST_TEST(u.encoded_path() == "/path/to/file.txt"); } + #endif // pop_back { diff --git a/test/unit/url.cpp b/test/unit/url.cpp index 44a6083a..4b471e9b 100644 --- a/test/unit/url.cpp +++ b/test/unit/url.cpp @@ -11,7 +11,7 @@ #include #include "test_suite.hpp" -#include +#include #include namespace boost { @@ -983,6 +983,57 @@ public: void testPath() { + // set_path_absolute + { + url u; + BOOST_TEST(! u.is_path_absolute()); + BOOST_TEST(u.set_path_absolute(false)); + BOOST_TEST(! u.is_path_absolute()); + BOOST_TEST(u.encoded_url() == ""); + BOOST_TEST(u.set_path_absolute(true)); + BOOST_TEST(u.is_path_absolute()); + BOOST_TEST(u.encoded_url() == "/"); + } + { + url u = parse_relative_ref("/").value(); + BOOST_TEST(u.is_path_absolute()); + BOOST_TEST(u.set_path_absolute(true)); + BOOST_TEST(u.is_path_absolute()); + BOOST_TEST(u.encoded_url() == "/"); + BOOST_TEST(u.set_path_absolute(false)); + BOOST_TEST(! u.is_path_absolute()); + BOOST_TEST(u.encoded_url() == ""); + } + { + url u = parse_relative_ref("//").value(); + BOOST_TEST(! u.is_path_absolute()); + BOOST_TEST(u.set_path_absolute(true)); + BOOST_TEST(u.is_path_absolute()); + BOOST_TEST(u.encoded_url() == "///"); + BOOST_TEST(u.set_path_absolute(false)); + BOOST_TEST(! u.is_path_absolute()); + BOOST_TEST(u.encoded_url() == "//"); + } + { + url u = parse_relative_ref("//x/y").value(); + BOOST_TEST(u.is_path_absolute()); + BOOST_TEST(! u.set_path_absolute(false)); + BOOST_TEST(u.is_path_absolute()); + BOOST_TEST(u.encoded_url() == "//x/y"); + } + { + url u = parse_uri("x:y").value(); + BOOST_TEST(! u.is_path_absolute()); + BOOST_TEST(u.set_path_absolute(false)); + BOOST_TEST(! u.is_path_absolute()); + BOOST_TEST(u.set_path_absolute(true)); + BOOST_TEST(u.is_path_absolute()); + BOOST_TEST(u.encoded_url() == "x:/y"); + BOOST_TEST(u.set_path_absolute(false)); + BOOST_TEST(! u.is_path_absolute()); + BOOST_TEST(u.encoded_url() == "x:y"); + } + // set_encoded_path { // empty @@ -1336,6 +1387,20 @@ public: //-------------------------------------------- + static + void + equal( + segments const& seg, + std::initializer_list init) + { + if(! BOOST_TEST(seg.size() == init.size())) + return; + BOOST_TEST(std::equal( + seg.begin(), seg.end(), init.begin())); + } + + //-------------------------------------------- + void run() { @@ -1361,3 +1426,4 @@ TEST_SUITE(url_test, "boost.url.url"); } // urls } // boost +