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