Back to index

lightning-sunbird  0.9+nobinonly
xpctest_echo.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  *
00003  * ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is Mozilla Communicator client code, released
00017  * March 31, 1998.
00018  *
00019  * The Initial Developer of the Original Code is
00020  * Netscape Communications Corporation.
00021  * Portions created by the Initial Developer are Copyright (C) 1998
00022  * the Initial Developer. All Rights Reserved.
00023  *
00024  * Contributor(s):
00025  *   John Bandhauer <jband@netscape.com>
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 /* implement nsIEcho for testing. */
00042 
00043 #include "xpctest_private.h"
00044 
00045 #if defined(WIN32) && !defined(XPCONNECT_STANDALONE)
00046 #define IMPLEMENT_TIMER_STUFF 1
00047 #endif
00048 
00049 class xpctestEcho : public nsIEcho
00050 #ifdef IMPLEMENT_TIMER_STUFF
00051 , public nsITimerCallback
00052 #endif // IMPLEMENT_TIMER_STUFF
00053 {
00054 public:
00055     NS_DECL_ISUPPORTS
00056     NS_DECL_NSIECHO
00057 
00058 #ifdef IMPLEMENT_TIMER_STUFF
00059     NS_DECL_NSITIMERCALLBACK
00060 #endif // IMPLEMENT_TIMER_STUFF
00061 
00062     xpctestEcho();
00063     virtual ~xpctestEcho();
00064 private:
00065     nsIEcho* mReceiver;
00066     char*    mString;
00067     PRInt32  mSomeValue;
00068 };
00069 
00070 /***************************************************************************/
00071 
00072 #ifdef IMPLEMENT_TIMER_STUFF
00073 NS_IMPL_ISUPPORTS2(xpctestEcho, nsIEcho, nsITimerCallback)
00074 #else
00075 NS_IMPL_ISUPPORTS1(xpctestEcho, nsIEcho)
00076 #endif // IMPLEMENT_TIMER_STUFF
00077 
00078 xpctestEcho::xpctestEcho()
00079     : mReceiver(nsnull), mString(nsnull), mSomeValue(0)
00080 {
00081     NS_ADDREF_THIS();
00082 }
00083 
00084 xpctestEcho::~xpctestEcho()
00085 {
00086     NS_IF_RELEASE(mReceiver);
00087     if(mString)
00088         nsMemory::Free(mString);
00089 }
00090 
00091 NS_IMETHODIMP xpctestEcho::SetReceiver(nsIEcho* aReceiver)
00092 {
00093     NS_IF_ADDREF(aReceiver);
00094     NS_IF_RELEASE(mReceiver);
00095     mReceiver = aReceiver;
00096     return NS_OK;
00097 }
00098 
00099 NS_IMETHODIMP xpctestEcho::SendOneString(const char* str)
00100 {
00101     if(mReceiver)
00102         return mReceiver->SendOneString(str);
00103     return NS_OK;
00104 }
00105 
00106 NS_IMETHODIMP xpctestEcho::In2OutOneInt(int input, int* output)
00107 {
00108     *output = input;
00109     return NS_OK;
00110 }
00111 
00112 /* DOMString In2OutOneDOMString (in DOMString input); */
00113 NS_IMETHODIMP xpctestEcho::In2OutOneDOMString(const nsAString & input, 
00114                                               nsAString & _retval)
00115 {
00116     _retval.Assign(input);
00117     return NS_OK;
00118 }
00119 
00120 /* DOMString EchoIn2OutOneDOMString (in DOMString input); */
00121 NS_IMETHODIMP xpctestEcho::EchoIn2OutOneDOMString(const nsAString & input, nsAString & _retval)
00122 {
00123     if(mReceiver)
00124         return mReceiver->EchoIn2OutOneDOMString(input, _retval);
00125     return NS_OK;
00126 }
00127 
00128 /* AString In2OutOneAString (in AString input); */
00129 NS_IMETHODIMP xpctestEcho::In2OutOneAString(const nsAString & input, 
00130                                               nsAString & _retval)
00131 {
00132     _retval.Assign(input);
00133     return NS_OK;
00134 }
00135 
00136 /* AString EchoIn2OutOneAString (in AString input); */
00137 NS_IMETHODIMP xpctestEcho::EchoIn2OutOneAString(const nsAString & input, nsAString & _retval)
00138 {
00139     if(mReceiver)
00140         return mReceiver->EchoIn2OutOneAString(input, _retval);
00141     return NS_OK;
00142 }
00143 
00144 
00145 /* UTF8String In2OutOneUTF8String (in UTF8String input); */
00146 NS_IMETHODIMP xpctestEcho::In2OutOneUTF8String(const nsACString & input, 
00147                                               nsACString & _retval)
00148 {
00149     _retval.Assign(input);
00150     return NS_OK;
00151 }
00152 
00153 /* UTF8String EchoIn2OutOneUTF8String (in UTF8String input); */
00154 NS_IMETHODIMP xpctestEcho::EchoIn2OutOneUTF8String(const nsACString & input, 
00155                                                    nsACString & _retval)
00156 {
00157     if(mReceiver)
00158         return mReceiver->EchoIn2OutOneUTF8String(input, _retval);
00159     return NS_OK;
00160 }
00161 
00162 /* CString In2OutOneCString (in CString input); */
00163 NS_IMETHODIMP xpctestEcho::In2OutOneCString(const nsACString & input, 
00164                                             nsACString & _retval)
00165 {
00166     _retval.Assign(input);
00167     return NS_OK;
00168 }
00169 
00170 /* CString EchoIn2OutOneCString (in CString input); */
00171 NS_IMETHODIMP xpctestEcho::EchoIn2OutOneCString(const nsACString & input, 
00172                                                 nsACString & _retval)
00173 {
00174     if(mReceiver)
00175         return mReceiver->EchoIn2OutOneCString(input, _retval);
00176     return NS_OK;
00177 }
00178 
00179 
00180 NS_IMETHODIMP xpctestEcho::In2OutAddTwoInts(int input1,
00181                                        int input2,
00182                                        int* output1,
00183                                        int* output2,
00184                                        int* result)
00185 {
00186     *output1 = input1;
00187     *output2 = input2;
00188     *result = input1+input2;
00189     return NS_OK;
00190 }
00191 
00192 NS_IMETHODIMP xpctestEcho::In2OutOneString(const char* input, char** output)
00193 {
00194     char* p;
00195     int len;
00196     if(input && output &&
00197        (nsnull != (p = (char*)nsMemory::Alloc(len=strlen(input)+1))))
00198     {
00199         memcpy(p, input, len);
00200         *output = p;
00201         return NS_OK;
00202     }
00203     if(output)
00204         *output = nsnull;
00205     return NS_ERROR_FAILURE;
00206 }
00207 
00208 NS_IMETHODIMP xpctestEcho::SimpleCallNoEcho()
00209 {
00210     return NS_OK;
00211 }
00212 
00213 NS_IMETHODIMP
00214 xpctestEcho::SendManyTypes(PRUint8              p1,
00215                       PRInt16             p2,
00216                       PRInt32             p3,
00217                       PRInt64             p4,
00218                       PRUint8              p5,
00219                       PRUint16            p6,
00220                       PRUint32            p7,
00221                       PRUint64            p8,
00222                       float             p9,
00223                       double            p10,
00224                       PRBool            p11,
00225                       char              p12,
00226                       PRUnichar            p13,
00227                       const nsID*       p14,
00228                       const char*       p15,
00229                       const PRUnichar*  p16)
00230 {
00231     if(mReceiver)
00232         return mReceiver->SendManyTypes(p1, p2, p3, p4, p5, p6, p7, p8, p9,
00233                                         p10, p11, p12, p13, p14, p15, p16);
00234     return NS_OK;
00235 }
00236 
00237 NS_IMETHODIMP
00238 xpctestEcho::SendInOutManyTypes(PRUint8*    p1,
00239                            PRInt16*   p2,
00240                            PRInt32*   p3,
00241                            PRInt64*   p4,
00242                            PRUint8*    p5,
00243                            PRUint16*  p6,
00244                            PRUint32*  p7,
00245                            PRUint64*  p8,
00246                            float*   p9,
00247                            double*  p10,
00248                            PRBool*  p11,
00249                            char*    p12,
00250                            PRUnichar*  p13,
00251                            nsID**   p14,
00252                            char**   p15,
00253                            PRUnichar** p16)
00254 {
00255     if(mReceiver)
00256         return mReceiver->SendInOutManyTypes(p1, p2, p3, p4, p5, p6, p7, p8, p9,
00257                                              p10, p11, p12, p13, p14, p15, p16);
00258     return NS_OK;
00259 }
00260 
00261 NS_IMETHODIMP
00262 xpctestEcho::MethodWithNative(int p1, void* p2)
00263 {
00264     return NS_OK;
00265 }
00266 
00267 NS_IMETHODIMP
00268 xpctestEcho::ReturnCode(int code)
00269 {
00270     return (nsresult) code;
00271 }
00272 
00273 NS_IMETHODIMP
00274 xpctestEcho::FailInJSTest(int fail)
00275 {
00276     if(mReceiver)
00277         return mReceiver->FailInJSTest(fail);
00278     return NS_OK;
00279 }
00280 
00281 NS_IMETHODIMP
00282 xpctestEcho::SharedString(const char **str)
00283 {
00284     *str = "a static string";
00285 /*
00286     // to do non-shared we clone the string:
00287     char buf[] = "a static string";
00288     int len;
00289     *str = (char*)nsMemory::Alloc(len=strlen(buf)+1);
00290     memcpy(*str, buf, len);
00291 */
00292     return NS_OK;
00293 }
00294 
00295 NS_IMETHODIMP
00296 xpctestEcho::ReturnCode_NS_OK()
00297 {return NS_OK;}
00298 
00299 NS_IMETHODIMP
00300 xpctestEcho::ReturnCode_NS_ERROR_NULL_POINTER()
00301 {return NS_ERROR_NULL_POINTER;}
00302 
00303 NS_IMETHODIMP
00304 xpctestEcho::ReturnCode_NS_ERROR_UNEXPECTED()
00305 {return NS_ERROR_UNEXPECTED;}
00306 
00307 NS_IMETHODIMP
00308 xpctestEcho::ReturnCode_NS_ERROR_OUT_OF_MEMORY()
00309 {return NS_ERROR_OUT_OF_MEMORY;}
00310 
00311 NS_IMETHODIMP
00312 xpctestEcho::ReturnInterface(nsISupports *obj, nsISupports **_retval)
00313 {
00314     if(!_retval)
00315         return NS_ERROR_NULL_POINTER;
00316     if(obj)
00317         NS_ADDREF(obj);
00318     *_retval = obj;
00319     return NS_OK;
00320 }
00321 
00322 /* nsIStackFrame GetStack (); */
00323 NS_IMETHODIMP
00324 xpctestEcho::GetStack(nsIStackFrame **_retval)
00325 {
00326     nsIStackFrame* stack = nsnull;
00327     if(!_retval)
00328         return NS_ERROR_NULL_POINTER;
00329 
00330     nsresult rv;
00331     nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv));
00332     if(NS_SUCCEEDED(rv))
00333     {
00334         nsIStackFrame* jsstack;
00335         if(NS_SUCCEEDED(xpc->GetCurrentJSStack(&jsstack)) && jsstack)
00336         {
00337             xpc->CreateStackFrameLocation(nsIProgrammingLanguage::CPLUSPLUS,
00338                                           __FILE__,
00339                                           "xpctestEcho::GetStack",
00340                                           __LINE__,
00341                                           jsstack,
00342                                           &stack);
00343             NS_RELEASE(jsstack);
00344         }
00345     }
00346 
00347     if(stack)
00348     {
00349         *_retval = stack;
00350         return NS_OK;
00351     }
00352     return NS_ERROR_FAILURE;
00353 }
00354 
00355 /* void SetReceiverReturnOldReceiver (inout nsIEcho aReceiver); */
00356 NS_IMETHODIMP
00357 xpctestEcho::SetReceiverReturnOldReceiver(nsIEcho **aReceiver)
00358 {
00359     if(!aReceiver)
00360         return NS_ERROR_NULL_POINTER;
00361 
00362     nsIEcho* oldReceiver = mReceiver;
00363     mReceiver = *aReceiver;
00364     if(mReceiver)
00365         NS_ADDREF(mReceiver);
00366 
00367     /* don't release the reference, that is the caller's problem */
00368     *aReceiver = oldReceiver;
00369     return NS_OK;
00370 }
00371 
00372 /* void MethodWithForwardDeclaredParam (in nsITestXPCSomeUselessThing sut); */
00373 NS_IMETHODIMP
00374 xpctestEcho::MethodWithForwardDeclaredParam(nsITestXPCSomeUselessThing *sut)
00375 {
00376     return NS_OK;
00377 }
00378 
00379 /* void PseudoQueryInterface (in nsIIDRef uuid, [iid_is (uuid), retval] out nsQIResult result); */
00380 NS_IMETHODIMP
00381 xpctestEcho::PseudoQueryInterface(const nsIID & uuid, void * *result)
00382 {
00383     if(!result)
00384         return NS_ERROR_NULL_POINTER;
00385     if(mReceiver)
00386         return mReceiver->PseudoQueryInterface(uuid, result);
00387     return NS_OK;
00388 }        
00389 
00390 /* void DebugDumpJSStack (); */
00391 NS_IMETHODIMP
00392 xpctestEcho::DebugDumpJSStack()
00393 {
00394     nsresult rv;
00395     nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv));
00396     if(NS_SUCCEEDED(rv))
00397     {
00398         rv = xpc->DebugDumpJSStack(JS_TRUE, JS_TRUE, JS_TRUE);
00399     }
00400     return rv;
00401 }        
00402 
00403 /* attribute string aString; */
00404 NS_IMETHODIMP 
00405 xpctestEcho::GetAString(char * *aAString)
00406 {
00407     printf(">>>> xpctestEcho::GetAString called\n");
00408     if(mString)
00409         *aAString = (char*) nsMemory::Clone(mString, strlen(mString)+1);
00410     else
00411         *aAString = nsnull;
00412     return NS_OK;
00413 }
00414 NS_IMETHODIMP 
00415 xpctestEcho::SetAString(const char * aAString)
00416 {
00417     printf("<<<< xpctestEcho::SetAString called\n");
00418     if(mString)
00419         nsMemory::Free(mString);
00420     if(aAString)
00421         mString = (char*) nsMemory::Clone(aAString, strlen(aAString)+1);
00422     else
00423         mString = nsnull;
00424     return NS_OK;
00425 }
00426 
00427 
00428 
00429 /***************************************************/
00430 
00431 // some tests of nsIXPCNativeCallContext
00432 
00433 #define GET_CALL_CONTEXT \
00434   nsresult rv; \
00435   nsCOMPtr<nsIXPCNativeCallContext> cc; \
00436   nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv)); \
00437   if(NS_SUCCEEDED(rv)) \
00438     rv = xpc->GetCurrentNativeCallContext(getter_AddRefs(cc)) /* no ';' */        
00439 
00440 /* void printArgTypes (); */
00441 NS_IMETHODIMP
00442 xpctestEcho::PrintArgTypes(void)
00443 {
00444     GET_CALL_CONTEXT;
00445     if(NS_FAILED(rv) || !cc)
00446         return NS_ERROR_FAILURE;
00447 
00448     nsCOMPtr<nsISupports> callee;
00449     if(NS_FAILED(cc->GetCallee(getter_AddRefs(callee))) ||
00450        callee != NS_STATIC_CAST(nsIEcho*, this))
00451         return NS_ERROR_FAILURE;
00452 
00453     PRUint32 argc;
00454     if(NS_SUCCEEDED(cc->GetArgc(&argc)))
00455         printf("argc = %d  ", (int)argc);
00456     else
00457         return NS_ERROR_FAILURE;
00458 
00459     jsval* argv;
00460     if(NS_FAILED(cc->GetArgvPtr(&argv)))
00461         return NS_ERROR_FAILURE;
00462 
00463     printf("argv types = [");
00464 
00465     for(PRUint32 i = 0; i < argc; i++)
00466     {
00467         const char* type = "<unknown>";
00468         if(JSVAL_IS_OBJECT(argv[i]))
00469         {
00470             if(JSVAL_IS_NULL(argv[i]))
00471                 type = "null";
00472             else
00473                 type = "object";
00474         }
00475         else if (JSVAL_IS_BOOLEAN(argv[i]))
00476             type = "boolean";
00477         else if (JSVAL_IS_STRING(argv[i]))
00478             type = "string";
00479         else if (JSVAL_IS_DOUBLE(argv[i]))
00480             type = "double";
00481         else if (JSVAL_IS_INT(argv[i]))
00482             type = "int";
00483         else if (JSVAL_IS_VOID(argv[i]))
00484             type = "void";
00485 
00486         printf(type);
00487 
00488         if(i < argc-1)
00489             printf(", ");
00490     }
00491     printf("]\n");
00492     
00493     return NS_OK;
00494 }
00495 
00496 /* void throwArg (); */
00497 NS_IMETHODIMP
00498 xpctestEcho::ThrowArg(void)
00499 {
00500     GET_CALL_CONTEXT;
00501     if(NS_FAILED(rv) || !cc)
00502         return NS_ERROR_FAILURE;
00503 
00504     nsCOMPtr<nsISupports> callee;
00505     if(NS_FAILED(cc->GetCallee(getter_AddRefs(callee))) || 
00506        callee != NS_STATIC_CAST(nsIEcho*, this))
00507         return NS_ERROR_FAILURE;
00508 
00509     PRUint32 argc;
00510     if(NS_FAILED(cc->GetArgc(&argc)) || !argc)
00511         return NS_OK;
00512 
00513     jsval* argv;
00514     JSContext* cx;
00515     if(NS_FAILED(cc->GetArgvPtr(&argv)) ||
00516        NS_FAILED(cc->GetJSContext(&cx)))
00517         return NS_ERROR_FAILURE;
00518 
00519     JS_SetPendingException(cx, argv[0]);
00520     cc->SetExceptionWasThrown(JS_TRUE);
00521         
00522     return NS_OK;
00523 }
00524 
00525 /* void callReceiverSometimeLater (); */
00526 NS_IMETHODIMP
00527 xpctestEcho::CallReceiverSometimeLater(void)
00528 {
00529     // Mac does not even compile this code and Unix build systems
00530     // have build order problems with linking to the static timer lib
00531     // as it is built today. This is only test code and we can stand to 
00532     // have it only work on Win32 for now.
00533 
00534 #ifdef IMPLEMENT_TIMER_STUFF
00535     nsCOMPtr<nsITimer> timer;
00536     nsresult rv;
00537     timer = do_CreateInstance("@mozilla.org/timer;1", &rv);
00538     if(NS_FAILED(rv))
00539         return NS_ERROR_FAILURE;
00540     timer->InitWithCallback(NS_STATIC_CAST(nsITimerCallback*,this), 2000,
00541                             nsITimer::TYPE_ONE_SHOT);
00542     return NS_OK;
00543 #else
00544     return NS_ERROR_NOT_IMPLEMENTED;
00545 #endif // IMPLEMENT_TIMER_STUFF
00546 }
00547 
00548 #ifdef IMPLEMENT_TIMER_STUFF
00549 NS_IMETHODIMP
00550 xpctestEcho::Notify(nsITimer *timer)
00551 {
00552     if(mReceiver)
00553         mReceiver->CallReceiverSometimeLater();
00554     NS_RELEASE(timer);
00555     return NS_OK;
00556 }        
00557 #endif // IMPLEMENT_TIMER_STUFF
00558 
00559 /* readonly attribute short throwInGetter; */
00560 NS_IMETHODIMP
00561 xpctestEcho::GetThrowInGetter(PRInt16 *aThrowInGetter)
00562 {
00563     return NS_ERROR_FAILURE;
00564 }        
00565 
00566 /* void callFunction (in nsITestXPCFunctionCallback callback, in string s); */
00567 NS_IMETHODIMP 
00568 xpctestEcho::CallFunction(nsITestXPCFunctionCallback *callback, const char *s)
00569 {
00570     return callback->Call(s);
00571 }
00572 
00573 /* void callFunction (in nsITestXPCFunctionCallback callback, in string s); */
00574 NS_IMETHODIMP 
00575 xpctestEcho::CallFunctionWithThis(nsITestXPCFunctionCallback *callback, nsISupports* self, const char *s)
00576 {
00577     return callback->CallWithThis(self, s);
00578 }
00579 
00580 /* attribute PRInt32 SomeValue; */
00581 NS_IMETHODIMP 
00582 xpctestEcho::GetSomeValue(PRInt32 *aSomeValue)
00583 {
00584     *aSomeValue = mSomeValue;
00585     return NS_OK;
00586 }
00587 
00588 NS_IMETHODIMP xpctestEcho::SetSomeValue(PRInt32 aSomeValue)
00589 
00590 {
00591     mSomeValue = aSomeValue;
00592     return NS_OK;
00593 }
00594 
00595 /***************************************************************************/
00596 
00597 // static
00598 NS_IMETHODIMP
00599 xpctest::ConstructEcho(nsISupports *aOuter, REFNSIID aIID, void **aResult)
00600 {
00601     nsresult rv;
00602     NS_ASSERTION(aOuter == nsnull, "no aggregation");
00603     xpctestEcho* obj = new xpctestEcho();
00604 
00605     if(obj)
00606     {
00607         rv = obj->QueryInterface(aIID, aResult);
00608         NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
00609         NS_RELEASE(obj);
00610     }
00611     else
00612     {
00613         *aResult = nsnull;
00614         rv = NS_ERROR_OUT_OF_MEMORY;
00615     }
00616 
00617     return rv;
00618 }