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
13IndexDirectory::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
39IndexDirectory::~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
61status_t
62IndexDirectory::InitCheck() const
63{
64	return (fNameIndex && fLastModifiedIndex && fSizeIndex ? B_OK
65														   : B_NO_MEMORY);
66}
67
68// CreateIndex
69status_t
70IndexDirectory::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
130bool
131IndexDirectory::DeleteIndex(const char *name, uint32 type)
132{
133	return DeleteIndex(FindIndex(name, type));
134}
135
136// DeleteIndex
137bool
138IndexDirectory::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
153Index *
154IndexDirectory::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
168Index *
169IndexDirectory::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
178AttributeIndex *
179IndexDirectory::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
188AttributeIndex *
189IndexDirectory::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
198bool
199IndexDirectory::IsSpecialIndex(Index *index) const
200{
201	return (index == fNameIndex || index == fLastModifiedIndex
202			|| index == fSizeIndex);
203}
204
205