VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/xpcom/tests/TestHashtables.cpp@ 86419

Last change on this file since 86419 was 86419, checked in by vboxsync, 4 years ago

xpcom/TestHashTables: Fixed use-after-free issue in IFoo::Release(). bugref:9841

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.8 KB
Line 
1/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is C++ hashtable templates.
16 *
17 * The Initial Developer of the Original Code is
18 * Benjamin Smedberg.
19 * Portions created by the Initial Developer are Copyright (C) 2002
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 *
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38#include "nsTHashtable.h"
39#include "nsBaseHashtable.h"
40#include "nsDataHashtable.h"
41#include "nsInterfaceHashtable.h"
42#include "nsClassHashtable.h"
43
44#include "nsCOMPtr.h"
45#include "nsISupports.h"
46#include "nsCRT.h"
47#include "nsCOMArray.h"
48
49class TestUniChar // for nsClassHashtable
50{
51public:
52 TestUniChar(PRUint32 aWord)
53 {
54 printf(" TestUniChar::TestUniChar() %u\n", aWord);
55 mWord = aWord;
56 }
57
58 ~TestUniChar()
59 {
60 printf(" TestUniChar::~TestUniChar() %u\n", mWord);
61 }
62
63 PRUint32 GetChar() const { return mWord; }
64
65private:
66 PRUint32 mWord;
67};
68
69struct EntityNode {
70 const char* mStr; // never owns buffer
71 PRUint32 mUnicode;
72};
73
74EntityNode gEntities[] = {
75 {"nbsp",160},
76 {"iexcl",161},
77 {"cent",162},
78 {"pound",163},
79 {"curren",164},
80 {"yen",165},
81 {"brvbar",166},
82 {"sect",167},
83 {"uml",168},
84 {"copy",169},
85 {"ordf",170},
86 {"laquo",171},
87 {"not",172},
88 {"shy",173},
89 {"reg",174},
90 {"macr",175}
91};
92
93#define ENTITY_COUNT (sizeof(gEntities)/sizeof(EntityNode))
94
95class EntityToUnicodeEntry : public PLDHashEntryHdr
96{
97public:
98 typedef const char* KeyType;
99 typedef const char* KeyTypePointer;
100
101 EntityToUnicodeEntry(const char* aKey) { mNode = nsnull; }
102 EntityToUnicodeEntry(const EntityToUnicodeEntry& aEntry) { mNode = aEntry.mNode; }
103 ~EntityToUnicodeEntry() { };
104
105 const char* GetKeyPointer() const { return mNode->mStr; }
106 PRBool KeyEquals(const char* aEntity) const { return !strcmp(mNode->mStr, aEntity); }
107 static const char* KeyToPointer(const char* aEntity) { return aEntity; }
108 static PLDHashNumber HashKey(const char* aEntity) { return nsCRT::HashCode(aEntity); }
109 enum { ALLOW_MEMMOVE = PR_TRUE };
110
111 const EntityNode* mNode;
112};
113
114PLDHashOperator
115nsTEnumGo(EntityToUnicodeEntry* aEntry, void* userArg) {
116 printf(" enumerated \"%s\" = %u\n",
117 aEntry->mNode->mStr, aEntry->mNode->mUnicode);
118
119 return PL_DHASH_NEXT;
120}
121
122PLDHashOperator
123nsTEnumStop(EntityToUnicodeEntry* aEntry, void* userArg) {
124 printf(" enumerated \"%s\" = %u\n",
125 aEntry->mNode->mStr, aEntry->mNode->mUnicode);
126
127 return PL_DHASH_REMOVE;
128}
129
130void
131testTHashtable(nsTHashtable<EntityToUnicodeEntry>& hash, PRUint32 numEntries) {
132 printf("Filling hash with %d entries.\n", numEntries);
133
134 PRUint32 i;
135 for (i = 0; i < numEntries; ++i) {
136 printf(" Putting entry \"%s\"...", gEntities[i].mStr);
137 EntityToUnicodeEntry* entry =
138 hash.PutEntry(gEntities[i].mStr);
139
140 if (!entry) {
141 printf("FAILED\n");
142 exit (2);
143 }
144 printf("OK...");
145
146 if (entry->mNode) {
147 printf("entry already exists!\n");
148 exit (3);
149 }
150 printf("\n");
151
152 entry->mNode = &gEntities[i];
153 }
154
155 printf("Testing Get:\n");
156
157 for (i = 0; i < numEntries; ++i) {
158 printf(" Getting entry \"%s\"...", gEntities[i].mStr);
159 EntityToUnicodeEntry* entry =
160 hash.GetEntry(gEntities[i].mStr);
161
162 if (!entry) {
163 printf("FAILED\n");
164 exit (4);
165 }
166
167 printf("Found %u\n", entry->mNode->mUnicode);
168 }
169
170 printf("Testing non-existent entries...");
171
172 EntityToUnicodeEntry* entry =
173 hash.GetEntry("xxxy");
174
175 if (entry) {
176 printf("FOUND! BAD!\n");
177 exit (5);
178 }
179
180 printf("not found; good.\n");
181
182 printf("Enumerating:\n");
183 PRUint32 count = hash.EnumerateEntries(nsTEnumGo, nsnull);
184 if (count != numEntries) {
185 printf(" Bad count!\n");
186 exit (6);
187 }
188}
189
190PLDHashOperator
191nsDEnumRead(const PRUint32& aKey, const char* aData, void* userArg) {
192 printf(" enumerated %u = \"%s\"\n", aKey, aData);
193 return PL_DHASH_NEXT;
194}
195
196PLDHashOperator
197nsDEnum(const PRUint32& aKey, const char*& aData, void* userArg) {
198 printf(" enumerated %u = \"%s\"\n", aKey, aData);
199 return PL_DHASH_NEXT;
200}
201
202PLDHashOperator
203nsCEnumRead(const nsACString& aKey, TestUniChar* aData, void* userArg) {
204 printf(" enumerated \"%s\" = %c\n",
205 PromiseFlatCString(aKey).get(), aData->GetChar());
206 return PL_DHASH_NEXT;
207}
208
209PLDHashOperator
210nsCEnum(const nsACString& aKey, nsAutoPtr<TestUniChar>& aData, void* userArg) {
211 printf(" enumerated \"%s\" = %c\n",
212 PromiseFlatCString(aKey).get(), aData->GetChar());
213 return PL_DHASH_NEXT;
214}
215
216//
217// all this nsIFoo stuff was copied wholesale from TestCOMPTr.cpp
218//
219
220#define NS_IFOO_IID \
221{ 0x6f7652e0, 0xee43, 0x11d1, \
222 { 0x9c, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
223
224class IFoo : public nsISupports
225 {
226 public:
227 NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFOO_IID)
228
229 public:
230 IFoo();
231
232 NS_IMETHOD_(nsrefcnt) AddRef();
233 NS_IMETHOD_(nsrefcnt) Release();
234 NS_IMETHOD QueryInterface( const nsIID&, void** );
235
236 NS_IMETHOD SetString(const nsACString& /*in*/ aString);
237 NS_IMETHOD GetString(nsACString& /*out*/ aString);
238
239 static void print_totals();
240
241 private:
242 ~IFoo();
243
244 unsigned int refcount_;
245
246 static unsigned int total_constructions_;
247 static unsigned int total_destructions_;
248 nsCString mString;
249 };
250
251unsigned int IFoo::total_constructions_;
252unsigned int IFoo::total_destructions_;
253
254void
255IFoo::print_totals()
256 {
257 printf("total constructions/destructions --> %d/%d\n",
258 total_constructions_, total_destructions_);
259 }
260
261IFoo::IFoo()
262 : refcount_(0)
263 {
264 ++total_constructions_;
265 printf(" new IFoo@%p [#%d]\n",
266 NS_STATIC_CAST(void*, this), total_constructions_);
267 }
268
269IFoo::~IFoo()
270 {
271 ++total_destructions_;
272 printf("IFoo@%p::~IFoo() [#%d]\n",
273 NS_STATIC_CAST(void*, this), total_destructions_);
274 }
275
276nsrefcnt
277IFoo::AddRef()
278 {
279 ++refcount_;
280 printf("IFoo@%p::AddRef(), refcount --> %d\n",
281 NS_STATIC_CAST(void*, this), refcount_);
282 return refcount_;
283 }
284
285nsrefcnt
286IFoo::Release()
287 {
288 int wrap_message = (refcount_ == 1);
289 if ( wrap_message )
290 printf(">>");
291
292 nsrefcnt newrefcount = --refcount_;
293 printf("IFoo@%p::Release(), refcount --> %d\n",
294 NS_STATIC_CAST(void*, this), newrefcount);
295
296 if ( !newrefcount )
297 {
298 printf(" delete IFoo@%p\n", NS_STATIC_CAST(void*, this));
299 delete this;
300 }
301
302 if ( wrap_message )
303 printf(" delete IFoo@%p\n", NS_STATIC_CAST(void*, this));
304
305 return newrefcount;
306 }
307
308nsresult
309IFoo::QueryInterface( const nsIID& aIID, void** aResult )
310 {
311 printf("IFoo@%p::QueryInterface()\n", NS_STATIC_CAST(void*, this));
312 nsISupports* rawPtr = 0;
313 nsresult status = NS_OK;
314
315 if ( aIID.Equals(GetIID()) )
316 rawPtr = this;
317 else
318 {
319 nsID iid_of_ISupports = NS_ISUPPORTS_IID;
320 if ( aIID.Equals(iid_of_ISupports) )
321 rawPtr = NS_STATIC_CAST(nsISupports*, this);
322 else
323 status = NS_ERROR_NO_INTERFACE;
324 }
325
326 NS_IF_ADDREF(rawPtr);
327 *aResult = rawPtr;
328
329 return status;
330 }
331
332nsresult
333IFoo::SetString(const nsACString& aString)
334{
335 mString = aString;
336 return NS_OK;
337}
338
339nsresult
340IFoo::GetString(nsACString& aString)
341{
342 aString = mString;
343 return NS_OK;
344}
345
346nsresult
347CreateIFoo( IFoo** result )
348 // a typical factory function (that calls AddRef)
349 {
350 printf(" >>CreateIFoo() --> ");
351 IFoo* foop = new IFoo();
352 printf("IFoo@%p\n", NS_STATIC_CAST(void*, foop));
353
354 foop->AddRef();
355 *result = foop;
356
357 printf("<<CreateIFoo()\n");
358 return 0;
359 }
360
361PLDHashOperator
362nsIEnumRead(const PRUint32& aKey, IFoo* aFoo, void* userArg) {
363 nsCAutoString str;
364 aFoo->GetString(str);
365
366 printf(" enumerated %u = \"%s\"\n", aKey, str.get());
367 return PL_DHASH_NEXT;
368}
369
370PLDHashOperator
371nsIEnum(const PRUint32& aKey, nsCOMPtr<IFoo>& aData, void* userArg) {
372 nsCAutoString str;
373 aData->GetString(str);
374
375 printf(" enumerated %u = \"%s\"\n", aKey, str.get());
376 return PL_DHASH_NEXT;
377}
378
379PLDHashOperator
380nsIEnum2Read(nsISupports* aKey, PRUint32 aData, void* userArg) {
381 nsCAutoString str;
382 nsCOMPtr<IFoo> foo = do_QueryInterface(aKey);
383 foo->GetString(str);
384
385
386 printf(" enumerated \"%s\" = %u\n", str.get(), aData);
387 return PL_DHASH_NEXT;
388}
389
390PLDHashOperator
391nsIEnum2(nsISupports* aKey, PRUint32& aData, void* userArg) {
392 nsCAutoString str;
393 nsCOMPtr<IFoo> foo = do_QueryInterface(aKey);
394 foo->GetString(str);
395
396 printf(" enumerated \"%s\" = %u\n", str.get(), aData);
397 return PL_DHASH_NEXT;
398}
399
400int
401main(void) {
402 // check an nsTHashtable
403 nsTHashtable<EntityToUnicodeEntry> EntityToUnicode;
404
405 printf("Initializing nsTHashtable...");
406 if (!EntityToUnicode.Init(ENTITY_COUNT)) {
407 printf("FAILED\n");
408 exit (1);
409 }
410 printf("OK\n");
411
412 printf("Partially filling nsTHashtable:\n");
413 testTHashtable(EntityToUnicode, 5);
414
415 printf("Enumerate-removing...\n");
416 PRUint32 count = EntityToUnicode.EnumerateEntries(nsTEnumStop, nsnull);
417 if (count != 5) {
418 printf("wrong count\n");
419 exit (7);
420 }
421 printf("OK\n");
422
423 printf("Check enumeration...");
424 count = EntityToUnicode.EnumerateEntries(nsTEnumGo, nsnull);
425 if (count) {
426 printf("entries remain in table!\n");
427 exit (8);
428 }
429 printf("OK\n");
430
431 printf("Filling nsTHashtable:\n");
432 testTHashtable(EntityToUnicode, ENTITY_COUNT);
433
434 printf("Clearing...");
435 EntityToUnicode.Clear();
436 printf("OK\n");
437
438 printf("Check enumeration...");
439 count = EntityToUnicode.EnumerateEntries(nsTEnumGo, nsnull);
440 if (count) {
441 printf("entries remain in table!\n");
442 exit (9);
443 }
444 printf("OK\n");
445
446 //
447 // now check a data-hashtable
448 //
449
450 nsDataHashtable<nsUint32HashKey,const char*> UniToEntity;
451
452 printf("Initializing nsDataHashtable...");
453 if (!UniToEntity.Init(ENTITY_COUNT)) {
454 printf("FAILED\n");
455 exit (10);
456 }
457 printf("OK\n");
458
459 printf("Filling hash with %zd entries.\n", ENTITY_COUNT);
460
461 PRUint32 i;
462 for (i = 0; i < ENTITY_COUNT; ++i) {
463 printf(" Putting entry %u...", gEntities[i].mUnicode);
464 if (!UniToEntity.Put(gEntities[i].mUnicode, gEntities[i].mStr)) {
465 printf("FAILED\n");
466 exit (11);
467 }
468 printf("OK...\n");
469 }
470
471 printf("Testing Get:\n");
472 const char* str;
473
474 for (i = 0; i < ENTITY_COUNT; ++i) {
475 printf(" Getting entry %u...", gEntities[i].mUnicode);
476 if (!UniToEntity.Get(gEntities[i].mUnicode, &str)) {
477 printf("FAILED\n");
478 exit (12);
479 }
480
481 printf("Found %s\n", str);
482 }
483
484 printf("Testing non-existent entries...");
485 if (UniToEntity.Get(99446, &str)) {
486 printf("FOUND! BAD!\n");
487 exit (13);
488 }
489
490 printf("not found; good.\n");
491
492 printf("Enumerating:\n");
493
494 count = UniToEntity.EnumerateRead(nsDEnumRead, nsnull);
495 if (count != ENTITY_COUNT) {
496 printf(" Bad count!\n");
497 exit (14);
498 }
499
500 printf("Clearing...");
501 UniToEntity.Clear();
502 printf("OK\n");
503
504 printf("Checking count...");
505 count = UniToEntity.Enumerate(nsDEnum, nsnull);
506 if (count) {
507 printf(" Clear did not remove all entries.\n");
508 exit (15);
509 }
510
511 printf("OK\n");
512
513 //
514 // now check a thread-safe data-hashtable
515 //
516
517 nsDataHashtableMT<nsUint32HashKey,const char*> UniToEntityL;
518
519 printf("Initializing nsDataHashtableMT...");
520 if (!UniToEntityL.Init(ENTITY_COUNT)) {
521 printf("FAILED\n");
522 exit (10);
523 }
524 printf("OK\n");
525
526 printf("Filling hash with %zd entries.\n", ENTITY_COUNT);
527
528 for (i = 0; i < ENTITY_COUNT; ++i) {
529 printf(" Putting entry %u...", gEntities[i].mUnicode);
530 if (!UniToEntityL.Put(gEntities[i].mUnicode, gEntities[i].mStr)) {
531 printf("FAILED\n");
532 exit (11);
533 }
534 printf("OK...\n");
535 }
536
537 printf("Testing Get:\n");
538
539 for (i = 0; i < ENTITY_COUNT; ++i) {
540 printf(" Getting entry %u...", gEntities[i].mUnicode);
541 if (!UniToEntityL.Get(gEntities[i].mUnicode, &str)) {
542 printf("FAILED\n");
543 exit (12);
544 }
545
546 printf("Found %s\n", str);
547 }
548
549 printf("Testing non-existent entries...");
550 if (UniToEntityL.Get(99446, &str)) {
551 printf("FOUND! BAD!\n");
552 exit (13);
553 }
554
555 printf("not found; good.\n");
556
557 printf("Enumerating:\n");
558
559 count = UniToEntityL.EnumerateRead(nsDEnumRead, nsnull);
560 if (count != ENTITY_COUNT) {
561 printf(" Bad count!\n");
562 exit (14);
563 }
564
565 printf("Clearing...");
566 UniToEntityL.Clear();
567 printf("OK\n");
568
569 printf("Checking count...");
570 count = UniToEntityL.Enumerate(nsDEnum, nsnull);
571 if (count) {
572 printf(" Clear did not remove all entries.\n");
573 exit (15);
574 }
575
576 printf("OK\n");
577
578 //
579 // now check a class-hashtable
580 //
581
582 nsClassHashtable<nsCStringHashKey,TestUniChar> EntToUniClass;
583
584 printf("Initializing nsClassHashtable...");
585 if (!EntToUniClass.Init(ENTITY_COUNT)) {
586 printf("FAILED\n");
587 exit (16);
588 }
589 printf("OK\n");
590
591 printf("Filling hash with %zd entries.\n", ENTITY_COUNT);
592
593 for (i = 0; i < ENTITY_COUNT; ++i) {
594 printf(" Putting entry %u...", gEntities[i].mUnicode);
595 TestUniChar* temp = new TestUniChar(gEntities[i].mUnicode);
596
597 if (!EntToUniClass.Put(nsDependentCString(gEntities[i].mStr), temp)) {
598 printf("FAILED\n");
599 delete temp;
600 exit (17);
601 }
602 printf("OK...\n");
603 }
604
605 printf("Testing Get:\n");
606 TestUniChar* myChar;
607
608 for (i = 0; i < ENTITY_COUNT; ++i) {
609 printf(" Getting entry %s...", gEntities[i].mStr);
610 if (!EntToUniClass.Get(nsDependentCString(gEntities[i].mStr), &myChar)) {
611 printf("FAILED\n");
612 exit (18);
613 }
614
615 printf("Found %c\n", myChar->GetChar());
616 }
617
618 printf("Testing non-existent entries...");
619 if (EntToUniClass.Get(NS_LITERAL_CSTRING("xxxx"), &myChar)) {
620 printf("FOUND! BAD!\n");
621 exit (19);
622 }
623
624 printf("not found; good.\n");
625
626 printf("Enumerating:\n");
627
628 count = EntToUniClass.EnumerateRead(nsCEnumRead, nsnull);
629 if (count != ENTITY_COUNT) {
630 printf(" Bad count!\n");
631 exit (20);
632 }
633
634 printf("Clearing...\n");
635 EntToUniClass.Clear();
636 printf(" Clearing OK\n");
637
638 printf("Checking count...");
639 count = EntToUniClass.Enumerate(nsCEnum, nsnull);
640 if (count) {
641 printf(" Clear did not remove all entries.\n");
642 exit (21);
643 }
644
645 printf("OK\n");
646
647 //
648 // now check a thread-safe class-hashtable
649 //
650
651 nsClassHashtableMT<nsCStringHashKey,TestUniChar> EntToUniClassL;
652
653 printf("Initializing nsClassHashtableMT...");
654 if (!EntToUniClassL.Init(ENTITY_COUNT)) {
655 printf("FAILED\n");
656 exit (16);
657 }
658 printf("OK\n");
659
660 printf("Filling hash with %zd entries.\n", ENTITY_COUNT);
661
662 for (i = 0; i < ENTITY_COUNT; ++i) {
663 printf(" Putting entry %u...", gEntities[i].mUnicode);
664 TestUniChar* temp = new TestUniChar(gEntities[i].mUnicode);
665
666 if (!EntToUniClassL.Put(nsDependentCString(gEntities[i].mStr), temp)) {
667 printf("FAILED\n");
668 delete temp;
669 exit (17);
670 }
671 printf("OK...\n");
672 }
673
674 printf("Testing Get:\n");
675
676 for (i = 0; i < ENTITY_COUNT; ++i) {
677 printf(" Getting entry %s...", gEntities[i].mStr);
678 if (!EntToUniClassL.Get(nsDependentCString(gEntities[i].mStr), &myChar)) {
679 printf("FAILED\n");
680 exit (18);
681 }
682
683 printf("Found %c\n", myChar->GetChar());
684 }
685
686 printf("Testing non-existent entries...");
687 if (EntToUniClassL.Get(NS_LITERAL_CSTRING("xxxx"), &myChar)) {
688 printf("FOUND! BAD!\n");
689 exit (19);
690 }
691
692 printf("not found; good.\n");
693
694 printf("Enumerating:\n");
695
696 count = EntToUniClassL.EnumerateRead(nsCEnumRead, nsnull);
697 if (count != ENTITY_COUNT) {
698 printf(" Bad count!\n");
699 exit (20);
700 }
701
702 printf("Clearing...\n");
703 EntToUniClassL.Clear();
704 printf(" Clearing OK\n");
705
706 printf("Checking count...");
707 count = EntToUniClassL.Enumerate(nsCEnum, nsnull);
708 if (count) {
709 printf(" Clear did not remove all entries.\n");
710 exit (21);
711 }
712
713 printf("OK\n");
714
715 //
716 // now check a data-hashtable with an interface key
717 //
718
719 nsDataHashtable<nsISupportsHashKey,PRUint32> EntToUniClass2;
720
721 printf("Initializing nsDataHashtable with interface key...");
722 if (!EntToUniClass2.Init(ENTITY_COUNT)) {
723 printf("FAILED\n");
724 exit (22);
725 }
726 printf("OK\n");
727
728 printf("Filling hash with %zd entries.\n", ENTITY_COUNT);
729
730 nsCOMArray<IFoo> fooArray;
731
732 for (i = 0; i < ENTITY_COUNT; ++i) {
733 printf(" Putting entry %u...", gEntities[i].mUnicode);
734 nsCOMPtr<IFoo> foo;
735 CreateIFoo(getter_AddRefs(foo));
736 foo->SetString(nsDependentCString(gEntities[i].mStr));
737
738
739 fooArray.InsertObjectAt(foo, i);
740
741 if (!EntToUniClass2.Put(foo, gEntities[i].mUnicode)) {
742 printf("FAILED\n");
743 exit (23);
744 }
745 printf("OK...\n");
746 }
747
748 printf("Testing Get:\n");
749 PRUint32 myChar2;
750
751 for (i = 0; i < ENTITY_COUNT; ++i) {
752 printf(" Getting entry %s...", gEntities[i].mStr);
753
754 if (!EntToUniClass2.Get(fooArray[i], &myChar2)) {
755 printf("FAILED\n");
756 exit (24);
757 }
758
759 printf("Found %c\n", myChar2);
760 }
761
762 printf("Testing non-existent entries...");
763 if (EntToUniClass2.Get((nsISupports*) 0x55443316, &myChar2)) {
764 printf("FOUND! BAD!\n");
765 exit (25);
766 }
767
768 printf("not found; good.\n");
769
770 printf("Enumerating:\n");
771
772 count = EntToUniClass2.EnumerateRead(nsIEnum2Read, nsnull);
773 if (count != ENTITY_COUNT) {
774 printf(" Bad count!\n");
775 exit (26);
776 }
777
778 printf("Clearing...\n");
779 EntToUniClass2.Clear();
780 printf(" Clearing OK\n");
781
782 printf("Checking count...");
783 count = EntToUniClass2.Enumerate(nsIEnum2, nsnull);
784 if (count) {
785 printf(" Clear did not remove all entries.\n");
786 exit (27);
787 }
788
789 printf("OK\n");
790
791 //
792 // now check an interface-hashtable with an PRUint32 key
793 //
794
795 nsInterfaceHashtable<nsUint32HashKey,IFoo> UniToEntClass2;
796
797 printf("Initializing nsInterfaceHashtable...");
798 if (!UniToEntClass2.Init(ENTITY_COUNT)) {
799 printf("FAILED\n");
800 exit (28);
801 }
802 printf("OK\n");
803
804 printf("Filling hash with %zd entries.\n", ENTITY_COUNT);
805
806 for (i = 0; i < ENTITY_COUNT; ++i) {
807 printf(" Putting entry %u...", gEntities[i].mUnicode);
808 nsCOMPtr<IFoo> foo;
809 CreateIFoo(getter_AddRefs(foo));
810 foo->SetString(nsDependentCString(gEntities[i].mStr));
811
812 if (!UniToEntClass2.Put(gEntities[i].mUnicode, foo)) {
813 printf("FAILED\n");
814 exit (29);
815 }
816 printf("OK...\n");
817 }
818
819 printf("Testing Get:\n");
820
821 for (i = 0; i < ENTITY_COUNT; ++i) {
822 printf(" Getting entry %s...", gEntities[i].mStr);
823
824 nsCOMPtr<IFoo> myEnt;
825 if (!UniToEntClass2.Get(gEntities[i].mUnicode, getter_AddRefs(myEnt))) {
826 printf("FAILED\n");
827 exit (30);
828 }
829
830 nsCAutoString str;
831 myEnt->GetString(str);
832 printf("Found %s\n", str.get());
833 }
834
835 printf("Testing non-existent entries...");
836 nsCOMPtr<IFoo> myEnt;
837 if (UniToEntClass2.Get(9462, getter_AddRefs(myEnt))) {
838 printf("FOUND! BAD!\n");
839 exit (31);
840 }
841
842 printf("not found; good.\n");
843
844 printf("Enumerating:\n");
845
846 count = UniToEntClass2.EnumerateRead(nsIEnumRead, nsnull);
847 if (count != ENTITY_COUNT) {
848 printf(" Bad count!\n");
849 exit (32);
850 }
851
852 printf("Clearing...\n");
853 UniToEntClass2.Clear();
854 printf(" Clearing OK\n");
855
856 printf("Checking count...");
857 count = UniToEntClass2.Enumerate(nsIEnum, nsnull);
858 if (count) {
859 printf(" Clear did not remove all entries.\n");
860 exit (33);
861 }
862
863 printf("OK\n");
864
865 //
866 // now check a thread-safe interface hashtable
867 //
868
869 nsInterfaceHashtableMT<nsUint32HashKey,IFoo> UniToEntClass2L;
870
871 printf("Initializing nsInterfaceHashtableMT...");
872 if (!UniToEntClass2L.Init(ENTITY_COUNT)) {
873 printf("FAILED\n");
874 exit (28);
875 }
876 printf("OK\n");
877
878 printf("Filling hash with %zd entries.\n", ENTITY_COUNT);
879
880 for (i = 0; i < ENTITY_COUNT; ++i) {
881 printf(" Putting entry %u...", gEntities[i].mUnicode);
882 nsCOMPtr<IFoo> foo;
883 CreateIFoo(getter_AddRefs(foo));
884 foo->SetString(nsDependentCString(gEntities[i].mStr));
885
886 if (!UniToEntClass2L.Put(gEntities[i].mUnicode, foo)) {
887 printf("FAILED\n");
888 exit (29);
889 }
890 printf("OK...\n");
891 }
892
893 printf("Testing Get:\n");
894
895 for (i = 0; i < ENTITY_COUNT; ++i) {
896 printf(" Getting entry %s...", gEntities[i].mStr);
897
898 nsCOMPtr<IFoo> myEnt;
899 if (!UniToEntClass2L.Get(gEntities[i].mUnicode, getter_AddRefs(myEnt))) {
900 printf("FAILED\n");
901 exit (30);
902 }
903
904 nsCAutoString str;
905 myEnt->GetString(str);
906 printf("Found %s\n", str.get());
907 }
908
909 printf("Testing non-existent entries...");
910 if (UniToEntClass2L.Get(9462, getter_AddRefs(myEnt))) {
911 printf("FOUND! BAD!\n");
912 exit (31);
913 }
914
915 printf("not found; good.\n");
916
917 printf("Enumerating:\n");
918
919 count = UniToEntClass2L.EnumerateRead(nsIEnumRead, nsnull);
920 if (count != ENTITY_COUNT) {
921 printf(" Bad count!\n");
922 exit (32);
923 }
924
925 printf("Clearing...\n");
926 UniToEntClass2L.Clear();
927 printf(" Clearing OK\n");
928
929 printf("Checking count...");
930 count = UniToEntClass2L.Enumerate(nsIEnum, nsnull);
931 if (count) {
932 printf(" Clear did not remove all entries.\n");
933 exit (33);
934 }
935
936 printf("OK\n");
937
938 return 0;
939}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette