xpcom/tests/TestCOMPtr.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 "nsISupports.h"
    11 #define NS_IFOO_IID \
    12 { 0x6f7652e0,  0xee43, 0x11d1, \
    13  { 0x9c, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
    15 class IFoo : public nsISupports
    16   {
    17 		public:
    18 			NS_DECLARE_STATIC_IID_ACCESSOR(NS_IFOO_IID)
    20 		public:
    21       IFoo();
    22       // virtual dtor because IBar uses our Release()
    23       virtual ~IFoo();
    25       NS_IMETHOD_(MozExternalRefCountType) AddRef();
    26       NS_IMETHOD_(MozExternalRefCountType) Release();
    27       NS_IMETHOD QueryInterface( const nsIID&, void** );
    29       static void print_totals();
    31     private:
    32       unsigned int refcount_;
    34       static unsigned int total_constructions_;
    35       static unsigned int total_destructions_;
    36   };
    38 NS_DEFINE_STATIC_IID_ACCESSOR(IFoo, NS_IFOO_IID)
    40 class IBar;
    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_;
    60 class test_message
    61   {
    62     public:
    63       test_message()
    64         {
    65           printf("BEGIN unit tests for |nsCOMPtr|, compiled " __DATE__ "\n");
    66         }
    68      ~test_message()
    69         {
    70           IFoo::print_totals();
    71           printf("END unit tests for |nsCOMPtr|.\n");
    72         }
    73   };
    75 test_message gTestMessage;
    78   /*
    79     ...
    80   */
    82 void
    83 IFoo::print_totals()
    84   {
    85     printf("total constructions/destructions --> %d/%d\n", 
    86            total_constructions_, total_destructions_);
    87   }
    89 IFoo::IFoo()
    90     : refcount_(0)
    91   {
    92     ++total_constructions_;
    93     printf("  new IFoo@%p [#%d]\n",
    94            static_cast<void*>(this), total_constructions_);
    95   }
    97 IFoo::~IFoo()
    98   {
    99     ++total_destructions_;
   100     printf("IFoo@%p::~IFoo() [#%d]\n",
   101            static_cast<void*>(this), total_destructions_);
   102   }
   104 MozExternalRefCountType
   105 IFoo::AddRef()
   106   {
   107     ++refcount_;
   108     printf("IFoo@%p::AddRef(), refcount --> %d\n", 
   109            static_cast<void*>(this), refcount_);
   110     return refcount_;
   111   }
   113 MozExternalRefCountType
   114 IFoo::Release()
   115   {
   116     int newcount = --refcount_;
   117     if ( newcount == 0 )
   118       printf(">>");
   120     printf("IFoo@%p::Release(), refcount --> %d\n",
   121            static_cast<void*>(this), refcount_);
   123     if ( newcount == 0 )
   124       {
   125         printf("  delete IFoo@%p\n", static_cast<void*>(this));
   126         printf("<<IFoo@%p::Release()\n", static_cast<void*>(this));
   127         delete this;
   128       }
   130     return newcount;
   131   }
   133 nsresult
   134 IFoo::QueryInterface( const nsIID& aIID, void** aResult )
   135 	{
   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)) )
   141 			rawPtr = this;
   142 		else
   143 			{
   144 				nsID iid_of_ISupports = NS_ISUPPORTS_IID;
   145 				if ( aIID.Equals(iid_of_ISupports) )
   146 					rawPtr = static_cast<nsISupports*>(this);
   147 				else
   148 					status = NS_ERROR_NO_INTERFACE;
   149 			}
   151 		NS_IF_ADDREF(rawPtr);
   152 		*aResult = rawPtr;
   154 		return status;
   155 	}
   157 nsresult
   158 CreateIFoo( void** result )
   159     // a typical factory function (that calls AddRef)
   160   {
   161     printf(">>CreateIFoo() --> ");
   162     IFoo* foop = new IFoo;
   163     printf("IFoo@%p\n", static_cast<void*>(foop));
   165     foop->AddRef();
   166     *result = foop;
   168     printf("<<CreateIFoo()\n");
   169     return NS_OK;
   170   }
   172 void
   173 set_a_IFoo( nsCOMPtr<IFoo>* result )
   174   {
   175     printf(">>set_a_IFoo()\n");
   176     assert(result);
   178     nsCOMPtr<IFoo> foop( do_QueryInterface(new IFoo) );
   179     *result = foop;
   180     printf("<<set_a_IFoo()\n");
   181   }
   183 nsCOMPtr<IFoo>
   184 return_a_IFoo()
   185   {
   186     printf(">>return_a_IFoo()\n");
   187     nsCOMPtr<IFoo> foop( do_QueryInterface(new IFoo) );
   188     printf("<<return_a_IFoo()\n");
   189     return foop;
   190   }
   195 #define NS_IBAR_IID \
   196 { 0x6f7652e1,  0xee43, 0x11d1, \
   197  { 0x9c, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
   199 class IBar : public IFoo
   200   {
   201   	public:
   202   		NS_DECLARE_STATIC_IID_ACCESSOR(NS_IBAR_IID)
   204     public:
   205       IBar();
   206       virtual ~IBar();
   208       NS_IMETHOD QueryInterface( const nsIID&, void** );
   209   };
   211 NS_DEFINE_STATIC_IID_ACCESSOR(IBar, NS_IBAR_IID)
   213 IBar::IBar()
   214   {
   215     printf("  new IBar@%p\n", static_cast<void*>(this));
   216   }
   218 IBar::~IBar()
   219   {
   220     printf("IBar@%p::~IBar()\n", static_cast<void*>(this));
   221   }
   223 nsresult
   224 IBar::QueryInterface( const nsID& aIID, void** aResult )
   225 	{
   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)) )
   231 			rawPtr = this;
   232 		else if ( aIID.Equals(NS_GET_IID(IFoo)) )
   233 			rawPtr = static_cast<IFoo*>(this);
   234 		else
   235 			{
   236 				nsID iid_of_ISupports = NS_ISUPPORTS_IID;
   237 				if ( aIID.Equals(iid_of_ISupports) )
   238 					rawPtr = static_cast<nsISupports*>(this);
   239 				else
   240 					status = NS_ERROR_NO_INTERFACE;
   241 			}
   243 		NS_IF_ADDREF(rawPtr);
   244 		*aResult = rawPtr;
   246 		return status;
   247 	}
   251 nsresult
   252 CreateIBar( void** result )
   253     // a typical factory function (that calls AddRef)
   254   {
   255     printf(">>CreateIBar() --> ");
   256     IBar* barp = new IBar;
   257     printf("IBar@%p\n", static_cast<void*>(barp));
   259     barp->AddRef();
   260     *result = barp;
   262     printf("<<CreateIBar()\n");
   263     return NS_OK;
   264   }
   266 void
   267 AnIFooPtrPtrContext( IFoo** )
   268   {
   269   }
   271 void
   272 AVoidPtrPtrContext( void** )
   273   {
   274   }
   276 void
   277 AnISupportsPtrPtrContext( nsISupports** )
   278 	{
   279 	}
   281 static
   282 nsresult
   283 TestBloat_Raw_Unsafe()
   284 	{
   285 		IBar* barP = 0;
   286 		nsresult result = CreateIBar(reinterpret_cast<void**>(&barP));
   288 		if ( barP )
   289 			{
   290 				IFoo* fooP = 0;
   291 				if ( NS_SUCCEEDED( result = barP->QueryInterface(NS_GET_IID(IFoo), 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 		nsCOMPtr<IBar> barP;
   309 		nsresult result = CreateIBar( getter_AddRefs(barP) );
   311 		nsCOMPtr<IFoo> fooP( do_QueryInterface(barP, &result) );
   313 		if ( fooP )
   314 			fooP->print_totals();
   316 		return result;
   317 	}
   322 nsCOMPtr<IFoo> gFoop;
   324 int
   325 main()
   326   {
   327     printf(">>main()\n");
   329 		printf("sizeof(nsCOMPtr<IFoo>) --> %u\n", unsigned(sizeof(nsCOMPtr<IFoo>)));
   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       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?
   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<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");
   358     }
   360     {
   361       printf("\n### Test  6: will a |nsCOMPtr| call the correct destructor?\n");
   362       nsCOMPtr<IFoo> foop( do_QueryInterface(new IBar) );
   363     }
   365     {
   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");
   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       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");
   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 ( nsCOMPtr<IFoo>( 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       IFoo* raw_foo1p = new IFoo;
   449       raw_foo1p->AddRef();
   451       IFoo* raw_foo2p = new IFoo;
   452       raw_foo2p->AddRef();
   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);
   461     }
   469     {
   470     	printf("\n### setup for Test 17\n");
   471       nsCOMPtr<IFoo> foop;
   472       printf("### Test 17: basic parameter behavior?\n");
   473       CreateIFoo( nsGetterAddRefs<IFoo>(foop) );
   474     }
   475     printf("### End Test 17\n");
   478     {
   479     	printf("\n### setup for Test 18\n");
   480       nsCOMPtr<IFoo> foop;
   481       printf("### Test 18: basic parameter behavior, using the short form?\n");
   482       CreateIFoo( getter_AddRefs(foop) );
   483     }
   484     printf("### End Test 18\n");
   487     {
   488     	printf("\n### setup for Test 19, 20\n");
   489       nsCOMPtr<IFoo> foop;
   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();
   495     }
   496     printf("### End Test 19, 20\n");
   498 		{
   499     	printf("\n### setup for Test 21\n");
   500 			nsCOMPtr<IFoo> fooP;
   502 			printf("### Test 21: is |QueryInterface| called on assigning in a raw pointer?\n");
   503 			fooP = do_QueryInterface(new IFoo);
   504 		}
   505     printf("### End Test 21\n");
   507 		{
   508     	printf("\n### setup for Test 22\n");
   509 			nsCOMPtr<IFoo> fooP;
   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");
   515 			foo2P = fooP;
   516 		}
   517     printf("### End Test 22\n");
   519 		{
   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) );
   526 			if ( fooP )
   527 				printf("an IBar* is an IFoo*\n");
   528 		}
   529     printf("### End Test 23\n");
   532 		{
   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() );
   538 		}
   539     printf("### End Test 24\n");
   541 		{
   542 			nsCOMPtr<IFoo> fooP;
   544 			AnIFooPtrPtrContext( getter_AddRefs(fooP) );
   545 			AVoidPtrPtrContext( getter_AddRefs(fooP) );
   546 		}
   549 		{
   550 			nsCOMPtr<nsISupports> supportsP;
   552 			AVoidPtrPtrContext( getter_AddRefs(supportsP) );
   553 			AnISupportsPtrPtrContext( getter_AddRefs(supportsP) );
   554 		}
   557     printf("\n### Test 25: will a static |nsCOMPtr| |Release| before program termination?\n");
   558     gFoop = do_QueryInterface(new IFoo);
   560     printf("<<main()\n");
   561     return 0;
   562   }

mercurial