* Copyright 2001-2008, pinc Software. All Rights Reserved.
* Released under the terms of the MIT license.
*/
#ifndef INODE_H
#define INODE_H
#include <SupportDefs.h>
#include "Disk.h"
class BPlusTree;
class Directory;
class Inode {
public:
Inode(Disk* disk, bfs_inode* inode, bool ownBuffer = true);
Inode(const Inode &inode);
virtual ~Inode();
status_t SetTo(bfs_inode *inode);
virtual status_t InitCheck() const;
bool IsFile() const { return S_ISREG(fInode->mode); }
bool IsDirectory() const { return S_ISDIR(fInode->mode); }
bool IsSymlink() const { return S_ISLNK(fInode->mode); }
bool IsIndex() const { return S_ISINDEX(fInode->mode); }
bool IsAttribute() const
{ return (fInode->mode & S_ATTR) != 0; }
bool IsAttributeDirectory() const
{ return (fInode->mode & S_ATTR_DIR) != 0; }
bool IsRoot() const { return BlockRun() == fDisk->Root(); }
int32 Mode() const { return fInode->mode; }
int32 Flags() const { return fInode->flags; }
off_t Size() const { return fInode->data.size; }
off_t Offset() const
{ return fDisk->ToOffset(BlockRun()); }
off_t Block() const { return fDisk->ToBlock(BlockRun()); }
const block_run& BlockRun() const { return fBlockRun; }
block_run Parent() const { return fInode->parent; }
block_run Attributes() const { return fInode->attributes; }
const bfs_inode* InodeBuffer() const { return fInode; }
status_t CopyBuffer();
void ReleaseBuffer();
status_t AcquireBuffer();
void BufferClobbered();
void SetParent(const block_run& run);
void SetBlockRun(const block_run& run);
void SetMode(uint32 mode);
status_t SetName(const char* name);
const char* Name() const;
status_t GetNextSmallData(small_data** smallData);
status_t RewindAttributes();
status_t GetNextAttribute(char* name, uint32* type, void** data,
size_t* length);
class Source;
const char* Path(Inode::Source* source = NULL);
virtual status_t CopyTo(const char* path, bool fullPath = true,
Inode::Source* source = NULL);
status_t CopyAttributesTo(BNode* node);
static Inode* Factory(Disk* disk, bfs_inode* inode,
bool ownBuffer = true);
static Inode* Factory(Disk* disk, block_run run);
static Inode* Factory(Disk* disk, Inode* inode,
bool copyBuffer = true);
static Inode* EmptyInode(Disk* disk,const char* name, int32 mode);
class Source {
public:
virtual Inode *InodeAt(block_run run) = 0;
};
protected:
static bool _LowMemory();
void _Unset();
status_t _FindPath(Inode::Source *source = NULL);
Disk *fDisk;
bfs_inode *fInode;
bool fOwnBuffer;
char *fPath;
block_run fBlockRun;
int32 fRefCount;
small_data *fCurrentSmallData;
Directory *fAttributes;
void *fAttributeBuffer;
};
class DataStream : public Inode, public BPositionIO {
public:
DataStream(Disk *disk, bfs_inode *inode, bool ownBuffer = true);
DataStream(const Inode &inode);
~DataStream();
status_t FindBlockRun(off_t pos);
virtual ssize_t ReadAt(off_t pos, void *buffer, size_t size);
virtual ssize_t WriteAt(off_t pos, const void *buffer, size_t size);
virtual off_t Seek(off_t position, uint32 seek_mode);
virtual off_t Position() const;
virtual status_t SetSize(off_t size);
private:
int32 fCurrent;
int32 fLevel;
block_run fRun;
off_t fRunFileOffset;
off_t fRunBlockEnd;
off_t fPosition;
};
class File : public DataStream {
public:
File(Disk *disk, bfs_inode *inode, bool ownBuffer = true);
File(const Inode &inode);
~File();
virtual status_t InitCheck() const;
virtual status_t CopyTo(const char *path, bool fullPath = true,
Inode::Source *source = NULL);
};
class Attribute : public File {
public:
Attribute(Disk *disk, bfs_inode *inode, bool ownBuffer = true);
Attribute(const Inode &inode);
~Attribute();
virtual status_t InitCheck() const;
virtual status_t CopyTo(const char *path, bool fullPath = true,
Inode::Source *source = NULL);
uint32 Type() const { return fInode->type; }
};
class Directory : public DataStream {
public:
Directory(Disk *disk, bfs_inode *inode, bool ownBuffer = true);
Directory(const Inode &inode);
~Directory();
virtual status_t InitCheck() const;
virtual status_t CopyTo(const char *path, bool fullPath = true,
Inode::Source *source = NULL);
virtual status_t Rewind();
virtual status_t GetNextEntry(char *name, block_run *run);
virtual status_t GetNextEntry(block_run *run);
virtual status_t Contains(const block_run *run);
virtual status_t Contains(const Inode *inode);
virtual status_t FindEntry(const char *name, block_run *run);
virtual status_t AddEntry(Inode *inode);
status_t GetTree(BPlusTree **tree);
private:
virtual status_t CreateTree();
BPlusTree *fTree;
};
class Symlink : public Inode {
public:
Symlink(Disk *disk, bfs_inode *inode, bool ownBuffer = true);
Symlink(const Inode &inode);
~Symlink();
virtual status_t InitCheck() const;
virtual status_t CopyTo(const char *path, bool fullPath = true,
Inode::Source *source = NULL);
status_t LinksTo(char *to, size_t maxLength);
private:
char *fTo;
};
#endif