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