1/*
2 * Copyright 1999-2009 Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Jeremy Friesner
7 */
8
9
10#include "BitFieldTesters.h"
11
12
13#include <stdio.h>
14
15#define NOTE "NotFieldTester : "
16#define MINI "MinMatchFieldTester : "
17
18BitFieldTester::BitFieldTester()
19{
20	// empty
21}
22
23
24BitFieldTester::BitFieldTester(BMessage* from)
25	:
26	BArchivable(from)
27{
28	// empty
29}
30
31
32status_t
33BitFieldTester::Archive(BMessage* into, bool deep) const
34{
35	return BArchivable::Archive(into, deep);
36}
37
38
39// ---------------- ConstantFieldTester starts -------------------------------
40ConstantFieldTester::ConstantFieldTester(bool result)
41	:
42	fResult(result)
43{
44	// empty
45}
46
47
48ConstantFieldTester::ConstantFieldTester(BMessage* from)
49	:
50	BitFieldTester(from)
51{
52	if (from->FindBool("ctRes", &fResult) != B_NO_ERROR)
53		printf("ConstantFieldTester: Error, no ctRes!\n");
54}
55
56
57status_t
58ConstantFieldTester::Archive(BMessage* into, bool deep) const
59{
60	status_t ret = BitFieldTester::Archive(into, deep);
61	into->AddBool("ctRes", fResult);
62	return ret;
63}
64
65
66BArchivable*
67ConstantFieldTester::Instantiate(BMessage* from)
68{
69	if (validate_instantiation(from, "ConstantFieldTester"))
70		return new ConstantFieldTester(from);
71	else
72		return NULL;
73}
74
75
76bool
77ConstantFieldTester::IsMatching(uint32 field)
78{
79	return fResult;
80}
81
82
83// ---------------- HasBitsFieldTester starts -------------------------------
84HasBitsFieldTester::HasBitsFieldTester(uint32 requiredBits,
85	uint32 forbiddenBits)
86	:
87	fRequiredBits(requiredBits),
88	fForbiddenBits(forbiddenBits)
89{
90	// empty
91}
92
93
94HasBitsFieldTester::HasBitsFieldTester(BMessage* from)
95	:
96	BitFieldTester(from)
97{
98	if (from->FindInt32("rqBits", (int32*) &fRequiredBits) != B_NO_ERROR)
99		printf("HasBitsFieldTester: Error, no rqBits!\n");
100
101	if (from->FindInt32("fbBits", (int32*) &fForbiddenBits) != B_NO_ERROR)
102		printf("HasBitsFieldTester: Error, no fbBits!\n");
103}
104
105
106status_t
107HasBitsFieldTester::Archive(BMessage* into, bool deep) const
108{
109	status_t ret = BitFieldTester::Archive(into, deep);
110	into->AddInt32("rqBits", fRequiredBits);
111	into->AddInt32("fbBits", fForbiddenBits);
112	return ret;
113}
114
115
116BArchivable*
117HasBitsFieldTester::Instantiate(BMessage* from)
118{
119	if (validate_instantiation(from, "HasBitsFieldTester"))
120		return new HasBitsFieldTester(from);
121	else
122		return NULL;
123}
124
125
126bool
127HasBitsFieldTester::IsMatching(uint32 field)
128{
129	return ((((fRequiredBits & (~field)) == 0))
130				&& ((fForbiddenBits & (~field)) == fForbiddenBits));
131}
132
133
134// ---------------- NotFieldTester starts -------------------------------
135NotFieldTester::NotFieldTester(BitFieldTester* slave)
136	:
137	fSlave(slave)
138{
139	// empty
140}
141
142
143NotFieldTester::~NotFieldTester()
144{
145	delete fSlave;
146}
147
148
149NotFieldTester::NotFieldTester(BMessage* from)
150	:
151	BitFieldTester(from),
152	fSlave(NULL)
153{
154	BMessage slaveMsg;
155	if (from->FindMessage("nSlave", &slaveMsg) == B_NO_ERROR) {
156		BArchivable* slaveObj = instantiate_object(&slaveMsg);
157		if (slaveObj) {
158			fSlave = dynamic_cast<BitFieldTester*>(slaveObj);
159			if (fSlave == NULL) {
160				printf(NOTE "Error casting slaveObj to BitFieldTester!\n");
161				delete slaveObj;
162			}
163		} else
164			printf(NOTE "instantiate_object returned NULL!\n");
165	} else
166		printf(NOTE "Couldn't unarchive NotFieldTester slave!\n");
167}
168
169
170status_t
171NotFieldTester::Archive(BMessage* into, bool deep) const
172{
173	if (fSlave == NULL)
174		return B_ERROR;
175
176	status_t ret = BitFieldTester::Archive(into, deep);
177
178	if (ret == B_NO_ERROR) {
179		BMessage msg;
180		ret = fSlave->Archive(&msg, deep);
181		into->AddMessage("nSlave", &msg);
182	}
183
184	return ret;
185}
186
187
188BArchivable*
189NotFieldTester::Instantiate(BMessage* from)
190{
191	if (validate_instantiation(from, "NotFieldTester"))
192		return new NotFieldTester(from);
193	else
194		return NULL;
195}
196
197
198bool
199NotFieldTester::IsMatching(uint32 field)
200{
201	return fSlave ? (!fSlave->IsMatching(field)) : false;
202}
203
204
205// ---------------- MinMatchFieldTester starts -------------------------------
206MinMatchFieldTester::MinMatchFieldTester(int minNum, bool deleteSlaves)
207	:
208	fMinNum(minNum),
209	fDeleteSlaves(deleteSlaves) // fDeleteSlaves state not archived!
210{
211	// empty
212}
213
214
215MinMatchFieldTester::~MinMatchFieldTester()
216{
217	if (fDeleteSlaves) {
218		int nr = fSlaves.CountItems();
219		for (int i = 0; i < nr; i++)
220			delete ((BitFieldTester*) fSlaves.ItemAt(i));
221	}
222}
223
224
225MinMatchFieldTester::MinMatchFieldTester(BMessage* from)
226	:
227	BitFieldTester(from),
228	fDeleteSlaves(true)
229{
230	int i = 0;
231	BMessage slaveMsg;
232	while (from->FindMessage("mSlave", i++, &slaveMsg) == B_NO_ERROR) {
233		BArchivable* slaveObj = instantiate_object(&slaveMsg);
234		if (slaveObj) {
235			BitFieldTester* nextSlave = dynamic_cast<BitFieldTester*>(slaveObj);
236			if (nextSlave)
237				fSlaves.AddItem(nextSlave);
238			else {
239				printf(MINI "Error casting slaveObj to BitFieldTester!\n");
240				delete slaveObj;
241			}
242		} else
243			printf(MINI "instantiate_object returned NULL!\n");
244	}
245
246	if (from->FindInt32("mMin", (int32*) &fMinNum) != B_NO_ERROR)
247		printf(MINI "Error getting mMin!\n");
248}
249
250
251// (slave) should be allocated with new, becomes property of this object.
252void
253MinMatchFieldTester::AddSlave(const BitFieldTester* slave)
254{
255	fSlaves.AddItem((void*) slave);
256}
257
258
259status_t
260MinMatchFieldTester::Archive(BMessage* into, bool deep) const
261{
262	status_t ret = BitFieldTester::Archive(into, deep);
263
264	if (ret == B_NO_ERROR) {
265		int nr = fSlaves.CountItems();
266		for (int i = 0; i < nr; i++) {
267			BMessage msg;
268			ret = ((BitFieldTester*)fSlaves.ItemAt(i))->Archive(&msg, deep);
269			if (ret != B_NO_ERROR)
270				return ret;
271
272			into->AddMessage("mSlave", &msg);
273		}
274	}
275
276	into->AddInt32("mMin", fMinNum);
277	return ret;
278}
279
280
281BArchivable*
282MinMatchFieldTester::Instantiate(BMessage* from)
283{
284	if (validate_instantiation(from, "MinMatchFieldTester"))
285		return new MinMatchFieldTester(from);
286	else
287		return NULL;
288}
289
290
291// Returns true if at least (fMinNum) slaves return true.
292bool
293MinMatchFieldTester::IsMatching(uint32 field)
294{
295	int nr = fSlaves.CountItems();
296	if ((fMinNum == 0) && (nr == 0))
297		return true; // 0 >= 0, so this should return true!
298
299	int count = 0;
300
301	for (int i = 0; i < nr; i++)
302		if ((((BitFieldTester*)fSlaves.ItemAt(i))->IsMatching(field))
303				&& (++count >= fMinNum))
304			return true;
305	return false;
306}
307