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