LCOV - code coverage report
Current view: directory - content/xslt/src/xpath - txXPCOMExtensionFunction.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 234 0 0.0 %
Date: 2012-06-02 Functions: 29 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Peter Van der Beken.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2005
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Peter Van der Beken <peterv@propagandism.org>
      24                 :  *   Merle Sterling <msterlin@us.ibm.com>
      25                 :  *
      26                 :  *
      27                 :  * Alternatively, the contents of this file may be used under the terms of
      28                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      29                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      30                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      31                 :  * of those above. If you wish to allow use of your version of this file only
      32                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      33                 :  * use your version of this file under the terms of the MPL, indicate your
      34                 :  * decision by deleting the provisions above and replace them with the notice
      35                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      36                 :  * the provisions above, a recipient may use your version of this file under
      37                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      38                 :  *
      39                 :  * ***** END LICENSE BLOCK ***** */
      40                 : 
      41                 : #include "nsAutoPtr.h"
      42                 : #include "nsComponentManagerUtils.h"
      43                 : #include "nsDependentString.h"
      44                 : #include "nsIAtom.h"
      45                 : #include "nsIInterfaceInfoManager.h"
      46                 : #include "nsServiceManagerUtils.h"
      47                 : #include "txExpr.h"
      48                 : #include "txIFunctionEvaluationContext.h"
      49                 : #include "txIXPathContext.h"
      50                 : #include "txNodeSetAdaptor.h"
      51                 : #include "txXPathTreeWalker.h"
      52                 : #include "xptcall.h"
      53                 : #include "txXPathObjectAdaptor.h"
      54                 : 
      55               0 : NS_IMPL_ISUPPORTS1(txXPathObjectAdaptor, txIXPathObject)
      56                 : 
      57                 : class txFunctionEvaluationContext : public txIFunctionEvaluationContext
      58               0 : {
      59                 : public:
      60                 :     txFunctionEvaluationContext(txIEvalContext *aContext, nsISupports *aState);
      61                 : 
      62                 :     NS_DECL_ISUPPORTS
      63                 :     NS_DECL_TXIFUNCTIONEVALUATIONCONTEXT
      64                 : 
      65               0 :     void ClearContext()
      66                 :     {
      67               0 :         mContext = nsnull;
      68               0 :     }
      69                 : 
      70                 : private:
      71                 :     txIEvalContext *mContext;
      72                 :     nsCOMPtr<nsISupports> mState;
      73                 : };
      74                 : 
      75               0 : txFunctionEvaluationContext::txFunctionEvaluationContext(txIEvalContext *aContext,
      76                 :                                                          nsISupports *aState)
      77                 :     : mContext(aContext),
      78               0 :       mState(aState)
      79                 : {
      80               0 : }
      81                 : 
      82               0 : NS_IMPL_ISUPPORTS1(txFunctionEvaluationContext, txIFunctionEvaluationContext)
      83                 : 
      84                 : NS_IMETHODIMP
      85               0 : txFunctionEvaluationContext::GetPosition(PRUint32 *aPosition)
      86                 : {
      87               0 :     NS_ENSURE_TRUE(mContext, NS_ERROR_FAILURE);
      88                 : 
      89               0 :     *aPosition = mContext->position();
      90                 : 
      91               0 :     return NS_OK;
      92                 : }
      93                 : 
      94                 : NS_IMETHODIMP
      95               0 : txFunctionEvaluationContext::GetSize(PRUint32 *aSize)
      96                 : {
      97               0 :     NS_ENSURE_TRUE(mContext, NS_ERROR_FAILURE);
      98                 : 
      99               0 :     *aSize = mContext->size();
     100                 : 
     101               0 :     return NS_OK;
     102                 : }
     103                 : 
     104                 : NS_IMETHODIMP
     105               0 : txFunctionEvaluationContext::GetContextNode(nsIDOMNode **aNode)
     106                 : {
     107               0 :     NS_ENSURE_TRUE(mContext, NS_ERROR_FAILURE);
     108                 : 
     109               0 :     return txXPathNativeNode::getNode(mContext->getContextNode(), aNode);
     110                 : }
     111                 : 
     112                 : NS_IMETHODIMP
     113               0 : txFunctionEvaluationContext::GetState(nsISupports **aState)
     114                 : {
     115               0 :     NS_IF_ADDREF(*aState = mState);
     116                 : 
     117               0 :     return NS_OK;
     118                 : }
     119                 : 
     120                 : enum txArgumentType {
     121                 :     eBOOLEAN = nsXPTType::T_BOOL,
     122                 :     eNUMBER = nsXPTType::T_DOUBLE,
     123                 :     eSTRING = nsXPTType::T_DOMSTRING,
     124                 :     eNODESET,
     125                 :     eCONTEXT,
     126                 :     eOBJECT,
     127                 :     eUNKNOWN
     128                 : };
     129                 : 
     130                 : class txXPCOMExtensionFunctionCall : public FunctionCall
     131               0 : {
     132                 : public:
     133                 :     txXPCOMExtensionFunctionCall(nsISupports *aHelper, const nsIID &aIID,
     134                 :                                  PRUint16 aMethodIndex,
     135                 : #ifdef TX_TO_STRING
     136                 :                                  PRInt32 aNamespaceID, nsIAtom *aName,
     137                 : #endif
     138                 :                                   nsISupports *aState);
     139                 : 
     140                 :     TX_DECL_FUNCTION
     141                 : 
     142                 : private:
     143                 :     txArgumentType GetParamType(const nsXPTParamInfo &aParam,
     144                 :                                 nsIInterfaceInfo *aInfo);
     145                 : 
     146                 :     nsCOMPtr<nsISupports> mHelper;
     147                 :     nsIID mIID;
     148                 :     PRUint16 mMethodIndex;
     149                 : #ifdef TX_TO_STRING
     150                 :     PRInt32 mNamespaceID;
     151                 :     nsCOMPtr<nsIAtom> mName;
     152                 : #endif
     153                 :     nsCOMPtr<nsISupports> mState;
     154                 : };
     155                 : 
     156               0 : txXPCOMExtensionFunctionCall::txXPCOMExtensionFunctionCall(nsISupports *aHelper,
     157                 :                                                            const nsIID &aIID,
     158                 :                                                            PRUint16 aMethodIndex,
     159                 : #ifdef TX_TO_STRING
     160                 :                                                            PRInt32 aNamespaceID,
     161                 :                                                            nsIAtom *aName,
     162                 : #endif
     163                 :                                                            nsISupports *aState)
     164                 :     : mHelper(aHelper),
     165                 :       mIID(aIID),
     166                 :       mMethodIndex(aMethodIndex),
     167                 : #ifdef TX_TO_STRING
     168                 :       mNamespaceID(aNamespaceID),
     169                 :       mName(aName),
     170                 : #endif
     171               0 :       mState(aState)
     172                 : {
     173               0 : }
     174                 : 
     175                 : class txInterfacesArrayHolder
     176                 : {
     177                 : public:
     178               0 :     txInterfacesArrayHolder(nsIID **aArray, PRUint32 aCount) : mArray(aArray),
     179               0 :                                                                mCount(aCount)
     180                 :     {
     181               0 :     }
     182               0 :     ~txInterfacesArrayHolder()
     183                 :     {
     184               0 :         NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(mCount, mArray);
     185               0 :     }
     186                 : 
     187                 : private:
     188                 :     nsIID **mArray;
     189                 :     PRUint32 mCount;
     190                 : };
     191                 : 
     192                 : static nsresult
     193               0 : LookupFunction(const char *aContractID, nsIAtom* aName, nsIID &aIID,
     194                 :                PRUint16 &aMethodIndex, nsISupports **aHelper)
     195                 : {
     196                 :     nsresult rv;
     197               0 :     nsCOMPtr<nsISupports> helper = do_GetService(aContractID, &rv);
     198               0 :     NS_ENSURE_SUCCESS(rv, rv);
     199                 : 
     200               0 :     nsCOMPtr<nsIClassInfo> classInfo = do_QueryInterface(helper, &rv);
     201               0 :     NS_ENSURE_SUCCESS(rv, rv);
     202                 : 
     203                 :     nsCOMPtr<nsIInterfaceInfoManager> iim =
     204               0 :         do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID);
     205               0 :     NS_ENSURE_TRUE(iim, NS_ERROR_FAILURE);
     206                 : 
     207               0 :     nsIID** iidArray = nsnull;
     208               0 :     PRUint32 iidCount = 0;
     209               0 :     rv = classInfo->GetInterfaces(&iidCount, &iidArray);
     210               0 :     NS_ENSURE_SUCCESS(rv, rv);
     211                 : 
     212               0 :     txInterfacesArrayHolder holder(iidArray, iidCount);
     213                 : 
     214                 :     // Remove any minus signs and uppercase the following letter (so
     215                 :     // foo-bar becomes fooBar). Note that if there are any names that already
     216                 :     // have uppercase letters they might cause false matches (both fooBar and
     217                 :     // foo-bar matching fooBar).
     218               0 :     const PRUnichar *name = aName->GetUTF16String();
     219               0 :     nsCAutoString methodName;
     220                 :     PRUnichar letter;
     221               0 :     bool upperNext = false;
     222               0 :     while ((letter = *name)) {
     223               0 :         if (letter == '-') {
     224               0 :             upperNext = true;
     225                 :         }
     226                 :         else {
     227               0 :             methodName.Append(upperNext ? nsCRT::ToUpper(letter) : letter);
     228               0 :             upperNext = false;
     229                 :         }
     230               0 :         ++name;
     231                 :     }
     232                 : 
     233                 :     PRUint32 i;
     234               0 :     for (i = 0; i < iidCount; ++i) {
     235               0 :         nsIID *iid = iidArray[i];
     236                 : 
     237               0 :         nsCOMPtr<nsIInterfaceInfo> info;
     238               0 :         rv = iim->GetInfoForIID(iid, getter_AddRefs(info));
     239               0 :         NS_ENSURE_SUCCESS(rv, rv);
     240                 : 
     241                 :         PRUint16 methodIndex;
     242                 :         const nsXPTMethodInfo *methodInfo;
     243               0 :         rv = info->GetMethodInfoForName(methodName.get(), &methodIndex,
     244               0 :                                         &methodInfo);
     245               0 :         if (NS_SUCCEEDED(rv)) {
     246                 :             // Exclude notxpcom and hidden. Also check that we have at least a
     247                 :             // return value (the xpidl compiler ensures that that return value
     248                 :             // is the last argument).
     249               0 :             PRUint8 paramCount = methodInfo->GetParamCount();
     250               0 :             if (methodInfo->IsNotXPCOM() || methodInfo->IsHidden() ||
     251                 :                 paramCount == 0 ||
     252               0 :                 !methodInfo->GetParam(paramCount - 1).IsRetval()) {
     253               0 :                 return NS_ERROR_FAILURE;
     254                 :             }
     255                 : 
     256               0 :             aIID = *iid;
     257               0 :             aMethodIndex = methodIndex;
     258               0 :             return helper->QueryInterface(aIID, (void**)aHelper);
     259                 :         }
     260                 :     }
     261                 : 
     262               0 :     return NS_ERROR_XPATH_UNKNOWN_FUNCTION;
     263                 : }
     264                 : 
     265                 : /* static */
     266                 : nsresult
     267               0 : TX_ResolveFunctionCallXPCOM(const nsCString &aContractID, PRInt32 aNamespaceID,
     268                 :                             nsIAtom* aName, nsISupports *aState,
     269                 :                             FunctionCall **aFunction)
     270                 : {
     271                 :     nsIID iid;
     272               0 :     PRUint16 methodIndex = 0;
     273               0 :     nsCOMPtr<nsISupports> helper;
     274                 : 
     275                 :     nsresult rv = LookupFunction(aContractID.get(), aName, iid, methodIndex,
     276               0 :                                  getter_AddRefs(helper));
     277               0 :     NS_ENSURE_SUCCESS(rv, rv);
     278                 : 
     279               0 :     if (!aFunction) {
     280               0 :         return NS_OK;
     281                 :     }
     282                 : 
     283                 :     *aFunction = new txXPCOMExtensionFunctionCall(helper, iid, methodIndex,
     284                 : #ifdef TX_TO_STRING
     285                 :                                                   aNamespaceID, aName,
     286                 : #endif
     287               0 :                                                   aState);
     288                 : 
     289               0 :     return *aFunction ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
     290                 : }
     291                 : 
     292                 : txArgumentType
     293               0 : txXPCOMExtensionFunctionCall::GetParamType(const nsXPTParamInfo &aParam,
     294                 :                                            nsIInterfaceInfo *aInfo)
     295                 : {
     296               0 :     PRUint8 tag = aParam.GetType().TagPart();
     297               0 :     switch (tag) {
     298                 :         case nsXPTType::T_BOOL:
     299                 :         case nsXPTType::T_DOUBLE:
     300                 :         case nsXPTType::T_DOMSTRING:
     301                 :         {
     302               0 :             return txArgumentType(tag);
     303                 :         }
     304                 :         case nsXPTType::T_INTERFACE:
     305                 :         case nsXPTType::T_INTERFACE_IS:
     306                 :         {
     307                 :             nsIID iid;
     308               0 :             aInfo->GetIIDForParamNoAlloc(mMethodIndex, &aParam, &iid);
     309               0 :             if (iid.Equals(NS_GET_IID(txINodeSet))) {
     310               0 :                 return eNODESET;
     311                 :             }
     312               0 :             if (iid.Equals(NS_GET_IID(txIFunctionEvaluationContext))) {
     313               0 :                 return eCONTEXT;
     314                 :             }
     315               0 :             if (iid.Equals(NS_GET_IID(txIXPathObject))) {
     316               0 :                 return eOBJECT;
     317                 :             }
     318                 :         }
     319                 :         // FALLTHROUGH
     320                 :         default:
     321                 :         {
     322                 :             // XXX Error!
     323               0 :             return eUNKNOWN;
     324                 :         }
     325                 :     }
     326                 : }
     327                 : 
     328                 : class txParamArrayHolder
     329                 : {
     330                 : public:
     331               0 :     txParamArrayHolder()
     332               0 :         : mCount(0)
     333                 :     {
     334               0 :     }
     335                 :     ~txParamArrayHolder();
     336                 : 
     337                 :     bool Init(PRUint8 aCount);
     338               0 :     operator nsXPTCVariant*() const
     339                 :     {
     340               0 :       return mArray;
     341                 :     }
     342                 : 
     343                 : private:
     344                 :     nsAutoArrayPtr<nsXPTCVariant> mArray;
     345                 :     PRUint8 mCount;
     346                 : };
     347                 : 
     348               0 : txParamArrayHolder::~txParamArrayHolder()
     349                 : {
     350                 :     PRUint8 i;
     351               0 :     for (i = 0; i < mCount; ++i) {
     352               0 :         nsXPTCVariant &variant = mArray[i];
     353               0 :         if (variant.DoesValNeedCleanup()) {
     354               0 :             if (variant.type.TagPart() == nsXPTType::T_DOMSTRING)
     355               0 :                 delete (nsAString*)variant.val.p;
     356                 :             else {
     357               0 :                 NS_ABORT_IF_FALSE(variant.type.TagPart() == nsXPTType::T_INTERFACE ||
     358                 :                                   variant.type.TagPart() == nsXPTType::T_INTERFACE_IS,
     359                 :                                   "We only support cleanup of strings and interfaces "
     360                 :                                   "here, and this looks like neither!");
     361               0 :                 static_cast<nsISupports*>(variant.val.p)->Release();
     362                 :             }
     363                 :         }
     364                 :     }
     365               0 : }
     366                 : 
     367                 : bool
     368               0 : txParamArrayHolder::Init(PRUint8 aCount)
     369                 : {
     370               0 :     mCount = aCount;
     371               0 :     mArray = new nsXPTCVariant[mCount];
     372               0 :     if (!mArray) {
     373               0 :         return false;
     374                 :     }
     375                 : 
     376               0 :     memset(mArray, 0, mCount * sizeof(nsXPTCVariant));
     377                 : 
     378               0 :     return true;
     379                 : }
     380                 : 
     381                 : nsresult
     382               0 : txXPCOMExtensionFunctionCall::evaluate(txIEvalContext* aContext,
     383                 :                                        txAExprResult** aResult)
     384                 : {
     385                 :     nsCOMPtr<nsIInterfaceInfoManager> iim =
     386               0 :         do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID);
     387               0 :     NS_ENSURE_TRUE(iim, NS_ERROR_FAILURE);
     388                 : 
     389               0 :     nsCOMPtr<nsIInterfaceInfo> info;
     390               0 :     nsresult rv = iim->GetInfoForIID(&mIID, getter_AddRefs(info));
     391               0 :     NS_ENSURE_SUCCESS(rv, rv);
     392                 : 
     393                 :     const nsXPTMethodInfo *methodInfo;
     394               0 :     rv = info->GetMethodInfo(mMethodIndex, &methodInfo);
     395               0 :     NS_ENSURE_SUCCESS(rv, rv);
     396                 : 
     397               0 :     PRUint8 paramCount = methodInfo->GetParamCount();
     398               0 :     PRUint8 inArgs = paramCount - 1;
     399                 : 
     400               0 :     txParamArrayHolder invokeParams;
     401               0 :     if (!invokeParams.Init(paramCount)) {
     402               0 :         return NS_ERROR_OUT_OF_MEMORY;
     403                 :     }
     404                 : 
     405               0 :     const nsXPTParamInfo &paramInfo = methodInfo->GetParam(0);
     406               0 :     txArgumentType type = GetParamType(paramInfo, info);
     407               0 :     if (type == eUNKNOWN) {
     408               0 :         return NS_ERROR_FAILURE;
     409                 :     }
     410                 : 
     411                 :     txFunctionEvaluationContext *context;
     412               0 :     PRUint32 paramStart = 0;
     413               0 :     if (type == eCONTEXT) {
     414               0 :         if (paramInfo.IsOut()) {
     415                 :             // We don't support out values.
     416               0 :             return NS_ERROR_FAILURE;
     417                 :         }
     418                 : 
     419                 :         // Create context wrapper.
     420               0 :         context = new txFunctionEvaluationContext(aContext, mState);
     421               0 :         if (!context) {
     422               0 :             return NS_ERROR_OUT_OF_MEMORY;
     423                 :         }
     424                 : 
     425               0 :         nsXPTCVariant &invokeParam = invokeParams[0];
     426               0 :         invokeParam.type = paramInfo.GetType();
     427               0 :         invokeParam.SetValNeedsCleanup();
     428               0 :         NS_ADDREF((txIFunctionEvaluationContext*&)invokeParam.val.p = context);
     429                 : 
     430                 :         // Skip first argument, since it's the context.
     431               0 :         paramStart = 1;
     432                 :     }
     433                 :     else {
     434               0 :         context = nsnull;
     435                 :     }
     436                 : 
     437                 :     // XXX varargs
     438               0 :     if (!requireParams(inArgs - paramStart, inArgs - paramStart, aContext)) {
     439               0 :         return NS_ERROR_FAILURE;
     440                 :     }
     441                 : 
     442                 :     PRUint32 i;
     443               0 :     for (i = paramStart; i < inArgs; ++i) {
     444               0 :         Expr* expr = mParams[i - paramStart];
     445                 : 
     446               0 :         const nsXPTParamInfo &paramInfo = methodInfo->GetParam(i);
     447               0 :         txArgumentType type = GetParamType(paramInfo, info);
     448               0 :         if (type == eUNKNOWN) {
     449               0 :             return NS_ERROR_FAILURE;
     450                 :         }
     451                 : 
     452               0 :         nsXPTCVariant &invokeParam = invokeParams[i];
     453               0 :         if (paramInfo.IsOut()) {
     454                 :             // We don't support out values.
     455               0 :             return NS_ERROR_FAILURE;
     456                 :         }
     457                 : 
     458               0 :         invokeParam.type = paramInfo.GetType();
     459               0 :         switch (type) {
     460                 :             case eNODESET:
     461                 :             {
     462               0 :                 nsRefPtr<txNodeSet> nodes;
     463               0 :                 rv = evaluateToNodeSet(expr, aContext, getter_AddRefs(nodes));
     464               0 :                 NS_ENSURE_SUCCESS(rv, rv);
     465                 : 
     466               0 :                 txNodeSetAdaptor *adaptor = new txNodeSetAdaptor(nodes);
     467               0 :                 if (!adaptor) {
     468               0 :                     return NS_ERROR_OUT_OF_MEMORY;
     469                 :                 }
     470                 : 
     471               0 :                 nsCOMPtr<txINodeSet> nodeSet = adaptor;
     472               0 :                 rv = adaptor->Init();
     473               0 :                 NS_ENSURE_SUCCESS(rv, rv);
     474                 : 
     475               0 :                 invokeParam.SetValNeedsCleanup();
     476               0 :                 nodeSet.swap((txINodeSet*&)invokeParam.val.p);
     477               0 :                 break;
     478                 :             }
     479                 :             case eBOOLEAN:
     480                 :             {
     481               0 :                 rv = expr->evaluateToBool(aContext, invokeParam.val.b);
     482               0 :                 NS_ENSURE_SUCCESS(rv, rv);
     483                 : 
     484               0 :                 break;
     485                 :             }
     486                 :             case eNUMBER:
     487                 :             {
     488                 :                 double dbl;
     489               0 :                 rv = evaluateToNumber(mParams[0], aContext, &dbl);
     490               0 :                 NS_ENSURE_SUCCESS(rv, rv);
     491                 : 
     492               0 :                 invokeParam.val.d = dbl;
     493               0 :                 break;
     494                 :             }
     495                 :             case eSTRING:
     496                 :             {
     497               0 :                 nsString *value = new nsString();
     498               0 :                 if (!value) {
     499               0 :                     return NS_ERROR_OUT_OF_MEMORY;
     500                 :                 }
     501                 : 
     502               0 :                 rv = expr->evaluateToString(aContext, *value);
     503               0 :                 NS_ENSURE_SUCCESS(rv, rv);
     504                 : 
     505               0 :                 invokeParam.SetValNeedsCleanup();
     506               0 :                 invokeParam.val.p = value;
     507               0 :                 break;
     508                 :             }
     509                 :             case eOBJECT:
     510                 :             {
     511               0 :               nsRefPtr<txAExprResult> exprRes;
     512               0 :               rv = expr->evaluate(aContext, getter_AddRefs(exprRes));
     513               0 :               NS_ENSURE_SUCCESS(rv, rv);
     514                 : 
     515                 :               nsCOMPtr<txIXPathObject> adaptor =
     516               0 :                 new txXPathObjectAdaptor(exprRes);
     517               0 :               if (!adaptor) {
     518               0 :                   return NS_ERROR_OUT_OF_MEMORY;
     519                 :               }
     520                 : 
     521               0 :               invokeParam.SetValNeedsCleanup();
     522               0 :               adaptor.swap((txIXPathObject*&)invokeParam.val.p);
     523               0 :               break;
     524                 :             }
     525                 :             case eCONTEXT:
     526                 :             case eUNKNOWN:
     527                 :             {
     528                 :                 // We only support passing the context as the *first* argument.
     529               0 :                 return NS_ERROR_FAILURE;
     530                 :             }
     531                 :         }
     532                 :     }
     533                 : 
     534               0 :     const nsXPTParamInfo &returnInfo = methodInfo->GetParam(inArgs);
     535               0 :     txArgumentType returnType = GetParamType(returnInfo, info);
     536               0 :     if (returnType == eUNKNOWN) {
     537               0 :         return NS_ERROR_FAILURE;
     538                 :     }
     539                 : 
     540               0 :     nsXPTCVariant &returnParam = invokeParams[inArgs];
     541               0 :     returnParam.type = returnInfo.GetType();
     542               0 :     if (returnType == eSTRING) {
     543               0 :         nsString *value = new nsString();
     544               0 :         if (!value) {
     545               0 :             return NS_ERROR_FAILURE;
     546                 :         }
     547                 : 
     548               0 :         returnParam.SetValNeedsCleanup();
     549               0 :         returnParam.val.p = value;
     550                 :     }
     551                 :     else {
     552               0 :         returnParam.SetIndirect();
     553               0 :         if (returnType == eNODESET || returnType == eOBJECT) {
     554               0 :             returnParam.SetValNeedsCleanup();
     555                 :         }
     556                 :     }
     557                 : 
     558               0 :     rv = NS_InvokeByIndex(mHelper, mMethodIndex, paramCount, invokeParams);
     559                 : 
     560                 :     // In case someone is holding on to the txFunctionEvaluationContext which
     561                 :     // could thus stay alive longer than this function.
     562               0 :     if (context) {
     563               0 :         context->ClearContext();
     564                 :     }
     565                 : 
     566               0 :     NS_ENSURE_SUCCESS(rv, rv);
     567                 : 
     568               0 :     switch (returnType) {
     569                 :         case eNODESET:
     570                 :         {
     571               0 :             txINodeSet* nodeSet = static_cast<txINodeSet*>(returnParam.val.p);
     572               0 :             nsCOMPtr<txIXPathObject> object = do_QueryInterface(nodeSet, &rv);
     573               0 :             NS_ENSURE_SUCCESS(rv, rv);
     574                 : 
     575               0 :             NS_ADDREF(*aResult = object->GetResult());
     576                 : 
     577               0 :             return NS_OK;
     578                 :         }
     579                 :         case eBOOLEAN:
     580                 :         {
     581               0 :             aContext->recycler()->getBoolResult(returnParam.val.b, aResult);
     582                 : 
     583               0 :             return NS_OK;
     584                 :         }
     585                 :         case eNUMBER:
     586                 :         {
     587               0 :             return aContext->recycler()->getNumberResult(returnParam.val.d,
     588               0 :                                                          aResult);
     589                 :         }
     590                 :         case eSTRING:
     591                 :         {
     592                 :             nsString *returned = static_cast<nsString*>
     593               0 :                                             (returnParam.val.p);
     594               0 :             return aContext->recycler()->getStringResult(*returned, aResult);
     595                 :         }
     596                 :         case eOBJECT:
     597                 :         {
     598                 :             txIXPathObject *object =
     599               0 :                  static_cast<txIXPathObject*>(returnParam.val.p);
     600                 : 
     601               0 :             NS_ADDREF(*aResult = object->GetResult());
     602                 : 
     603               0 :             return NS_OK;
     604                 :         }
     605                 :         default:
     606                 :         {
     607                 :             // Huh?
     608               0 :             return NS_ERROR_FAILURE;
     609                 :         }
     610                 :     }
     611                 : }
     612                 : 
     613                 : Expr::ResultType
     614               0 : txXPCOMExtensionFunctionCall::getReturnType()
     615                 : {
     616                 :     // It doesn't really matter what we return here, but it might
     617                 :     // be a good idea to try to keep this as unoptimizable as possible
     618               0 :     return ANY_RESULT;
     619                 : }
     620                 : 
     621                 : bool
     622               0 : txXPCOMExtensionFunctionCall::isSensitiveTo(ContextSensitivity aContext)
     623                 : {
     624                 :     // It doesn't really matter what we return here, but it might
     625                 :     // be a good idea to try to keep this as unoptimizable as possible
     626               0 :     return true;
     627                 : }
     628                 : 
     629                 : #ifdef TX_TO_STRING
     630                 : nsresult
     631               0 : txXPCOMExtensionFunctionCall::getNameAtom(nsIAtom** aAtom)
     632                 : {
     633               0 :     NS_ADDREF(*aAtom = mName);
     634                 : 
     635               0 :     return NS_OK;
     636                 : }
     637                 : #endif

Generated by: LCOV version 1.7