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
15struct driver_parameter;
16class Directory;
17
18
19namespace PackageFS {
20
21
22class PackageSettingsItem {
23public:
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
128public:
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
147private:
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
178private:
179			status_t			_AddBlockedEntries(
180									const driver_parameter& parameter);
181
182private:
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