Back to index

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