1 /* 2 * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef BOOT_LOADER_FILE_SYSTEMS_PACKAGEFS_PACKAGE_SETTINGS_ITEM_H 6 #define BOOT_LOADER_FILE_SYSTEMS_PACKAGEFS_PACKAGE_SETTINGS_ITEM_H 7 8 9 #include <string.h> 10 11 #include <util/OpenHashTable.h> 12 #include <util/StringHash.h> 13 14 15 struct driver_parameter; 16 class Directory; 17 18 19 namespace PackageFS { 20 21 22 class PackageSettingsItem { 23 public: 24 class Entry { 25 public: 26 Entry(Entry* parent) 27 : 28 fParent(parent), 29 fName(NULL), 30 fIsBlocked(false), 31 fHashNext(NULL) 32 { 33 } 34 35 ~Entry() 36 { 37 free(fName); 38 } 39 40 bool SetName(const char* name, size_t nameLength) 41 { 42 fName = (char*)malloc(nameLength + 1); 43 if (fName == NULL) 44 return false; 45 46 memcpy(fName, name, nameLength); 47 fName[nameLength] = '\0'; 48 return true; 49 } 50 51 Entry* Parent() const 52 { 53 return fParent; 54 } 55 56 const char* Name() const 57 { 58 return fName; 59 } 60 61 bool IsBlocked() const 62 { 63 return fIsBlocked; 64 } 65 66 void SetBlocked(bool blocked) 67 { 68 fIsBlocked = blocked; 69 } 70 71 Entry*& HashNext() 72 { 73 return fHashNext; 74 } 75 76 private: 77 Entry* fParent; 78 char* fName; 79 bool fIsBlocked; 80 Entry* fHashNext; 81 }; 82 83 class EntryKey { 84 public: 85 EntryKey(Entry* parent, const char* name, size_t nameLength) 86 : 87 fParent(parent), 88 fName(name), 89 fNameLength(nameLength) 90 { 91 } 92 93 EntryKey(Entry* parent, const char* name) 94 : 95 fParent(parent), 96 fName(name), 97 fNameLength(strlen(name)) 98 { 99 } 100 101 Entry* Parent() const 102 { 103 return fParent; 104 } 105 106 const char* Name() const 107 { 108 return fName; 109 } 110 111 size_t NameLength() const 112 { 113 return fNameLength; 114 } 115 116 size_t Hash() const 117 { 118 return (addr_t)fParent / 8 119 ^ hash_hash_string_part(fName, fNameLength); 120 } 121 122 private: 123 Entry* fParent; 124 const char* fName; 125 size_t fNameLength; 126 }; 127 128 public: 129 PackageSettingsItem(); 130 ~PackageSettingsItem(); 131 132 static PackageSettingsItem* Load(::Directory* systemDirectory, 133 const char* name); 134 135 status_t Init(const driver_parameter& parameter); 136 137 void AddEntry(Entry* entry); 138 status_t AddEntry(const char* path, Entry*& _entry); 139 Entry* FindEntry(Entry* parent, const char* name) 140 const; 141 Entry* FindEntry(Entry* parent, const char* name, 142 size_t nameLength) const; 143 144 PackageSettingsItem*& HashNext() 145 { return fHashNext; } 146 147 private: 148 struct EntryHashDefinition { 149 typedef EntryKey KeyType; 150 typedef Entry ValueType; 151 152 size_t HashKey(const EntryKey& key) const 153 { 154 return key.Hash(); 155 } 156 157 size_t Hash(const Entry* value) const 158 { 159 return HashKey(EntryKey(value->Parent(), value->Name())); 160 } 161 162 bool Compare(const EntryKey& key, const Entry* value) const 163 { 164 const char* name = value->Name(); 165 return key.Parent() == value->Parent() 166 && strncmp(key.Name(), name, key.NameLength()) == 0 167 && name[key.NameLength()] == '\0'; 168 } 169 170 Entry*& GetLink(Entry* value) const 171 { 172 return value->HashNext(); 173 } 174 }; 175 176 typedef BOpenHashTable<EntryHashDefinition> EntryTable; 177 178 private: 179 status_t _AddBlockedEntries( 180 const driver_parameter& parameter); 181 182 private: 183 EntryTable fEntries; 184 PackageSettingsItem* fHashNext; 185 }; 186 187 188 } // namespace PackageFS 189 190 191 #endif // BOOT_LOADER_FILE_SYSTEMS_PACKAGEFS_PACKAGE_SETTINGS_ITEM_H 192