xref: /haiku/src/add-ons/kernel/file_systems/ramfs/IndexDirectory.cpp (revision 893988af824e65e49e55f517b157db8386e8002b)
1 // IndexDirectory.cpp
2 
3 #include <TypeConstants.h>
4 
5 #include "AttributeIndexImpl.h"
6 #include "Debug.h"
7 #include "IndexDirectory.h"
8 #include "LastModifiedIndex.h"
9 #include "NameIndex.h"
10 #include "SizeIndex.h"
11 
12 // constructor
13 IndexDirectory::IndexDirectory(Volume *volume)
14 	: fVolume(volume),
15 	  fNameIndex(NULL),
16 	  fLastModifiedIndex(NULL),
17 	  fSizeIndex(NULL),
18 	  fIndices()
19 {
20 	fNameIndex = new(nothrow) NameIndex(volume);
21 	fLastModifiedIndex = new(nothrow) LastModifiedIndex(volume);
22 	fSizeIndex = new(nothrow) SizeIndex(volume);
23 	if (fNameIndex && fLastModifiedIndex && fSizeIndex) {
24 		if (!fIndices.AddItem(fNameIndex)
25 			|| !fIndices.AddItem(fLastModifiedIndex)
26 			|| !fIndices.AddItem(fSizeIndex)) {
27 			fIndices.MakeEmpty();
28 			delete fNameIndex;
29 			delete fLastModifiedIndex;
30 			delete fSizeIndex;
31 			fNameIndex = NULL;
32 			fLastModifiedIndex = NULL;
33 			fSizeIndex = NULL;
34 		}
35 	}
36 }
37 
38 // destructor
39 IndexDirectory::~IndexDirectory()
40 {
41 	// delete the default indices
42 	if (fNameIndex) {
43 		fIndices.RemoveItem(fNameIndex);
44 		delete fNameIndex;
45 	}
46 	if (fLastModifiedIndex) {
47 		fIndices.RemoveItem(fLastModifiedIndex);
48 		delete fLastModifiedIndex;
49 	}
50 	if (fSizeIndex) {
51 		fIndices.RemoveItem(fSizeIndex);
52 		delete fSizeIndex;
53 	}
54 	// delete the attribute indices
55 	int32 count = fIndices.CountItems();
56 	for (int i = 0; i < count; i++)
57 		delete fIndices.ItemAt(i);
58 }
59 
60 // InitCheck
61 status_t
62 IndexDirectory::InitCheck() const
63 {
64 	return (fNameIndex && fLastModifiedIndex && fSizeIndex ? B_OK
65 														   : B_NO_MEMORY);
66 }
67 
68 // CreateIndex
69 status_t
70 IndexDirectory::CreateIndex(const char *name, uint32 type,
71 							AttributeIndex **_index)
72 {
73 	status_t error = (name ? B_OK : B_BAD_VALUE);
74 	if (error == B_OK) {
75 		if (!FindIndex(name)) {
76 			// create the index
77 			AttributeIndex *index = NULL;
78 			switch (type) {
79 				case B_INT32_TYPE:
80 					index = new(nothrow) AttributeIndexImpl(fVolume,
81 						name, type, sizeof(int32));
82 					break;
83 				case B_UINT32_TYPE:
84 					index = new(nothrow) AttributeIndexImpl(fVolume,
85 						name, type, sizeof(uint32));
86 					break;
87 				case B_INT64_TYPE:
88 					index = new(nothrow) AttributeIndexImpl(fVolume,
89 						name, type, sizeof(int64));
90 					break;
91 				case B_UINT64_TYPE:
92 					index = new(nothrow) AttributeIndexImpl(fVolume,
93 						name, type, sizeof(uint64));
94 					break;
95 				case B_FLOAT_TYPE:
96 					index = new(nothrow) AttributeIndexImpl(fVolume,
97 						name, type, sizeof(float));
98 					break;
99 				case B_DOUBLE_TYPE:
100 					index = new(nothrow) AttributeIndexImpl(fVolume,
101 						name, type, sizeof(double));
102 					break;
103 				case B_STRING_TYPE:
104 					index = new(nothrow) AttributeIndexImpl(fVolume,
105 						name, type, 0);
106 					break;
107 				default:
108 					error = B_BAD_VALUE;
109 					break;
110 			}
111 			if (error == B_OK && !index)
112 				error = B_NO_MEMORY;
113 			// add the index
114 			if (error == B_OK) {
115 				if (fIndices.AddItem(index)) {
116 					if (_index)
117 						*_index = index;
118 				} else {
119 					delete index;
120 					error = B_NO_MEMORY;
121 				}
122 			}
123 		} else
124 			error = B_FILE_EXISTS;
125 	}
126 	return error;
127 }
128 
129 // DeleteIndex
130 bool
131 IndexDirectory::DeleteIndex(const char *name, uint32 type)
132 {
133 	return DeleteIndex(FindIndex(name, type));
134 }
135 
136 // DeleteIndex
137 bool
138 IndexDirectory::DeleteIndex(Index *index)
139 {
140 	bool result = false;
141 	if (index && !IsSpecialIndex(index)) {
142 		int32 i = fIndices.IndexOf(index);
143 		if (i >= 0) {
144 			fIndices.RemoveItem(i);
145 			delete index;
146 			result = true;
147 		}
148 	}
149 	return result;
150 }
151 
152 // FindIndex
153 Index *
154 IndexDirectory::FindIndex(const char *name)
155 {
156 	if (name) {
157 		int32 count = fIndices.CountItems();
158 		for (int32 i = 0; i < count; i++) {
159 			Index *index = fIndices.ItemAt(i);
160 			if (!strcmp(index->GetName(), name))
161 				return index;
162 		}
163 	}
164 	return NULL;
165 }
166 
167 // FindIndex
168 Index *
169 IndexDirectory::FindIndex(const char *name, uint32 type)
170 {
171 	Index *index = FindIndex(name);
172 	if (index && index->GetType() != type)
173 		index = NULL;
174 	return index;
175 }
176 
177 // FindAttributeIndex
178 AttributeIndex *
179 IndexDirectory::FindAttributeIndex(const char *name)
180 {
181 	AttributeIndex *attrIndex = NULL;
182 	if (Index *index = FindIndex(name))
183 		attrIndex = dynamic_cast<AttributeIndex*>(index);
184 	return attrIndex;
185 }
186 
187 // FindAttributeIndex
188 AttributeIndex *
189 IndexDirectory::FindAttributeIndex(const char *name, uint32 type)
190 {
191 	AttributeIndex *attrIndex = NULL;
192 	if (Index *index = FindIndex(name, type))
193 		attrIndex = dynamic_cast<AttributeIndex*>(index);
194 	return attrIndex;
195 }
196 
197 // IsSpecialIndex
198 bool
199 IndexDirectory::IsSpecialIndex(Index *index) const
200 {
201 	return (index == fNameIndex || index == fLastModifiedIndex
202 			|| index == fSizeIndex);
203 }
204 
205