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;
GetParentUnchecked()46 Directory* GetParentUnchecked() const { return fParent; }
47
ID()48 ino_t ID() const { return fID; }
Name()49 const String& Name() const { return fName; }
50
NameHashTableNext()51 Node*& NameHashTableNext()
52 { return fNameHashTableNext; }
IDHashTableNext()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
IsKnownToVFS()106 Node::IsKnownToVFS() const
107 {
108 return (fFlags & NODE_FLAG_KNOWN_TO_VFS) != 0;
109 }
110
111
112 bool
HasVFSInitError()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
HashKeyNodeNameHashDefinition126 size_t HashKey(const StringKey& key) const
127 {
128 return key.Hash();
129 }
130
HashNodeNameHashDefinition131 size_t Hash(const Node* value) const
132 {
133 return value->Name().Hash();
134 }
135
CompareNodeNameHashDefinition136 bool Compare(const StringKey& key, const Node* value) const
137 {
138 return key == value->Name();
139 }
140
GetLinkNodeNameHashDefinition141 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
HashKeyNodeIDHashDefinition152 size_t HashKey(ino_t key) const
153 {
154 return (uint64)(key >> 32) ^ (uint32)key;
155 }
156
HashNodeIDHashDefinition157 size_t Hash(const Node* value) const
158 {
159 return HashKey(value->ID());
160 }
161
CompareNodeIDHashDefinition162 bool Compare(ino_t key, const Node* value) const
163 {
164 return value->ID() == key;
165 }
166
GetLinkNodeIDHashDefinition167 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