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