diff --git a/include/dwarfs/reader/filesystem_v2.h b/include/dwarfs/reader/filesystem_v2.h index 582a4509..49ed6608 100644 --- a/include/dwarfs/reader/filesystem_v2.h +++ b/include/dwarfs/reader/filesystem_v2.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -128,13 +129,13 @@ class filesystem_v2 { dir_entry_view root() const { return impl_->root(); } - std::optional find(const char* path) const { + std::optional find(std::string_view path) const { return impl_->find(path); } std::optional find(int inode) const { return impl_->find(inode); } - std::optional find(int inode, const char* name) const { + std::optional find(int inode, std::string_view name) const { return impl_->find(inode, name); } @@ -362,10 +363,10 @@ class filesystem_v2 { virtual void walk_data_order(std::function const& func) const = 0; virtual dir_entry_view root() const = 0; - virtual std::optional find(const char* path) const = 0; + virtual std::optional find(std::string_view path) const = 0; virtual std::optional find(int inode) const = 0; virtual std::optional - find(int inode, const char* name) const = 0; + find(int inode, std::string_view name) const = 0; virtual file_stat getattr(inode_view entry, std::error_code& ec) const = 0; virtual file_stat getattr(inode_view entry, getattr_options const& opts, std::error_code& ec) const = 0; diff --git a/include/dwarfs/reader/internal/metadata_v2.h b/include/dwarfs/reader/internal/metadata_v2.h index d59afa06..027b69a2 100644 --- a/include/dwarfs/reader/internal/metadata_v2.h +++ b/include/dwarfs/reader/internal/metadata_v2.h @@ -99,13 +99,13 @@ class metadata_v2 { dir_entry_view root() const { return impl_->root(); } - std::optional find(const char* path) const { + std::optional find(std::string_view path) const { return impl_->find(path); } std::optional find(int inode) const { return impl_->find(inode); } - std::optional find(int inode, const char* name) const { + std::optional find(int inode, std::string_view name) const { return impl_->find(inode, name); } @@ -201,10 +201,10 @@ class metadata_v2 { virtual dir_entry_view root() const = 0; - virtual std::optional find(const char* path) const = 0; + virtual std::optional find(std::string_view path) const = 0; virtual std::optional find(int inode) const = 0; virtual std::optional - find(int inode, const char* name) const = 0; + find(int inode, std::string_view name) const = 0; virtual file_stat getattr(inode_view iv, std::error_code& ec) const = 0; virtual file_stat getattr(inode_view iv, getattr_options const& opts, diff --git a/src/reader/filesystem_v2.cpp b/src/reader/filesystem_v2.cpp index d8e89265..e2f8e32f 100644 --- a/src/reader/filesystem_v2.cpp +++ b/src/reader/filesystem_v2.cpp @@ -223,10 +223,10 @@ class filesystem_ final : public filesystem_v2::impl { void walk_data_order( std::function const& func) const override; dir_entry_view root() const override; - std::optional find(const char* path) const override; + std::optional find(std::string_view path) const override; std::optional find(int inode) const override; std::optional - find(int inode, const char* name) const override; + find(int inode, std::string_view name) const override; file_stat getattr(inode_view entry, std::error_code& ec) const override; file_stat getattr(inode_view entry, getattr_options const& opts, std::error_code& ec) const override; @@ -743,7 +743,7 @@ dir_entry_view filesystem_::root() const { template std::optional -filesystem_::find(const char* path) const { +filesystem_::find(std::string_view path) const { PERFMON_CLS_SCOPED_SECTION(find_path) return meta_.find(path); } @@ -756,7 +756,7 @@ std::optional filesystem_::find(int inode) const { template std::optional -filesystem_::find(int inode, const char* name) const { +filesystem_::find(int inode, std::string_view name) const { PERFMON_CLS_SCOPED_SECTION(find_inode_name) return meta_.find(inode, name); } diff --git a/src/reader/internal/metadata_v2.cpp b/src/reader/internal/metadata_v2.cpp index e015f71c..88c47baf 100644 --- a/src/reader/internal/metadata_v2.cpp +++ b/src/reader/internal/metadata_v2.cpp @@ -501,10 +501,10 @@ class metadata_ final : public metadata_v2::impl { dir_entry_view root() const override { return root_; } - std::optional find(const char* path) const override; + std::optional find(std::string_view path) const override; std::optional find(int inode) const override; std::optional - find(int inode, const char* name) const override; + find(int inode, std::string_view name) const override; file_stat getattr(inode_view iv, std::error_code& ec) const override; file_stat getattr(inode_view iv, getattr_options const& opts, @@ -1650,30 +1650,38 @@ metadata_::find(directory_view dir, std::string_view name) const { template std::optional -metadata_::find(const char* path) const { - while (*path == '/') { - ++path; +metadata_::find(std::string_view path) const { + auto start = path.find_first_not_of('/'); + + if (start != std::string_view::npos) { + path.remove_prefix(start); + } else { + path = {}; } auto dev = std::make_optional(root_); - while (*path) { - const char* next = ::strchr(path, '/'); - size_t clen = next ? next - path : ::strlen(path); // Flawfinder: ignore - + while (!path.empty()) { auto iv = dev->inode(); if (!iv.is_directory()) { return std::nullopt; } - dev = find(make_directory_view(iv), std::string_view(path, clen)); + auto name = path; + + if (auto sep = path.find('/'); sep != std::string_view::npos) { + name = path.substr(0, sep); + path.remove_prefix(sep + 1); + } else { + path = {}; + } + + dev = find(make_directory_view(iv), name); if (!dev) { break; } - - path = next ? next + 1 : path + clen; } return dev; @@ -1686,9 +1694,9 @@ std::optional metadata_::find(int inode) const { template std::optional -metadata_::find(int inode, const char* name) const { +metadata_::find(int inode, std::string_view name) const { if (auto iv = get_entry(inode); iv and iv->is_directory()) { - return find(make_directory_view(*iv), std::string_view(name)); + return find(make_directory_view(*iv), name); } return std::nullopt; diff --git a/test/compat_test.cpp b/test/compat_test.cpp index 19faa793..2a83face 100644 --- a/test/compat_test.cpp +++ b/test/compat_test.cpp @@ -1105,7 +1105,7 @@ void check_compat(logger& lgr, reader::filesystem_v2 const& fs, }; for (auto const& [td, expected] : testdirs) { - auto entry = fs.find(td.c_str()); + auto entry = fs.find(td); ASSERT_TRUE(entry) << td; auto dir = fs.opendir(entry->inode()); ASSERT_TRUE(dir) << td; diff --git a/test/dwarfs_test.cpp b/test/dwarfs_test.cpp index 372bc106..f58ab06e 100644 --- a/test/dwarfs_test.cpp +++ b/test/dwarfs_test.cpp @@ -1306,10 +1306,10 @@ TEST(filesystem, find_by_path) { EXPECT_GT(paths.size(), 10); for (auto const& p : paths) { - auto dev = fs.find(p.c_str()); + auto dev = fs.find(p); ASSERT_TRUE(dev) << p; EXPECT_FALSE(fs.find(dev->inode().inode_num(), "desktop.ini")) << p; - EXPECT_FALSE(fs.find((p + "/desktop.ini").c_str())) << p; + EXPECT_FALSE(fs.find(p + "/desktop.ini")) << p; } } diff --git a/test/tool_main_test.cpp b/test/tool_main_test.cpp index b50a63d7..20e064e0 100644 --- a/test/tool_main_test.cpp +++ b/test/tool_main_test.cpp @@ -904,7 +904,7 @@ TEST(mkdwarfs_test, metadata_path) { auto e4 = entries.at(16); auto e5 = entries.at(32); - auto dev = fs.find(d1.string().c_str()); + auto dev = fs.find(d1.string()); ASSERT_TRUE(dev); auto iv = dev->inode(); @@ -1105,7 +1105,7 @@ TEST(mkdwarfs_test, metadata_directory_iterator) { }; for (auto const& [path, expected_names] : testdirs) { - auto dev = fs.find(path.c_str()); + auto dev = fs.find(path); ASSERT_TRUE(dev) << path; auto dir = fs.opendir(dev->inode()); @@ -2341,7 +2341,7 @@ TEST(mkdwarfs_test, max_similarity_size) { for (auto size : sizes) { auto path = "/file" + std::to_string(size); - auto dev = fs.find(path.c_str()); + auto dev = fs.find(path); assert(dev); auto info = fs.get_inode_info(dev->inode()); assert(1 == info["chunks"].size()); @@ -2815,7 +2815,7 @@ TEST(block_cache, sequential_access_detector) { #ifdef _WIN32 std::replace(pstr.begin(), pstr.end(), '\\', '/'); #endif - auto dev = fs.find(pstr.c_str()); + auto dev = fs.find(pstr); ASSERT_TRUE(dev); auto iv = dev->inode(); ASSERT_TRUE(iv.is_regular_file()); @@ -2921,7 +2921,7 @@ TEST(file_scanner, large_file_handling) { auto fs = t.fs_from_stdout(); for (size_t i = 0; i < data.size(); ++i) { - auto dev = fs.find(fmt::format("f{}", i).c_str()); + auto dev = fs.find(fmt::format("f{}", i)); ASSERT_TRUE(dev) << i; auto iv = dev->inode(); auto st = fs.getattr(iv);