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 |
|
---|
49 | class TestUniChar // for nsClassHashtable
|
---|
50 | {
|
---|
51 | public:
|
---|
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 |
|
---|
65 | private:
|
---|
66 | PRUint32 mWord;
|
---|
67 | };
|
---|
68 |
|
---|
69 | struct EntityNode {
|
---|
70 | const char* mStr; // never owns buffer
|
---|
71 | PRUint32 mUnicode;
|
---|
72 | };
|
---|
73 |
|
---|
74 | EntityNode 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 |
|
---|
95 | class EntityToUnicodeEntry : public PLDHashEntryHdr
|
---|
96 | {
|
---|
97 | public:
|
---|
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 |
|
---|
114 | PLDHashOperator
|
---|
115 | nsTEnumGo(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 |
|
---|
122 | PLDHashOperator
|
---|
123 | nsTEnumStop(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 |
|
---|
130 | void
|
---|
131 | testTHashtable(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 |
|
---|
190 | PLDHashOperator
|
---|
191 | nsDEnumRead(const PRUint32& aKey, const char* aData, void* userArg) {
|
---|
192 | printf(" enumerated %u = \"%s\"\n", aKey, aData);
|
---|
193 | return PL_DHASH_NEXT;
|
---|
194 | }
|
---|
195 |
|
---|
196 | PLDHashOperator
|
---|
197 | nsDEnum(const PRUint32& aKey, const char*& aData, void* userArg) {
|
---|
198 | printf(" enumerated %u = \"%s\"\n", aKey, aData);
|
---|
199 | return PL_DHASH_NEXT;
|
---|
200 | }
|
---|
201 |
|
---|
202 | PLDHashOperator
|
---|
203 | nsCEnumRead(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 |
|
---|
209 | PLDHashOperator
|
---|
210 | nsCEnum(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 |
|
---|
224 | class 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 |
|
---|
251 | unsigned int IFoo::total_constructions_;
|
---|
252 | unsigned int IFoo::total_destructions_;
|
---|
253 |
|
---|
254 | void
|
---|
255 | IFoo::print_totals()
|
---|
256 | {
|
---|
257 | printf("total constructions/destructions --> %d/%d\n",
|
---|
258 | total_constructions_, total_destructions_);
|
---|
259 | }
|
---|
260 |
|
---|
261 | IFoo::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 |
|
---|
269 | IFoo::~IFoo()
|
---|
270 | {
|
---|
271 | ++total_destructions_;
|
---|
272 | printf("IFoo@%p::~IFoo() [#%d]\n",
|
---|
273 | NS_STATIC_CAST(void*, this), total_destructions_);
|
---|
274 | }
|
---|
275 |
|
---|
276 | nsrefcnt
|
---|
277 | IFoo::AddRef()
|
---|
278 | {
|
---|
279 | ++refcount_;
|
---|
280 | printf("IFoo@%p::AddRef(), refcount --> %d\n",
|
---|
281 | NS_STATIC_CAST(void*, this), refcount_);
|
---|
282 | return refcount_;
|
---|
283 | }
|
---|
284 |
|
---|
285 | nsrefcnt
|
---|
286 | IFoo::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 |
|
---|
308 | nsresult
|
---|
309 | IFoo::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 |
|
---|
332 | nsresult
|
---|
333 | IFoo::SetString(const nsACString& aString)
|
---|
334 | {
|
---|
335 | mString = aString;
|
---|
336 | return NS_OK;
|
---|
337 | }
|
---|
338 |
|
---|
339 | nsresult
|
---|
340 | IFoo::GetString(nsACString& aString)
|
---|
341 | {
|
---|
342 | aString = mString;
|
---|
343 | return NS_OK;
|
---|
344 | }
|
---|
345 |
|
---|
346 | nsresult
|
---|
347 | CreateIFoo( 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 |
|
---|
361 | PLDHashOperator
|
---|
362 | nsIEnumRead(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 |
|
---|
370 | PLDHashOperator
|
---|
371 | nsIEnum(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 |
|
---|
379 | PLDHashOperator
|
---|
380 | nsIEnum2Read(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 |
|
---|
390 | PLDHashOperator
|
---|
391 | nsIEnum2(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 |
|
---|
400 | int
|
---|
401 | main(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 | }
|
---|