]> git.saurik.com Git - apple/xnu.git/blob - iokit/Tests/TestCollections.cpp
xnu-344.2.tar.gz
[apple/xnu.git] / iokit / Tests / TestCollections.cpp
1 /*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 #if DEBUG
23 #include "Tests.h"
24
25 #include <libkern/c++/OSArray.h>
26 #include <libkern/c++/OSSet.h>
27 #include <libkern/c++/OSDictionary.h>
28 #include <libkern/c++/OSString.h>
29 #include <libkern/c++/OSSymbol.h>
30 #include <libkern/c++/OSCollectionIterator.h>
31
32 void testArray()
33 {
34 bool res = true;
35 void *spaceCheck, *spaceCheck2 , *spaceCheck3;
36 int i, j, count, count2;
37 OSObject *cache[numStrCache], *str, *sym;
38 OSArray *array1, *array2;
39
40 // Do first test without memory leak tests to initialise the metaclass
41 array1 = OSArray::withCapacity(1);
42 TEST_ASSERT('A', "0a", array1);
43 if (array1)
44 array1->release();
45
46 // Grow the symbol pool to maximum
47 for (i = 0; i < numStrCache; i++)
48 cache[i] = (OSObject *) OSSymbol::withCStringNoCopy(strCache[i]);
49 for (i = 0; i < numStrCache; i++)
50 cache[i]->release();
51
52 // Create and destroy an array
53 spaceCheck = checkPointSpace();
54 array1 = OSArray::withCapacity(1);
55 TEST_ASSERT('A', "1a", array1);
56 if (array1) {
57 TEST_ASSERT('A', "1b", !array1->getCount());
58 TEST_ASSERT('A', "1c", 1 == array1->getCapacity());
59 TEST_ASSERT('A', "1d", 1 == array1->getCapacityIncrement());
60 TEST_ASSERT('A', "1e", 4 == array1->setCapacityIncrement(4));
61 TEST_ASSERT('A', "1f", 4 == array1->getCapacityIncrement());
62 TEST_ASSERT('A', "1g", 8 == array1->ensureCapacity(5));
63
64 spaceCheck2 = checkPointSpace();
65 cache[0] = IOString::withCStringNoCopy(strCache[0]);
66
67 spaceCheck3 = checkPointSpace();
68 TEST_ASSERT('A', "1h", array1->setObject(cache[0]));
69 TEST_ASSERT('A', "1i", cache[0] == array1->getObject(0));
70 cache[0]->release();
71 res = res && checkSpace("(A)1j", spaceCheck3, 0);
72
73 TEST_ASSERT('A', "1k", 1 == array1->getCount());
74 array1->flushCollection();
75 TEST_ASSERT('A', "1l", !array1->getCount());
76 res = res && checkSpace("(A)1m", spaceCheck2, 0);
77
78 array1->release();
79 }
80 res = res && checkSpace("(A)1", spaceCheck, 0);
81
82 // Check the creation of a sizable OSArray from an array of IOObjects
83 // Also check indexing into the array.
84 spaceCheck = checkPointSpace();
85 for (i = 0; i < numStrCache; i++)
86 cache[i] = OSString::withCStringNoCopy(strCache[i]);
87 array1 = OSArray::withObjects(cache, numStrCache, numStrCache);
88 TEST_ASSERT('A', "2a", array1);
89 for (i = 0; i < numStrCache; i++)
90 cache[i]->release();
91 if (array1) {
92 TEST_ASSERT('A', "2b", numStrCache == (int) array1->getCount());
93 TEST_ASSERT('A', "2c", numStrCache == (int) array1->getCapacity());
94 TEST_ASSERT('A', "2d",
95 numStrCache == (int) array1->getCapacityIncrement());
96
97 for (i = 0; (str = array1->getObject(i)); i++) {
98 if (str != cache[i]) {
99 verPrintf(("testArray(A) test 2e%d failed\n", i));
100 res = false;
101 }
102 }
103 TEST_ASSERT('A', "2f", numStrCache == i);
104 array1->release();
105 }
106 res = res && checkSpace("(A)2", spaceCheck, 0);
107
108 // Test array creation from another array by both the setObject method
109 // and the withArray factory. And test __takeObject code first
110 // with tail removal then with head removal
111 spaceCheck = checkPointSpace();
112 for (i = 0; i < numStrCache; i++)
113 cache[i] = OSString::withCStringNoCopy(strCache[i]);
114 array1 = OSArray::withObjects(cache, numStrCache, numStrCache);
115 TEST_ASSERT('A', "3a", array1);
116 for (i = 0; i < numStrCache; i++)
117 cache[i]->release();
118 array2 = 0;
119 if (array1) {
120 array2 = OSArray::withCapacity(1);
121 TEST_ASSERT('A', "3b", array2);
122 TEST_ASSERT('A', "3c", !array2->getCount());
123 TEST_ASSERT('A', "3d", array2->setObject(array1));
124 TEST_ASSERT('A', "3e", array1->getCount() == array2->getCount());
125 }
126 if (array2) {
127 count = 0;
128 TEST_ASSERT('A', "3f", numStrCache == (int) array2->getCount());
129 for (i = array2->getCount(); (str = array2->__takeObject(--i)); ) {
130 if (str != cache[i]) {
131 verPrintf(("testArray(A) test 3g%d failed\n", i));
132 res = false;
133 }
134 count += ((int) array2->getCount() == i);
135 str->release();
136 }
137 TEST_ASSERT('A', "3h", count == numStrCache);
138 TEST_ASSERT('A', "3i", -1 == i);
139 TEST_ASSERT('A', "3j", !array2->getCount());
140
141 spaceCheck2 = checkPointSpace();
142 array2->flushCollection();
143 res = res && checkSpace("(A)3k", spaceCheck2, 0);
144
145 array2->release();
146 array2 = 0;
147 }
148 if (array1) {
149 array2 = OSArray::withArray(array1, numStrCache - 1);
150 TEST_ASSERT('A', "3l", !array2);
151 array2 = OSArray::withArray(array1, array1->getCount());
152 TEST_ASSERT('A', "3m", array2);
153 array1->release();
154 }
155 if (array2) {
156 count = 0;
157 TEST_ASSERT('A', "3o", numStrCache == (int) array2->getCount());
158 for (i = 0; (str = array2->__takeObject(0)); i++) {
159 count += (str == cache[i]);
160 str->release();
161 }
162 TEST_ASSERT('A', "3p", count == numStrCache);
163 TEST_ASSERT('A', "3q", !array2->getCount());
164 array2->release();
165 array2 = 0;
166 }
167 res = res && checkSpace("(A)3", spaceCheck, 0);
168
169 // Test object replacement from one array to another
170 spaceCheck = checkPointSpace();
171 array1 = OSArray::withCapacity(numStrCache);
172 TEST_ASSERT('A', "4a", array1);
173 if (array1) {
174 count = count2 = 0;
175 for (i = 0; i < numStrCache; i++) {
176 str = OSString::withCStringNoCopy(strCache[i]);
177 count += array1->setObject(str);
178 count2 += (str == array1->lastObject());
179 str->release();
180 }
181 TEST_ASSERT('A', "4b", numStrCache == (int) array1->getCount());
182 TEST_ASSERT('A', "4c", count == numStrCache);
183 TEST_ASSERT('A', "4d", count2 == numStrCache);
184 }
185 array2 = OSArray::withCapacity(1);
186 TEST_ASSERT('A', "4e", array2);
187 if (array2) {
188 count = count2 = 0;
189 str = (OSObject *) OSSymbol::withCStringNoCopy(strCache[0]);
190 for (i = 0; i < numStrCache; i++) {
191 sym = (OSObject *) OSSymbol::withCStringNoCopy(strCache[i]);
192 count += array2->setObject(sym, 0);
193 count2 += (str == array2->lastObject());
194 sym->release();
195 }
196 str->release();
197 TEST_ASSERT('A', "4f", numStrCache == (int) array2->getCount());
198 TEST_ASSERT('A', "4g", count == numStrCache);
199 TEST_ASSERT('A', "4h", count2 == numStrCache);
200 }
201 if (array1 && array2) {
202
203 count = count2 = 0;
204 for (i = array1->getCount() - 1; (sym = array2->__takeObject(0)); i--) {
205 str = array1->replaceObject(sym, i);
206 count += (str != 0);
207 count2 += (sym != str);
208 if (str)
209 str->release();
210 if (sym)
211 sym->release();
212 }
213 TEST_ASSERT('A', "4k", numStrCache == (int) array1->getCount());
214 TEST_ASSERT('A', "4l", count == numStrCache);
215 TEST_ASSERT('A', "4m", count2 == numStrCache);
216 array1->release();
217 array2->release();
218 }
219 else {
220 if (array1) array1->release();
221 if (array2) array2->release();
222 }
223 res = res && checkSpace("(A)4", spaceCheck, 0);
224
225 // Test array duplicate removal
226 spaceCheck = checkPointSpace();
227 array1 = OSArray::withCapacity(numStrCache);
228 TEST_ASSERT('A', "5a", array1);
229 if (array1) {
230 for (i = 0; i < numStrCache; i++) {
231 sym = (OSObject *) OSSymbol::withCStringNoCopy(strCache[i]);
232 count += array1->setObject(sym);
233 sym->release();
234 }
235 TEST_ASSERT('A', "5b", numStrCache == (int) array1->getCount());
236
237 // remove duplicates
238 for (i = 0; (sym = array1->getObject(i)); )
239 if (sym->getRetainCount() == 1)
240 i++;
241 else {
242 //sym = array1->__takeObject(i);
243 //sym->release();
244 array1->removeObject(i);
245 }
246 TEST_ASSERT('A', "5c", numStrCache != (int) array1->getCount());
247
248 // check to see that all symbols are really there
249 for (count = 0, i = 0; i < numStrCache; i++) {
250 sym = (OSObject *) OSSymbol::withCStringNoCopy(strCache[i]);
251 for (count2 = false, j = 0; (str = array1->getObject(j)); j++)
252 if (str == sym) {
253 count2 = true;
254 break;
255 }
256 count += count2;
257 sym->release();
258 }
259 TEST_ASSERT('A', "5c", count == numStrCache);
260 array1->release();
261 }
262 res = res && checkSpace("(S)5", spaceCheck, 0);
263
264 if (res)
265 verPrintf(("testArray: All OSArray Tests passed\n"));
266 else
267 logPrintf(("testArray: Some OSArray Tests failed\n"));
268 }
269
270 void testSet()
271 {
272 bool res = true;
273 void *spaceCheck, *spaceCheck2 , *spaceCheck3;
274 int i, count, count2;
275 OSObject *cache[numStrCache], *str, *sym;
276 OSSet *set1, *set2;
277 OSArray *array;
278
279 // Do first test without memory leak tests to initialise the metaclass
280 set1 = OSSet::withCapacity(1);
281 TEST_ASSERT('S', "0a", set1);
282 if (set1)
283 set1->release();
284
285 // Grow the symbol pool to maximum
286 for (i = 0; i < numStrCache; i++)
287 cache[i] = (OSObject *) OSSymbol::withCStringNoCopy(strCache[i]);
288 for (i = 0; i < numStrCache; i++)
289 cache[i]->release();
290
291 // Create and destroy an set
292 spaceCheck = checkPointSpace();
293 set1 = OSSet::withCapacity(1);
294 TEST_ASSERT('S', "1a", set1);
295 if (set1) {
296 TEST_ASSERT('S', "1b", !set1->getCount());
297 TEST_ASSERT('S', "1c", 1 == set1->getCapacity());
298 TEST_ASSERT('S', "1d", 1 == set1->getCapacityIncrement());
299 TEST_ASSERT('S', "1e", 4 == set1->setCapacityIncrement(4));
300 TEST_ASSERT('S', "1f", 4 == set1->getCapacityIncrement());
301 TEST_ASSERT('S', "1g", 8 == set1->ensureCapacity(5));
302
303 spaceCheck2 = checkPointSpace();
304 cache[0] = IOString::withCStringNoCopy(strCache[0]);
305
306 spaceCheck3 = checkPointSpace();
307 TEST_ASSERT('S', "1h", set1->setObject(cache[0]));
308 TEST_ASSERT('S', "1i", set1->containsObject(cache[0]));
309 TEST_ASSERT('S', "1j", cache[0] == set1->getAnyObject());
310 cache[0]->release();
311 res = res && checkSpace("(S)1k", spaceCheck3, 0);
312
313 TEST_ASSERT('S', "1l", 1 == set1->getCount());
314 set1->flushCollection();
315 TEST_ASSERT('S', "1m", !set1->getCount());
316 res = res && checkSpace("(S)1n", spaceCheck2, 0);
317
318 set1->release();
319 }
320 res = res && checkSpace("(S)1", spaceCheck, 0);
321
322 // Check the creation of a sizable OSSet from an set of IOObjects
323 // Also check member test of set.
324 spaceCheck = checkPointSpace();
325 for (i = 0; i < numStrCache; i++)
326 cache[i] = OSString::withCStringNoCopy(strCache[i]);
327 set1 = OSSet::withObjects(cache, numStrCache, numStrCache);
328 TEST_ASSERT('S', "2a", set1);
329 for (i = 0; i < numStrCache; i++)
330 cache[i]->release();
331 if (set1) {
332 TEST_ASSERT('S', "2b", numStrCache == (int) set1->getCount());
333 TEST_ASSERT('S', "2c", numStrCache == (int) set1->getCapacity());
334 TEST_ASSERT('S', "2d",
335 numStrCache == (int) set1->getCapacityIncrement());
336
337 count = 0;
338 for (i = set1->getCount(); --i >= 0; )
339 count += set1->member(cache[i]);
340
341 TEST_ASSERT('S', "2e", numStrCache == count);
342 set1->release();
343 }
344 res = res && checkSpace("(S)2", spaceCheck, 0);
345
346 // Test set creation from another set by both the setObject method
347 // and the withArray factory. And test __takeObject code first
348 // with tail removal then with head removal
349 spaceCheck = checkPointSpace();
350 for (i = 0; i < numStrCache; i++)
351 cache[i] = OSString::withCStringNoCopy(strCache[i]);
352 set1 = OSSet::withObjects(cache, numStrCache, numStrCache);
353 TEST_ASSERT('S', "3a", set1);
354 for (i = 0; i < numStrCache; i++)
355 cache[i]->release();
356 set2 = 0;
357 if (set1) {
358 set2 = OSSet::withCapacity(set1->getCount());
359 TEST_ASSERT('S', "3b", set2);
360 TEST_ASSERT('S', "3c", !set2->getCount());
361 TEST_ASSERT('S', "3d", set2->setObject(set1));
362 TEST_ASSERT('S', "3e", set1->getCount() == set2->getCount());
363 }
364 if (set2) {
365 TEST_ASSERT('S', "3f", numStrCache == (int) set2->getCount());
366 count = count2 = 0;
367 while ( (str = set2->getAnyObject()) ) {
368 count += set2->__takeObject(str);
369 count2 += set1->member(str);
370 str->release();
371 }
372 TEST_ASSERT('S', "3g", !set2->getCount());
373 TEST_ASSERT('S', "3h", numStrCache == count);
374 TEST_ASSERT('S', "3i", numStrCache == count2);
375
376 spaceCheck2 = checkPointSpace();
377 set2->flushCollection();
378 res = res && checkSpace("(S)3j", spaceCheck2, 0);
379
380 set2->release();
381 set2 = 0;
382 }
383 if (set1) {
384 set2 = OSSet::withSet(set1, numStrCache - 1);
385 TEST_ASSERT('S', "3k", !set2);
386 set2 = OSSet::withSet(set1, set1->getCount());
387 TEST_ASSERT('S', "3l", set2);
388 set1->release();
389 }
390 if (set2) {
391 TEST_ASSERT('S', "3m", numStrCache == (int) set2->getCount());
392 i = count = count2 = 0;
393 while ( (str = set2->getAnyObject()) ) {
394 count += set2->__takeObject(str);
395 count2 += (cache[i++] == str);
396 str->release();
397 }
398 TEST_ASSERT('S', "3n", !set2->getCount());
399 TEST_ASSERT('S', "3o", numStrCache == count);
400 TEST_ASSERT('S', "3p", numStrCache == count2);
401
402 set2->release();
403 set2 = 0;
404 }
405 res = res && checkSpace("(S)3", spaceCheck, 0);
406
407 // Test duplicate removal
408 spaceCheck = checkPointSpace();
409 set2 = 0;
410 set1 = OSSet::withCapacity(numStrCache);
411 TEST_ASSERT('S', "4a", set1);
412 if (set1) {
413 count = 0;
414 for (i = 0; i < numStrCache; i++) {
415 sym = (OSObject *) OSSymbol::withCStringNoCopy(strCache[i]);
416 count += set1->setObject(sym);
417 sym->release();
418 }
419 TEST_ASSERT('S', "4b", numStrCache != (int) set1->getCount());
420 TEST_ASSERT('S', "4c", count == (int) set1->getCount());
421
422 count = count2 = 0;
423 for (i = 0; i < numStrCache; i++) {
424 sym = (OSObject *) OSSymbol::withCStringNoCopy(strCache[i]);
425 count += set1->member(sym);
426 count2 += sym->getRetainCount();
427 sym->release();
428 }
429 TEST_ASSERT('S', "4d", count == numStrCache);
430 TEST_ASSERT('S', "4e", count2 == numStrCache * 2);
431
432 set2 = OSSet::withSet(set1, 2 * set1->getCount());
433 }
434 TEST_ASSERT('S', "4f", set2);
435 if (set2) {
436 set2->setObject(set1);
437 TEST_ASSERT('S', "4g", set1->getCount() == set2->getCount());
438 set1->release();
439 set2->release();
440 }
441 res = res && checkSpace("(S)4", spaceCheck, 0);
442
443 // Test array duplicate removal
444 spaceCheck = checkPointSpace();
445 array = OSArray::withCapacity(numStrCache);
446 for (i = 0; i < numStrCache; i++) {
447 sym = (OSObject *) OSSymbol::withCStringNoCopy(strCache[i]);
448 count += array->setObject(sym);
449 sym->release();
450 }
451 set1 = OSSet::withArray(array, numStrCache);
452 TEST_ASSERT('S', "5a", set1);
453 if (set1) {
454 TEST_ASSERT('S', "5b", array->getCount() != set1->getCount());
455 array->release();
456
457 count = count2 = set1->getCount();
458 while ( (sym = set1->getAnyObject()) ) {
459 count -= set1->__takeObject(sym);
460 count2 -= sym->getRetainCount();
461 sym->release();
462 }
463 TEST_ASSERT('S', "5c", !count);
464 TEST_ASSERT('S', "5d", !count2);
465 set1->release();
466 }
467 res = res && checkSpace("(S)5", spaceCheck, 0);
468
469 if (res)
470 verPrintf(("testSet: All OSSet Tests passed\n"));
471 else
472 logPrintf(("testSet: Some OSSet Tests failed\n"));
473 }
474
475 void testDictionary()
476 {
477 bool res = true;
478 void *spaceCheck, *spaceCheck2, *spaceCheck3;
479 OSObject *cache[numStrCache];
480 OSString *str;
481 const OSSymbol *symCache[numStrCache], *sym;
482 OSDictionary *dict1, *dict2;
483 int i, numSymbols, count1, count2;
484
485 // Do first test without memory leak tests to initialise the metaclass
486 dict1 = OSDictionary::withCapacity(1);
487 TEST_ASSERT('D', "0a", dict1);
488 if (dict1)
489 dict1->release();
490
491 // Grow the symbol pool to maximum
492 for (i = 0; i < numStrCache; i++)
493 symCache[i] = OSSymbol::withCStringNoCopy(strCache[i]);
494 for (i = 0; i < numStrCache; i++)
495 symCache[i]->release();
496
497 // Create and destroy a dictionary
498 spaceCheck = checkPointSpace();
499 dict1 = OSDictionary::withCapacity(1);
500 TEST_ASSERT('D', "1a", dict1);
501 if (dict1) {
502 TEST_ASSERT('D', "1b", !dict1->getCount());
503 TEST_ASSERT('D', "1c", 1 == dict1->getCapacity());
504 TEST_ASSERT('D', "1d", 1 == dict1->getCapacityIncrement());
505 TEST_ASSERT('D', "1e", 4 == dict1->setCapacityIncrement(4));
506 TEST_ASSERT('D', "1f", 4 == dict1->getCapacityIncrement());
507 TEST_ASSERT('D', "1g", 8 == dict1->ensureCapacity(5));
508
509 spaceCheck2 = checkPointSpace();
510 sym = OSSymbol::withCStringNoCopy(strCache[0]);
511
512 spaceCheck3 = checkPointSpace();
513 TEST_ASSERT('D', "1h", dict1->setObject((OSObject *) sym, sym));
514 TEST_ASSERT('D', "1i", (OSObject *) sym == dict1->getObject(sym));
515 sym->release();
516 TEST_ASSERT('D', "1i", 2 == sym->getRetainCount());
517 res = res && checkSpace("(D)1j", spaceCheck3, 0);
518
519 TEST_ASSERT('D', "1k", 1 == dict1->getCount());
520 dict1->flushCollection();
521 TEST_ASSERT('D', "1l", !dict1->getCount());
522 res = res && checkSpace("(D)1m", spaceCheck2, 0);
523
524 dict1->release();
525 }
526 res = res && checkSpace("(D)1", spaceCheck, 0);
527
528 // Check the creation of a sizable OSDictionary from an array of IOObjects
529 // Also check indexing into the array.
530 spaceCheck = checkPointSpace();
531 for (i = 0, numSymbols = 0; i < numStrCache; i++) {
532 sym = OSSymbol::withCStringNoCopy(strCache[i]);
533 if (1 == sym->getRetainCount())
534 symCache[numSymbols++] = sym;
535 else
536 sym->release();
537 }
538 dict1 = OSDictionary::withObjects(
539 (OSObject **) symCache, symCache, numSymbols, numSymbols);
540 TEST_ASSERT('D', "2a", dict1);
541 count1 = count2 = 0;
542 for (i = 0; i < numSymbols; i++)
543 count1 += (symCache[i]->getRetainCount() == 3);
544 TEST_ASSERT('D', "2b", count1 == numSymbols);
545 if (dict1) {
546 TEST_ASSERT('D', "2c", numSymbols == (int) dict1->getCount());
547 TEST_ASSERT('D', "2d", numSymbols == (int) dict1->getCapacity());
548 TEST_ASSERT('D', "2e",
549 numSymbols == (int) dict1->getCapacityIncrement());
550
551 for (i = dict1->getCount(); --i >= 0; ) {
552 str = (OSString *) dict1->getObject(symCache[i]);
553 if (str != (OSString *) symCache[i]) {
554 verPrintf(("testDictionary(D) test 2f%d failed\n", i));
555 res = false;
556 }
557 }
558 dict1->release();
559 }
560 count1 = count2 = 0;
561 for (i = 0; i < numSymbols; i++) {
562 count1 += (symCache[i]->getRetainCount() == 1);
563 symCache[i]->release();
564 }
565 TEST_ASSERT('D', "2g", count1 == numSymbols);
566 res = res && checkSpace("(D)2", spaceCheck, 0);
567
568 // Check the creation of a sizable Dictionary from an array of IOStrings
569 // Also check searching dictionary use OSString for a key.
570 spaceCheck = checkPointSpace();
571 for (i = 0, numSymbols = 0; i < numStrCache; i++) {
572 sym = OSSymbol::withCStringNoCopy(strCache[i]);
573 if (1 == sym->getRetainCount()) {
574 cache[numSymbols] = OSString::withCStringNoCopy(strCache[i]);
575 symCache[numSymbols] = sym;
576 numSymbols++;
577 }
578 else
579 sym->release();
580 }
581 dict1 = OSDictionary::withObjects((OSObject **) symCache,
582 (OSString **) cache,
583 numSymbols, numSymbols);
584 TEST_ASSERT('D', "3a", dict1);
585 count1 = count2 = 0;
586 for (i = 0; i < numSymbols; i++) {
587 count1 += (symCache[i]->getRetainCount() == 3);
588 count2 += (cache[i]->getRetainCount() == 1);
589 }
590 TEST_ASSERT('D', "3b", count1 == numSymbols);
591 TEST_ASSERT('D', "3c", count2 == numSymbols);
592 if (dict1) {
593 count1 = count2 = 0;
594 for (i = 0; i < numSymbols; i++) {
595 str = (OSString *) cache[i];
596 count1 += (symCache[i] == (const OSSymbol *) dict1->getObject(str));
597 count2 += (symCache[i]->getRetainCount() == 3);
598 }
599 TEST_ASSERT('D', "3d", count1 == numSymbols);
600 TEST_ASSERT('D', "3e", count2 == numSymbols);
601
602 count1 = count2 = 0;
603 for (i = 0; i < numSymbols; i++) {
604 const char *cStr = ((OSString *) cache[i])->getCStringNoCopy();
605
606 count1 += (symCache[i] == (const OSSymbol *) dict1->getObject(cStr));
607 count2 += (symCache[i]->getRetainCount() == 3);
608 }
609 TEST_ASSERT('D', "3f", count1 == numSymbols);
610 TEST_ASSERT('D', "3g", count2 == numSymbols);
611
612 dict1->release();
613 }
614 count1 = count2 = 0;
615 for (i = 0; i < numSymbols; i++) {
616 count1 += (symCache[i]->getRetainCount() == 1);
617 count2 += (cache[i]->getRetainCount() == 1);
618 symCache[i]->release();
619 cache[i]->release();
620 }
621 TEST_ASSERT('D', "3h", count1 == numSymbols);
622 res = res && checkSpace("(D)3", spaceCheck, 0);
623
624 // Check the creation of a small dictionary then grow it one item at a time
625 // Create a new dictionary from the old dictionary.
626 // Finally remove each item permanently.
627 spaceCheck = checkPointSpace();
628 for (i = 0, numSymbols = 0; i < numStrCache; i++) {
629 sym = OSSymbol::withCStringNoCopy(strCache[i]);
630 if (1 == sym->getRetainCount()) {
631 cache[numSymbols] = OSString::withCStringNoCopy(strCache[i]);
632 symCache[numSymbols] = sym;
633 numSymbols++;
634 }
635 else
636 sym->release();
637 }
638 dict2 = 0;
639 dict1 = OSDictionary::withCapacity(1);
640 TEST_ASSERT('D', "4a", dict1);
641 if (dict1) {
642 count1 = count2 = 0;
643 for (i = 0; i < numSymbols; i++) {
644 sym = symCache[i];
645 count1 += ((OSObject *) sym == dict1->setObject((OSObject *) sym,
646 sym->getCStringNoCopy()));
647 count2 += (sym->getRetainCount() == 3);
648 }
649 TEST_ASSERT('D', "4b", numSymbols == (int) dict1->getCount());
650 TEST_ASSERT('D', "4c", numSymbols == count1);
651 TEST_ASSERT('D', "4d", numSymbols == count2);
652
653 dict2 = OSDictionary::withDictionary(dict1, numSymbols-1);
654 TEST_ASSERT('D', "4b", !dict2);
655 dict2 = OSDictionary::withDictionary(dict1, numSymbols);
656 }
657 TEST_ASSERT('D', "4e", dict2);
658 if (dict2) {
659 dict1->release(); dict1 = 0;
660
661 TEST_ASSERT('D', "4f", numSymbols == (int) dict2->getCount());
662
663 count1 = count2 = 0;
664 for (i = 0; i < numSymbols; i++) {
665 OSObject *replacedObject;
666
667 sym = symCache[i];
668 str = (OSString *) cache[i];
669 replacedObject = dict2->setObject(str, str);
670 count1 += ((OSString *) sym == replacedObject);
671 replacedObject->release();
672 count2 += (sym->getRetainCount() == 2);
673 str->release();
674 }
675 TEST_ASSERT('D', "4g", numSymbols == count1);
676 TEST_ASSERT('D', "4h", numSymbols == count2);
677
678 count1 = count2 = 0;
679 for (i = 0; i < numSymbols; i++) {
680 sym = symCache[i];
681 str = (OSString *) cache[i];
682 count1 += (str == dict2->__takeObject(sym));
683 str->release();
684 count2 += (sym->getRetainCount() == 1);
685 sym->release();
686 }
687 TEST_ASSERT('D', "4i", numSymbols == count1);
688 TEST_ASSERT('D', "4j", numSymbols == count2);
689 TEST_ASSERT('D', "4k", !dict2->getCount());
690 dict2->release(); dict2 = 0;
691 }
692 else if (dict1)
693 dict1->release();
694 res = res && checkSpace("(D)4", spaceCheck, 0);
695
696 if (res)
697 verPrintf(("testDictionary: All OSDictionary Tests passed\n"));
698 else
699 logPrintf(("testDictionary: Some OSDictionary Tests failed\n"));
700 }
701
702 void testIterator()
703 {
704 bool res = true;
705 void *spaceCheck;
706 OSObject *cache[numStrCache];
707 OSString *str = 0;
708 const OSSymbol *symCache[numStrCache], *sym;
709 OSDictionary *dict;
710 OSSet *set;
711 OSArray *array, *bigReturn;
712 OSCollectionIterator *iter1, *iter2;
713 int i, numSymbols, count1, count2, count3;
714
715 // Setup symbol and string pools
716 for (i = 0, numSymbols = 0; i < numStrCache; i++) {
717 sym = OSSymbol::withCStringNoCopy(strCache[i]);
718 if (1 == sym->getRetainCount()) {
719 cache[numSymbols] = OSString::withCStringNoCopy(strCache[i]);
720 symCache[numSymbols] = sym;
721 numSymbols++;
722 }
723 else
724 sym->release();
725 }
726
727 // Test the array iterator
728 spaceCheck = checkPointSpace();
729 iter1 = iter2 = 0;
730 array = OSArray::withCapacity(numSymbols);
731 TEST_ASSERT('I', "1a", array);
732 if (array) {
733 count1 = count2 = 0;
734 for (i = numSymbols; --i >= 0; )
735 count1 += array->setObject(cache[i], 0);
736 TEST_ASSERT('I', "1b", count1 == numSymbols);
737
738 iter1 = OSCollectionIterator::withCollection(array);
739 iter2 = OSCollectionIterator::withCollection(array);
740 }
741 TEST_ASSERT('I', "1c", iter1);
742 TEST_ASSERT('I', "1d", iter2);
743 if (iter1 && iter2) {
744 count1 = count2 = count3 = 0;
745 for (i = 0; (str = (IOString *) iter1->getNextObject()); i++) {
746 bigReturn = iter2->nextEntries();
747 count1 += (bigReturn->getCount() == 1);
748 count2 += (cache[i] == bigReturn->getObject(0));
749 count3 += (cache[i] == str);
750 }
751 TEST_ASSERT('I', "1e", count1 == numSymbols);
752 TEST_ASSERT('I', "1f", count2 == numSymbols);
753 TEST_ASSERT('I', "1g", count3 == numSymbols);
754 TEST_ASSERT('I', "1h", iter1->valid());
755 TEST_ASSERT('I', "1i", iter2->valid());
756
757 iter1->reset();
758 str = (OSString *) array->__takeObject(0);
759 array->setObject(str, 0);
760 str->release();
761 TEST_ASSERT('I', "1j", !iter1->getNextObject());
762 TEST_ASSERT('I', "1k", !iter1->valid());
763
764 iter1->reset();
765 count1 = count2 = count3 = 0;
766 for (i = 0; ; i++) {
767 if (i & 1)
768 str = (OSString *) iter1->getNextObject();
769 else if ( (bigReturn = iter1->nextEntries()) )
770 str = (OSString *) bigReturn->getObject(0);
771 else
772 str = 0;
773
774 if (!str)
775 break;
776 count1 += (cache[i] == str);
777 }
778 TEST_ASSERT('I', "1l", count1 == numSymbols);
779 TEST_ASSERT('I', "1m", i == numSymbols);
780 TEST_ASSERT('I', "1n", iter1->valid());
781
782 TEST_ASSERT('I', "1o", 3 == array->getRetainCount());
783 array->release();
784 }
785
786 if (iter1) iter1->release();
787 if (iter2) iter2->release();
788 res = res && checkSpace("(I)1", spaceCheck, 0);
789
790 // Test the set iterator
791 spaceCheck = checkPointSpace();
792 iter1 = 0;
793 set = OSSet::withCapacity(numSymbols);
794 TEST_ASSERT('I', "2a", set);
795 if (set) {
796 count1 = count2 = 0;
797 for (i = 0; i < numSymbols; i++)
798 count1 += set->setObject(cache[i]);
799 TEST_ASSERT('I', "2b", count1 == numSymbols);
800
801 iter1 = OSCollectionIterator::withCollection(set);
802 iter2 = OSCollectionIterator::withCollection(set);
803 }
804 TEST_ASSERT('I', "2c", iter1);
805 TEST_ASSERT('I', "2d", iter2);
806 if (iter1 && iter2) {
807 count1 = count2 = count3 = 0;
808 for (i = 0; (str = (IOString *) iter1->getNextObject()); i++) {
809 bigReturn = iter2->nextEntries();
810 count1 += (bigReturn->getCount() == 1);
811 count2 += (cache[i] == bigReturn->getObject(0));
812 count3 += (cache[i] == str);
813 }
814 TEST_ASSERT('I', "2e", count1 == numSymbols);
815 TEST_ASSERT('I', "2f", count2 == numSymbols);
816 TEST_ASSERT('I', "2g", count3 == numSymbols);
817 TEST_ASSERT('I', "2h", iter1->valid());
818 TEST_ASSERT('I', "2i", iter2->valid());
819
820 iter1->reset();
821 count1 = count2 = count3 = 0;
822 for (i = 0; ; i++) {
823 if (i & 1)
824 str = (OSString *) iter1->getNextObject();
825 else if ( (bigReturn = iter1->nextEntries()) )
826 str = (OSString *) bigReturn->getObject(0);
827 else
828 str = 0;
829
830 if (!str)
831 break;
832 count1 += (cache[i] == str);
833 }
834 TEST_ASSERT('I', "2l", count1 == numSymbols);
835 TEST_ASSERT('I', "2m", i == numSymbols);
836 TEST_ASSERT('I', "2n", iter1->valid());
837
838 iter1->reset();
839 str = (OSString *) set->getAnyObject();
840 (void) set->__takeObject(str);
841 set->setObject(str);
842 str->release();
843 TEST_ASSERT('I', "2j", !iter1->getNextObject());
844 TEST_ASSERT('I', "2k", !iter1->valid());
845
846 TEST_ASSERT('I', "2o", 3 == set->getRetainCount());
847 set->release();
848 }
849
850 if (iter1) iter1->release();
851 if (iter2) iter2->release();
852 res = res && checkSpace("(I)2", spaceCheck, 0);
853
854 // Test the dictionary iterator
855 spaceCheck = checkPointSpace();
856 iter1 = 0;
857 dict = OSDictionary::withCapacity(numSymbols);
858 TEST_ASSERT('I', "3a", dict);
859 if (dict) {
860 count1 = count2 = 0;
861 for (i = 0; i < numSymbols; i++)
862 count1 += (0 != dict->setObject(cache[i], symCache[i]));
863 TEST_ASSERT('I', "3b", count1 == numSymbols);
864
865 iter1 = OSCollectionIterator::withCollection(dict);
866 iter2 = OSCollectionIterator::withCollection(dict);
867 }
868 TEST_ASSERT('I', "3c", iter1);
869 TEST_ASSERT('I', "3d", iter2);
870 if (iter1 && iter2) {
871 count1 = count2 = count3 = 0;
872 for (i = 0; (sym = (const IOSymbol *) iter1->getNextObject()); i++) {
873 bigReturn = iter2->nextEntries();
874 count1 += (bigReturn->getCount() == 2);
875 count2 += (cache[i] == bigReturn->getObject(1));
876 count3 += (symCache[i] == sym);
877 }
878 TEST_ASSERT('I', "3e", count1 == numSymbols);
879 TEST_ASSERT('I', "3f", count2 == numSymbols);
880 TEST_ASSERT('I', "3g", count3 == numSymbols);
881 TEST_ASSERT('I', "3h", iter1->valid());
882 TEST_ASSERT('I', "3i", iter2->valid());
883
884 iter1->reset();
885 count1 = count2 = count3 = 0;
886 i = 0;
887 for (i = 0; ; i++) {
888 if (i & 1) {
889 sym = (const OSSymbol *) iter1->getNextObject();
890 str = 0;
891 }
892 else if ( (bigReturn = iter1->nextEntries()) ) {
893 sym = (const OSSymbol *) bigReturn->getObject(0);
894 str = (OSString *) bigReturn->getObject(1);
895 }
896 else
897 sym = 0;
898
899 if (!sym)
900 break;
901
902 count1 += (symCache[i] == sym);
903 count2 += (!str || cache[i] == str);
904 }
905 TEST_ASSERT('I', "3l", count1 == numSymbols);
906 TEST_ASSERT('I', "3m", count2 == numSymbols);
907 TEST_ASSERT('I', "3n", i == numSymbols);
908 TEST_ASSERT('I', "3o", iter1->valid());
909
910 iter1->reset();
911 str = (OSString *) dict->__takeObject(symCache[numSymbols-1]);
912 dict->setObject(str, symCache[numSymbols-1]);
913 str->release();
914 TEST_ASSERT('I', "3j", !iter1->getNextObject());
915 TEST_ASSERT('I', "3k", !iter1->valid());
916
917 TEST_ASSERT('I', "3p", 3 == dict->getRetainCount());
918 dict->release();
919 }
920
921 if (iter1) iter1->release();
922 if (iter2) iter2->release();
923 res = res && checkSpace("(I)3", spaceCheck, 0);
924
925 count1 = count2 = count3 = 0;
926 for (i = 0; i < numSymbols; i++) {
927 count1 += (1 == cache[i]->getRetainCount());
928 count2 += (1 == symCache[i]->getRetainCount());
929 cache[i]->release();
930 symCache[i]->release();
931 }
932 TEST_ASSERT('I', "4a", count1 == numSymbols);
933 TEST_ASSERT('I', "4b", count2 == numSymbols);
934
935 if (res)
936 verPrintf(("testIterator: All OSCollectionIterator Tests passed\n"));
937 else
938 logPrintf(("testIterator: Some OSCollectionIterator Tests failed\n"));
939 }
940
941 #endif /* DEBUG */