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
This commit is contained in:
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "Stream.h"
|
#include "Stream.h"
|
||||||
|
#include "Directory.h"
|
||||||
|
#include "File.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -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()
|
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
|
status_t
|
||||||
Stream::FindBlockRun(off_t pos, block_run &run, off_t &offset)
|
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 (partial) {
|
||||||
// if the last block was read only partially, point block_run
|
// if the last block was read only partially, point block_run
|
||||||
// to the remaining part
|
// to the remaining part
|
||||||
run.start += run.length;
|
run.start = HOST_ENDIAN_TO_BFS_INT16(run.Start() + run.Length());
|
||||||
run.length = 1;
|
run.length = 1;
|
||||||
offset = pos;
|
offset = pos;
|
||||||
} else if (FindBlockRun(pos, run, offset) < B_OK) {
|
} 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 -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,20 +9,33 @@
|
|||||||
|
|
||||||
#include "Volume.h"
|
#include "Volume.h"
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
|
||||||
namespace BFS {
|
namespace BFS {
|
||||||
|
|
||||||
class Stream : public bfs_inode {
|
class Stream : public bfs_inode {
|
||||||
public:
|
public:
|
||||||
Stream(Volume &volume, block_run run);
|
Stream(Volume &volume, block_run run);
|
||||||
|
Stream(Volume &volume, off_t id);
|
||||||
~Stream();
|
~Stream();
|
||||||
|
|
||||||
status_t InitCheck();
|
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 FindBlockRun(off_t pos, block_run &run, off_t &offset);
|
||||||
status_t ReadAt(off_t pos, uint8 *buffer, size_t *length);
|
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:
|
private:
|
||||||
|
status_t GetNextSmallData(const small_data **_smallData) const;
|
||||||
|
|
||||||
Volume &fVolume;
|
Volume &fVolume;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user