LCOV - code coverage report
Current view: directory - content/xslt/src/xpath - nsXPathEvaluator.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 101 40 39.6 %
Date: 2012-06-02 Functions: 22 13 59.1 %

       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 TransforMiiX XSLT processor code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2001
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Peter Van der Beken <peterv@propagandism.org>
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      27                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #include "nsXPathEvaluator.h"
      40                 : #include "nsCOMPtr.h"
      41                 : #include "nsIAtom.h"
      42                 : #include "nsDOMClassInfoID.h"
      43                 : #include "nsXPathExpression.h"
      44                 : #include "nsXPathNSResolver.h"
      45                 : #include "nsXPathResult.h"
      46                 : #include "nsContentCID.h"
      47                 : #include "txExpr.h"
      48                 : #include "txExprParser.h"
      49                 : #include "nsDOMError.h"
      50                 : #include "txURIUtils.h"
      51                 : #include "nsIDocument.h"
      52                 : #include "nsIDOMDocument.h"
      53                 : #include "nsDOMString.h"
      54                 : #include "nsINameSpaceManager.h"
      55                 : #include "txError.h"
      56                 : #include "nsContentUtils.h"
      57                 : 
      58                 : // txIParseContext implementation
      59                 : class nsXPathEvaluatorParseContext : public txIParseContext
      60              84 : {
      61                 : public:
      62              42 :     nsXPathEvaluatorParseContext(nsXPathEvaluator &aEvaluator,
      63                 :                                  nsIDOMXPathNSResolver* aResolver,
      64                 :                                  nsTArray<PRInt32> *aNamespaceIDs,
      65                 :                                  nsTArray<nsCString> *aContractIDs,
      66                 :                                  nsCOMArray<nsISupports> *aState,
      67                 :                                  bool aIsCaseSensitive)
      68                 :         : mEvaluator(aEvaluator),
      69                 :           mResolver(aResolver),
      70                 :           mNamespaceIDs(aNamespaceIDs),
      71                 :           mContractIDs(aContractIDs),
      72                 :           mState(aState),
      73                 :           mLastError(NS_OK),
      74              42 :           mIsCaseSensitive(aIsCaseSensitive)
      75                 :     {
      76              42 :         NS_ASSERTION(mContractIDs ||
      77                 :                      (!mNamespaceIDs || mNamespaceIDs->Length() == 0),
      78                 :                      "Need contract IDs if there are namespaces.");
      79              42 :     }
      80                 : 
      81                 :     nsresult getError()
      82                 :     {
      83                 :         return mLastError;
      84                 :     }
      85                 : 
      86                 :     nsresult resolveNamespacePrefix(nsIAtom* aPrefix, PRInt32& aID);
      87                 :     nsresult resolveFunctionCall(nsIAtom* aName, PRInt32 aID,
      88                 :                                  FunctionCall** aFunction);
      89                 :     bool caseInsensitiveNameTests();
      90                 :     void SetErrorOffset(PRUint32 aOffset);
      91                 : 
      92                 : private:
      93                 :     nsXPathEvaluator &mEvaluator;
      94                 :     nsIDOMXPathNSResolver* mResolver;
      95                 :     nsTArray<PRInt32> *mNamespaceIDs;
      96                 :     nsTArray<nsCString> *mContractIDs;
      97                 :     nsCOMArray<nsISupports> *mState;
      98                 :     nsresult mLastError;
      99                 :     bool mIsCaseSensitive;
     100                 : };
     101                 : 
     102                 : DOMCI_DATA(XPathEvaluator, nsXPathEvaluator)
     103                 : 
     104             140 : NS_IMPL_AGGREGATED(nsXPathEvaluator)
     105              46 : NS_INTERFACE_MAP_BEGIN_AGGREGATED(nsXPathEvaluator)
     106              44 :     NS_INTERFACE_MAP_ENTRY(nsIDOMXPathEvaluator)
     107               2 :     NS_INTERFACE_MAP_ENTRY(nsIXPathEvaluatorInternal)
     108               2 :     NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(XPathEvaluator)
     109               2 : NS_INTERFACE_MAP_END
     110                 : 
     111               2 : nsXPathEvaluator::nsXPathEvaluator(nsISupports *aOuter)
     112                 : {
     113               2 :     NS_INIT_AGGREGATED(aOuter);
     114               2 : }
     115                 : 
     116                 : nsresult
     117               2 : nsXPathEvaluator::Init()
     118                 : {
     119               4 :     nsCOMPtr<nsIDOMDocument> document = do_QueryInterface(fOuter);
     120                 : 
     121               2 :     return document ? SetDocument(document) : NS_OK;
     122                 : }
     123                 : 
     124                 : NS_IMETHODIMP
     125              42 : nsXPathEvaluator::CreateExpression(const nsAString & aExpression,
     126                 :                                    nsIDOMXPathNSResolver *aResolver,
     127                 :                                    nsIDOMXPathExpression **aResult)
     128                 : {
     129                 :     return CreateExpression(aExpression, aResolver, (nsTArray<PRInt32>*)nsnull,
     130              42 :                             nsnull, nsnull, aResult);
     131                 : }
     132                 : 
     133                 : NS_IMETHODIMP
     134               0 : nsXPathEvaluator::CreateNSResolver(nsIDOMNode *aNodeResolver,
     135                 :                                    nsIDOMXPathNSResolver **aResult)
     136                 : {
     137               0 :     NS_ENSURE_ARG(aNodeResolver);
     138               0 :     if (!nsContentUtils::CanCallerAccess(aNodeResolver))
     139               0 :         return NS_ERROR_DOM_SECURITY_ERR;
     140                 : 
     141               0 :     *aResult = new nsXPathNSResolver(aNodeResolver);
     142               0 :     NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
     143                 : 
     144               0 :     NS_ADDREF(*aResult);
     145               0 :     return NS_OK;
     146                 : }
     147                 : 
     148                 : NS_IMETHODIMP
     149               0 : nsXPathEvaluator::Evaluate(const nsAString & aExpression,
     150                 :                            nsIDOMNode *aContextNode,
     151                 :                            nsIDOMXPathNSResolver *aResolver,
     152                 :                            PRUint16 aType,
     153                 :                            nsISupports *aInResult,
     154                 :                            nsISupports **aResult)
     155                 : {
     156               0 :     nsCOMPtr<nsIDOMXPathExpression> expression;
     157                 :     nsresult rv = CreateExpression(aExpression, aResolver,
     158               0 :                                    getter_AddRefs(expression));
     159               0 :     NS_ENSURE_SUCCESS(rv, rv);
     160                 : 
     161               0 :     return expression->Evaluate(aContextNode, aType, aInResult, aResult);
     162                 : }
     163                 : 
     164                 : 
     165                 : NS_IMETHODIMP
     166               2 : nsXPathEvaluator::SetDocument(nsIDOMDocument* aDocument)
     167                 : {
     168               2 :     mDocument = do_GetWeakReference(aDocument);
     169               2 :     return NS_OK;
     170                 : }
     171                 : 
     172                 : NS_IMETHODIMP
     173               0 : nsXPathEvaluator::CreateExpression(const nsAString & aExpression,
     174                 :                                    nsIDOMXPathNSResolver *aResolver,
     175                 :                                    nsTArray<nsString> *aNamespaceURIs,
     176                 :                                    nsTArray<nsCString> *aContractIDs,
     177                 :                                    nsCOMArray<nsISupports> *aState,
     178                 :                                    nsIDOMXPathExpression **aResult)
     179                 : {
     180               0 :     nsTArray<PRInt32> namespaceIDs;
     181               0 :     if (aNamespaceURIs) {
     182               0 :         PRUint32 count = aNamespaceURIs->Length();
     183                 : 
     184               0 :         if (!aContractIDs || aContractIDs->Length() != count) {
     185               0 :             return NS_ERROR_FAILURE;
     186                 :         }
     187                 : 
     188               0 :         if (!namespaceIDs.SetLength(count)) {
     189               0 :             return NS_ERROR_OUT_OF_MEMORY;
     190                 :         }
     191                 : 
     192                 :         PRUint32 i;
     193               0 :         for (i = 0; i < count; ++i) {
     194               0 :             if (aContractIDs->ElementAt(i).IsEmpty()) {
     195               0 :                 return NS_ERROR_FAILURE;
     196                 :             }
     197                 : 
     198               0 :             nsContentUtils::NameSpaceManager()->RegisterNameSpace(aNamespaceURIs->ElementAt(i), namespaceIDs[i]);
     199                 :         }
     200                 :     }
     201                 : 
     202                 : 
     203                 :     return CreateExpression(aExpression, aResolver, &namespaceIDs, aContractIDs,
     204               0 :                             aState, aResult);
     205                 : }
     206                 : 
     207                 : nsresult
     208              42 : nsXPathEvaluator::CreateExpression(const nsAString & aExpression,
     209                 :                                    nsIDOMXPathNSResolver *aResolver,
     210                 :                                    nsTArray<PRInt32> *aNamespaceIDs,
     211                 :                                    nsTArray<nsCString> *aContractIDs,
     212                 :                                    nsCOMArray<nsISupports> *aState,
     213                 :                                    nsIDOMXPathExpression **aResult)
     214                 : {
     215                 :     nsresult rv;
     216              42 :     if (!mRecycler) {
     217               4 :         nsRefPtr<txResultRecycler> recycler = new txResultRecycler;
     218               2 :         NS_ENSURE_TRUE(recycler, NS_ERROR_OUT_OF_MEMORY);
     219                 :         
     220               2 :         rv = recycler->init();
     221               2 :         NS_ENSURE_SUCCESS(rv, rv);
     222                 :         
     223               4 :         mRecycler = recycler;
     224                 :     }
     225                 : 
     226              84 :     nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument);
     227                 :     nsXPathEvaluatorParseContext pContext(*this, aResolver, aNamespaceIDs,
     228                 :                                           aContractIDs, aState,
     229              84 :                                           !(doc && doc->IsHTML()));
     230                 : 
     231              84 :     nsAutoPtr<Expr> expression;
     232              42 :     rv = txExprParser::createExpr(PromiseFlatString(aExpression), &pContext,
     233              42 :                                   getter_Transfers(expression));
     234              42 :     if (NS_FAILED(rv)) {
     235               0 :         if (rv == NS_ERROR_DOM_NAMESPACE_ERR) {
     236               0 :             return NS_ERROR_DOM_NAMESPACE_ERR;
     237                 :         }
     238                 : 
     239               0 :         return NS_ERROR_DOM_INVALID_EXPRESSION_ERR;
     240                 :     }
     241                 : 
     242              84 :     nsCOMPtr<nsIDOMDocument> document = do_QueryReferent(mDocument);
     243                 : 
     244              84 :     *aResult = new nsXPathExpression(expression, mRecycler, document);
     245              42 :     if (!*aResult) {
     246               0 :         return NS_ERROR_OUT_OF_MEMORY;
     247                 :     }
     248                 : 
     249              42 :     NS_ADDREF(*aResult);
     250              42 :     return NS_OK;
     251                 : }
     252                 : 
     253                 : /*
     254                 :  * Implementation of txIParseContext private to nsXPathEvaluator, based on a
     255                 :  * nsIDOMXPathNSResolver
     256                 :  */
     257                 : 
     258               0 : nsresult nsXPathEvaluatorParseContext::resolveNamespacePrefix
     259                 :     (nsIAtom* aPrefix, PRInt32& aID)
     260                 : {
     261               0 :     aID = kNameSpaceID_Unknown;
     262                 : 
     263               0 :     if (!mResolver) {
     264               0 :         return NS_ERROR_DOM_NAMESPACE_ERR;
     265                 :     }
     266                 : 
     267               0 :     nsAutoString prefix;
     268               0 :     if (aPrefix) {
     269               0 :         aPrefix->ToString(prefix);
     270                 :     }
     271                 : 
     272               0 :     nsVoidableString ns;
     273               0 :     nsresult rv = mResolver->LookupNamespaceURI(prefix, ns);
     274               0 :     NS_ENSURE_SUCCESS(rv, rv);
     275                 : 
     276               0 :     if (DOMStringIsNull(ns)) {
     277               0 :         return NS_ERROR_DOM_NAMESPACE_ERR;
     278                 :     }
     279                 : 
     280               0 :     if (ns.IsEmpty()) {
     281               0 :         aID = kNameSpaceID_None;
     282                 : 
     283               0 :         return NS_OK;
     284                 :     }
     285                 : 
     286                 :     // get the namespaceID for the URI
     287               0 :     return nsContentUtils::NameSpaceManager()->RegisterNameSpace(ns, aID);
     288                 : }
     289                 : 
     290                 : extern nsresult
     291                 : TX_ResolveFunctionCallXPCOM(const nsCString &aContractID, PRInt32 aNamespaceID,
     292                 :                             nsIAtom *aName, nsISupports *aState,
     293                 :                             FunctionCall **aFunction);
     294                 : 
     295                 : nsresult
     296               0 : nsXPathEvaluatorParseContext::resolveFunctionCall(nsIAtom* aName,
     297                 :                                                   PRInt32 aID,
     298                 :                                                   FunctionCall** aFn)
     299                 : {
     300               0 :     nsresult rv = NS_ERROR_XPATH_UNKNOWN_FUNCTION;
     301                 : 
     302               0 :     PRUint32 i, count = mNamespaceIDs ? mNamespaceIDs->Length() : 0;
     303               0 :     for (i = 0; i < count; ++i) {
     304               0 :         if (mNamespaceIDs->ElementAt(i) == aID) {
     305               0 :             nsISupports *state = mState ? mState->SafeObjectAt(i) : nsnull;
     306               0 :             rv = TX_ResolveFunctionCallXPCOM(mContractIDs->ElementAt(i), aID,
     307               0 :                                              aName, state, aFn);
     308               0 :             if (NS_SUCCEEDED(rv)) {
     309               0 :                 break;
     310                 :             }
     311                 :         }
     312                 :     }
     313                 : 
     314               0 :     return rv;
     315                 : }
     316                 : 
     317               0 : bool nsXPathEvaluatorParseContext::caseInsensitiveNameTests()
     318                 : {
     319               0 :     return !mIsCaseSensitive;
     320                 : }
     321                 : 
     322                 : void
     323               0 : nsXPathEvaluatorParseContext::SetErrorOffset(PRUint32 aOffset)
     324                 : {
     325               0 : }

Generated by: LCOV version 1.7