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