xref: /haiku/src/add-ons/kernel/file_systems/packagefs/nodes/Node.h (revision fc7456e9b1ec38c941134ed6d01c438cf289381e)
1 /*
2  * Copyright 2009-2013, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef NODE_H
6 #define NODE_H
7 
8 
9 #include <fs_interface.h>
10 
11 #include <Referenceable.h>
12 
13 #include <util/DoublyLinkedList.h>
14 #include <util/OpenHashTable.h>
15 
16 #include "InlineReferenceable.h"
17 #include "String.h"
18 #include "StringKey.h"
19 
20 
21 class AttributeCookie;
22 class AttributeDirectoryCookie;
23 class AttributeIndexer;
24 class Directory;
25 class PackageNode;
26 
27 
28 // internal node flags
29 enum {
30 	NODE_FLAG_KNOWN_TO_VFS		= 0x01,
31 	NODE_FLAG_VFS_INIT_ERROR	= 0x02,
32 		// used by subclasses
33 };
34 
35 
36 class Node : public DoublyLinkedListLinkImpl<Node> {
37 public:
38 								Node(ino_t id);
39 	virtual						~Node();
40 
41 			void				AcquireReference();
42 			void				ReleaseReference();
43 			int32				CountReferences();
44 
45 			BReference<Directory> GetParent() const;
46 			Directory*			GetParentUnchecked() const	{ return fParent; }
47 
48 			ino_t				ID() const		{ return fID; }
49 			const String&		Name() const	{ return fName; }
50 
51 			Node*&				NameHashTableNext()
52 									{ return fNameHashTableNext; }
53 			Node*&				IDHashTableNext()
54 									{ return fIDHashTableNext; }
55 
56 	virtual	status_t			Init(const String& name);
57 			void				SetID(ino_t id);
58 
59 	virtual	status_t			VFSInit(dev_t deviceID);
60 									// base class version must be called on
61 									// success
62 	virtual	void				VFSUninit();
63 									// base class version must be called
64 	inline	bool				IsKnownToVFS() const;
65 	inline	bool				HasVFSInitError() const;
66 
67 	virtual	mode_t				Mode() const = 0;
68 	virtual	uid_t				UserID() const;
69 	virtual	gid_t				GroupID() const;
70 	virtual	timespec			ModifiedTime() const = 0;
71 	virtual	off_t				FileSize() const = 0;
72 
73 	virtual	status_t			Read(off_t offset, void* buffer,
74 									size_t* bufferSize) = 0;
75 	virtual	status_t			Read(io_request* request) = 0;
76 
77 	virtual	status_t			ReadSymlink(void* buffer,
78 									size_t* bufferSize) = 0;
79 
80 	virtual	status_t			OpenAttributeDirectory(
81 									AttributeDirectoryCookie*& _cookie);
82 	virtual	status_t			OpenAttribute(const StringKey& name,
83 									int openMode, AttributeCookie*& _cookie);
84 
85 	virtual	status_t			IndexAttribute(AttributeIndexer* indexer);
86 	virtual	void*				IndexCookieForAttribute(const StringKey& name)
87 									const;
88 
89 private:
90 			friend class Directory;
91 
92 			void				_SetParent(Directory* parent);
93 
94 protected:
95 			ino_t				fID;
96 			Directory*			fParent;
97 			String				fName;
98 			Node*				fNameHashTableNext;
99 			Node*				fIDHashTableNext;
100 			uint32				fFlags;
101 			InlineReferenceable	fReferenceable;
102 };
103 
104 
105 bool
106 Node::IsKnownToVFS() const
107 {
108 	return (fFlags & NODE_FLAG_KNOWN_TO_VFS) != 0;
109 }
110 
111 
112 bool
113 Node::HasVFSInitError() const
114 {
115 	return (fFlags & NODE_FLAG_VFS_INIT_ERROR) != 0;
116 }
117 
118 
119 // #pragma mark -
120 
121 
122 struct NodeNameHashDefinition {
123 	typedef StringKey	KeyType;
124 	typedef	Node		ValueType;
125 
126 	size_t HashKey(const StringKey& key) const
127 	{
128 		return key.Hash();
129 	}
130 
131 	size_t Hash(const Node* value) const
132 	{
133 		return value->Name().Hash();
134 	}
135 
136 	bool Compare(const StringKey& key, const Node* value) const
137 	{
138 		return key == value->Name();
139 	}
140 
141 	Node*& GetLink(Node* value) const
142 	{
143 		return value->NameHashTableNext();
144 	}
145 };
146 
147 
148 struct NodeIDHashDefinition {
149 	typedef ino_t	KeyType;
150 	typedef	Node	ValueType;
151 
152 	size_t HashKey(ino_t key) const
153 	{
154 		return (uint64)(key >> 32) ^ (uint32)key;
155 	}
156 
157 	size_t Hash(const Node* value) const
158 	{
159 		return HashKey(value->ID());
160 	}
161 
162 	bool Compare(ino_t key, const Node* value) const
163 	{
164 		return value->ID() == key;
165 	}
166 
167 	Node*& GetLink(Node* value) const
168 	{
169 		return value->IDHashTableNext();
170 	}
171 };
172 
173 typedef DoublyLinkedList<Node> NodeList;
174 
175 typedef BOpenHashTable<NodeNameHashDefinition> NodeNameHashTable;
176 typedef BOpenHashTable<NodeIDHashDefinition> NodeIDHashTable;
177 
178 
179 #endif	// NODE_H
180