Make FilterExpr check type of ExprResult before casting to NodeSet. Also sort nodeset in document order before filtering.

Bug 88736. r=peterv, sr=jst
This commit is contained in:
sicking%bigfoot.com 2005-11-02 07:36:46 +00:00
parent fb3a49384f
commit b912e24ffe

View File

@ -23,7 +23,7 @@
* Bob Miller, kbob@oblix.com * Bob Miller, kbob@oblix.com
* -- plugged core leak. * -- plugged core leak.
* *
* $Id: txFilterExpr.cpp,v 1.2 2005/11/02 07:33:51 sicking%bigfoot.com Exp $ * $Id: txFilterExpr.cpp,v 1.3 2005/11/02 07:33:52 sicking%bigfoot.com Exp $
*/ */
#include "Expr.h" #include "Expr.h"
@ -31,7 +31,7 @@
/** /**
* @author <a href="mailto:kvisco@ziplink.net">Keith Visco</a> * @author <a href="mailto:kvisco@ziplink.net">Keith Visco</a>
* @version $Revision: 1.2 $ $Date: 2005/11/02 07:33:51 $ * @version $Revision: 1.3 $ $Date: 2005/11/02 07:33:52 $
**/ **/
//-- Implementation of FilterExpr --/ //-- Implementation of FilterExpr --/
@ -51,9 +51,9 @@ FilterExpr::~FilterExpr() {
delete expr; delete expr;
} //-- ~FilterExpr } //-- ~FilterExpr
//------------------------------------/ //-----------------------------/
//- Virtual methods from PatternExpr -/ //- Virtual methods from Expr -/
//------------------------------------/ //-----------------------------/
/** /**
* Evaluates this Expr based on the given context node and processor state * Evaluates this Expr based on the given context node and processor state
@ -61,38 +61,32 @@ FilterExpr::~FilterExpr() {
* @param ps the ProcessorState containing the stack information needed * @param ps the ProcessorState containing the stack information needed
* for evaluation * for evaluation
* @return the result of the evaluation * @return the result of the evaluation
* @see PatternExpr * @see Expr
**/ **/
ExprResult* FilterExpr::evaluate(Node* context, ContextState* cs) { ExprResult* FilterExpr::evaluate(Node* context, ContextState* cs) {
if (( !context ) || (! expr )) return new NodeSet; if (!context || !expr)
return new NodeSet;
ExprResult* exprResult = expr->evaluate(context, cs); ExprResult* exprResult = expr->evaluate(context, cs);
NodeSet* nodeSet = 0; if (!exprResult)
return 0;
switch (exprResult->getResultType()) { if (exprResult->getResultType() == ExprResult::NODESET) {
case ExprResult::NODESET: // Result is a nodeset, filter it.
nodeSet = (NodeSet*)exprResult; cs->sortByDocumentOrder((NodeSet*)exprResult);
break; evaluatePredicates((NodeSet*)exprResult, cs);
/* }
case ExprResult.TREE_FRAGMENT: else if(!isEmpty()) {
nodeSet = new NodeSet(1); // We can't filter a non-nodeset
nodeSet.add(((TreeFragmentResult)exprResult).getValue()); String err("Expecting nodeset as result of: ");
break; expr->toString(err);
*/ cs->recieveError(err);
default: delete exprResult;
break; return new NodeSet;
/*
throw new InvalidExprException
("expecting NodeSet or TreeFragment as the result of the "+
"expression: " + primaryExpr);
*/
} }
//-- filter nodes (apply predicates) return exprResult;
evaluatePredicates(nodeSet, cs);
return nodeSet;
} //-- evaluate } //-- evaluate
/** /**
@ -108,15 +102,23 @@ double FilterExpr::getDefaultPriority(Node* node, Node* context, ContextState* c
} //-- getDefaultPriority } //-- getDefaultPriority
/** /**
* Determines whether this PatternExpr matches the given node within * Determines whether this Expr matches the given node within
* the given context * the given context
**/ **/
MBool FilterExpr::matches(Node* node, Node* context, ContextState* cs) { MBool FilterExpr::matches(Node* node, Node* context, ContextState* cs) {
if ( !expr ) return MB_FALSE; if (!expr)
NodeSet* nodes = (NodeSet*)evaluate(node, cs); return MB_FALSE;
MBool result = (nodes->contains(node));
delete nodes; ExprResult* exprResult = evaluate(node, cs);
if (!exprResult)
return MB_FALSE;
MBool result = MB_FALSE;
if(exprResult->getResultType() == ExprResult::NODESET)
result = ((NodeSet*)exprResult)->contains(node);
delete exprResult;
return result; return result;
} //-- matches } //-- matches