LCOV - app.info - content/xslt/src/xpath/txLocationStep.cpp

LCOV - code coverage report
| Current view: | directory - content/xslt/src/xpath - txLocationStep.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 144 | 21 | 14.6 %
| Date: | 2012-06-02 | Functions: | 9 | 4 | 44.4 %

           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                 :  * The MITRE Corporation.
          19                 :  * Portions created by the Initial Developer are Copyright (C) 1999
          20                 :  * the Initial Developer. All Rights Reserved.
          21                 :  *
          22                 :  * Contributor(s):
          23                 :  *   Keith Visco <kvisco@ziplink.net> (Original Author)
          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                 : /*
          40                 :   Implementation of an XPath LocationStep
          41                 : */
          42                 :
          43                 : #include "txExpr.h"
          44                 : #include "txIXPathContext.h"
          45                 : #include "txNodeSet.h"
          46                 : #include "txXPathTreeWalker.h"
          47                 :
          48                 :   //-----------------------------/
          49                 :  //- Virtual methods from Expr -/
          50                 : //-----------------------------/
          51                 :
          52                 : /**
          53                 :  * Evaluates this Expr based on the given context node and processor state
          54                 :  * @param context the context node for evaluation of this Expr
          55                 :  * @param ps the ProcessorState containing the stack information needed
          56                 :  * for evaluation
          57                 :  * @return the result of the evaluation
          58                 :  * @see Expr
          59                 : **/
          60                 : nsresult
          61              42 : LocationStep::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
          62                 : {
          63              42 :     NS_ASSERTION(aContext, "internal error");
          64              42 :     *aResult = nsnull;
          65                 :
          66              84 :     nsRefPtr<txNodeSet> nodes;
          67              42 :     nsresult rv = aContext->recycler()->getNodeSet(getter_AddRefs(nodes));
          68              42 :     NS_ENSURE_SUCCESS(rv, rv);
          69                 :
          70              84 :     txXPathTreeWalker walker(aContext->getContextNode());
          71                 :
          72              42 :     switch (mAxisIdentifier) {
          73                 :         case ANCESTOR_AXIS:
          74                 :         {
          75               0 :             if (!walker.moveToParent()) {
          76               0 :                 break;
          77                 :             }
          78                 :             // do not break here
          79                 :         }
          80                 :         case ANCESTOR_OR_SELF_AXIS:
          81                 :         {
          82               0 :             nodes->setReverse();
          83                 :
          84               0 :             do {
          85               0 :                 if (mNodeTest->matches(walker.getCurrentPosition(), aContext)) {
          86               0 :                     nodes->append(walker.getCurrentPosition());
          87                 :                 }
          88                 :             } while (walker.moveToParent());
          89                 :
          90               0 :             break;
          91                 :         }
          92                 :         case ATTRIBUTE_AXIS:
          93                 :         {
          94               0 :             if (!walker.moveToFirstAttribute()) {
          95               0 :                 break;
          96                 :             }
          97                 :
          98               0 :             do {
          99               0 :                 if (mNodeTest->matches(walker.getCurrentPosition(), aContext)) {
         100               0 :                     nodes->append(walker.getCurrentPosition());
         101                 :                 }
         102                 :             } while (walker.moveToNextAttribute());
         103               0 :             break;
         104                 :         }
         105                 :         case DESCENDANT_OR_SELF_AXIS:
         106                 :         {
         107               0 :             if (mNodeTest->matches(walker.getCurrentPosition(), aContext)) {
         108               0 :                 nodes->append(walker.getCurrentPosition());
         109                 :             }
         110                 :             // do not break here
         111                 :         }
         112                 :         case DESCENDANT_AXIS:
         113                 :         {
         114               0 :             fromDescendants(walker.getCurrentPosition(), aContext, nodes);
         115               0 :             break;
         116                 :         }
         117                 :         case FOLLOWING_AXIS:
         118                 :         {
         119               0 :             if (txXPathNodeUtils::isAttribute(walker.getCurrentPosition())) {
         120               0 :                 walker.moveToParent();
         121               0 :                 fromDescendants(walker.getCurrentPosition(), aContext, nodes);
         122                 :             }
         123               0 :             bool cont = true;
         124               0 :             while (!walker.moveToNextSibling()) {
         125               0 :                 if (!walker.moveToParent()) {
         126               0 :                     cont = false;
         127               0 :                     break;
         128                 :                 }
         129                 :             }
         130               0 :             while (cont) {
         131               0 :                 if (mNodeTest->matches(walker.getCurrentPosition(), aContext)) {
         132               0 :                     nodes->append(walker.getCurrentPosition());
         133                 :                 }
         134                 :
         135               0 :                 fromDescendants(walker.getCurrentPosition(), aContext, nodes);
         136                 :
         137               0 :                 while (!walker.moveToNextSibling()) {
         138               0 :                     if (!walker.moveToParent()) {
         139               0 :                         cont = false;
         140               0 :                         break;
         141                 :                     }
         142                 :                 }
         143                 :             }
         144               0 :             break;
         145                 :         }
         146                 :         case FOLLOWING_SIBLING_AXIS:
         147                 :         {
         148               0 :             while (walker.moveToNextSibling()) {
         149               0 :                 if (mNodeTest->matches(walker.getCurrentPosition(), aContext)) {
         150               0 :                     nodes->append(walker.getCurrentPosition());
         151                 :                 }
         152                 :             }
         153               0 :             break;
         154                 :         }
         155                 :         case NAMESPACE_AXIS: //-- not yet implemented
         156                 : #if 0
         157                 :             // XXX DEBUG OUTPUT
         158                 :             cout << "namespace axis not yet implemented"<<endl;
         159                 : #endif
         160               0 :             break;
         161                 :         case PARENT_AXIS :
         162                 :         {
         163               0 :             if (walker.moveToParent() &&
         164               0 :                 mNodeTest->matches(walker.getCurrentPosition(), aContext)) {
         165               0 :                 nodes->append(walker.getCurrentPosition());
         166                 :             }
         167               0 :             break;
         168                 :         }
         169                 :         case PRECEDING_AXIS:
         170                 :         {
         171               0 :             nodes->setReverse();
         172                 :
         173               0 :             bool cont = true;
         174               0 :             while (!walker.moveToPreviousSibling()) {
         175               0 :                 if (!walker.moveToParent()) {
         176               0 :                     cont = false;
         177               0 :                     break;
         178                 :                 }
         179                 :             }
         180               0 :             while (cont) {
         181               0 :                 fromDescendantsRev(walker.getCurrentPosition(), aContext, nodes);
         182                 :
         183               0 :                 if (mNodeTest->matches(walker.getCurrentPosition(), aContext)) {
         184               0 :                     nodes->append(walker.getCurrentPosition());
         185                 :                 }
         186                 :
         187               0 :                 while (!walker.moveToPreviousSibling()) {
         188               0 :                     if (!walker.moveToParent()) {
         189               0 :                         cont = false;
         190               0 :                         break;
         191                 :                     }
         192                 :                 }
         193                 :             }
         194               0 :             break;
         195                 :         }
         196                 :         case PRECEDING_SIBLING_AXIS:
         197                 :         {
         198               0 :             nodes->setReverse();
         199                 :
         200               0 :             while (walker.moveToPreviousSibling()) {
         201               0 :                 if (mNodeTest->matches(walker.getCurrentPosition(), aContext)) {
         202               0 :                     nodes->append(walker.getCurrentPosition());
         203                 :                 }
         204                 :             }
         205               0 :             break;
         206                 :         }
         207                 :         case SELF_AXIS:
         208                 :         {
         209              42 :             if (mNodeTest->matches(walker.getCurrentPosition(), aContext)) {
         210              42 :                 nodes->append(walker.getCurrentPosition());
         211                 :             }
         212              42 :             break;
         213                 :         }
         214                 :         default: // Children Axis
         215                 :         {
         216               0 :             if (!walker.moveToFirstChild()) {
         217               0 :                 break;
         218                 :             }
         219                 :
         220               0 :             do {
         221               0 :                 if (mNodeTest->matches(walker.getCurrentPosition(), aContext)) {
         222               0 :                     nodes->append(walker.getCurrentPosition());
         223                 :                 }
         224                 :             } while (walker.moveToNextSibling());
         225               0 :             break;
         226                 :         }
         227                 :     }
         228                 :
         229                 :     // Apply predicates
         230              42 :     if (!isEmpty()) {
         231               0 :         rv = evaluatePredicates(nodes, aContext);
         232               0 :         NS_ENSURE_SUCCESS(rv, rv);
         233                 :     }
         234                 :
         235              42 :     nodes->unsetReverse();
         236                 :
         237              42 :     NS_ADDREF(*aResult = nodes);
         238                 :
         239              42 :     return NS_OK;
         240                 : }
         241                 :
         242               0 : void LocationStep::fromDescendants(const txXPathNode& aNode,
         243                 :                                    txIMatchContext* aCs,
         244                 :                                    txNodeSet* aNodes)
         245                 : {
         246               0 :     txXPathTreeWalker walker(aNode);
         247               0 :     if (!walker.moveToFirstChild()) {
         248                 :         return;
         249                 :     }
         250                 :
         251               0 :     do {
         252               0 :         const txXPathNode& child = walker.getCurrentPosition();
         253               0 :         if (mNodeTest->matches(child, aCs)) {
         254               0 :             aNodes->append(child);
         255                 :         }
         256               0 :         fromDescendants(child, aCs, aNodes);
         257                 :     } while (walker.moveToNextSibling());
         258                 : }
         259                 :
         260               0 : void LocationStep::fromDescendantsRev(const txXPathNode& aNode,
         261                 :                                       txIMatchContext* aCs,
         262                 :                                       txNodeSet* aNodes)
         263                 : {
         264               0 :     txXPathTreeWalker walker(aNode);
         265               0 :     if (!walker.moveToLastChild()) {
         266                 :         return;
         267                 :     }
         268                 :
         269               0 :     do {
         270               0 :         const txXPathNode& child = walker.getCurrentPosition();
         271               0 :         fromDescendantsRev(child, aCs, aNodes);
         272                 :
         273               0 :         if (mNodeTest->matches(child, aCs)) {
         274               0 :             aNodes->append(child);
         275                 :         }
         276                 :
         277                 :     } while (walker.moveToPreviousSibling());
         278                 : }
         279                 :
         280                 : Expr::ExprType
         281              42 : LocationStep::getType()
         282                 : {
         283              42 :   return LOCATIONSTEP_EXPR;
         284                 : }
         285                 :
         286                 :
         287               0 : TX_IMPL_EXPR_STUBS_BASE(LocationStep, NODESET_RESULT)
         288                 :
         289                 : Expr*
         290              84 : LocationStep::getSubExprAt(PRUint32 aPos)
         291                 : {
         292              84 :     return PredicateList::getSubExprAt(aPos);
         293                 : }
         294                 :
         295                 : void
         296               0 : LocationStep::setSubExprAt(PRUint32 aPos, Expr* aExpr)
         297                 : {
         298               0 :     PredicateList::setSubExprAt(aPos, aExpr);
         299               0 : }
         300                 :
         301                 : bool
         302              42 : LocationStep::isSensitiveTo(ContextSensitivity aContext)
         303                 : {
         304                 :     return (aContext & NODE_CONTEXT) ||
         305               0 :            mNodeTest->isSensitiveTo(aContext) ||
         306              42 :            PredicateList::isSensitiveTo(aContext);
         307                 : }
         308                 :
         309                 : #ifdef TX_TO_STRING
         310                 : void
         311               0 : LocationStep::toString(nsAString& str)
         312                 : {
         313               0 :     switch (mAxisIdentifier) {
         314                 :         case ANCESTOR_AXIS :
         315               0 :             str.AppendLiteral("ancestor::");
         316               0 :             break;
         317                 :         case ANCESTOR_OR_SELF_AXIS :
         318               0 :             str.AppendLiteral("ancestor-or-self::");
         319               0 :             break;
         320                 :         case ATTRIBUTE_AXIS:
         321               0 :             str.Append(PRUnichar('@'));
         322               0 :             break;
         323                 :         case DESCENDANT_AXIS:
         324               0 :             str.AppendLiteral("descendant::");
         325               0 :             break;
         326                 :         case DESCENDANT_OR_SELF_AXIS:
         327               0 :             str.AppendLiteral("descendant-or-self::");
         328               0 :             break;
         329                 :         case FOLLOWING_AXIS :
         330               0 :             str.AppendLiteral("following::");
         331               0 :             break;
         332                 :         case FOLLOWING_SIBLING_AXIS:
         333               0 :             str.AppendLiteral("following-sibling::");
         334               0 :             break;
         335                 :         case NAMESPACE_AXIS:
         336               0 :             str.AppendLiteral("namespace::");
         337               0 :             break;
         338                 :         case PARENT_AXIS :
         339               0 :             str.AppendLiteral("parent::");
         340               0 :             break;
         341                 :         case PRECEDING_AXIS :
         342               0 :             str.AppendLiteral("preceding::");
         343               0 :             break;
         344                 :         case PRECEDING_SIBLING_AXIS :
         345               0 :             str.AppendLiteral("preceding-sibling::");
         346               0 :             break;
         347                 :         case SELF_AXIS :
         348               0 :             str.AppendLiteral("self::");
         349               0 :             break;
         350                 :         default:
         351               0 :             break;
         352                 :     }
         353               0 :     NS_ASSERTION(mNodeTest, "mNodeTest is null, that's verboten");
         354               0 :     mNodeTest->toString(str);
         355                 :
         356               0 :     PredicateList::toString(str);
         357               0 : }
         358                 : #endif

Generated by: LCOV version 1.7