diff options
Diffstat (limited to 'src/dir.cpp')
-rw-r--r-- | src/dir.cpp | 55 |
1 files changed, 50 insertions, 5 deletions
diff --git a/src/dir.cpp b/src/dir.cpp index 8a9fd86..cee26f0 100644 --- a/src/dir.cpp +++ b/src/dir.cpp @@ -1,10 +1,36 @@ #include <Ice/ObjectAdapter.h> +#include <sys/stat.h> +#include "repo.h" #include "dir.h" -GitFS::Directory::Directory(const GitFS::Git::TreePtr & t, const std::string & p) : - tree(t), - path(p) +GitFS::Directory::Directory(const Repo * r, const std::string & p) : + repo(r), + path(p), + subTreeCacheRootId({}) { + getSubtree(); +} + +GitFS::Git::TreePtr +GitFS::Directory::getSubtree() const +{ + if (!git_oid_equal(&subTreeCacheRootId, git_tree_id(repo->tree.get()))) { + if (path == "/") { + subTreeCache = repo->tree; + } + else { + try { + auto e = Git::TreeEntryByPath(repo->tree, path); + if (!S_ISDIR(git_tree_entry_filemode(e.get()))) throw NetFS::SystemError(ENOTDIR); + subTreeCache = Git::TreeLookup(repo->repo, *git_tree_entry_id(e.get())); + } + catch (const Git::Error & e) { + Git::ErrorToSystemError(e); + } + } + subTreeCacheRootId = *git_tree_id(repo->tree.get()); + } + return subTreeCache; } void @@ -17,14 +43,33 @@ GitFS::Directory::close(const ::Ice::Current& current) NetFS::NameList GitFS::Directory::readdir(const ::Ice::Current&) { - return {}; + const auto subTree = getSubtree(); + NetFS::NameList list; + for (int idx = git_tree_entrycount(subTree.get()); idx--;) { + const auto entry = git_tree_entry_byindex(subTree.get(), idx); + list.push_back(git_tree_entry_name(entry)); + } + return list; } NetFS::DirectoryContents GitFS::Directory::listdir(const ::Ice::Current&) { - return {}; + const auto subTree = getSubtree(); + NetFS::DirectoryContents list; + for (int idx = git_tree_entrycount(subTree.get()); idx--;) { + const auto entry = git_tree_entry_byindex(subTree.get(), idx); + NetFS::Attr a {}; + a << *entry << *repo->commit; + if (S_ISREG(git_tree_entry_filemode(entry))) { + auto blob = Git::BlobLookup(repo->repo, *git_tree_entry_id(entry)); + a << *blob; + } + a.gid = a.uid = "root"; + list.emplace(git_tree_entry_name(entry), a); + } + return list; } |