diff --git a/src/kernel/boot/loader/file_systems/bfs/Directory.cpp b/src/kernel/boot/loader/file_systems/bfs/Directory.cpp index 5048347cef..ae5962eaf6 100644 --- a/src/kernel/boot/loader/file_systems/bfs/Directory.cpp +++ b/src/kernel/boot/loader/file_systems/bfs/Directory.cpp @@ -5,14 +5,34 @@ #include "Directory.h" -#include "Volume.h" +#include "File.h" + +#include +#include namespace BFS { Directory::Directory(Volume &volume, block_run run) : - fStream(volume, run) + fStream(volume, run), + fTree(&fStream) +{ +} + + +Directory::Directory(Volume &volume, off_t id) + : + fStream(volume, id), + fTree(&fStream) +{ +} + + +Directory::Directory(const Stream &stream) + : + fStream(stream), + fTree(&fStream) { } @@ -25,42 +45,96 @@ Directory::~Directory() status_t Directory::InitCheck() { - return B_ERROR; + return fStream.InitCheck(); } status_t Directory::Open(void **_cookie, int mode) { - return B_ERROR; + *_cookie = (void *)new TreeIterator(&fTree); + if (*_cookie == NULL) + return B_NO_MEMORY; + + return B_OK; } status_t Directory::Close(void *cookie) { - return B_ERROR; + delete (TreeIterator *)cookie; + return B_OK; } Node * Directory::Lookup(const char *name, bool traverseLinks) { - return NULL; + off_t id; + if (fTree.Find((uint8 *)name, strlen(name), &id) < B_OK) + return NULL; + + Node *node = Stream::NodeFactory(fStream.GetVolume(), id); + if (node->Type() == S_IFLNK) { + // ToDo: support links! + delete node; + return NULL; + } + + return node; +} + + +status_t +Directory::GetNextEntry(void *cookie, char *name, size_t size) +{ + TreeIterator *iterator = (TreeIterator *)cookie; + uint16 length; + off_t id; + + return iterator->GetNextEntry(name, &length, size, &id); } status_t Directory::GetNextNode(void *cookie, Node **_node) { - return B_ERROR; + TreeIterator *iterator = (TreeIterator *)cookie; + char name[B_FILE_NAME_LENGTH]; + uint16 length; + off_t id; + + status_t status = iterator->GetNextEntry(name, &length, sizeof(name), &id); + if (status != B_OK) + return status; + + *_node = Stream::NodeFactory(fStream.GetVolume(), id); + if (*_node == NULL) + return B_ERROR; + + return B_OK; } status_t Directory::Rewind(void *cookie) { - return B_ERROR; + TreeIterator *iterator = (TreeIterator *)cookie; + + return iterator->Rewind(); +} + + +status_t +Directory::GetName(char *name, size_t size) const +{ + if (fStream.inode_num == fStream.GetVolume().Root()) { + strlcpy(name, fStream.GetVolume().SuperBlock().name, size); + return B_OK; + } + + return fStream.GetName(name, size); } } // namespace BFS diff --git a/src/kernel/boot/loader/file_systems/bfs/Directory.h b/src/kernel/boot/loader/file_systems/bfs/Directory.h index 8047b76424..b252278f97 100644 --- a/src/kernel/boot/loader/file_systems/bfs/Directory.h +++ b/src/kernel/boot/loader/file_systems/bfs/Directory.h @@ -10,13 +10,16 @@ #include "Volume.h" #include "Stream.h" +#include "BPlusTree.h" namespace BFS { class Directory : public ::Directory { public: - Directory(BFS::Volume &volume, block_run run); + Directory(Volume &volume, block_run run); + Directory(Volume &volume, off_t id); + Directory(const Stream &stream); virtual ~Directory(); status_t InitCheck(); @@ -26,11 +29,15 @@ class Directory : public ::Directory { virtual Node *Lookup(const char *name, bool traverseLinks); + virtual status_t GetNextEntry(void *cookie, char *nameBuffer, size_t bufferSize); virtual status_t GetNextNode(void *cookie, Node **_node); virtual status_t Rewind(void *cookie); + virtual status_t GetName(char *name, size_t size) const; + private: Stream fStream; + BPlusTree fTree; }; } // namespace BFS