1/*
2 * Copyright 2001-2008, pinc Software. All Rights Reserved.
3 * Released under the terms of the MIT license.
4 */
5#ifndef INODE_H
6#define INODE_H
7
8
9#include <SupportDefs.h>
10
11#include "Disk.h"
12
13class BPlusTree;
14class Directory;
15
16
17class Inode {
18	public:
19		Inode(Disk* disk, bfs_inode* inode, bool ownBuffer = true);
20		Inode(const Inode &inode);
21		virtual ~Inode();
22
23		status_t SetTo(bfs_inode *inode);
24		virtual status_t InitCheck() const;
25
26		bool			IsFile() const { return S_ISREG(fInode->mode); }
27		bool			IsDirectory() const { return S_ISDIR(fInode->mode); }
28		bool			IsSymlink() const { return S_ISLNK(fInode->mode); }
29		bool			IsIndex() const { return S_ISINDEX(fInode->mode); }
30		bool			IsAttribute() const
31							{ return (fInode->mode & S_ATTR) != 0; }
32		bool			IsAttributeDirectory() const
33							{ return (fInode->mode & S_ATTR_DIR) != 0; }
34		bool			IsRoot() const { return BlockRun() == fDisk->Root(); }
35
36		int32			Mode() const { return fInode->mode; }
37		int32			Flags() const { return fInode->flags; }
38		off_t			Size() const { return fInode->data.size; }
39
40		off_t			Offset() const
41							{ return fDisk->ToOffset(BlockRun()); }
42		off_t			Block() const { return fDisk->ToBlock(BlockRun()); }
43		const block_run& BlockRun() const { return fBlockRun; }
44		block_run		Parent() const { return fInode->parent; }
45		block_run		Attributes() const { return fInode->attributes; }
46
47		const bfs_inode* InodeBuffer() const { return fInode; }
48		status_t		CopyBuffer();
49
50		void			ReleaseBuffer();
51		status_t		AcquireBuffer();
52		void			BufferClobbered();
53
54		void			SetParent(const block_run& run);
55		void			SetBlockRun(const block_run& run);
56		void			SetMode(uint32 mode);
57
58		status_t		SetName(const char* name);
59		const char*		Name() const;
60		status_t		GetNextSmallData(small_data** smallData);
61
62		status_t		RewindAttributes();
63		status_t		GetNextAttribute(char* name, uint32* type, void** data,
64							size_t* length);
65
66		class Source;
67		const char*		Path(Inode::Source* source = NULL);
68		virtual status_t CopyTo(const char* path, bool fullPath = true,
69							Inode::Source* source = NULL);
70		status_t		CopyAttributesTo(BNode* node);
71
72		static Inode*	Factory(Disk* disk, bfs_inode* inode,
73							bool ownBuffer = true);
74		static Inode*	Factory(Disk* disk, block_run run);
75		static Inode*	Factory(Disk* disk, Inode* inode,
76							bool copyBuffer = true);
77
78		static Inode*	EmptyInode(Disk* disk,const char* name, int32 mode);
79
80		class Source {
81			public:
82				virtual Inode *InodeAt(block_run run) = 0;
83		};
84
85	protected:
86		static bool	_LowMemory();
87		void		_Unset();
88		status_t	_FindPath(Inode::Source *source = NULL);
89
90		Disk		*fDisk;
91		bfs_inode	*fInode;
92		bool		fOwnBuffer;
93		char		*fPath;
94		block_run	fBlockRun;
95		int32		fRefCount;
96
97		small_data	*fCurrentSmallData;
98		Directory	*fAttributes;
99		void		*fAttributeBuffer;
100};
101
102
103class DataStream : public Inode, public BPositionIO {
104	public:
105		DataStream(Disk *disk, bfs_inode *inode, bool ownBuffer = true);
106		DataStream(const Inode &inode);
107		~DataStream();
108
109		status_t			FindBlockRun(off_t pos);
110
111		virtual ssize_t		ReadAt(off_t pos, void *buffer, size_t size);
112		virtual ssize_t		WriteAt(off_t pos, const void *buffer, size_t size);
113
114		virtual off_t		Seek(off_t position, uint32 seek_mode);
115		virtual off_t		Position() const;
116
117		virtual status_t	SetSize(off_t size);
118
119	private:
120		int32		fCurrent;
121		int32		fLevel;
122		block_run	fRun;
123		off_t		fRunFileOffset;
124		off_t		fRunBlockEnd;
125		off_t		fPosition;
126};
127
128
129class File : public DataStream {
130	public:
131		File(Disk *disk, bfs_inode *inode, bool ownBuffer = true);
132		File(const Inode &inode);
133		~File();
134
135		virtual status_t	InitCheck() const;
136		virtual status_t	CopyTo(const char *path, bool fullPath = true,
137								Inode::Source *source = NULL);
138};
139
140
141class Attribute : public File {
142	public:
143		Attribute(Disk *disk, bfs_inode *inode, bool ownBuffer = true);
144		Attribute(const Inode &inode);
145		~Attribute();
146
147		virtual status_t	InitCheck() const;
148		virtual status_t	CopyTo(const char *path, bool fullPath = true,
149								Inode::Source *source = NULL);
150
151		uint32 Type() const { return fInode->type; }
152};
153
154
155class Directory : public DataStream {
156	public:
157		Directory(Disk *disk, bfs_inode *inode, bool ownBuffer = true);
158		Directory(const Inode &inode);
159		~Directory();
160
161		virtual status_t	InitCheck() const;
162		virtual status_t	CopyTo(const char *path, bool fullPath = true,
163								Inode::Source *source = NULL);
164
165		virtual status_t	Rewind();
166		virtual status_t	GetNextEntry(char *name, block_run *run);
167		virtual status_t	GetNextEntry(block_run *run);
168
169		virtual status_t	Contains(const block_run *run);
170		virtual status_t	Contains(const Inode *inode);
171		virtual status_t	FindEntry(const char *name, block_run *run);
172
173		virtual status_t	AddEntry(Inode *inode);
174
175		status_t			GetTree(BPlusTree **tree);
176
177	private:
178		virtual status_t	CreateTree();
179
180		BPlusTree	*fTree;
181};
182
183
184class Symlink : public Inode {
185	public:
186		Symlink(Disk *disk, bfs_inode *inode, bool ownBuffer = true);
187		Symlink(const Inode &inode);
188		~Symlink();
189
190		virtual status_t	InitCheck() const;
191		virtual status_t	CopyTo(const char *path, bool fullPath = true,
192								Inode::Source *source = NULL);
193
194		status_t			LinksTo(char *to, size_t maxLength);
195
196	private:
197		char	*fTo;
198};
199
200#endif	/* INODE_H */
201