diff --git a/include/dwarfs/filesystem_v2.h b/include/dwarfs/filesystem_v2.h index 17349563..348a0de1 100644 --- a/include/dwarfs/filesystem_v2.h +++ b/include/dwarfs/filesystem_v2.h @@ -83,6 +83,10 @@ class filesystem_v2 { impl_->walk(func); } + void walk(std::function const& func) const { + impl_->walk(func); + } + std::optional find(const char* path) const { return impl_->find(path); } @@ -141,6 +145,8 @@ class filesystem_v2 { virtual folly::dynamic metadata_as_dynamic() const = 0; virtual std::string serialize_metadata_as_json(bool simple) const = 0; virtual void walk(std::function const& func) const = 0; + virtual void + walk(std::function const& func) const = 0; virtual std::optional find(const char* path) const = 0; virtual std::optional find(int inode) const = 0; virtual std::optional diff --git a/include/dwarfs/metadata_v2.h b/include/dwarfs/metadata_v2.h index e68191d6..ed865d31 100644 --- a/include/dwarfs/metadata_v2.h +++ b/include/dwarfs/metadata_v2.h @@ -87,6 +87,10 @@ class metadata_v2 { impl_->walk(func); } + void walk(std::function const& func) const { + impl_->walk(func); + } + std::optional find(const char* path) const { return impl_->find(path); } @@ -152,6 +156,8 @@ class metadata_v2 { virtual bool empty() const = 0; virtual void walk(std::function const& func) const = 0; + virtual void + walk(std::function const& func) const = 0; virtual std::optional find(const char* path) const = 0; virtual std::optional find(int inode) const = 0; diff --git a/src/dwarfs/filesystem_v2.cpp b/src/dwarfs/filesystem_v2.cpp index e92fe11f..659f695b 100644 --- a/src/dwarfs/filesystem_v2.cpp +++ b/src/dwarfs/filesystem_v2.cpp @@ -183,6 +183,8 @@ class filesystem_ : public filesystem_v2::impl { folly::dynamic metadata_as_dynamic() const override; std::string serialize_metadata_as_json(bool simple) const override; void walk(std::function const& func) const override; + void walk(std::function const& func) + const override; std::optional find(const char* path) const override; std::optional find(int inode) const override; std::optional find(int inode, const char* name) const override; @@ -281,6 +283,12 @@ void filesystem_::walk( meta_.walk(func); } +template +void filesystem_::walk( + std::function const& func) const { + meta_.walk(func); +} + template std::optional filesystem_::find(const char* path) const { diff --git a/src/dwarfs/metadata_v2.cpp b/src/dwarfs/metadata_v2.cpp index 93fef80a..ddddc74e 100644 --- a/src/dwarfs/metadata_v2.cpp +++ b/src/dwarfs/metadata_v2.cpp @@ -179,6 +179,8 @@ class metadata_ : public metadata_v2::impl { bool empty() const override { return data_.empty(); } void walk(std::function const& func) const override; + void walk(std::function const& func) + const override; std::optional find(const char* path) const override; std::optional find(int inode) const override; @@ -331,8 +333,21 @@ class metadata_ : public metadata_v2::impl { } } - void walk(entry_view entry, std::unordered_set& seen, - std::function const& func) const; + static void walk_call(std::function const& func, + entry_view entry, directory_view) { + func(entry); + } + + static void + walk_call(std::function const& func, + entry_view entry, directory_view dir) { + func(entry, dir); + } + + template + void + walk(directory_view parent, entry_view entry, std::unordered_set& seen, + std::function const& func) const; std::optional get_entry(int inode) const { inode -= inode_offset_; @@ -572,10 +587,11 @@ std::string metadata_::modestring(uint16_t mode) const { } template -void metadata_::walk( - entry_view entry, std::unordered_set& seen, - std::function const& func) const { - func(entry); +template +void metadata_::walk(directory_view parent, entry_view entry, + std::unordered_set& seen, + std::function const& func) const { + walk_call(func, entry, parent); if (S_ISDIR(entry.mode())) { auto inode = entry.inode(); if (!seen.emplace(inode).second) { @@ -583,7 +599,7 @@ void metadata_::walk( } auto dir = make_directory_view(entry); for (auto cur : dir.entry_range()) { - walk(make_entry_view(cur), seen, func); + walk(dir, make_entry_view(cur), seen, func); } seen.erase(inode); } @@ -593,7 +609,14 @@ template void metadata_::walk( std::function const& func) const { std::unordered_set seen; - walk(root_, seen, func); + walk(make_directory_view(root_), root_, seen, func); +} + +template +void metadata_::walk( + std::function const& func) const { + std::unordered_set seen; + walk(make_directory_view(root_), root_, seen, func); } template