xpcom/tests/TestRefPtr.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     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/. */
     6 #include <assert.h>
     7 #include <stdio.h>
     8 #include "nsCOMPtr.h"
     9 #include "nsAutoPtr.h"
    10 #include "nsISupports.h"
    12 #define NS_FOO_IID \
    13 { 0x6f7652e0,  0xee43, 0x11d1, \
    14  { 0x9c, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
    16 class Foo : public nsISupports
    17   {
    18 		public:
    19 			NS_DECLARE_STATIC_IID_ACCESSOR(NS_FOO_IID)
    21 		public:
    22       Foo();
    23       // virtual dtor because Bar uses our Release()
    24       virtual ~Foo();
    26       NS_IMETHOD_(MozExternalRefCountType) AddRef();
    27       NS_IMETHOD_(MozExternalRefCountType) Release();
    28       NS_IMETHOD QueryInterface( const nsIID&, void** );
    30       static void print_totals();
    32     private:
    33       unsigned int refcount_;
    35       static unsigned int total_constructions_;
    36       static unsigned int total_destructions_;
    37   };
    39 NS_DEFINE_STATIC_IID_ACCESSOR(Foo, NS_FOO_IID)
    41 class Bar;
    43   // some types I'll need
    44 typedef unsigned long NS_RESULT;
    46   // some functions I'll need (and define below)
    47           nsresult  CreateFoo( void** );
    48           nsresult  CreateBar( void** result );
    49               void  AnFooPtrPtrContext( Foo** );
    50               void	AnISupportsPtrPtrContext( nsISupports** );
    51               void  AVoidPtrPtrContext( void** );
    52               void  set_a_Foo( nsRefPtr<Foo>* result );
    53 nsRefPtr<Foo>  return_a_Foo();
    58 unsigned int Foo::total_constructions_;
    59 unsigned int Foo::total_destructions_;
    61 class test_message
    62   {
    63     public:
    64       test_message()
    65         {
    66           printf("BEGIN unit tests for |nsRefPtr|, compiled " __DATE__ "\n");
    67         }
    69      ~test_message()
    70         {
    71           Foo::print_totals();
    72           printf("END unit tests for |nsRefPtr|.\n");
    73         }
    74   };
    76 test_message gTestMessage;
    79   /*
    80     ...
    81   */
    83 void
    84 Foo::print_totals()
    85   {
    86     printf("total constructions/destructions --> %d/%d\n", 
    87            total_constructions_, total_destructions_);
    88   }
    90 Foo::Foo()
    91     : refcount_(0)
    92   {
    93     ++total_constructions_;
    94     printf("  new Foo@%p [#%d]\n",
    95            static_cast<void*>(this), total_constructions_);
    96   }
    98 Foo::~Foo()
    99   {
   100     ++total_destructions_;
   101     printf("Foo@%p::~Foo() [#%d]\n",
   102            static_cast<void*>(this), total_destructions_);
   103   }
   105 MozExternalRefCountType
   106 Foo::AddRef()
   107   {
   108     ++refcount_;
   109     printf("Foo@%p::AddRef(), refcount --> %d\n",
   110            static_cast<void*>(this), refcount_);
   111     return refcount_;
   112   }
   114 MozExternalRefCountType
   115 Foo::Release()
   116   {
   117     int newcount = --refcount_;
   118     if ( newcount == 0 )
   119       printf(">>");
   121     printf("Foo@%p::Release(), refcount --> %d\n",
   122            static_cast<void*>(this), refcount_);
   124     if ( newcount == 0 )
   125       {
   126         printf("  delete Foo@%p\n", static_cast<void*>(this));
   127         printf("<<Foo@%p::Release()\n", static_cast<void*>(this));
   128         delete this;
   129       }
   131     return newcount;
   132   }
   134 nsresult
   135 Foo::QueryInterface( const nsIID& aIID, void** aResult )
   136 	{
   137     printf("Foo@%p::QueryInterface()\n", static_cast<void*>(this));
   138 		nsISupports* rawPtr = 0;
   139 		nsresult status = NS_OK;
   141 		if ( aIID.Equals(NS_GET_IID(Foo)) )
   142 			rawPtr = this;
   143 		else
   144 			{
   145 				nsID iid_of_ISupports = NS_ISUPPORTS_IID;
   146 				if ( aIID.Equals(iid_of_ISupports) )
   147 					rawPtr = static_cast<nsISupports*>(this);
   148 				else
   149 					status = NS_ERROR_NO_INTERFACE;
   150 			}
   152 		NS_IF_ADDREF(rawPtr);
   153 		*aResult = rawPtr;
   155 		return status;
   156 	}
   158 nsresult
   159 CreateFoo( void** result )
   160     // a typical factory function (that calls AddRef)
   161   {
   162     printf(">>CreateFoo() --> ");
   163     Foo* foop = new Foo;
   164     printf("Foo@%p\n", static_cast<void*>(foop));
   166     foop->AddRef();
   167     *result = foop;
   169     printf("<<CreateFoo()\n");
   170     return NS_OK;
   171   }
   173 void
   174 set_a_Foo( nsRefPtr<Foo>* result )
   175   {
   176     printf(">>set_a_Foo()\n");
   177     assert(result);
   179     nsRefPtr<Foo> foop( do_QueryObject(new Foo) );
   180     *result = foop;
   181     printf("<<set_a_Foo()\n");
   182   }
   184 nsRefPtr<Foo>
   185 return_a_Foo()
   186   {
   187     printf(">>return_a_Foo()\n");
   188     nsRefPtr<Foo> foop( do_QueryObject(new Foo) );
   189     printf("<<return_a_Foo()\n");
   190     return foop;
   191   }
   196 #define NS_BAR_IID \
   197 { 0x6f7652e1,  0xee43, 0x11d1, \
   198  { 0x9c, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
   200 class Bar : public Foo
   201   {
   202   	public:
   203 		NS_DECLARE_STATIC_IID_ACCESSOR(NS_BAR_IID)
   205     public:
   206       Bar();
   207       virtual ~Bar();
   209       NS_IMETHOD QueryInterface( const nsIID&, void** );
   210   };
   212 NS_DEFINE_STATIC_IID_ACCESSOR(Bar, NS_BAR_IID)
   214 Bar::Bar()
   215   {
   216     printf("  new Bar@%p\n", static_cast<void*>(this));
   217   }
   219 Bar::~Bar()
   220   {
   221     printf("Bar@%p::~Bar()\n", static_cast<void*>(this));
   222   }
   224 nsresult
   225 Bar::QueryInterface( const nsID& aIID, void** aResult )
   226 	{
   227     printf("Bar@%p::QueryInterface()\n", static_cast<void*>(this));
   228 		nsISupports* rawPtr = 0;
   229 		nsresult status = NS_OK;
   231 		if ( aIID.Equals(NS_GET_IID(Bar)) )
   232 			rawPtr = this;
   233 		else if ( aIID.Equals(NS_GET_IID(Foo)) )
   234 			rawPtr = static_cast<Foo*>(this);
   235 		else
   236 			{
   237 				nsID iid_of_ISupports = NS_ISUPPORTS_IID;
   238 				if ( aIID.Equals(iid_of_ISupports) )
   239 					rawPtr = static_cast<nsISupports*>(this);
   240 				else
   241 					status = NS_ERROR_NO_INTERFACE;
   242 			}
   244 		NS_IF_ADDREF(rawPtr);
   245 		*aResult = rawPtr;
   247 		return status;
   248 	}
   252 nsresult
   253 CreateBar( void** result )
   254     // a typical factory function (that calls AddRef)
   255   {
   256     printf(">>CreateBar() --> ");
   257     Bar* barp = new Bar;
   258     printf("Bar@%p\n", static_cast<void*>(barp));
   260     barp->AddRef();
   261     *result = barp;
   263     printf("<<CreateBar()\n");
   264     return NS_OK;
   265   }
   267 void
   268 AnFooPtrPtrContext( Foo** )
   269   {
   270   }
   272 void
   273 AVoidPtrPtrContext( void** )
   274   {
   275   }
   277 void
   278 AnISupportsPtrPtrContext( nsISupports** )
   279 	{
   280 	}
   282 nsresult
   283 TestBloat_Raw_Unsafe()
   284 	{
   285 		Bar* barP = 0;
   286 		nsresult result = CreateBar(reinterpret_cast<void**>(&barP));
   288 		if ( barP )
   289 			{
   290 				Foo* fooP = 0;
   291 				if ( NS_SUCCEEDED( result = barP->QueryInterface(NS_GET_IID(Foo), reinterpret_cast<void**>(&fooP)) ) )
   292 					{
   293 						fooP->print_totals();
   294 						NS_RELEASE(fooP);
   295 					}
   297 				NS_RELEASE(barP);
   298 			}
   300 		return result;
   301 	}
   304 static
   305 nsresult
   306 TestBloat_Smart()
   307 	{
   308 		nsRefPtr<Bar> barP;
   309 		nsresult result = CreateBar( getter_AddRefs(barP) );
   311 		nsRefPtr<Foo> fooP( do_QueryObject(barP, &result) );
   313 		if ( fooP )
   314 			fooP->print_totals();
   316 		return result;
   317 	}
   322 nsRefPtr<Foo> gFoop;
   324 int
   325 main()
   326   {
   327     printf(">>main()\n");
   329 		printf("sizeof(nsRefPtr<Foo>) --> %u\n", unsigned(sizeof(nsRefPtr<Foo>)));
   331 		TestBloat_Raw_Unsafe();
   332 		TestBloat_Smart();
   335     {
   336       printf("\n### Test  1: will a |nsCOMPtr| call |AddRef| on a pointer assigned into it?\n");
   337       nsRefPtr<Foo> foop( do_QueryObject(new Foo) );
   339       printf("\n### Test  2: will a |nsCOMPtr| |Release| its old pointer when a new one is assigned in?\n");
   340       foop = do_QueryObject(new Foo);
   342         // [Shouldn't compile] Is it a compile time error to try to |AddRef| by hand?
   343       //foop->AddRef();
   345         // [Shouldn't compile] Is it a compile time error to try to |Release| be hand?
   346       //foop->Release();
   348 				// [Shouldn't compile] Is it a compile time error to try to |delete| an |nsCOMPtr|?
   349 			//delete foop;
   351       printf("\n### Test  3: can you |AddRef| if you must?\n");
   352       static_cast<Foo*>(foop)->AddRef();
   354       printf("\n### Test  4: can you |Release| if you must?\n");
   355       static_cast<Foo*>(foop)->Release();
   357       printf("\n### Test  5: will a |nsCOMPtr| |Release| when it goes out of scope?\n");
   358     }
   360     {
   361       printf("\n### Test  6: will a |nsCOMPtr| call the correct destructor?\n");
   362       nsRefPtr<Foo> foop( do_QueryObject(new Bar) );
   363     }
   365     {
   366       printf("\n### Test  7: can you compare one |nsCOMPtr| with another [!=]?\n");
   368       nsRefPtr<Foo> foo1p( do_QueryObject(new Foo) );
   370         // [Shouldn't compile] Is it a compile time error to omit |getter_[doesnt_]AddRef[s]|?
   371       //AnFooPtrPtrContext(&foo1p);
   373         // [Shouldn't compile] Is it a compile time error to omit |getter_[doesnt_]AddRef[s]|?
   374       //AVoidPtrPtrContext(&foo1p);
   376       nsRefPtr<Foo> foo2p( do_QueryObject(new Foo) );
   378       if ( foo1p != foo2p )
   379         printf("foo1p != foo2p\n");
   380       else
   381         printf("foo1p == foo2p\n");
   383       printf("\n### Test  7.5: can you compare a |nsCOMPtr| with NULL, 0, nullptr [!=]?\n");
   384       if ( foo1p != 0 )
   385       	printf("foo1p != 0\n");
   386       if ( 0 != foo1p )
   387       	printf("0 != foo1p\n");
   388       if ( foo1p == 0 )
   389       	printf("foo1p == 0\n");
   390       if ( 0 == foo1p )
   391       	printf("0 == foo1p\n");
   394       Foo* 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");
   399       else
   400         printf("foo1p == raw_foo2p\n");
   403       printf("\n### Test  9: can you assign one |nsCOMPtr| into another?\n");
   404       foo1p = foo2p;
   406       printf("\n### Test 10: can you compare one |nsCOMPtr| with another [==]?\n");
   407       if ( foo1p == foo2p )
   408         printf("foo1p == foo2p\n");
   409       else
   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");
   415       else
   416         printf("raw_foo2p != foo2p\n");
   418 #if 1
   419       printf("\n### Test 11.5: can you compare a |nsCOMPtr| with a raw interface pointer [==]?\n");
   420       if ( nsRefPtr<Foo>( raw_foo2p ) == foo2p )
   421         printf("raw_foo2p == foo2p\n");
   422       else
   423         printf("raw_foo2p != foo2p\n");
   424 #endif
   426       printf("\n### Test 12: bare pointer test?\n");
   427       if ( foo1p )
   428         printf("foo1p is not NULL\n");
   429       else
   430         printf("foo1p is NULL\n");
   432       printf("\n### Test 13: numeric pointer test?\n");
   433       if ( foo1p == 0 )
   434         printf("foo1p is NULL\n");
   435       else
   436         printf("foo1p is not NULL\n");
   438 #if 0
   439 			if ( foo1p == 1 )
   440 				printf("foo1p allowed compare with in\n");
   441 #endif
   443       printf("\n### Test 14: how about when two |nsCOMPtr|s referring to the same object go out of scope?\n");
   444     }
   446     {
   447       printf("\n### Test 15,16 ...setup...\n");
   448       Foo* raw_foo1p = new Foo;
   449       raw_foo1p->AddRef();
   451       Foo* raw_foo2p = new Foo;
   452       raw_foo2p->AddRef();
   454       printf("\n### Test 15: what if I don't want to |AddRef| when I construct?\n");
   455       nsRefPtr<Foo> foo1p( dont_AddRef(raw_foo1p) );
   456       //nsRefPtr<Foo> foo1p = dont_AddRef(raw_foo1p);
   458       printf("\n### Test 16: what if I don't want to |AddRef| when I assign in?\n");
   459       nsRefPtr<Foo> foo2p;
   460       foo2p = dont_AddRef(raw_foo2p);
   461     }
   469     {
   470     	printf("\n### setup for Test 17\n");
   471       nsRefPtr<Foo> foop;
   472       printf("### Test 17: basic parameter behavior?\n");
   473       CreateFoo( nsRefPtrGetterAddRefs<Foo>(foop) );
   474     }
   475     printf("### End Test 17\n");
   478     {
   479     	printf("\n### setup for Test 18\n");
   480       nsRefPtr<Foo> foop;
   481       printf("### Test 18: basic parameter behavior, using the short form?\n");
   482       CreateFoo( getter_AddRefs(foop) );
   483     }
   484     printf("### End Test 18\n");
   487     {
   488     	printf("\n### setup for Test 19, 20\n");
   489       nsRefPtr<Foo> foop;
   490       printf("### Test 19: reference parameter behavior?\n");
   491       set_a_Foo(address_of(foop));
   493       printf("### Test 20: return value behavior?\n");
   494       foop = return_a_Foo();
   495     }
   496     printf("### End Test 19, 20\n");
   498 		{
   499     	printf("\n### setup for Test 21\n");
   500 			nsRefPtr<Foo> fooP;
   502 			printf("### Test 21: is |QueryInterface| called on assigning in a raw pointer?\n");
   503 			fooP = do_QueryObject(new Foo);
   504 		}
   505     printf("### End Test 21\n");
   507 		{
   508     	printf("\n### setup for Test 22\n");
   509 			nsRefPtr<Foo> fooP;
   510 			fooP = do_QueryObject(new Foo);
   512 			nsRefPtr<Foo> foo2P;
   514 			printf("### Test 22: is |QueryInterface| _not_ called when assigning in a smart-pointer of the same type?\n");
   515 			foo2P = fooP;
   516 		}
   517     printf("### End Test 22\n");
   519 		{
   520     	printf("\n### setup for Test 23\n");
   521 			nsRefPtr<Bar> barP( do_QueryObject(new Bar) );
   523 			printf("### Test 23: is |QueryInterface| called when assigning in a smart-pointer of a different type?\n");
   525 			nsRefPtr<Foo> fooP( do_QueryObject(barP) );
   526 			if ( fooP )
   527 				printf("an Bar* is an Foo*\n");
   528 		}
   529     printf("### End Test 23\n");
   532 		{
   533     	printf("\n### setup for Test 24\n");
   534 			nsRefPtr<Foo> fooP( do_QueryObject(new Foo) );
   536 			printf("### Test 24: does |forget| avoid an AddRef/Release when assigning to another nsCOMPtr?\n");
   537       nsRefPtr<Foo> fooP2( fooP.forget() );
   538 		}
   539     printf("### End Test 24\n");
   541 		{
   542 			nsRefPtr<Foo> fooP;
   544 			AnFooPtrPtrContext( getter_AddRefs(fooP) );
   545 			AVoidPtrPtrContext( getter_AddRefs(fooP) );
   546 		}
   549     printf("\n### Test 25: will a static |nsCOMPtr| |Release| before program termination?\n");
   550     gFoop = do_QueryObject(new Foo);
   552     printf("<<main()\n");
   553     return 0;
   554   }

mercurial