xref: /haiku/src/kits/storage/ResourcesContainer.cpp (revision 4c8e85b316c35a9161f5a1c50ad70bc91c83a76f)
1 //----------------------------------------------------------------------
2 //  This software is part of the Haiku distribution and is covered
3 //  by the MIT License.
4 //---------------------------------------------------------------------
5 /*!
6 	\file ResourcesContainer.cpp
7 	ResourcesContainer implementation.
8 */
9 
10 #include <stdio.h>
11 
12 #include "ResourcesContainer.h"
13 
14 #include "ResourceItem.h"
15 
16 namespace BPrivate {
17 namespace Storage {
18 
19 // constructor
20 ResourcesContainer::ResourcesContainer()
21 				  : fResources(),
22 					fIsModified(false)
23 {
24 }
25 
26 // destructor
27 ResourcesContainer::~ResourcesContainer()
28 {
29 	MakeEmpty();
30 }
31 
32 // AddResource
33 //
34 // Returns false, if item is NULL or memory is insufficient, true otherwise.
35 bool
36 ResourcesContainer::AddResource(ResourceItem *item, int32 index,
37 								bool replace)
38 {
39 	bool result = false;
40 	if (item) {
41 		// replace an item with the same type and id
42 		if (replace)
43 			delete RemoveResource(IndexOf(item->Type(), item->ID()));
44 		int32 count = CountResources();
45 		if (index < 0 || index > count)
46 			index = count;
47 		result = fResources.AddItem(item, index);
48 		SetModified(true);
49 	}
50 	return result;
51 }
52 
53 // RemoveResource
54 ResourceItem*
55 ResourcesContainer::RemoveResource(int32 index)
56 {
57 	ResourceItem* item = (ResourceItem*)fResources.RemoveItem(index);
58 	if (item)
59 		SetModified(true);
60 	return item;
61 }
62 
63 // RemoveResource
64 bool
65 ResourcesContainer::RemoveResource(ResourceItem *item)
66 {
67 	return RemoveResource(IndexOf(item));
68 }
69 
70 // MakeEmpty
71 void
72 ResourcesContainer::MakeEmpty()
73 {
74 	for (int32 i = 0; ResourceItem *item = ResourceAt(i); i++)
75 		delete item;
76 	fResources.MakeEmpty();
77 	SetModified(false);
78 }
79 
80 // AssimilateResources
81 void
82 ResourcesContainer::AssimilateResources(ResourcesContainer &container)
83 {
84 	// Resistance is futile! ;-)
85 	int32 newCount = container.CountResources();
86 	for (int32 i = 0; i < newCount; i++) {
87 		ResourceItem *item = container.ResourceAt(i);
88 		if (item->IsLoaded())
89 			AddResource(item);
90 		else {
91 			// That should not happen.
92 			// Delete the item to have a consistent behavior.
93 			delete item;
94 		}
95 	}
96 	container.fResources.MakeEmpty();
97 	container.SetModified(true);
98 	SetModified(true);
99 }
100 
101 // IndexOf
102 int32
103 ResourcesContainer::IndexOf(ResourceItem *item) const
104 {
105 	return fResources.IndexOf(item);
106 }
107 
108 // IndexOf
109 int32
110 ResourcesContainer::IndexOf(const void *data) const
111 {
112 	int32 index = -1;
113 	if (data) {
114 		int32 count = CountResources();
115 		for (int32 i = 0; index == -1 && i < count; i++) {
116 			if (ResourceAt(i)->Data() == data)
117 				index = i;
118 		}
119 	}
120 	return index;
121 }
122 
123 // IndexOf
124 int32
125 ResourcesContainer::IndexOf(type_code type, int32 id) const
126 {
127 	int32 index = -1;
128 	int32 count = CountResources();
129 	for (int32 i = 0; index == -1 && i < count; i++) {
130 		ResourceItem *item = ResourceAt(i);
131 		if (item->Type() == type && item->ID() == id)
132 			index = i;
133 	}
134 	return index;
135 }
136 
137 // IndexOf
138 int32
139 ResourcesContainer::IndexOf(type_code type, const char *name) const
140 {
141 	int32 index = -1;
142 	int32 count = CountResources();
143 	for (int32 i = 0; index == -1 && i < count; i++) {
144 		ResourceItem *item = ResourceAt(i);
145 		const char *itemName = item->Name();
146 		if (item->Type() == type && ((name == NULL && itemName == NULL)
147 									 || (name != NULL && itemName != NULL
148 										&& strcmp(name, itemName) == 0))) {
149 			index = i;
150 		}
151 	}
152 	return index;
153 }
154 
155 // IndexOfType
156 int32
157 ResourcesContainer::IndexOfType(type_code type, int32 typeIndex) const
158 {
159 	int32 index = -1;
160 	int32 count = CountResources();
161 	for (int32 i = 0; index == -1 && i < count; i++) {
162 		ResourceItem *item = ResourceAt(i);
163 		if (item->Type() == type) {
164 			if (typeIndex == 0)
165 				index = i;
166 			typeIndex--;
167 		}
168 	}
169 	return index;
170 }
171 
172 // ResourceAt
173 ResourceItem*
174 ResourcesContainer::ResourceAt(int32 index) const
175 {
176 	return (ResourceItem*)fResources.ItemAt(index);
177 }
178 
179 // CountResources
180 int32
181 ResourcesContainer::CountResources() const
182 {
183 	return fResources.CountItems();
184 }
185 
186 // SetModified
187 void
188 ResourcesContainer::SetModified(bool modified)
189 {
190 	fIsModified = modified;
191 	// If unmodified, set the resource item's modified flag as well.
192 	if (!modified) {
193 		int32 count = CountResources();
194 		for (int32 i = 0; i < count; i++)
195 			ResourceAt(i)->SetModified(false);
196 	}
197 }
198 
199 // IsModified
200 bool
201 ResourcesContainer::IsModified() const
202 {
203 	bool isModified = fIsModified;
204 	int32 count = CountResources();
205 	for (int32 i = 0; !isModified && i < count; i++)
206 		isModified |= ResourceAt(i)->IsModified();
207 	return isModified;
208 }
209 
210 
211 };	// namespace Storage
212 };	// namespace BPrivate
213 
214 
215 
216 
217