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