Back to index

lightning-sunbird  0.9+nobinonly
TestXPTCInvokeInIDE.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Pierre Phaneuf <pp@ludusdesign.com>
00024  *   Stuart Parmenter <pavlov@netscape.com>
00025  *   Chris Seawood <cls@seawood.org>
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either of the GNU General Public License Version 2 or later (the "GPL"),
00029  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040 
00041 /* Invoke tests xptcall. */
00042 
00043 //#include <stdio.h>
00044 #include "stdafx.h"
00045 #include "xptcall.h"
00046 #include "prlong.h"
00047 #include "prinrval.h"
00048 #include "nsMemory.h"
00049 #include "nsXPCOM.h"
00050 #include "nsID.h"
00051 #include "nsIProxyObjectManager.h"
00052 #include "nsEmbedAPI.h"
00053 //#include "nsString.h"
00054 
00055 #include "InvokeTestTargetInterface.h"
00056 static NS_DEFINE_IID(kTheCID, INVOKETESTTARGETINTERFACE_IID);
00057 
00058 
00059 void MyOutputFunction(const char *str, ...);
00060 #define printf       MyOutputFunction
00061 
00062 
00063 // forward declration
00064 static void DoMultipleInheritenceTest();
00065 static void DoMultipleInheritenceTest2();
00066 static void DoSpeedTest();
00067 
00068 
00069 class InvokeTestTarget : public InvokeTestTargetInterface
00070 {
00071 public:
00072        NS_DECL_ISUPPORTS
00073        NS_DECL_INVOKETESTTARGETINTERFACE
00074 
00075     InvokeTestTarget();
00076 };
00077 
00078 NS_IMETHODIMP
00079 InvokeTestTarget::QueryInterface(REFNSIID aIID, void** aInstancePtr)
00080 {
00081   if (NULL == aInstancePtr) {
00082     return NS_ERROR_NULL_POINTER;
00083   }
00084 
00085   *aInstancePtr = NULL;
00086 
00087 
00088   if (aIID.Equals(kTheCID)) {
00089     *aInstancePtr = (void*) NS_STATIC_CAST(InvokeTestTargetInterface*,this);
00090     NS_ADDREF_THIS();
00091     return NS_OK;
00092   }
00093 
00094   if (aIID.Equals(NS_GET_IID(nsISupports))) {
00095     *aInstancePtr = (void*) NS_STATIC_CAST(nsISupports*,
00096                                            NS_STATIC_CAST(InvokeTestTargetInterface*,this));
00097     NS_ADDREF_THIS();
00098     return NS_OK;
00099   }
00100   return NS_NOINTERFACE;
00101 }
00102 
00103 NS_IMPL_ADDREF(InvokeTestTarget)
00104 NS_IMPL_RELEASE(InvokeTestTarget)
00105 
00106 
00107 InvokeTestTarget::InvokeTestTarget()
00108 {
00109     NS_ADDREF_THIS();
00110 }
00111 
00112 NS_IMETHODIMP
00113 InvokeTestTarget::AddTwoInts(PRInt32 p1, PRInt32 p2, PRInt32* retval)
00114 {
00115     *retval = p1 + p2;
00116     return NS_OK;
00117 }
00118 
00119 NS_IMETHODIMP
00120 InvokeTestTarget::MultTwoInts(PRInt32 p1, PRInt32 p2, PRInt32* retval)
00121 {
00122     *retval = p1 * p2;
00123     return NS_OK;
00124 }
00125 
00126 NS_IMETHODIMP
00127 InvokeTestTarget::AddTwoLLs(PRInt64 p1, PRInt64 p2, PRInt64* retval)
00128 {
00129     LL_ADD(*retval, p1, p2);
00130     return NS_OK;
00131 }
00132 
00133 NS_IMETHODIMP
00134 InvokeTestTarget::MultTwoLLs(PRInt64 p1, PRInt64 p2, PRInt64* retval)
00135 {
00136     LL_MUL(*retval, p1, p2);
00137     return NS_OK;
00138 }
00139 
00140 NS_IMETHODIMP
00141 InvokeTestTarget::AddManyInts(PRInt32 p1, PRInt32 p2, PRInt32 p3, PRInt32 p4,
00142                               PRInt32 p5, PRInt32 p6, PRInt32 p7, PRInt32 p8,
00143                               PRInt32 p9, PRInt32 p10, PRInt32* retval)
00144 {
00145 #ifdef DEBUG_TESTINVOKE
00146     printf("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n", 
00147            p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
00148 #endif
00149     *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10;
00150     return NS_OK;
00151 }
00152 
00153 NS_IMETHODIMP
00154 InvokeTestTarget::AddTwoFloats(float p1, float p2, float *retval)
00155 {
00156 #ifdef DEBUG_TESTINVOKE
00157     printf("%f, %f\n", p1, p2);
00158 #endif
00159     *retval = p1 + p2;
00160     return NS_OK;
00161 }
00162 
00163 NS_IMETHODIMP
00164 InvokeTestTarget::AddManyDoubles(double p1, double p2, double p3, double p4,
00165                                  double p5, double p6, double p7, double p8,
00166                                  double p9, double p10, double* retval)
00167 {
00168 #ifdef DEBUG_TESTINVOKE
00169     printf("%lf, %lf, %lf, %lf, %lf, %lf, %lf, %lf, %lf, %lf\n", 
00170            p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
00171 #endif
00172     *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10;
00173     return NS_OK;
00174 }
00175 
00176 NS_IMETHODIMP
00177 InvokeTestTarget::AddManyFloats(float p1, float p2, float p3, float p4,
00178                                 float p5, float p6, float p7, float p8,
00179                                 float p9, float p10, float* retval)
00180 {
00181 #ifdef DEBUG_TESTINVOKE
00182     printf("%f, %f, %f, %f, %f, %f, %f, %f, %f, %f\n", 
00183            p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
00184 #endif
00185     *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10;
00186     return NS_OK;
00187 }
00188 
00189 NS_IMETHODIMP
00190 InvokeTestTarget::AddMixedFloats(float p1, float p2, double p3, double p4,
00191                                  float p5, float p6, double p7, double p8,
00192                                  float p9, double p10, float p11,
00193                                  double *retval)
00194 {
00195 #ifdef DEBUG_TESTINVOKE
00196     printf("%f, %f, %lf, %lf, %f, %f, %lf, %lf, %f, %lf, %f\n", 
00197            p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
00198 #endif
00199     *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10 + p11;
00200     return NS_OK;
00201 }
00202 
00203 NS_IMETHODIMP
00204 InvokeTestTarget::AddManyManyFloats(float p1, float p2, float p3, float p4,
00205                                     float p5, float p6, float p7, float p8,
00206                                     float p9, float p10, float p11, float p12, 
00207                                     float p13, float p14, float p15, float p16, 
00208                                     float p17, float p18, float p19, float p20,
00209                                     float *retval)
00210 {
00211 #ifdef DEBUG_TESTINVOKE
00212     printf("%f, %f, %f, %f, %f, %f, %f, %f, %f, %f, "
00213            "%f, %f, %f, %f, %f, %f, %f, %f, %f, %f\n", 
00214            p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
00215            p11, p12, p13, p14, p15, p16, p17, p18, p19, p20);
00216 #endif
00217     *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10 +
00218         p11 + p12 + p13 + p14 + p15 + p16 + p17 + p18 + p19 + p20;
00219     return NS_OK;
00220 }
00221 
00222 NS_IMETHODIMP
00223 InvokeTestTarget::AddMixedInts(PRInt64 p1, PRInt32 p2, PRInt64 p3, PRInt32 p4,
00224                             PRInt32 p5, PRInt64 p6, PRInt32 p7, PRInt32 p8,
00225                             PRInt64 p9, PRInt32 p10, PRInt64* retval)
00226 {
00227     *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10;
00228     return NS_OK;
00229 }
00230 
00231 NS_IMETHODIMP
00232 InvokeTestTarget::AddMixedInts2(PRInt32 p1, PRInt64 p2, PRInt32 p3, PRInt64 p4,
00233                             PRInt64 p5, PRInt32 p6, PRInt64 p7, PRInt64 p8,
00234                             PRInt32 p9, PRInt64 p10, PRInt64* retval)
00235 {
00236     *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10;
00237     return NS_OK;
00238 }
00239 
00240 NS_IMETHODIMP
00241 InvokeTestTarget::PassTwoStrings(const char *ignore, const char* s1, const char* s2, char** retval)
00242 {
00243     const char milk[] = "milk";
00244     char *ret = (char*)malloc(sizeof(milk));
00245     if (!ret)
00246       return NS_ERROR_OUT_OF_MEMORY;
00247 
00248     strncpy(ret, milk, sizeof(milk));
00249     printf("\t%s %s", s1, s2);
00250     *retval = ret;
00251     return NS_OK;
00252 }
00253 
00254 int main()
00255 {
00256 
00257        int x = NS_InitEmbedding(NULL, NULL);
00258 
00259     InvokeTestTarget *test = new InvokeTestTarget();
00260 
00261     /* here we make the global 'check for alloc failure' checker happy */
00262     if(!test)
00263         return 1;
00264 
00265 
00266     InvokeTestTargetInterface* proxy;
00267     NS_GetProxyForObject(NS_UI_THREAD_EVENTQ,
00268                          kTheCID, 
00269                          test, 
00270                          PROXY_SYNC | PROXY_ALWAYS, 
00271                          (void**)(&proxy));
00272 
00273 
00274        char *buffer;
00275        proxy->PassTwoStrings("", "a", "b",&buffer);
00276 
00277 
00278     NS_RELEASE(test);
00279 
00280        extern int x_main();
00281        x_main();
00282     return NS_OK;
00283 }
00284 
00285 int x_main()
00286 {
00287     InvokeTestTarget *test = new InvokeTestTarget();
00288 
00289     /* here we make the global 'check for alloc failure' checker happy */
00290     if(!test)
00291         return 1;
00292 
00293     PRInt32 out, tmp32 = 0;
00294     PRInt64 out64;
00295     printf("calling direct:\n");
00296 
00297     if(NS_SUCCEEDED(test->AddTwoInts(1,1,&out)))
00298         printf("\t1 + 1 = %d\n", out);
00299     else
00300         printf("\tFAILED");
00301     PRInt64 one, two;
00302     LL_I2L(one, 1);
00303     LL_I2L(two, 2);
00304     if(NS_SUCCEEDED(test->AddTwoLLs(one,one,&out64)))
00305     {
00306         LL_L2I(tmp32, out64);
00307         printf("\t1L + 1L = %d\n", (int)tmp32);
00308     }
00309     else
00310         printf("\tFAILED");
00311     if(NS_SUCCEEDED(test->MultTwoInts(2,2,&out)))
00312         printf("\t2 * 2 = %d\n", out);
00313     else
00314         printf("\tFAILED");
00315     if(NS_SUCCEEDED(test->MultTwoLLs(two,two,&out64)))
00316     {
00317         LL_L2I(tmp32, out64);
00318         printf("\t2L * 2L = %d\n", (int)tmp32);
00319     }
00320     else
00321         printf("\tFAILED");
00322 
00323     double outD;
00324     float outF;
00325     PRInt32 outI;
00326     char *outS;
00327 
00328     if(NS_SUCCEEDED(test->AddManyInts(1,2,3,4,5,6,7,8,9,10,&outI)))
00329         printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %d\n", outI);
00330     else
00331         printf("\tFAILED");
00332 
00333     if(NS_SUCCEEDED(test->AddTwoFloats(1,2,&outF)))
00334         printf("\t1 + 2 = %ff\n", (double)outF);
00335     else
00336         printf("\tFAILED");
00337 
00338     if(NS_SUCCEEDED(test->AddManyDoubles(1,2,3,4,5,6,7,8,9,10,&outD)))
00339         printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %f\n", outD);
00340     else
00341         printf("\tFAILED");
00342 
00343     if(NS_SUCCEEDED(test->AddManyFloats(1,2,3,4,5,6,7,8,9,10,&outF)))
00344         printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %ff\n", (double)outF);
00345     else
00346         printf("\tFAILED");
00347 
00348     if(NS_SUCCEEDED(test->AddManyManyFloats(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,&outF)))
00349         printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 +1 15 + 16 + 17 + 18 + 19 + 20 = %ff\n", (double)outF);
00350     else
00351         printf("\tFAILED");
00352 
00353     if(NS_SUCCEEDED(test->AddMixedInts(1,2,3,4,5,6,7,8,9,10,&out64)))
00354      {
00355          LL_L2I(tmp32, out64);
00356          printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %d\n", (int)tmp32);
00357      }
00358      else
00359          printf("\tFAILED");
00360  
00361      if(NS_SUCCEEDED(test->AddMixedInts2(1,2,3,4,5,6,7,8,9,10,&out64)))
00362      {
00363           LL_L2I(tmp32, out64);
00364          printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %d\n", (int)tmp32);
00365      }
00366      else
00367          printf("\tFAILED");
00368 
00369      if(NS_SUCCEEDED(test->AddMixedFloats(1,2,3,4,5,6,7,8,9,10,11,&outD)))
00370          printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 = %f\n", (double)outD);
00371      else
00372          printf("\tFAILED");
00373 
00374      if (NS_SUCCEEDED(test->PassTwoStrings("", "moo","cow",&outS))) {
00375        printf(" = %s\n", outS);
00376         free(outS);
00377       } else
00378         printf("\tFAILED");
00379 
00380     printf("calling via invoke:\n");
00381 
00382     nsXPTCVariant var[21];
00383 
00384     var[0].val.i32 = 1;
00385     var[0].type = nsXPTType::T_I32;
00386     var[0].flags = 0;
00387 
00388     var[1].val.i32 = 1;
00389     var[1].type = nsXPTType::T_I32;
00390     var[1].flags = 0;
00391 
00392     var[2].val.i32 = 0;
00393     var[2].type = nsXPTType::T_I32;
00394     var[2].flags = nsXPTCVariant::PTR_IS_DATA;
00395     var[2].ptr = &var[2].val.i32;
00396 
00397     if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 3, 3, var)))
00398         printf("\t1 + 1 = %d\n", var[2].val.i32);
00399     else
00400         printf("\tFAILED");
00401 
00402     LL_I2L(var[0].val.i64, 1);
00403     var[0].type = nsXPTType::T_I64;
00404     var[0].flags = 0;
00405 
00406     LL_I2L(var[1].val.i64, 1);
00407     var[1].type = nsXPTType::T_I64;
00408     var[1].flags = 0;
00409 
00410     LL_I2L(var[2].val.i64, 0);
00411     var[2].type = nsXPTType::T_I64;
00412     var[2].flags = nsXPTCVariant::PTR_IS_DATA;
00413     var[2].ptr = &var[2].val.i64;
00414 
00415     if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 5, 3, var)))
00416         printf("\t1L + 1L = %d\n", (int)var[2].val.i64);
00417     else
00418         printf("\tFAILED");
00419 
00420     var[0].val.i32 = 2;
00421     var[0].type = nsXPTType::T_I32;
00422     var[0].flags = 0;
00423 
00424     var[1].val.i32 = 2;
00425     var[1].type = nsXPTType::T_I32;
00426     var[1].flags = 0;
00427 
00428     var[2].val.i32 = 0;
00429     var[2].type = nsXPTType::T_I32;
00430     var[2].flags = nsXPTCVariant::PTR_IS_DATA;
00431     var[2].ptr = &var[2].val.i32;
00432 
00433     if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 4, 3, var)))
00434         printf("\t2 * 2 = %d\n", var[2].val.i32);
00435     else
00436         printf("\tFAILED");
00437 
00438     LL_I2L(var[0].val.i64,2);
00439     var[0].type = nsXPTType::T_I64;
00440     var[0].flags = 0;
00441 
00442     LL_I2L(var[1].val.i64,2);
00443     var[1].type = nsXPTType::T_I64;
00444     var[1].flags = 0;
00445 
00446     LL_I2L(var[2].val.i64,0);
00447     var[2].type = nsXPTType::T_I64;
00448     var[2].flags = nsXPTCVariant::PTR_IS_DATA;
00449     var[2].ptr = &var[2].val.i64;
00450 
00451     if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 6, 3, var)))
00452         printf("\t2L * 2L = %d\n", (int)var[2].val.i64);
00453     else
00454         printf("\tFAILED");
00455 
00456     var[0].val.i32 = 1;
00457     var[0].type = nsXPTType::T_I32;
00458     var[0].flags = 0;
00459 
00460     var[1].val.i32 = 2;
00461     var[1].type = nsXPTType::T_I32;
00462     var[1].flags = 0;
00463 
00464     var[2].val.i32 = 3;
00465     var[2].type = nsXPTType::T_I32;
00466     var[2].flags = 0;
00467 
00468     var[3].val.i32 = 4;
00469     var[3].type = nsXPTType::T_I32;
00470     var[3].flags = 0;
00471 
00472     var[4].val.i32 = 5;
00473     var[4].type = nsXPTType::T_I32;
00474     var[4].flags = 0;
00475 
00476     var[5].val.i32 = 6;
00477     var[5].type = nsXPTType::T_I32;
00478     var[5].flags = 0;
00479 
00480     var[6].val.i32 = 7;
00481     var[6].type = nsXPTType::T_I32;
00482     var[6].flags = 0;
00483 
00484     var[7].val.i32 = 8;
00485     var[7].type = nsXPTType::T_I32;
00486     var[7].flags = 0;
00487 
00488     var[8].val.i32 = 9;
00489     var[8].type = nsXPTType::T_I32;
00490     var[8].flags = 0;
00491 
00492     var[9].val.i32 = 10;
00493     var[9].type = nsXPTType::T_I32;
00494     var[9].flags = 0;
00495 
00496     var[10].val.i32 = 0;
00497     var[10].type = nsXPTType::T_I32;
00498     var[10].flags = nsXPTCVariant::PTR_IS_DATA;
00499     var[10].ptr = &var[10].val.i32;
00500 
00501     if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 7, 11, var)))
00502         printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %d\n",
00503                 var[10].val.i32);
00504 
00505     var[0].val.f = 1.0f;
00506     var[0].type = nsXPTType::T_FLOAT;
00507     var[0].flags = 0;
00508 
00509     var[1].val.f = 2.0f;
00510     var[1].type = nsXPTType::T_FLOAT;
00511     var[1].flags = 0;
00512 
00513     var[2].val.f = 0.0f;
00514     var[2].type = nsXPTType::T_FLOAT;
00515     var[2].flags = nsXPTCVariant::PTR_IS_DATA;
00516     var[2].ptr = &var[2].val.f;
00517 
00518     if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 8, 3, var)))
00519         printf("\t1 + 2 = %ff\n",
00520                 (double) var[2].val.f);
00521 
00522 
00523     var[0].val.d = 1.0;
00524     var[0].type = nsXPTType::T_DOUBLE;
00525     var[0].flags = 0;
00526 
00527     var[1].val.d = 2.0;
00528     var[1].type = nsXPTType::T_DOUBLE;
00529     var[1].flags = 0;
00530 
00531     var[2].val.d = 3.0;
00532     var[2].type = nsXPTType::T_DOUBLE;
00533     var[2].flags = 0;
00534 
00535     var[3].val.d = 4.0;
00536     var[3].type = nsXPTType::T_DOUBLE;
00537     var[3].flags = 0;
00538 
00539     var[4].val.d = 5.0;
00540     var[4].type = nsXPTType::T_DOUBLE;
00541     var[4].flags = 0;
00542 
00543     var[5].val.d = 6.0;
00544     var[5].type = nsXPTType::T_DOUBLE;
00545     var[5].flags = 0;
00546 
00547     var[6].val.d = 7.0;
00548     var[6].type = nsXPTType::T_DOUBLE;
00549     var[6].flags = 0;
00550 
00551     var[7].val.d = 8.0;
00552     var[7].type = nsXPTType::T_DOUBLE;
00553     var[7].flags = 0;
00554 
00555     var[8].val.d = 9.0;
00556     var[8].type = nsXPTType::T_DOUBLE;
00557     var[8].flags = 0;
00558 
00559     var[9].val.d = 10.0;
00560     var[9].type = nsXPTType::T_DOUBLE;
00561     var[9].flags = 0;
00562 
00563     var[10].val.d = 0.0;
00564     var[10].type = nsXPTType::T_DOUBLE;
00565     var[10].flags = nsXPTCVariant::PTR_IS_DATA;
00566     var[10].ptr = &var[10].val.d;
00567 
00568     if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 9, 11, var)))
00569         printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %f\n",
00570                 var[10].val.d);
00571     else
00572         printf("\tFAILED");
00573 
00574     var[0].val.f = 1.0f;
00575     var[0].type = nsXPTType::T_FLOAT;
00576     var[0].flags = 0;
00577 
00578     var[1].val.f = 2.0f;
00579     var[1].type = nsXPTType::T_FLOAT;
00580     var[1].flags = 0;
00581 
00582     var[2].val.f = 3.0f;
00583     var[2].type = nsXPTType::T_FLOAT;
00584     var[2].flags = 0;
00585 
00586     var[3].val.f = 4.0f;
00587     var[3].type = nsXPTType::T_FLOAT;
00588     var[3].flags = 0;
00589 
00590     var[4].val.f = 5.0f;
00591     var[4].type = nsXPTType::T_FLOAT;
00592     var[4].flags = 0;
00593 
00594     var[5].val.f = 6.0f;
00595     var[5].type = nsXPTType::T_FLOAT;
00596     var[5].flags = 0;
00597 
00598     var[6].val.f = 7.0f;
00599     var[6].type = nsXPTType::T_FLOAT;
00600     var[6].flags = 0;
00601 
00602     var[7].val.f = 8.0f;
00603     var[7].type = nsXPTType::T_FLOAT;
00604     var[7].flags = 0;
00605 
00606     var[8].val.f = 9.0f;
00607     var[8].type = nsXPTType::T_FLOAT;
00608     var[8].flags = 0;
00609 
00610     var[9].val.f = 10.0f;
00611     var[9].type = nsXPTType::T_FLOAT;
00612     var[9].flags = 0;
00613 
00614     var[10].val.f = 0.0f;
00615     var[10].type = nsXPTType::T_FLOAT;
00616     var[10].flags = nsXPTCVariant::PTR_IS_DATA;
00617     var[10].ptr = &var[10].val.f;
00618 
00619     if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 10, 11, var)))
00620         printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %ff\n",
00621                 (double) var[10].val.f);
00622     else
00623         printf("\tFAILED");
00624 
00625     var[0].val.f = 1.0f;
00626     var[0].type = nsXPTType::T_FLOAT;
00627     var[0].flags = 0;
00628 
00629     var[1].val.f = 2.0f;
00630     var[1].type = nsXPTType::T_FLOAT;
00631     var[1].flags = 0;
00632 
00633     var[2].val.f = 3.0f;
00634     var[2].type = nsXPTType::T_FLOAT;
00635     var[2].flags = 0;
00636 
00637     var[3].val.f = 4.0f;
00638     var[3].type = nsXPTType::T_FLOAT;
00639     var[3].flags = 0;
00640 
00641     var[4].val.f = 5.0f;
00642     var[4].type = nsXPTType::T_FLOAT;
00643     var[4].flags = 0;
00644 
00645     var[5].val.f = 6.0f;
00646     var[5].type = nsXPTType::T_FLOAT;
00647     var[5].flags = 0;
00648 
00649     var[6].val.f = 7.0f;
00650     var[6].type = nsXPTType::T_FLOAT;
00651     var[6].flags = 0;
00652 
00653     var[7].val.f = 8.0f;
00654     var[7].type = nsXPTType::T_FLOAT;
00655     var[7].flags = 0;
00656 
00657     var[8].val.f = 9.0f;
00658     var[8].type = nsXPTType::T_FLOAT;
00659     var[8].flags = 0;
00660 
00661     var[9].val.f = 10.0f;
00662     var[9].type = nsXPTType::T_FLOAT;
00663     var[9].flags = 0;
00664 
00665     var[10].val.f = 11.0f;
00666     var[10].type = nsXPTType::T_FLOAT;
00667     var[10].flags = 0;
00668 
00669     var[11].val.f = 12.0f;
00670     var[11].type = nsXPTType::T_FLOAT;
00671     var[11].flags = 0;
00672 
00673     var[12].val.f = 13.0f;
00674     var[12].type = nsXPTType::T_FLOAT;
00675     var[12].flags = 0;
00676 
00677     var[13].val.f = 14.0f;
00678     var[13].type = nsXPTType::T_FLOAT;
00679     var[13].flags = 0;
00680 
00681     var[14].val.f = 15.0f;
00682     var[14].type = nsXPTType::T_FLOAT;
00683     var[14].flags = 0;
00684 
00685     var[15].val.f = 16.0f;
00686     var[15].type = nsXPTType::T_FLOAT;
00687     var[15].flags = 0;
00688 
00689     var[16].val.f = 17.0f;
00690     var[16].type = nsXPTType::T_FLOAT;
00691     var[16].flags = 0;
00692 
00693     var[17].val.f = 18.0f;
00694     var[17].type = nsXPTType::T_FLOAT;
00695     var[17].flags = 0;
00696 
00697     var[18].val.f = 19.0f;
00698     var[18].type = nsXPTType::T_FLOAT;
00699     var[18].flags = 0;
00700 
00701     var[19].val.f = 20.0f;
00702     var[19].type = nsXPTType::T_FLOAT;
00703     var[19].flags = 0;
00704 
00705     var[20].val.f = 0.0f;
00706     var[20].type = nsXPTType::T_FLOAT;
00707     var[20].flags = nsXPTCVariant::PTR_IS_DATA;
00708     var[20].ptr = &var[20].val.f;
00709 
00710     if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 11, 21, var)))
00711         printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 = %ff\n",
00712                 (double) var[20].val.f);
00713 
00714     var[0].val.i64 = 1;
00715     var[0].type = nsXPTType::T_I64;
00716     var[0].flags = 0;
00717 
00718     var[1].val.i32 = 2;
00719     var[1].type = nsXPTType::T_I32;
00720     var[1].flags = 0;
00721 
00722     var[2].val.i64 = 3;
00723     var[2].type = nsXPTType::T_I64;
00724     var[2].flags = 0;
00725 
00726     var[3].val.i32 = 4;
00727     var[3].type = nsXPTType::T_I32;
00728     var[3].flags = 0;
00729 
00730     var[4].val.i32 = 5;
00731     var[4].type = nsXPTType::T_I32;
00732     var[4].flags = 0;
00733 
00734     var[5].val.i64 = 6;
00735     var[5].type = nsXPTType::T_I64;
00736     var[5].flags = 0;
00737 
00738     var[6].val.i32 = 7;
00739     var[6].type = nsXPTType::T_I32;
00740     var[6].flags = 0;
00741 
00742     var[7].val.i32 = 8;
00743     var[7].type = nsXPTType::T_I32;
00744     var[7].flags = 0;
00745 
00746     var[8].val.i64 = 9;
00747     var[8].type = nsXPTType::T_I64;
00748     var[8].flags = 0;
00749 
00750     var[9].val.i32 = 10;
00751     var[9].type = nsXPTType::T_I32;
00752     var[9].flags = 0;
00753 
00754     var[10].val.i64 = 0;
00755     var[10].type = nsXPTType::T_I64;
00756     var[10].flags = nsXPTCVariant::PTR_IS_DATA;
00757     var[10].ptr = &var[10].val.i64;
00758 
00759     if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 12, 11, var)))
00760         printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %d\n",
00761               (int)var[10].val.i64);
00762     else
00763         printf("\tFAILED");
00764 
00765     var[0].val.i32 = 1;
00766     var[0].type = nsXPTType::T_I32;
00767     var[0].flags = 0;
00768 
00769     var[1].val.i64 = 2;
00770     var[1].type = nsXPTType::T_I64;
00771     var[1].flags = 0;
00772 
00773     var[2].val.i32 = 3;
00774     var[2].type = nsXPTType::T_I32;
00775     var[2].flags = 0;
00776 
00777     var[3].val.i64 = 4;
00778     var[3].type = nsXPTType::T_I64;
00779     var[3].flags = 0;
00780 
00781     var[4].val.i64 = 5;
00782     var[4].type = nsXPTType::T_I64;
00783     var[4].flags = 0;
00784 
00785     var[5].val.i32 = 6;
00786     var[5].type = nsXPTType::T_I32;
00787     var[5].flags = 0;
00788 
00789     var[6].val.i64 = 7;
00790     var[6].type = nsXPTType::T_I64;
00791     var[6].flags = 0;
00792 
00793     var[7].val.i64 = 8;
00794     var[7].type = nsXPTType::T_I64;
00795     var[7].flags = 0;
00796 
00797     var[8].val.i32 = 9;
00798     var[8].type = nsXPTType::T_I32;
00799     var[8].flags = 0;
00800 
00801     var[9].val.i64 = 10;
00802     var[9].type = nsXPTType::T_I64;
00803     var[9].flags = 0;
00804 
00805     var[10].val.i64 = 0;
00806     var[10].type = nsXPTType::T_I64;
00807     var[10].flags = nsXPTCVariant::PTR_IS_DATA;
00808     var[10].ptr = &var[10].val.i64;
00809 
00810     if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 13, 11, var)))
00811         printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %d\n",
00812               (int)var[10].val.i64);
00813     else
00814         printf("\tFAILED");
00815 
00816     var[0].val.f = 1.0f;
00817     var[0].type = nsXPTType::T_FLOAT;
00818     var[0].flags = 0;
00819 
00820     var[1].val.f = 2.0f;
00821     var[1].type = nsXPTType::T_FLOAT;
00822     var[1].flags = 0;
00823 
00824     var[2].val.d = 3.0;
00825     var[2].type = nsXPTType::T_DOUBLE;
00826     var[2].flags = 0;
00827 
00828     var[3].val.d = 4.0;
00829     var[3].type = nsXPTType::T_DOUBLE;
00830     var[3].flags = 0;
00831 
00832     var[4].val.f = 5.0f;
00833     var[4].type = nsXPTType::T_FLOAT;
00834     var[4].flags = 0;
00835 
00836     var[5].val.f = 6.0f;
00837     var[5].type = nsXPTType::T_FLOAT;
00838     var[5].flags = 0;
00839 
00840     var[6].val.d = 7.0;
00841     var[6].type = nsXPTType::T_DOUBLE;
00842     var[6].flags = 0;
00843 
00844     var[7].val.d = 8.0;
00845     var[7].type = nsXPTType::T_DOUBLE;
00846     var[7].flags = 0;
00847 
00848     var[8].val.f = 9.0f;
00849     var[8].type = nsXPTType::T_FLOAT;
00850     var[8].flags = 0;
00851 
00852     var[9].val.d = 10.0;
00853     var[9].type = nsXPTType::T_DOUBLE;
00854     var[9].flags = 0;
00855 
00856     var[10].val.f = 11.0f;
00857     var[10].type = nsXPTType::T_FLOAT;
00858     var[10].flags = 0;
00859 
00860     var[11].val.d = 0.0;
00861     var[11].type = nsXPTType::T_DOUBLE;
00862     var[11].flags = nsXPTCVariant::PTR_IS_DATA;
00863     var[11].ptr = &var[11].val.d;
00864 
00865     if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 14, 12, var)))
00866         printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 = %f\n",
00867                 var[11].val.d);
00868     else
00869         printf("\tFAILED");
00870 
00871        var[0].val.p = (void*)"";
00872     var[0].type = nsXPTType::T_CHAR_STR;
00873     var[0].flags = 0;
00874 
00875     var[1].val.p = (void*)"moo";
00876     var[1].type = nsXPTType::T_CHAR_STR;
00877     var[1].flags = 0;
00878 
00879     var[2].val.p = (void*)"cow";
00880     var[2].type = nsXPTType::T_CHAR_STR;
00881     var[2].flags = 0;
00882     
00883     var[3].val.p = 0;
00884     var[3].type = nsXPTType::T_CHAR_STR;
00885     var[3].flags = nsXPTCVariant::PTR_IS_DATA;
00886     var[3].ptr = &var[2].val.p;
00887     
00888     if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 15, 4, var)))
00889         printf(" = %s\n", var[2].val.p);
00890     else
00891         printf("\tFAILED");
00892 
00893     DoMultipleInheritenceTest();
00894     DoMultipleInheritenceTest2();
00895     // Disabled by default - takes too much time on slow machines
00896     //DoSpeedTest();
00897 
00898     return 0;
00899 }
00900 
00901 /***************************************************************************/
00902 /***************************************************************************/
00903 /***************************************************************************/
00904 
00905 // {491C65A0-3317-11d3-9885-006008962422}
00906 #define FOO_IID \
00907 { 0x491c65a0, 0x3317, 0x11d3, \
00908     { 0x98, 0x85, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } }
00909 
00910 // {491C65A1-3317-11d3-9885-006008962422}
00911 #define BAR_IID \
00912 { 0x491c65a1, 0x3317, 0x11d3, \
00913     { 0x98, 0x85, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } }
00914 
00915 /***************************/
00916 
00917 class nsIFoo : public nsISupports
00918 {
00919 public:
00920     NS_DEFINE_STATIC_IID_ACCESSOR(FOO_IID)
00921     NS_IMETHOD FooMethod1(PRInt32 i) = 0;
00922     NS_IMETHOD FooMethod2(PRInt32 i) = 0;
00923 };
00924 
00925 class nsIBar : public nsISupports
00926 {
00927 public:
00928     NS_DEFINE_STATIC_IID_ACCESSOR(BAR_IID)
00929     NS_IMETHOD BarMethod1(PRInt32 i) = 0;
00930     NS_IMETHOD BarMethod2(PRInt32 i) = 0;
00931 };
00932 
00933 /***************************/
00934 
00935 class FooImpl : public nsIFoo
00936 {
00937 public:
00938     NS_IMETHOD FooMethod1(PRInt32 i);
00939     NS_IMETHOD FooMethod2(PRInt32 i);
00940 
00941     FooImpl();
00942 
00943 protected:
00944     ~FooImpl() {}
00945 
00946 public:
00947     virtual const char* ImplName() = 0;
00948 
00949     int SomeData1;
00950     int SomeData2;
00951     const char* Name;
00952 };
00953 
00954 class BarImpl : public nsIBar
00955 {
00956 public:
00957     NS_IMETHOD BarMethod1(PRInt32 i);
00958     NS_IMETHOD BarMethod2(PRInt32 i);
00959 
00960     BarImpl();
00961 
00962 protected:
00963     ~BarImpl() {}
00964 
00965 public:
00966     virtual const char * ImplName() = 0;
00967 
00968     int SomeData1;
00969     int SomeData2;
00970     const char* Name;
00971 };
00972 
00973 /***************************/
00974 
00975 FooImpl::FooImpl() : Name("FooImpl")
00976 {
00977 }
00978 
00979 NS_IMETHODIMP FooImpl::FooMethod1(PRInt32 i)
00980 {
00981     printf("\tFooImpl::FooMethod1 called with i == %d, %s part of a %s\n", 
00982            i, Name, ImplName());
00983     return NS_OK;
00984 }
00985 
00986 NS_IMETHODIMP FooImpl::FooMethod2(PRInt32 i)
00987 {
00988     printf("\tFooImpl::FooMethod2 called with i == %d, %s part of a %s\n", 
00989            i, Name, ImplName());
00990     return NS_OK;
00991 }
00992 
00993 /***************************/
00994 
00995 BarImpl::BarImpl() : Name("BarImpl")
00996 {
00997 }
00998 
00999 NS_IMETHODIMP BarImpl::BarMethod1(PRInt32 i)
01000 {
01001     printf("\tBarImpl::BarMethod1 called with i == %d, %s part of a %s\n", 
01002            i, Name, ImplName());
01003     return NS_OK;
01004 }
01005 
01006 NS_IMETHODIMP BarImpl::BarMethod2(PRInt32 i)
01007 {
01008     printf("\tBarImpl::BarMethod2 called with i == %d, %s part of a %s\n", 
01009            i, Name, ImplName());
01010     return NS_OK;
01011 }
01012 
01013 /***************************/
01014 
01015 class FooBarImpl : public FooImpl, public BarImpl
01016 {
01017 public:
01018     NS_DECL_ISUPPORTS
01019 
01020     const char* ImplName();
01021 
01022     FooBarImpl();
01023 
01024 private:
01025     ~FooBarImpl() {}
01026 
01027 public:
01028     const char* MyName;
01029 };
01030 
01031 FooBarImpl::FooBarImpl() : MyName("FooBarImpl")
01032 {
01033     NS_ADDREF_THIS();
01034 }
01035 
01036 const char* FooBarImpl::ImplName()
01037 {
01038     return MyName;
01039 }
01040 
01041 NS_IMETHODIMP
01042 FooBarImpl::QueryInterface(REFNSIID aIID, void** aInstancePtr)
01043 {
01044   if (NULL == aInstancePtr) {
01045     return NS_ERROR_NULL_POINTER;
01046   }
01047 
01048   *aInstancePtr = NULL;
01049 
01050 
01051   if (aIID.Equals(NS_GET_IID(nsIFoo))) {
01052     *aInstancePtr = (void*) NS_STATIC_CAST(nsIFoo*,this);
01053     NS_ADDREF_THIS();
01054     return NS_OK;
01055   }
01056   if (aIID.Equals(NS_GET_IID(nsIBar))) {
01057     *aInstancePtr = (void*) NS_STATIC_CAST(nsIBar*,this);
01058     NS_ADDREF_THIS();
01059     return NS_OK;
01060   }
01061 
01062   if (aIID.Equals(NS_GET_IID(nsISupports))) {
01063     *aInstancePtr = (void*) NS_STATIC_CAST(nsISupports*,
01064                                            NS_STATIC_CAST(nsIFoo*,this));
01065     NS_ADDREF_THIS();
01066     return NS_OK;
01067   }
01068   return NS_NOINTERFACE;
01069 }
01070 
01071 NS_IMPL_ADDREF(FooBarImpl)
01072 NS_IMPL_RELEASE(FooBarImpl)
01073 
01074 
01075 static void DoMultipleInheritenceTest()
01076 {
01077     FooBarImpl* impl = new FooBarImpl();
01078     if(!impl)
01079         return;
01080 
01081     nsIFoo* foo;
01082     nsIBar* bar;
01083 
01084     nsXPTCVariant var[1];
01085 
01086     printf("\n");
01087     if(NS_SUCCEEDED(impl->QueryInterface(NS_GET_IID(nsIFoo), (void**)&foo)) &&
01088        NS_SUCCEEDED(impl->QueryInterface(NS_GET_IID(nsIBar), (void**)&bar)))
01089     {
01090         printf("impl == %p\n", impl);
01091         printf("foo  == %p\n", foo);
01092         printf("bar  == %p\n", bar);
01093 
01094         printf("Calling Foo...\n");
01095         printf("direct calls:\n");
01096         foo->FooMethod1(1);
01097         foo->FooMethod2(2);
01098 
01099         printf("invoke calls:\n");
01100         var[0].val.i32 = 1;
01101         var[0].type = nsXPTType::T_I32;
01102         var[0].flags = 0;
01103         XPTC_InvokeByIndex(foo, 3, 1, var);
01104 
01105         var[0].val.i32 = 2;
01106         var[0].type = nsXPTType::T_I32;
01107         var[0].flags = 0;
01108         XPTC_InvokeByIndex(foo, 4, 1, var);
01109 
01110         printf("\n");
01111 
01112         printf("Calling Bar...\n");
01113         printf("direct calls:\n");
01114         bar->BarMethod1(1);
01115         bar->BarMethod2(2);
01116 
01117         printf("invoke calls:\n");
01118         var[0].val.i32 = 1;
01119         var[0].type = nsXPTType::T_I32;
01120         var[0].flags = 0;
01121         XPTC_InvokeByIndex(bar, 3, 1, var);
01122 
01123         var[0].val.i32 = 2;
01124         var[0].type = nsXPTType::T_I32;
01125         var[0].flags = 0;
01126         XPTC_InvokeByIndex(bar, 4, 1, var);
01127 
01128         printf("\n");
01129 
01130         NS_RELEASE(foo);
01131         NS_RELEASE(bar);
01132     }
01133     NS_RELEASE(impl);
01134 }
01135 /***************************************************************************/
01136 /***************************************************************************/
01137 /***************************************************************************/
01138 /* This is a variation on the theme submitted by duncan@be.com (Duncan Wilcox).
01139 *  He was seeing the other test work and this test not work. They should both
01140 *  Work on any given platform
01141 */
01142 
01143 class nsIFoo2 : public nsISupports
01144 {
01145 public:
01146     NS_IMETHOD FooMethod1(PRInt32 i) = 0;
01147     NS_IMETHOD FooMethod2(PRInt32 i) = 0;
01148 };
01149 
01150 class nsIBar2 : public nsISupports
01151 {
01152 public:
01153     NS_IMETHOD BarMethod1(PRInt32 i) = 0;
01154     NS_IMETHOD BarMethod2(PRInt32 i) = 0;
01155 };
01156 
01157 class FooBarImpl2 : public nsIFoo2, public nsIBar2
01158 {
01159 public:
01160     // Foo interface
01161     NS_IMETHOD FooMethod1(PRInt32 i);
01162     NS_IMETHOD FooMethod2(PRInt32 i);
01163 
01164     // Bar interface
01165     NS_IMETHOD BarMethod1(PRInt32 i);
01166     NS_IMETHOD BarMethod2(PRInt32 i);
01167 
01168     NS_DECL_ISUPPORTS
01169 
01170     FooBarImpl2();
01171 
01172 private:
01173     ~FooBarImpl2() {}
01174 
01175 public:
01176     PRInt32 value;
01177 };
01178 
01179 FooBarImpl2::FooBarImpl2() : value(0x12345678)
01180 {
01181     NS_ADDREF_THIS();
01182 }
01183 
01184 NS_IMETHODIMP FooBarImpl2::FooMethod1(PRInt32 i)
01185 {
01186     printf("\tFooBarImpl2::FooMethod1 called with i == %d, local value = %x\n", 
01187            i, value);
01188     return NS_OK;
01189 }
01190 
01191 NS_IMETHODIMP FooBarImpl2::FooMethod2(PRInt32 i)
01192 {
01193     printf("\tFooBarImpl2::FooMethod2 called with i == %d, local value = %x\n", 
01194            i, value);
01195     return NS_OK;
01196 }
01197 
01198 NS_IMETHODIMP FooBarImpl2::BarMethod1(PRInt32 i)
01199 {
01200     printf("\tFooBarImpl2::BarMethod1 called with i == %d, local value = %x\n", 
01201            i, value);
01202     return NS_OK;
01203 }
01204 
01205 NS_IMETHODIMP FooBarImpl2::BarMethod2(PRInt32 i)
01206 {
01207     printf("\tFooBarImpl2::BarMethod2 called with i == %d, local value = %x\n", 
01208            i, value);
01209     return NS_OK;
01210 }
01211 
01212 NS_IMETHODIMP
01213 FooBarImpl2::QueryInterface(REFNSIID aIID, void** aInstancePtr)
01214 {
01215   if (NULL == aInstancePtr) {
01216     return NS_ERROR_NULL_POINTER;
01217   }
01218 
01219   *aInstancePtr = NULL;
01220 
01221 
01222   if (aIID.Equals(NS_GET_IID(nsIFoo))) {
01223     *aInstancePtr = (void*) NS_STATIC_CAST(nsIFoo2*,this);
01224     NS_ADDREF_THIS();
01225     return NS_OK;
01226   }
01227   if (aIID.Equals(NS_GET_IID(nsIBar))) {
01228     *aInstancePtr = (void*) NS_STATIC_CAST(nsIBar2*,this);
01229     NS_ADDREF_THIS();
01230     return NS_OK;
01231   }
01232 
01233   if (aIID.Equals(NS_GET_IID(nsISupports))) {
01234     *aInstancePtr = (void*) NS_STATIC_CAST(nsISupports*,
01235                                            NS_STATIC_CAST(nsIFoo2*,this));
01236     NS_ADDREF_THIS();
01237     return NS_OK;
01238   }
01239   return NS_NOINTERFACE;
01240 }
01241 
01242 NS_IMPL_ADDREF(FooBarImpl2)
01243 NS_IMPL_RELEASE(FooBarImpl2)
01244 
01245 static void DoMultipleInheritenceTest2()
01246 {
01247     FooBarImpl2* impl = new FooBarImpl2();
01248     if(!impl)
01249         return;
01250 
01251     nsIFoo2* foo;
01252     nsIBar2* bar;
01253 
01254     nsXPTCVariant var[1];
01255 
01256     printf("\n");
01257     if(NS_SUCCEEDED(impl->QueryInterface(NS_GET_IID(nsIFoo), (void**)&foo)) &&
01258        NS_SUCCEEDED(impl->QueryInterface(NS_GET_IID(nsIBar), (void**)&bar)))
01259     {
01260         printf("impl == %p\n", impl);
01261         printf("foo  == %p\n", foo);
01262         printf("bar  == %p\n", bar);
01263 
01264         printf("Calling Foo...\n");
01265         printf("direct calls:\n");
01266         foo->FooMethod1(1);
01267         foo->FooMethod2(2);
01268 
01269         printf("invoke calls:\n");
01270         var[0].val.i32 = 1;
01271         var[0].type = nsXPTType::T_I32;
01272         var[0].flags = 0;
01273         XPTC_InvokeByIndex(foo, 3, 1, var);
01274 
01275         var[0].val.i32 = 2;
01276         var[0].type = nsXPTType::T_I32;
01277         var[0].flags = 0;
01278         XPTC_InvokeByIndex(foo, 4, 1, var);
01279 
01280         printf("\n");
01281 
01282         printf("Calling Bar...\n");
01283         printf("direct calls:\n");
01284         bar->BarMethod1(1);
01285         bar->BarMethod2(2);
01286 
01287         printf("invoke calls:\n");
01288         var[0].val.i32 = 1;
01289         var[0].type = nsXPTType::T_I32;
01290         var[0].flags = 0;
01291         XPTC_InvokeByIndex(bar, 3, 1, var);
01292 
01293         var[0].val.i32 = 2;
01294         var[0].type = nsXPTType::T_I32;
01295         var[0].flags = 0;
01296         XPTC_InvokeByIndex(bar, 4, 1, var);
01297 
01298         printf("\n");
01299 
01300         NS_RELEASE(foo);
01301         NS_RELEASE(bar);
01302     }
01303     NS_RELEASE(impl);
01304 }
01305 
01306 static void DoSpeedTest()
01307 {
01308     InvokeTestTarget *test = new InvokeTestTarget();
01309 
01310     nsXPTCVariant var[3];
01311 
01312     var[0].val.i32 = 1;
01313     var[0].type = nsXPTType::T_I32;
01314     var[0].flags = 0;
01315 
01316     var[1].val.i32 = 1;
01317     var[1].type = nsXPTType::T_I32;
01318     var[1].flags = 0;
01319 
01320     var[2].val.i32 = 0;
01321     var[2].type = nsXPTType::T_I32;
01322     var[2].flags = nsXPTCVariant::PTR_IS_DATA;
01323     var[2].ptr = &var[2].val.i32;
01324 
01325     PRInt32 in1 = 1;
01326     PRInt32 in2 = 1;
01327     PRInt32 out;
01328 
01329     // Crank this number down if your platform is slow :)
01330     static const int count = 100000000;
01331     int i;
01332     PRIntervalTime start;
01333     PRIntervalTime interval_direct;
01334     PRIntervalTime interval_invoke;
01335 
01336     printf("Speed test...\n\n");
01337     printf("Doing %d direct call iterations...\n", count); 
01338     start = PR_IntervalNow();
01339     for(i = count; i; i--)
01340         (void)test->AddTwoInts(in1, in2, &out);
01341     interval_direct = PR_IntervalNow() - start;
01342 
01343     printf("Doing %d invoked call iterations...\n", count); 
01344     start = PR_IntervalNow();
01345     for(i = count; i; i--)
01346         (void)XPTC_InvokeByIndex(test, 3, 3, var);
01347     interval_invoke = PR_IntervalNow() - start;
01348 
01349     printf(" direct took %0.2f seconds\n", 
01350             (double)interval_direct/(double)PR_TicksPerSecond());
01351     printf(" invoke took %0.2f seconds\n", 
01352             (double)interval_invoke/(double)PR_TicksPerSecond());
01353     printf(" So, invoke overhead was ~ %0.2f seconds (~ %0.0f%%)\n", 
01354             (double)(interval_invoke-interval_direct)/(double)PR_TicksPerSecond(),
01355             (double)(interval_invoke-interval_direct)/(double)interval_invoke*100);
01356 }