From 8565a87552a7453397f545c3cde6fd363ab11d77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 12 Sep 2003 07:32:21 +0000 Subject: [PATCH] Added some convenience functions, a method to get the node's name, and a node factory to get the correct type of node (Directory/File). git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4653 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../boot/loader/file_systems/bfs/Stream.cpp | 63 ++++++++++++++++++- .../boot/loader/file_systems/bfs/Stream.h | 15 ++++- 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/kernel/boot/loader/file_systems/bfs/Stream.cpp b/src/kernel/boot/loader/file_systems/bfs/Stream.cpp index a754847c67..4ebc3cf356 100644 --- a/src/kernel/boot/loader/file_systems/bfs/Stream.cpp +++ b/src/kernel/boot/loader/file_systems/bfs/Stream.cpp @@ -6,6 +6,8 @@ #include "Stream.h" +#include "Directory.h" +#include "File.h" #include #include @@ -107,6 +109,15 @@ Stream::Stream(Volume &volume, block_run run) } +Stream::Stream(Volume &volume, off_t id) + : + fVolume(volume) +{ + if (read_pos(volume.Device(), volume.ToOffset(id), this, sizeof(bfs_inode)) != sizeof(bfs_inode)) + return; +} + + Stream::~Stream() { } @@ -119,6 +130,42 @@ Stream::InitCheck() } +status_t +Stream::GetNextSmallData(const small_data **_smallData) const +{ + const small_data *smallData = *_smallData; + + // begin from the start? + if (smallData == NULL) + smallData = small_data_start; + else + smallData = smallData->Next(); + + // is already last item? + if (smallData->IsLast(this)) + return B_ENTRY_NOT_FOUND; + + *_smallData = smallData; + + return B_OK; +} + + +status_t +Stream::GetName(char *name, size_t size) const +{ + const small_data *smallData = NULL; + while (GetNextSmallData(&smallData) == B_OK) { + if (*smallData->Name() == FILE_NAME_NAME + && smallData->NameSize() == FILE_NAME_NAME_LENGTH) { + strlcpy(name, (const char *)smallData->Data(), size); + return B_OK; + } + } + return B_ERROR; +} + + status_t Stream::FindBlockRun(off_t pos, block_run &run, off_t &offset) { @@ -315,7 +362,7 @@ Stream::ReadAt(off_t pos, uint8 *buffer, size_t *_length) if (partial) { // if the last block was read only partially, point block_run // to the remaining part - run.start += run.length; + run.start = HOST_ENDIAN_TO_BFS_INT16(run.Start() + run.Length()); run.length = 1; offset = pos; } else if (FindBlockRun(pos, run, offset) < B_OK) { @@ -329,6 +376,20 @@ Stream::ReadAt(off_t pos, uint8 *buffer, size_t *_length) } +Node * +Stream::NodeFactory(Volume &volume, off_t id) +{ + Stream stream(volume, id); + if (stream.InitCheck() != B_OK) + return NULL; + + if (stream.IsContainer()) + return new Directory(stream); + + return new File(stream); +} + + // #pragma mark - diff --git a/src/kernel/boot/loader/file_systems/bfs/Stream.h b/src/kernel/boot/loader/file_systems/bfs/Stream.h index 99930bd207..d5d2fc7137 100644 --- a/src/kernel/boot/loader/file_systems/bfs/Stream.h +++ b/src/kernel/boot/loader/file_systems/bfs/Stream.h @@ -9,20 +9,33 @@ #include "Volume.h" +#include + + namespace BFS { class Stream : public bfs_inode { public: Stream(Volume &volume, block_run run); + Stream(Volume &volume, off_t id); ~Stream(); status_t InitCheck(); - Volume &GetVolume() { return fVolume; } + Volume &GetVolume() const { return fVolume; } status_t FindBlockRun(off_t pos, block_run &run, off_t &offset); status_t ReadAt(off_t pos, uint8 *buffer, size_t *length); + status_t GetName(char *name, size_t size) const; + off_t Size() const { return data.Size(); } + off_t ID() const { return fVolume.ToVnode(inode_num); } + bool IsContainer() const { return Mode() & (S_IFDIR | S_INDEX_DIR | S_ATTR_DIR); } + + static Node *NodeFactory(Volume &volume, off_t id); + private: + status_t GetNextSmallData(const small_data **_smallData) const; + Volume &fVolume; };