1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
9 #include "nsISupports.h"
12 { 0x6f7652e0, 0xee43, 0x11d1, \
13 { 0x9c, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
15 class IFoo
: public nsISupports
18 NS_DECLARE_STATIC_IID_ACCESSOR(NS_IFOO_IID
)
22 // virtual dtor because IBar uses our Release()
25 NS_IMETHOD_(MozExternalRefCountType
) AddRef();
26 NS_IMETHOD_(MozExternalRefCountType
) Release();
27 NS_IMETHOD
QueryInterface( const nsIID
&, void** );
29 static void print_totals();
32 unsigned int refcount_
;
34 static unsigned int total_constructions_
;
35 static unsigned int total_destructions_
;
38 NS_DEFINE_STATIC_IID_ACCESSOR(IFoo
, NS_IFOO_IID
)
42 // some types I'll need
43 typedef unsigned long NS_RESULT
;
45 // some functions I'll need (and define below)
46 nsresult
CreateIFoo( void** );
47 nsresult
CreateIBar( void** result
);
48 void AnIFooPtrPtrContext( IFoo
** );
49 void AnISupportsPtrPtrContext( nsISupports
** );
50 void AVoidPtrPtrContext( void** );
51 void set_a_IFoo( nsCOMPtr
<IFoo
>* result
);
52 nsCOMPtr
<IFoo
> return_a_IFoo();
57 unsigned int IFoo::total_constructions_
;
58 unsigned int IFoo::total_destructions_
;
65 printf("BEGIN unit tests for |nsCOMPtr|, compiled " __DATE__
"\n");
71 printf("END unit tests for |nsCOMPtr|.\n");
75 test_message gTestMessage
;
85 printf("total constructions/destructions --> %d/%d\n",
86 total_constructions_
, total_destructions_
);
92 ++total_constructions_
;
93 printf(" new IFoo@%p [#%d]\n",
94 static_cast<void*>(this), total_constructions_
);
99 ++total_destructions_
;
100 printf("IFoo@%p::~IFoo() [#%d]\n",
101 static_cast<void*>(this), total_destructions_
);
104 MozExternalRefCountType
108 printf("IFoo@%p::AddRef(), refcount --> %d\n",
109 static_cast<void*>(this), refcount_
);
113 MozExternalRefCountType
116 int newcount
= --refcount_
;
120 printf("IFoo@%p::Release(), refcount --> %d\n",
121 static_cast<void*>(this), refcount_
);
125 printf(" delete IFoo@%p\n", static_cast<void*>(this));
126 printf("<<IFoo@%p::Release()\n", static_cast<void*>(this));
134 IFoo::QueryInterface( const nsIID
& aIID
, void** aResult
)
136 printf("IFoo@%p::QueryInterface()\n", static_cast<void*>(this));
137 nsISupports
* rawPtr
= 0;
138 nsresult status
= NS_OK
;
140 if ( aIID
.Equals(NS_GET_IID(IFoo
)) )
144 nsID iid_of_ISupports
= NS_ISUPPORTS_IID
;
145 if ( aIID
.Equals(iid_of_ISupports
) )
146 rawPtr
= static_cast<nsISupports
*>(this);
148 status
= NS_ERROR_NO_INTERFACE
;
151 NS_IF_ADDREF(rawPtr
);
158 CreateIFoo( void** result
)
159 // a typical factory function (that calls AddRef)
161 printf(">>CreateIFoo() --> ");
162 IFoo
* foop
= new IFoo
;
163 printf("IFoo@%p\n", static_cast<void*>(foop
));
168 printf("<<CreateIFoo()\n");
173 set_a_IFoo( nsCOMPtr
<IFoo
>* result
)
175 printf(">>set_a_IFoo()\n");
178 nsCOMPtr
<IFoo
> foop( do_QueryInterface(new IFoo
) );
180 printf("<<set_a_IFoo()\n");
186 printf(">>return_a_IFoo()\n");
187 nsCOMPtr
<IFoo
> foop( do_QueryInterface(new IFoo
) );
188 printf("<<return_a_IFoo()\n");
195 #define NS_IBAR_IID \
196 { 0x6f7652e1, 0xee43, 0x11d1, \
197 { 0x9c, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
199 class IBar
: public IFoo
202 NS_DECLARE_STATIC_IID_ACCESSOR(NS_IBAR_IID
)
208 NS_IMETHOD
QueryInterface( const nsIID
&, void** );
211 NS_DEFINE_STATIC_IID_ACCESSOR(IBar
, NS_IBAR_IID
)
215 printf(" new IBar@%p\n", static_cast<void*>(this));
220 printf("IBar@%p::~IBar()\n", static_cast<void*>(this));
224 IBar::QueryInterface( const nsID
& aIID
, void** aResult
)
226 printf("IBar@%p::QueryInterface()\n", static_cast<void*>(this));
227 nsISupports
* rawPtr
= 0;
228 nsresult status
= NS_OK
;
230 if ( aIID
.Equals(NS_GET_IID(IBar
)) )
232 else if ( aIID
.Equals(NS_GET_IID(IFoo
)) )
233 rawPtr
= static_cast<IFoo
*>(this);
236 nsID iid_of_ISupports
= NS_ISUPPORTS_IID
;
237 if ( aIID
.Equals(iid_of_ISupports
) )
238 rawPtr
= static_cast<nsISupports
*>(this);
240 status
= NS_ERROR_NO_INTERFACE
;
243 NS_IF_ADDREF(rawPtr
);
252 CreateIBar( void** result
)
253 // a typical factory function (that calls AddRef)
255 printf(">>CreateIBar() --> ");
256 IBar
* barp
= new IBar
;
257 printf("IBar@%p\n", static_cast<void*>(barp
));
262 printf("<<CreateIBar()\n");
267 AnIFooPtrPtrContext( IFoo
** )
272 AVoidPtrPtrContext( void** )
277 AnISupportsPtrPtrContext( nsISupports
** )
283 TestBloat_Raw_Unsafe()
286 nsresult result
= CreateIBar(reinterpret_cast<void**>(&barP
));
291 if ( NS_SUCCEEDED( result
= barP
->QueryInterface(NS_GET_IID(IFoo
), reinterpret_cast<void**>(&fooP
)) ) )
293 fooP
->print_totals();
309 nsresult result
= CreateIBar( getter_AddRefs(barP
) );
311 nsCOMPtr
<IFoo
> fooP( do_QueryInterface(barP
, &result
) );
314 fooP
->print_totals();
322 nsCOMPtr
<IFoo
> gFoop
;
327 printf(">>main()\n");
329 printf("sizeof(nsCOMPtr<IFoo>) --> %u\n", unsigned(sizeof(nsCOMPtr
<IFoo
>)));
331 TestBloat_Raw_Unsafe();
336 printf("\n### Test 1: will a |nsCOMPtr| call |AddRef| on a pointer assigned into it?\n");
337 nsCOMPtr
<IFoo
> foop( do_QueryInterface(new IFoo
) );
339 printf("\n### Test 2: will a |nsCOMPtr| |Release| its old pointer when a new one is assigned in?\n");
340 foop
= do_QueryInterface(new IFoo
);
342 // [Shouldn't compile] Is it a compile time error to try to |AddRef| by hand?
345 // [Shouldn't compile] Is it a compile time error to try to |Release| be hand?
348 // [Shouldn't compile] Is it a compile time error to try to |delete| an |nsCOMPtr|?
351 printf("\n### Test 3: can you |AddRef| if you must?\n");
352 static_cast<IFoo
*>(foop
)->AddRef();
354 printf("\n### Test 4: can you |Release| if you must?\n");
355 static_cast<IFoo
*>(foop
)->Release();
357 printf("\n### Test 5: will a |nsCOMPtr| |Release| when it goes out of scope?\n");
361 printf("\n### Test 6: will a |nsCOMPtr| call the correct destructor?\n");
362 nsCOMPtr
<IFoo
> foop( do_QueryInterface(new IBar
) );
366 printf("\n### Test 7: can you compare one |nsCOMPtr| with another [!=]?\n");
368 nsCOMPtr
<IFoo
> foo1p( do_QueryInterface(new IFoo
) );
370 // [Shouldn't compile] Is it a compile time error to omit |getter_[doesnt_]AddRef[s]|?
371 //AnIFooPtrPtrContext(&foo1p);
373 // [Shouldn't compile] Is it a compile time error to omit |getter_[doesnt_]AddRef[s]|?
374 //AVoidPtrPtrContext(&foo1p);
376 nsCOMPtr
<IFoo
> foo2p( do_QueryInterface(new IFoo
) );
378 if ( foo1p
!= foo2p
)
379 printf("foo1p != foo2p\n");
381 printf("foo1p == foo2p\n");
383 printf("\n### Test 7.5: can you compare a |nsCOMPtr| with NULL, 0, nullptr [!=]?\n");
385 printf("foo1p != 0\n");
387 printf("0 != foo1p\n");
389 printf("foo1p == 0\n");
391 printf("0 == foo1p\n");
394 IFoo
* raw_foo2p
= foo2p
.get();
396 printf("\n### Test 8: can you compare a |nsCOMPtr| with a raw interface pointer [!=]?\n");
397 if ( foo1p
.get() != raw_foo2p
)
398 printf("foo1p != raw_foo2p\n");
400 printf("foo1p == raw_foo2p\n");
403 printf("\n### Test 9: can you assign one |nsCOMPtr| into another?\n");
406 printf("\n### Test 10: can you compare one |nsCOMPtr| with another [==]?\n");
407 if ( foo1p
== foo2p
)
408 printf("foo1p == foo2p\n");
410 printf("foo1p != foo2p\n");
412 printf("\n### Test 11: can you compare a |nsCOMPtr| with a raw interface pointer [==]?\n");
413 if ( raw_foo2p
== foo2p
.get() )
414 printf("raw_foo2p == foo2p\n");
416 printf("raw_foo2p != foo2p\n");
419 printf("\n### Test 11.5: can you compare a |nsCOMPtr| with a raw interface pointer [==]?\n");
420 if ( nsCOMPtr
<IFoo
>( raw_foo2p
) == foo2p
)
421 printf("raw_foo2p == foo2p\n");
423 printf("raw_foo2p != foo2p\n");
426 printf("\n### Test 12: bare pointer test?\n");
428 printf("foo1p is not NULL\n");
430 printf("foo1p is NULL\n");
432 printf("\n### Test 13: numeric pointer test?\n");
434 printf("foo1p is NULL\n");
436 printf("foo1p is not NULL\n");
440 printf("foo1p allowed compare with in\n");
443 printf("\n### Test 14: how about when two |nsCOMPtr|s referring to the same object go out of scope?\n");
447 printf("\n### Test 15,16 ...setup...\n");
448 IFoo
* raw_foo1p
= new IFoo
;
451 IFoo
* raw_foo2p
= new IFoo
;
454 printf("\n### Test 15: what if I don't want to |AddRef| when I construct?\n");
455 nsCOMPtr
<IFoo
> foo1p( dont_AddRef(raw_foo1p
) );
456 //nsCOMPtr<IFoo> foo1p = dont_AddRef(raw_foo1p);
458 printf("\n### Test 16: what if I don't want to |AddRef| when I assign in?\n");
459 nsCOMPtr
<IFoo
> foo2p
;
460 foo2p
= dont_AddRef(raw_foo2p
);
470 printf("\n### setup for Test 17\n");
472 printf("### Test 17: basic parameter behavior?\n");
473 CreateIFoo( nsGetterAddRefs
<IFoo
>(foop
) );
475 printf("### End Test 17\n");
479 printf("\n### setup for Test 18\n");
481 printf("### Test 18: basic parameter behavior, using the short form?\n");
482 CreateIFoo( getter_AddRefs(foop
) );
484 printf("### End Test 18\n");
488 printf("\n### setup for Test 19, 20\n");
490 printf("### Test 19: reference parameter behavior?\n");
491 set_a_IFoo(address_of(foop
));
493 printf("### Test 20: return value behavior?\n");
494 foop
= return_a_IFoo();
496 printf("### End Test 19, 20\n");
499 printf("\n### setup for Test 21\n");
502 printf("### Test 21: is |QueryInterface| called on assigning in a raw pointer?\n");
503 fooP
= do_QueryInterface(new IFoo
);
505 printf("### End Test 21\n");
508 printf("\n### setup for Test 22\n");
510 fooP
= do_QueryInterface(new IFoo
);
512 nsCOMPtr
<IFoo
> foo2P
;
514 printf("### Test 22: is |QueryInterface| _not_ called when assigning in a smart-pointer of the same type?\n");
517 printf("### End Test 22\n");
520 printf("\n### setup for Test 23\n");
521 nsCOMPtr
<IBar
> barP( do_QueryInterface(new IBar
) );
523 printf("### Test 23: is |QueryInterface| called when assigning in a smart-pointer of a different type?\n");
525 nsCOMPtr
<IFoo
> fooP( do_QueryInterface(barP
) );
527 printf("an IBar* is an IFoo*\n");
529 printf("### End Test 23\n");
533 printf("\n### setup for Test 24\n");
534 nsCOMPtr
<IFoo
> fooP( do_QueryInterface(new IFoo
) );
536 printf("### Test 24: does |forget| avoid an AddRef/Release when assigning to another nsCOMPtr?\n");
537 nsCOMPtr
<IFoo
> fooP2( fooP
.forget() );
539 printf("### End Test 24\n");
544 AnIFooPtrPtrContext( getter_AddRefs(fooP
) );
545 AVoidPtrPtrContext( getter_AddRefs(fooP
) );
550 nsCOMPtr
<nsISupports
> supportsP
;
552 AVoidPtrPtrContext( getter_AddRefs(supportsP
) );
553 AnISupportsPtrPtrContext( getter_AddRefs(supportsP
) );
557 printf("\n### Test 25: will a static |nsCOMPtr| |Release| before program termination?\n");
558 gFoop
= do_QueryInterface(new IFoo
);
560 printf("<<main()\n");