txFilterExpr.cpp (2470B)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #include "txExpr.h" 7 #include "txIXPathContext.h" 8 #include "txNodeSet.h" 9 10 using mozilla::WrapUnique; 11 12 //-- Implementation of FilterExpr --/ 13 14 //-----------------------------/ 15 //- Virtual methods from Expr -/ 16 //-----------------------------/ 17 18 /** 19 * Evaluates this Expr based on the given context node and processor state 20 * @param context the context node for evaluation of this Expr 21 * @param ps the ProcessorState containing the stack information needed 22 * for evaluation 23 * @return the result of the evaluation 24 * @see Expr 25 **/ 26 nsresult FilterExpr::evaluate(txIEvalContext* aContext, 27 txAExprResult** aResult) { 28 *aResult = nullptr; 29 30 RefPtr<txAExprResult> exprRes; 31 nsresult rv = expr->evaluate(aContext, getter_AddRefs(exprRes)); 32 NS_ENSURE_SUCCESS(rv, rv); 33 34 NS_ENSURE_TRUE(exprRes->getResultType() == txAExprResult::NODESET, 35 NS_ERROR_XSLT_NODESET_EXPECTED); 36 37 RefPtr<txNodeSet> nodes = 38 static_cast<txNodeSet*>(static_cast<txAExprResult*>(exprRes)); 39 // null out exprRes so that we can test for shared-ness 40 exprRes = nullptr; 41 42 RefPtr<txNodeSet> nonShared; 43 rv = aContext->recycler()->getNonSharedNodeSet(nodes, 44 getter_AddRefs(nonShared)); 45 NS_ENSURE_SUCCESS(rv, rv); 46 47 rv = evaluatePredicates(nonShared, aContext); 48 NS_ENSURE_SUCCESS(rv, rv); 49 50 *aResult = nonShared; 51 NS_ADDREF(*aResult); 52 53 return NS_OK; 54 } //-- evaluate 55 56 TX_IMPL_EXPR_STUBS_BASE(FilterExpr, NODESET_RESULT) 57 58 Expr* FilterExpr::getSubExprAt(uint32_t aPos) { 59 if (aPos == 0) { 60 return expr.get(); 61 } 62 return PredicateList::getSubExprAt(aPos - 1); 63 } 64 65 void FilterExpr::setSubExprAt(uint32_t aPos, Expr* aExpr) { 66 if (aPos == 0) { 67 (void)expr.release(); 68 expr = WrapUnique(aExpr); 69 } else { 70 PredicateList::setSubExprAt(aPos - 1, aExpr); 71 } 72 } 73 74 bool FilterExpr::isSensitiveTo(ContextSensitivity aContext) { 75 return expr->isSensitiveTo(aContext) || 76 PredicateList::isSensitiveTo(aContext); 77 } 78 79 #ifdef TX_TO_STRING 80 void FilterExpr::toString(nsAString& str) { 81 if (expr) 82 expr->toString(str); 83 else 84 str.AppendLiteral("null"); 85 PredicateList::toString(str); 86 } 87 #endif