diff --git a/mozilla/extensions/transformiix/build/Makefile.in b/mozilla/extensions/transformiix/build/Makefile.in index 4bd5a288c42..79534041883 100644 --- a/mozilla/extensions/transformiix/build/Makefile.in +++ b/mozilla/extensions/transformiix/build/Makefile.in @@ -86,20 +86,20 @@ LOBJS = ../source/base/Double.$(OBJ_SUFFIX) \ ../source/xpath/nsXPathNSResolver.$(OBJ_SUFFIX) \ ../source/xpath/nsXPathResult.$(OBJ_SUFFIX) \ ../source/xpath/nsXPath1Scheme.$(OBJ_SUFFIX) \ - ../source/xpath/NumberExpr.$(OBJ_SUFFIX) \ ../source/xpath/NumberFunctionCall.$(OBJ_SUFFIX) \ ../source/xpath/NumberResult.$(OBJ_SUFFIX) \ ../source/xpath/PathExpr.$(OBJ_SUFFIX) \ ../source/xpath/PredicateList.$(OBJ_SUFFIX) \ ../source/xpath/RelationalExpr.$(OBJ_SUFFIX) \ ../source/xpath/RootExpr.$(OBJ_SUFFIX) \ - ../source/xpath/StringExpr.$(OBJ_SUFFIX) \ ../source/xpath/StringFunctionCall.$(OBJ_SUFFIX) \ ../source/xpath/StringResult.$(OBJ_SUFFIX) \ + ../source/xpath/txLiteralExpr.$(OBJ_SUFFIX) \ ../source/xpath/txNameTest.$(OBJ_SUFFIX) \ ../source/xpath/txNodeTypeTest.$(OBJ_SUFFIX) \ ../source/xpath/txForwardContext.$(OBJ_SUFFIX) \ ../source/xpath/txNodeSetContext.$(OBJ_SUFFIX) \ + ../source/xpath/txResultRecycler.$(OBJ_SUFFIX) \ ../source/xpath/UnionExpr.$(OBJ_SUFFIX) \ ../source/xpath/UnaryExpr.$(OBJ_SUFFIX) \ ../source/xpath/VariableRefExpr.$(OBJ_SUFFIX) \ diff --git a/mozilla/extensions/transformiix/resources/xslt.properties b/mozilla/extensions/transformiix/resources/xslt.properties index 38118cd7c18..b95a3e4751d 100644 --- a/mozilla/extensions/transformiix/resources/xslt.properties +++ b/mozilla/extensions/transformiix/resources/xslt.properties @@ -46,6 +46,7 @@ 10 = A network error occured loading a XSLT stylesheet: 11 = An XSLT stylesheet does not have an XML mimetype: 12 = An XSLT stylesheet directly or indirectly imports or includes itself: +13 = An XPath function was called with the wrong number of arguments. LoadingError = Error loading stylesheet: %S TransformError = Error during XSLT transformation: %S diff --git a/mozilla/extensions/transformiix/source/base/txError.h b/mozilla/extensions/transformiix/source/base/txError.h index 34a11a7489e..9227350792d 100644 --- a/mozilla/extensions/transformiix/source/base/txError.h +++ b/mozilla/extensions/transformiix/source/base/txError.h @@ -87,4 +87,7 @@ #define NS_ERROR_XSLT_LOAD_RECURSION \ NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 12) +#define NS_ERROR_XPATH_BAD_ARGUMENT_COUNT \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 13) + #endif // __TX_ERROR diff --git a/mozilla/extensions/transformiix/source/lib/Makefile.in b/mozilla/extensions/transformiix/source/lib/Makefile.in index 4af9300585c..ef71ef25836 100644 --- a/mozilla/extensions/transformiix/source/lib/Makefile.in +++ b/mozilla/extensions/transformiix/source/lib/Makefile.in @@ -62,20 +62,20 @@ OBJS = ../base/Double.$(OBJ_SUFFIX) \ ../xpath/MultiplicativeExpr.$(OBJ_SUFFIX) \ ../xpath/NodeSet.$(OBJ_SUFFIX) \ ../xpath/NodeSetFunctionCall.$(OBJ_SUFFIX) \ - ../xpath/NumberExpr.$(OBJ_SUFFIX) \ ../xpath/NumberFunctionCall.$(OBJ_SUFFIX) \ ../xpath/NumberResult.$(OBJ_SUFFIX) \ ../xpath/PathExpr.$(OBJ_SUFFIX) \ ../xpath/PredicateList.$(OBJ_SUFFIX) \ ../xpath/RelationalExpr.$(OBJ_SUFFIX) \ ../xpath/RootExpr.$(OBJ_SUFFIX) \ - ../xpath/StringExpr.$(OBJ_SUFFIX) \ ../xpath/StringFunctionCall.$(OBJ_SUFFIX) \ ../xpath/StringResult.$(OBJ_SUFFIX) \ + ../xpath/txLiteralExpr.$(OBJ_SUFFIX) \ ../xpath/txNameTest.$(OBJ_SUFFIX) \ ../xpath/txNodeTypeTest.$(OBJ_SUFFIX) \ ../xpath/txForwardContext.$(OBJ_SUFFIX) \ ../xpath/txNodeSetContext.$(OBJ_SUFFIX) \ + ../xpath/txResultRecycler.$(OBJ_SUFFIX) \ ../xpath/UnionExpr.$(OBJ_SUFFIX) \ ../xpath/UnaryExpr.$(OBJ_SUFFIX) \ ../xpath/VariableRefExpr.$(OBJ_SUFFIX) \ diff --git a/mozilla/extensions/transformiix/source/xpath/AdditiveExpr.cpp b/mozilla/extensions/transformiix/source/xpath/AdditiveExpr.cpp index 137784f9c53..58931d2b3af 100644 --- a/mozilla/extensions/transformiix/source/xpath/AdditiveExpr.cpp +++ b/mozilla/extensions/transformiix/source/xpath/AdditiveExpr.cpp @@ -33,6 +33,7 @@ #include "Expr.h" #include "ExprResult.h" #include "primitives.h" +#include "txIXPathContext.h" /** * Creates a new AdditiveExpr using the given operator @@ -55,26 +56,23 @@ AdditiveExpr::~AdditiveExpr() { * for evaluation * @return the result of the evaluation **/ -ExprResult* AdditiveExpr::evaluate(txIEvalContext* aContext) +nsresult +AdditiveExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult) { - double rightDbl = Double::NaN; - ExprResult* exprRes = 0; + *aResult = nsnull; - if ( rightExpr ) { - exprRes = rightExpr->evaluate(aContext); - if ( exprRes ) rightDbl = exprRes->numberValue(); - delete exprRes; - } + nsRefPtr exprRes; + nsresult rv = rightExpr->evaluate(aContext, getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); - double leftDbl = Double::NaN; - if ( leftExpr ) { - exprRes = leftExpr->evaluate(aContext); - if ( exprRes ) leftDbl = exprRes->numberValue(); - delete exprRes; - } + double rightDbl = exprRes->numberValue(); + + rv = leftExpr->evaluate(aContext, getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); + + double leftDbl = exprRes->numberValue(); double result = 0; - switch ( op ) { case SUBTRACTION: result = leftDbl - rightDbl; @@ -83,7 +81,8 @@ ExprResult* AdditiveExpr::evaluate(txIEvalContext* aContext) result = leftDbl + rightDbl; break; } - return new NumberResult(result); + + return aContext->recycler()->getNumberResult(result, aResult); } //-- evaluate /** diff --git a/mozilla/extensions/transformiix/source/xpath/AttributeValueTemplate.cpp b/mozilla/extensions/transformiix/source/xpath/AttributeValueTemplate.cpp index 5a81b6080a7..ae04266b9e9 100644 --- a/mozilla/extensions/transformiix/source/xpath/AttributeValueTemplate.cpp +++ b/mozilla/extensions/transformiix/source/xpath/AttributeValueTemplate.cpp @@ -29,6 +29,7 @@ #include "Expr.h" #include "ExprResult.h" +#include "txIXPathContext.h" /** * Create a new AttributeValueTemplate @@ -59,17 +60,31 @@ void AttributeValueTemplate::addExpr(Expr* expr) { * for evaluation * @return the result of the evaluation **/ -ExprResult* AttributeValueTemplate::evaluate(txIEvalContext* aContext) +nsresult +AttributeValueTemplate::evaluate(txIEvalContext* aContext, + txAExprResult** aResult) { + *aResult = nsnull; + txListIterator iter(&expressions); - nsAutoString result; + nsRefPtr strRes; + nsresult rv = aContext->recycler()->getStringResult(getter_AddRefs(strRes)); + NS_ENSURE_SUCCESS(rv, rv); + while (iter.hasNext()) { Expr* expr = (Expr*)iter.next(); - ExprResult* exprResult = expr->evaluate(aContext); - exprResult->stringValue(result); - delete exprResult; + nsRefPtr exprResult; + nsresult rv = expr->evaluate(aContext, getter_AddRefs(exprResult)); + NS_ENSURE_SUCCESS(rv, rv); + + exprResult->stringValue(strRes->mValue); } - return new StringResult(result); + + *aResult = strRes; + + NS_ADDREF(*aResult); + + return NS_OK; } //-- evaluate /** diff --git a/mozilla/extensions/transformiix/source/xpath/BooleanExpr.cpp b/mozilla/extensions/transformiix/source/xpath/BooleanExpr.cpp index 1459718e862..a6071f6474f 100644 --- a/mozilla/extensions/transformiix/source/xpath/BooleanExpr.cpp +++ b/mozilla/extensions/transformiix/source/xpath/BooleanExpr.cpp @@ -36,6 +36,7 @@ #include "Expr.h" #include "ExprResult.h" +#include "txIXPathContext.h" /** * Creates a new BooleanExpr using the given operator @@ -58,30 +59,36 @@ BooleanExpr::~BooleanExpr() { * for evaluation * @return the result of the evaluation **/ -ExprResult* BooleanExpr::evaluate(txIEvalContext* aContext) +nsresult +BooleanExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult) { - MBool lval = MB_FALSE; - ExprResult* exprRes = 0; - if ( leftExpr ) { - exprRes = leftExpr->evaluate(aContext); - if ( exprRes ) lval = exprRes->booleanValue(); - delete exprRes; + *aResult = nsnull; + + nsRefPtr exprRes; + nsresult rv = leftExpr->evaluate(aContext, getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); + + PRBool lval = exprRes->booleanValue(); + + // check for early decision + if (op == OR && lval) { + aContext->recycler()->getBoolResult(PR_TRUE, aResult); + + return NS_OK; + } + if (op == AND && !lval) { + aContext->recycler()->getBoolResult(PR_FALSE, aResult); + + return NS_OK; } + rv = rightExpr->evaluate(aContext, getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); - //-- check left expression for early decision - if (( op == OR ) && (lval)) return new BooleanResult(MB_TRUE); - else if ((op == AND) && (!lval)) return new BooleanResult(MB_FALSE); - - MBool rval = MB_FALSE; - if ( rightExpr ) { - exprRes = rightExpr->evaluate(aContext); - if ( exprRes ) rval = exprRes->booleanValue(); - delete exprRes; - } - //-- just use rval, since we already checked lval - return new BooleanResult(rval); + // just use rval, since we already checked lval + aContext->recycler()->getBoolResult(exprRes->booleanValue(), aResult); + return NS_OK; } //-- evaluate /** diff --git a/mozilla/extensions/transformiix/source/xpath/BooleanFunctionCall.cpp b/mozilla/extensions/transformiix/source/xpath/BooleanFunctionCall.cpp index 50181ae862c..20546c8c1fc 100644 --- a/mozilla/extensions/transformiix/source/xpath/BooleanFunctionCall.cpp +++ b/mozilla/extensions/transformiix/source/xpath/BooleanFunctionCall.cpp @@ -49,23 +49,27 @@ BooleanFunctionCall::BooleanFunctionCall(BooleanFunctions aType) * for evaluation * @return the result of the evaluation **/ -ExprResult* BooleanFunctionCall::evaluate(txIEvalContext* aContext) +nsresult +BooleanFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult) { - txListIterator iter(¶ms); + *aResult = nsnull; + txListIterator iter(¶ms); switch (mType) { case TX_BOOLEAN: { if (!requireParams(1, 1, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; - return new BooleanResult(evaluateToBoolean((Expr*)iter.next(), - aContext)); + aContext->recycler()->getBoolResult( + evaluateToBoolean((Expr*)iter.next(), aContext), aResult); + + return NS_OK; } case TX_LANG: { if (!requireParams(1, 1, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; nsAutoString lang; Node* node = aContext->getContextNode(); @@ -89,35 +93,43 @@ ExprResult* BooleanFunctionCall::evaluate(txIEvalContext* aContext) lang.CharAt(arg.Length()) == '-'); } - return new BooleanResult(result); + aContext->recycler()->getBoolResult(result, aResult); + + return NS_OK; } case TX_NOT: { if (!requireParams(1, 1, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; - return new BooleanResult(!evaluateToBoolean((Expr*)iter.next(), - aContext)); + aContext->recycler()->getBoolResult( + !evaluateToBoolean((Expr*)iter.next(), aContext), aResult); + + return NS_OK; } case TX_TRUE: { if (!requireParams(0, 0, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; - return new BooleanResult(MB_TRUE); + aContext->recycler()->getBoolResult(PR_TRUE, aResult); + + return NS_OK; } case TX_FALSE: { if (!requireParams(0, 0, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; - return new BooleanResult(MB_FALSE); + aContext->recycler()->getBoolResult(PR_FALSE, aResult); + + return NS_OK; } } aContext->receiveError(NS_LITERAL_STRING("Internal error"), NS_ERROR_UNEXPECTED); - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_UNEXPECTED; } nsresult BooleanFunctionCall::getNameAtom(nsIAtom** aAtom) diff --git a/mozilla/extensions/transformiix/source/xpath/BooleanResult.cpp b/mozilla/extensions/transformiix/source/xpath/BooleanResult.cpp index 119cc371a95..c72b8b42711 100644 --- a/mozilla/extensions/transformiix/source/xpath/BooleanResult.cpp +++ b/mozilla/extensions/transformiix/source/xpath/BooleanResult.cpp @@ -29,18 +29,13 @@ #include "ExprResult.h" -/** - * Default Constructor -**/ -BooleanResult::BooleanResult() { - value = MB_FALSE; -} //-- BooleanResult - /** * Creates a new BooleanResult with the value of the given MBool parameter * @param boolean the MBool to use for initialization of this BooleanResult's value **/ -BooleanResult::BooleanResult(MBool boolean) { +BooleanResult::BooleanResult(PRBool boolean) + : txAExprResult(nsnull) +{ this->value = boolean; } //-- BooleanResult @@ -48,13 +43,8 @@ BooleanResult::BooleanResult(MBool boolean) { * Virtual Methods from ExprResult */ -ExprResult* BooleanResult::clone() -{ - return new BooleanResult(value); -} - short BooleanResult::getResultType() { - return ExprResult::BOOLEAN; + return txAExprResult::BOOLEAN; } //-- getResultType void BooleanResult::stringValue(nsAString& str) { diff --git a/mozilla/extensions/transformiix/source/xpath/Expr.h b/mozilla/extensions/transformiix/source/xpath/Expr.h index df364629175..e703b12276a 100644 --- a/mozilla/extensions/transformiix/source/xpath/Expr.h +++ b/mozilla/extensions/transformiix/source/xpath/Expr.h @@ -42,13 +42,13 @@ #include "nsIAtom.h" #include "TxObject.h" #include "nsAutoPtr.h" +#include "ExprResult.h" /* XPath class definitions. Much of this code was ported from XSL:P. */ -class ExprResult; class NodeSet; class txIParseContext; class txIMatchContext; @@ -75,7 +75,8 @@ public: * for evaluation * @return the result of the evaluation **/ - virtual ExprResult* evaluate(txIEvalContext* aContext) = 0; + virtual nsresult evaluate(txIEvalContext* aContext, + txAExprResult** aResult) = 0; /** * Returns the String representation of this Expr. @@ -90,7 +91,7 @@ public: }; //-- Expr #define TX_DECL_EVALUATE \ - ExprResult* evaluate(txIEvalContext* aContext) + nsresult evaluate(txIEvalContext* aContext, txAExprResult** aResult) #define TX_DECL_EXPR \ TX_DECL_EVALUATE; \ @@ -112,7 +113,6 @@ public: /** * Virtual methods from Expr **/ - virtual ExprResult* evaluate(txIEvalContext* aContext) = 0; void toString(nsAString& aDest); /** @@ -161,9 +161,10 @@ protected: /* * Evaluates the given Expression and converts its result to a NodeSet. - * If the result is not a NodeSet NULL is returned. + * If the result is not a NodeSet an error is returned. */ - NodeSet* evaluateToNodeSet(Expr* aExpr, txIEvalContext* aContext); + nsresult evaluateToNodeSet(Expr* aExpr, txIEvalContext* aContext, + NodeSet** aResult); /* * Returns the name of the function as an atom. @@ -298,7 +299,7 @@ public: **/ void add(Expr* expr); - void evaluatePredicates(NodeSet* aNodes, txIMatchContext* aContext); + nsresult evaluatePredicates(NodeSet* aNodes, txIMatchContext* aContext); /** * returns true if this predicate list is empty @@ -387,36 +388,17 @@ private: }; //-- FilterExpr -class NumberExpr : public Expr { - +class txLiteralExpr : public Expr { public: - - NumberExpr(double dbl); + txLiteralExpr(double aDbl); + txLiteralExpr(const nsAString& aStr); TX_DECL_EXPR; private: - - double _value; + nsRefPtr mValue; }; -/** - * Represents a String expression -**/ -class StringExpr : public Expr { - -public: - - StringExpr(const nsAString& value); - - TX_DECL_EXPR; - -private: - - nsString value; -}; //-- StringExpr - - /** * Represents an AdditiveExpr, a binary expression that * performs an additive operation between it's lvalue and rvalue: @@ -534,7 +516,8 @@ public: TX_DECL_EXPR; private: - PRBool compareResults(ExprResult* aLeft, ExprResult* aRight); + PRBool compareResults(txIEvalContext* aContext, txAExprResult* aLeft, + txAExprResult* aRight); nsAutoPtr mLeftExpr; nsAutoPtr mRightExpr; @@ -602,9 +585,9 @@ private: * Selects from the descendants of the context node * all nodes that match the Expr */ - void evalDescendants(Expr* aStep, Node* aNode, - txIMatchContext* aContext, - NodeSet* resNodes); + nsresult evalDescendants(Expr* aStep, Node* aNode, + txIMatchContext* aContext, + NodeSet* resNodes); }; //-- PathExpr diff --git a/mozilla/extensions/transformiix/source/xpath/ExprParser.cpp b/mozilla/extensions/transformiix/source/xpath/ExprParser.cpp index 33edf8eb2cd..995fe0fb9ff 100644 --- a/mozilla/extensions/transformiix/source/xpath/ExprParser.cpp +++ b/mozilla/extensions/transformiix/source/xpath/ExprParser.cpp @@ -103,7 +103,7 @@ AttributeValueTemplate* ExprParser::createAttributeValueTemplate } else { if (!buffer.IsEmpty()) { - Expr* strExpr = new StringExpr(buffer); + Expr* strExpr = new txLiteralExpr(buffer); if (!strExpr) { // XXX ErrorReport: out of memory delete avt; @@ -154,7 +154,7 @@ AttributeValueTemplate* ExprParser::createAttributeValueTemplate } if (!buffer.IsEmpty()) { - Expr* strExpr = new StringExpr(buffer); + Expr* strExpr = new txLiteralExpr(buffer); if (!strExpr) { // XXX ErrorReport: out of memory delete avt; @@ -351,11 +351,11 @@ Expr* ExprParser::createFilterExpr(ExprLexer& lexer, txIParseContext* aContext) } break; case Token::LITERAL : - expr = new StringExpr(tok->value); + expr = new txLiteralExpr(tok->value); break; case Token::NUMBER: { - expr = new NumberExpr(Double::toDouble(tok->value)); + expr = new txLiteralExpr(Double::toDouble(tok->value)); break; } default: @@ -507,8 +507,8 @@ Expr* ExprParser::createFunctionCall(ExprLexer& lexer, if (!parseParameters(0, lexer, aContext)) { return 0; } - return new StringExpr(tok->value + - NS_LITERAL_STRING(" not implemented.")); + return new txLiteralExpr(tok->value + + NS_LITERAL_STRING(" not implemented.")); } if (NS_FAILED(rv)) { diff --git a/mozilla/extensions/transformiix/source/xpath/ExprResult.h b/mozilla/extensions/transformiix/source/xpath/ExprResult.h index dff54d084c4..564a53d709e 100644 --- a/mozilla/extensions/transformiix/source/xpath/ExprResult.h +++ b/mozilla/extensions/transformiix/source/xpath/ExprResult.h @@ -31,6 +31,8 @@ #include "primitives.h" #include "TxObject.h" #include "nsString.h" +#include "txResultRecycler.h" +#include "nsAutoPtr.h" /* * ExprResult @@ -41,11 +43,10 @@ * Note: for NodeSet, see NodeSet.h */ -class ExprResult : public TxObject { - +class txAExprResult : public TxObject +{ public: - - //-- ResultTypes + friend class txResultRecycler; enum ResultType { NODESET, BOOLEAN, @@ -54,13 +55,24 @@ public: RESULT_TREE_FRAGMENT }; - virtual ~ExprResult() {}; + txAExprResult(txResultRecycler* aRecycler) : mRecycler(aRecycler) {} + virtual ~txAExprResult() {}; - /* - * Clones this ExprResult - * @return clone of this ExprResult - */ - virtual ExprResult* clone() = 0; + void AddRef() + { + ++mRefCnt; + } + void Release() + { + if (--mRefCnt == 0) { + if (mRecycler) { + mRecycler->recycle(this); + } + else { + delete this; + } + } + } /** * Returns the type of ExprResult represented @@ -92,10 +104,12 @@ public: **/ virtual double numberValue() = 0; +private: + nsAutoRefCnt mRefCnt; + nsRefPtr mRecycler; }; #define TX_DECL_EXPRRESULT \ - virtual ExprResult* clone(); \ virtual short getResultType(); \ virtual void stringValue(nsAString& str); \ virtual nsAString* stringValuePointer(); \ @@ -103,12 +117,10 @@ public: virtual double numberValue(); \ -class BooleanResult : public ExprResult { +class BooleanResult : public txAExprResult { public: - - BooleanResult(); - BooleanResult(MBool boolean); + BooleanResult(MBool aValue); TX_DECL_EXPRRESULT @@ -116,25 +128,22 @@ private: MBool value; }; -class NumberResult : public ExprResult { +class NumberResult : public txAExprResult { public: - - NumberResult(); - NumberResult(double dbl); + NumberResult(double aValue, txResultRecycler* aRecycler); TX_DECL_EXPRRESULT -private: double value; }; -class StringResult : public ExprResult { +class StringResult : public txAExprResult { public: - StringResult(); - StringResult(const nsAString& str); + StringResult(txResultRecycler* aRecycler); + StringResult(const nsAString& aValue, txResultRecycler* aRecycler); TX_DECL_EXPRRESULT diff --git a/mozilla/extensions/transformiix/source/xpath/FilterExpr.cpp b/mozilla/extensions/transformiix/source/xpath/FilterExpr.cpp index 38284c8672d..9f77dc58056 100644 --- a/mozilla/extensions/transformiix/source/xpath/FilterExpr.cpp +++ b/mozilla/extensions/transformiix/source/xpath/FilterExpr.cpp @@ -58,29 +58,34 @@ FilterExpr::~FilterExpr() { * @return the result of the evaluation * @see Expr **/ -ExprResult* FilterExpr::evaluate(txIEvalContext* aContext) +nsresult +FilterExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult) { - if (!aContext || !expr) - return new NodeSet; + *aResult = nsnull; - ExprResult* exprResult = expr->evaluate(aContext); - if (!exprResult) - return 0; - - if (exprResult->getResultType() == ExprResult::NODESET) { - // Result is a nodeset, filter it. - evaluatePredicates((NodeSet*)exprResult, aContext); - } - else if(!isEmpty()) { - // We can't filter a non-nodeset - nsAutoString err(NS_LITERAL_STRING("Expecting nodeset as result of: ")); - expr->toString(err); - aContext->receiveError(err, NS_ERROR_XSLT_NODESET_EXPECTED); - delete exprResult; - return new NodeSet; - } + nsRefPtr exprRes; + nsresult rv = expr->evaluate(aContext, getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); - return exprResult; + NS_ENSURE_TRUE(exprRes->getResultType() == txAExprResult::NODESET, + NS_ERROR_XSLT_NODESET_EXPECTED); + + nsRefPtr nodes = + NS_STATIC_CAST(NodeSet*, NS_STATIC_CAST(txAExprResult*, exprRes)); + // null out exprRes so that we can test for shared-ness + exprRes = nsnull; + nsRefPtr nonShared; + rv = aContext->recycler()->getNonSharedNodeSet(nodes, + getter_AddRefs(nonShared)); + NS_ENSURE_SUCCESS(rv, rv); + + rv = evaluatePredicates(nonShared, aContext); + NS_ENSURE_SUCCESS(rv, rv); + + *aResult = nonShared; + NS_ADDREF(*aResult); + + return NS_OK; } //-- evaluate /** diff --git a/mozilla/extensions/transformiix/source/xpath/FunctionCall.cpp b/mozilla/extensions/transformiix/source/xpath/FunctionCall.cpp index 1ded6542310..f8d75c52fae 100644 --- a/mozilla/extensions/transformiix/source/xpath/FunctionCall.cpp +++ b/mozilla/extensions/transformiix/source/xpath/FunctionCall.cpp @@ -27,6 +27,7 @@ #include "ExprResult.h" #include "nsIAtom.h" #include "txIXPathContext.h" +#include "NodeSet.h" /** * This class represents a FunctionCall as defined by the XSL Working Draft @@ -70,12 +71,12 @@ void FunctionCall::evaluateToString(Expr* aExpr, txIEvalContext* aContext, nsAString& aDest) { NS_ASSERTION(aExpr, "missing expression"); - ExprResult* exprResult = aExpr->evaluate(aContext); - if (!exprResult) + nsRefPtr exprResult; + nsresult rv = aExpr->evaluate(aContext, getter_AddRefs(exprResult)); + if (NS_FAILED(rv)) return; exprResult->stringValue(aDest); - delete exprResult; } /* @@ -84,13 +85,12 @@ void FunctionCall::evaluateToString(Expr* aExpr, txIEvalContext* aContext, double FunctionCall::evaluateToNumber(Expr* aExpr, txIEvalContext* aContext) { NS_ASSERTION(aExpr, "missing expression"); - ExprResult* exprResult = aExpr->evaluate(aContext); - if (!exprResult) + nsRefPtr exprResult; + nsresult rv = aExpr->evaluate(aContext, getter_AddRefs(exprResult)); + if (NS_FAILED(rv)) return Double::NaN; - double result = exprResult->numberValue(); - delete exprResult; - return result; + return exprResult->numberValue(); } /* @@ -99,33 +99,39 @@ double FunctionCall::evaluateToNumber(Expr* aExpr, txIEvalContext* aContext) MBool FunctionCall::evaluateToBoolean(Expr* aExpr, txIEvalContext* aContext) { NS_ASSERTION(aExpr, "missing expression"); - ExprResult* exprResult = aExpr->evaluate(aContext); - if (!exprResult) - return MB_FALSE; + nsRefPtr exprResult; + nsresult rv = aExpr->evaluate(aContext, getter_AddRefs(exprResult)); + if (NS_FAILED(rv)) + return PR_FALSE; - MBool result = exprResult->booleanValue(); - delete exprResult; - return result; + return exprResult->booleanValue(); } /* * Evaluates the given Expression and converts its result to a NodeSet. * If the result is not a NodeSet NULL is returned. */ -NodeSet* FunctionCall::evaluateToNodeSet(Expr* aExpr, txIEvalContext* aContext) +nsresult +FunctionCall::evaluateToNodeSet(Expr* aExpr, txIEvalContext* aContext, + NodeSet** aResult) { NS_ASSERTION(aExpr, "Missing expression to evaluate"); - ExprResult* exprResult = aExpr->evaluate(aContext); - if (!exprResult) - return 0; + *aResult = nsnull; - if (exprResult->getResultType() != ExprResult::NODESET) { + nsRefPtr exprRes; + nsresult rv = aExpr->evaluate(aContext, getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); + + if (exprRes->getResultType() != txAExprResult::NODESET) { aContext->receiveError(NS_LITERAL_STRING("NodeSet expected as argument"), NS_ERROR_XSLT_NODESET_EXPECTED); - delete exprResult; - return 0; + return NS_ERROR_XSLT_NODESET_EXPECTED; } - return (NodeSet*)exprResult; + *aResult = + NS_STATIC_CAST(NodeSet*, NS_STATIC_CAST(txAExprResult*, exprRes)); + NS_ADDREF(*aResult); + + return NS_OK; } PRBool FunctionCall::requireParams(PRInt32 aParamCountMin, diff --git a/mozilla/extensions/transformiix/source/xpath/LocationStep.cpp b/mozilla/extensions/transformiix/source/xpath/LocationStep.cpp index dc40f3cfe05..35b38a8d578 100644 --- a/mozilla/extensions/transformiix/source/xpath/LocationStep.cpp +++ b/mozilla/extensions/transformiix/source/xpath/LocationStep.cpp @@ -54,13 +54,15 @@ LocationStep::LocationStep(nsAutoPtr aNodeTest, * @return the result of the evaluation * @see Expr **/ -ExprResult* LocationStep::evaluate(txIEvalContext* aContext) +nsresult +LocationStep::evaluate(txIEvalContext* aContext, txAExprResult** aResult) { NS_ASSERTION(aContext, "internal error"); + *aResult = nsnull; - NodeSet* nodes = new NodeSet(); - if (!nodes) - return 0; + nsRefPtr nodes; + nsresult rv = aContext->recycler()->getNodeSet(getter_AddRefs(nodes)); + NS_ENSURE_SUCCESS(rv, rv); MBool reverse = MB_FALSE; @@ -188,13 +190,18 @@ ExprResult* LocationStep::evaluate(txIEvalContext* aContext) } //-- switch //-- apply predicates - if (!isEmpty()) - evaluatePredicates(nodes, aContext); + if (!isEmpty()) { + rv = evaluatePredicates(nodes, aContext); + NS_ENSURE_SUCCESS(rv, rv); + } if (reverse) nodes->reverse(); - return nodes; + *aResult = nodes; + NS_ADDREF(*aResult); + + return NS_OK; } void LocationStep::fromDescendants(Node* node, txIMatchContext* cs, diff --git a/mozilla/extensions/transformiix/source/xpath/Makefile.in b/mozilla/extensions/transformiix/source/xpath/Makefile.in index 839faac6f8a..11ab87526ae 100644 --- a/mozilla/extensions/transformiix/source/xpath/Makefile.in +++ b/mozilla/extensions/transformiix/source/xpath/Makefile.in @@ -55,20 +55,20 @@ CPPSRCS = AdditiveExpr.cpp \ MultiplicativeExpr.cpp \ NodeSet.cpp \ NodeSetFunctionCall.cpp \ - NumberExpr.cpp \ NumberFunctionCall.cpp \ NumberResult.cpp \ PathExpr.cpp \ PredicateList.cpp \ RelationalExpr.cpp \ RootExpr.cpp \ - StringExpr.cpp \ StringFunctionCall.cpp \ StringResult.cpp \ + txLiteralExpr.cpp \ txNameTest.cpp \ txNodeTypeTest.cpp \ txForwardContext.cpp \ txNodeSetContext.cpp \ + txResultRecycler.cpp \ UnionExpr.cpp \ UnaryExpr.cpp \ VariableRefExpr.cpp diff --git a/mozilla/extensions/transformiix/source/xpath/MultiplicativeExpr.cpp b/mozilla/extensions/transformiix/source/xpath/MultiplicativeExpr.cpp index bfca5c19ca9..1618a77c4c3 100644 --- a/mozilla/extensions/transformiix/source/xpath/MultiplicativeExpr.cpp +++ b/mozilla/extensions/transformiix/source/xpath/MultiplicativeExpr.cpp @@ -39,6 +39,7 @@ #include "ExprResult.h" #include #include "primitives.h" +#include "txIXPathContext.h" /** * Creates a new MultiplicativeExpr using the given operator @@ -61,24 +62,21 @@ MultiplicativeExpr::~MultiplicativeExpr() { * for evaluation * @return the result of the evaluation **/ -ExprResult* MultiplicativeExpr::evaluate(txIEvalContext* aContext) +nsresult +MultiplicativeExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult) { - double rightDbl = Double::NaN; - ExprResult* exprRes = 0; + *aResult = nsnull; - if ( rightExpr ) { - exprRes = rightExpr->evaluate(aContext); - if ( exprRes ) rightDbl = exprRes->numberValue(); - delete exprRes; - } + nsRefPtr exprRes; + nsresult rv = rightExpr->evaluate(aContext, getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); - double leftDbl = Double::NaN; - if ( leftExpr ) { - exprRes = leftExpr->evaluate(aContext); - if ( exprRes ) leftDbl = exprRes->numberValue(); - delete exprRes; - } + double rightDbl = exprRes->numberValue(); + rv = leftExpr->evaluate(aContext, getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); + + double leftDbl = exprRes->numberValue(); double result = 0; switch ( op ) { @@ -118,7 +116,8 @@ ExprResult* MultiplicativeExpr::evaluate(txIEvalContext* aContext) result = leftDbl * rightDbl; break; } - return new NumberResult(result); + + return aContext->recycler()->getNumberResult(result, aResult); } //-- evaluate /** diff --git a/mozilla/extensions/transformiix/source/xpath/NodeSet.cpp b/mozilla/extensions/transformiix/source/xpath/NodeSet.cpp index 15feca9ea15..3def59e5f97 100644 --- a/mozilla/extensions/transformiix/source/xpath/NodeSet.cpp +++ b/mozilla/extensions/transformiix/source/xpath/NodeSet.cpp @@ -45,20 +45,24 @@ static const int kTxNodeSetGrowFactor = 2; /* * Creates a new empty NodeSet */ -NodeSet::NodeSet() : mElements(0), - mBufferSize(0), - mElementCount(0) +NodeSet::NodeSet(txResultRecycler* aRecycler) + : txAExprResult(aRecycler), + mElements(0), + mBufferSize(0), + mElementCount(0) { } /* * Creates a new NodeSet containing the supplied Node */ -NodeSet::NodeSet(Node* aNode) : mBufferSize(1), - mElementCount(1) +NodeSet::NodeSet(Node* aNode, txResultRecycler* aRecycler) + : txAExprResult(aRecycler), + mElements(new Node*[1]), + mBufferSize(1), + mElementCount(1) { - NS_ASSERTION(aNode, "missing node to NodeSet::add"); - mElements = new Node*[1]; + NS_ASSERTION(aNode, "missing node to NodeSet::NodeSet"); if (!mElements) { NS_ASSERTION(0, "out of memory"); mBufferSize = 0; @@ -73,9 +77,11 @@ NodeSet::NodeSet(Node* aNode) : mBufferSize(1), * Creates a new NodeSet, copying the Node references from the source * NodeSet */ -NodeSet::NodeSet(const NodeSet& aSource) : mElements(0), - mBufferSize(0), - mElementCount(0) +NodeSet::NodeSet(const NodeSet& aSource, txResultRecycler* aRecycler) + : txAExprResult(aRecycler), + mElements(0), + mBufferSize(0), + mElementCount(0) { append(&aSource); } @@ -347,22 +353,13 @@ Node* NodeSet::get(int aIndex) const return mElements[aIndex]; } -/* - * Clones this ExprResult - * @return clone of this ExprResult - */ -ExprResult* NodeSet::clone() -{ - return new NodeSet(*this); -} - /* * Returns the type of ExprResult represented * @return the type of ExprResult represented */ short NodeSet::getResultType() { - return ExprResult::NODESET; + return txAExprResult::NODESET; } /* @@ -415,7 +412,8 @@ MBool NodeSet::ensureSize(int aSize) // This isn't 100% safe. But until someone manages to make a 1gig nodeset // it should be ok. - int newSize = mBufferSize ? mBufferSize : kTxNodeSetMinSize; + int newSize = mBufferSize > kTxNodeSetMinSize ? mBufferSize : + kTxNodeSetMinSize; while (newSize < aSize) newSize *= kTxNodeSetGrowFactor; diff --git a/mozilla/extensions/transformiix/source/xpath/NodeSet.h b/mozilla/extensions/transformiix/source/xpath/NodeSet.h index 4b078eb9df2..3dd731477a7 100644 --- a/mozilla/extensions/transformiix/source/xpath/NodeSet.h +++ b/mozilla/extensions/transformiix/source/xpath/NodeSet.h @@ -39,7 +39,7 @@ class Node; -class NodeSet : public ExprResult +class NodeSet : public txAExprResult { public: @@ -47,18 +47,18 @@ public: /* * Creates a new empty NodeSet */ - NodeSet(); + NodeSet(txResultRecycler* aRecycler); /* * Creates a new NodeSet containing the supplied node */ - NodeSet(Node* aNode); + NodeSet(Node* aNode, txResultRecycler* aRecycler); /* * Creates a new NodeSet, copying the Node references from the source * NodeSet */ - NodeSet(const NodeSet& aSource); + NodeSet(const NodeSet& aSource, txResultRecycler* aRecycler); /* * Destructor for NodeSet, will not delete referenced Nodes diff --git a/mozilla/extensions/transformiix/source/xpath/NodeSetFunctionCall.cpp b/mozilla/extensions/transformiix/source/xpath/NodeSetFunctionCall.cpp index 5a933247483..781de54121e 100644 --- a/mozilla/extensions/transformiix/source/xpath/NodeSetFunctionCall.cpp +++ b/mozilla/extensions/transformiix/source/xpath/NodeSetFunctionCall.cpp @@ -57,38 +57,40 @@ NodeSetFunctionCall::NodeSetFunctionCall(NodeSetFunctions aType) * for evaluation * @return the result of the evaluation */ -ExprResult* NodeSetFunctionCall::evaluate(txIEvalContext* aContext) { +nsresult +NodeSetFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult) +{ + *aResult = nsnull; + nsresult rv = NS_OK; txListIterator iter(¶ms); + switch (mType) { case COUNT: { if (!requireParams(1, 1, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; - NodeSet* nodes; - nodes = evaluateToNodeSet((Expr*)iter.next(), aContext); - if (!nodes) - return new StringResult(NS_LITERAL_STRING("error")); + nsRefPtr nodes; + rv = evaluateToNodeSet((Expr*)iter.next(), aContext, + getter_AddRefs(nodes)); + NS_ENSURE_SUCCESS(rv, rv); - double count = nodes->size(); - delete nodes; - return new NumberResult(count); + return aContext->recycler()->getNumberResult(nodes->size(), + aResult); } case ID: { if (!requireParams(1, 1, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; - ExprResult* exprResult; - exprResult = ((Expr*)iter.next())->evaluate(aContext); - if (!exprResult) - return new StringResult(NS_LITERAL_STRING("error")); + nsRefPtr exprResult; + rv = ((Expr*)iter.next())->evaluate(aContext, + getter_AddRefs(exprResult)); + NS_ENSURE_SUCCESS(rv, rv); - NodeSet* resultSet = new NodeSet(); - if (!resultSet) { - // XXX ErrorReport: out of memory - return 0; - } + nsRefPtr resultSet; + rv = aContext->recycler()->getNodeSet(getter_AddRefs(resultSet)); + NS_ENSURE_SUCCESS(rv, rv); Document* contextDoc = 0; Node* contextNode = aContext->getContextNode(); @@ -97,8 +99,10 @@ ExprResult* NodeSetFunctionCall::evaluate(txIEvalContext* aContext) { else contextDoc = contextNode->getOwnerDocument(); - if (exprResult->getResultType() == ExprResult::NODESET) { - NodeSet* nodes = (NodeSet*)exprResult; + if (exprResult->getResultType() == txAExprResult::NODESET) { + NodeSet* nodes = NS_STATIC_CAST(NodeSet*, + NS_STATIC_CAST(txAExprResult*, + exprResult)); int i; for (i = 0; i < nodes->size(); i++) { nsAutoString idList; @@ -123,38 +127,41 @@ ExprResult* NodeSetFunctionCall::evaluate(txIEvalContext* aContext) { resultSet->add(idNode); } } - delete exprResult; - return resultSet; + *aResult = resultSet; + NS_ADDREF(*aResult); + + return NS_OK; } case LAST: { if (!requireParams(0, 0, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; - return new NumberResult(aContext->size()); + return aContext->recycler()->getNumberResult(aContext->size(), + aResult); } case LOCAL_NAME: case NAME: case NAMESPACE_URI: { if (!requireParams(0, 1, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; Node* node = 0; // Check for optional arg if (iter.hasNext()) { - NodeSet* nodes; - nodes = evaluateToNodeSet((Expr*)iter.next(), aContext); - if (!nodes) - return new StringResult(NS_LITERAL_STRING("error")); + nsRefPtr nodes; + rv = evaluateToNodeSet((Expr*)iter.next(), aContext, + getter_AddRefs(nodes)); + NS_ENSURE_SUCCESS(rv, rv); if (nodes->isEmpty()) { - delete nodes; - return new StringResult(); + aContext->recycler()->getEmptyStringResult(aResult); + + return NS_OK; } node = nodes->get(0); - delete nodes; } else { node = aContext->getContextNode(); @@ -163,13 +170,17 @@ ExprResult* NodeSetFunctionCall::evaluate(txIEvalContext* aContext) { switch (mType) { case LOCAL_NAME: { - nsAutoString localName; + StringResult* strRes = nsnull; + rv = aContext->recycler()->getStringResult(&strRes); + NS_ENSURE_SUCCESS(rv, rv); + + *aResult = strRes; #ifdef TX_EXE nsCOMPtr localNameAtom; node->getLocalName(getter_AddRefs(localNameAtom)); if (localNameAtom) { // Node has a localName - localNameAtom->ToString(localName); + localNameAtom->ToString(strRes->mValue); } #else // The mozilla HTML-elements returns different casing for @@ -179,18 +190,20 @@ ExprResult* NodeSetFunctionCall::evaluate(txIEvalContext* aContext) { nsCOMPtr mozNode = do_QueryInterface(node->getNSObj()); NS_ASSERTION(mozNode, "wrapper doesn't wrap a nsIDOMNode"); - mozNode->GetLocalName(localName); + mozNode->GetLocalName(strRes->mValue); #endif - - return new StringResult(localName); + return NS_OK; } case NAMESPACE_URI: { - StringResult* result = new StringResult(); - if (result) { - node->getNamespaceURI(result->mValue); - } - return result; + StringResult* strRes = nsnull; + rv = aContext->recycler()->getStringResult(&strRes); + NS_ENSURE_SUCCESS(rv, rv); + + *aResult = strRes; + node->getNamespaceURI(strRes->mValue); + + return NS_OK; } case NAME: { @@ -198,20 +211,24 @@ ExprResult* NodeSetFunctionCall::evaluate(txIEvalContext* aContext) { case Node::ATTRIBUTE_NODE: case Node::ELEMENT_NODE: case Node::PROCESSING_INSTRUCTION_NODE: - { // XXX Namespace: namespaces have a name - StringResult* result = new StringResult(); - if (result) { - node->getNodeName(result->mValue); - } - return result; + { + StringResult* strRes = nsnull; + rv = aContext->recycler()->getStringResult(&strRes); + NS_ENSURE_SUCCESS(rv, rv); + + *aResult = strRes; + node->getNodeName(strRes->mValue); + + return NS_OK; } default: { - break; + aContext->recycler()->getEmptyStringResult(aResult); + + return NS_OK; } } - return new StringResult(); } default: { @@ -222,15 +239,16 @@ ExprResult* NodeSetFunctionCall::evaluate(txIEvalContext* aContext) { case POSITION: { if (!requireParams(0, 0, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; - return new NumberResult(aContext->position()); + return aContext->recycler()->getNumberResult(aContext->position(), + aResult); } } aContext->receiveError(NS_LITERAL_STRING("Internal error"), NS_ERROR_UNEXPECTED); - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_UNEXPECTED; } nsresult NodeSetFunctionCall::getNameAtom(nsIAtom** aAtom) diff --git a/mozilla/extensions/transformiix/source/xpath/NumberExpr.cpp b/mozilla/extensions/transformiix/source/xpath/NumberExpr.cpp deleted file mode 100644 index cb5b449c0ee..00000000000 --- a/mozilla/extensions/transformiix/source/xpath/NumberExpr.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is TransforMiiX XSLT processor. - * - * The Initial Developer of the Original Code is The MITRE Corporation. - * Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation. - * - * Portions created by Keith Visco as a Non MITRE employee, - * (C) 1999 Keith Visco. All Rights Reserved. - * - * Contributor(s): - * Keith Visco, kvisco@ziplink.net - * -- original author. - * - */ - -#include "Expr.h" -#include "ExprResult.h" -#include "primitives.h" - - //--------------/ - //- NumberExpr -/ -//--------------/ - -NumberExpr::NumberExpr(double dbl) { - _value = dbl; -} //-- NumberExpr - -/** - * Evaluates this Expr based on the given context node and processor state - * @param context the context node for evaluation of this Expr - * @param ps the ContextState containing the stack information needed - * for evaluation - * @return the result of the evaluation -**/ -ExprResult* NumberExpr::evaluate(txIEvalContext* aContext) -{ - return new NumberResult(_value); -} //-- evaluate - -/** - * Returns the String representation of this Expr. - * @param dest the String to use when creating the String - * representation. The String representation will be appended to - * any data in the destination String, to allow cascading calls to - * other #toString() methods for Expressions. - * @return the String representation of this Expr. -**/ -void NumberExpr::toString(nsAString& str) { - Double::toString(_value, str); -} //-- toString - diff --git a/mozilla/extensions/transformiix/source/xpath/NumberFunctionCall.cpp b/mozilla/extensions/transformiix/source/xpath/NumberFunctionCall.cpp index 99b55b999ed..84d238b9a9c 100644 --- a/mozilla/extensions/transformiix/source/xpath/NumberFunctionCall.cpp +++ b/mozilla/extensions/transformiix/source/xpath/NumberFunctionCall.cpp @@ -55,59 +55,67 @@ NumberFunctionCall::NumberFunctionCall(NumberFunctions aType) * for evaluation * @return the result of the evaluation */ -ExprResult* NumberFunctionCall::evaluate(txIEvalContext* aContext) +nsresult +NumberFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult) { - txListIterator iter(¶ms); + *aResult = nsnull; + txListIterator iter(¶ms); if (mType == NUMBER) { if (!requireParams(0, 1, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; } else { if (!requireParams(1, 1, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; } switch (mType) { case CEILING: { double dbl = evaluateToNumber((Expr*)iter.next(), aContext); - if (Double::isNaN(dbl) || Double::isInfinite(dbl)) - return new NumberResult(dbl); + if (!Double::isNaN(dbl) && !Double::isInfinite(dbl)) { + if (Double::isNeg(dbl) && dbl > -1) { + dbl *= 0; + } + else { + dbl = ceil(dbl); + } + } - if (Double::isNeg(dbl) && dbl > -1) - return new NumberResult(0 * dbl); - - return new NumberResult(ceil(dbl)); + return aContext->recycler()->getNumberResult(dbl, aResult); } case FLOOR: { double dbl = evaluateToNumber((Expr*)iter.next(), aContext); - if (Double::isNaN(dbl) || - Double::isInfinite(dbl) || - (dbl == 0 && Double::isNeg(dbl))) - return new NumberResult(dbl); + if (!Double::isNaN(dbl) && + !Double::isInfinite(dbl) && + !(dbl == 0 && Double::isNeg(dbl))) { + dbl = floor(dbl); + } - return new NumberResult(floor(dbl)); + return aContext->recycler()->getNumberResult(dbl, aResult); } case ROUND: { double dbl = evaluateToNumber((Expr*)iter.next(), aContext); - if (Double::isNaN(dbl) || Double::isInfinite(dbl)) - return new NumberResult(dbl); + if (!Double::isNaN(dbl) && !Double::isInfinite(dbl)) { + if (Double::isNeg(dbl) && dbl >= -0.5) { + dbl *= 0; + } + else { + dbl = floor(dbl + 0.5); + } + } - if (Double::isNeg(dbl) && dbl >= -0.5) - return new NumberResult(0 * dbl); - - return new NumberResult(floor(dbl + 0.5)); + return aContext->recycler()->getNumberResult(dbl, aResult); } case SUM: { - NodeSet* nodes; - nodes = evaluateToNodeSet((Expr*)iter.next(), aContext); - - if (!nodes) - return new StringResult(NS_LITERAL_STRING("error")); + nsRefPtr nodes; + nsresult rv = evaluateToNodeSet((Expr*)iter.next(), aContext, + getter_AddRefs(nodes)); + NS_ENSURE_SUCCESS(rv, rv); double res = 0; int i; @@ -116,26 +124,27 @@ ExprResult* NumberFunctionCall::evaluate(txIEvalContext* aContext) XMLDOMUtils::getNodeValue(nodes->get(i), resultStr); res += Double::toDouble(resultStr); } - delete nodes; - - return new NumberResult(res); + return aContext->recycler()->getNumberResult(res, aResult); } case NUMBER: { + double res; if (iter.hasNext()) { - return new NumberResult( - evaluateToNumber((Expr*)iter.next(), aContext)); + res = evaluateToNumber((Expr*)iter.next(), aContext); } - - nsAutoString resultStr; - XMLDOMUtils::getNodeValue(aContext->getContextNode(), resultStr); - return new NumberResult(Double::toDouble(resultStr)); + else { + nsAutoString resultStr; + XMLDOMUtils::getNodeValue(aContext->getContextNode(), + resultStr); + res = Double::toDouble(resultStr); + } + return aContext->recycler()->getNumberResult(res, aResult); } } aContext->receiveError(NS_LITERAL_STRING("Internal error"), NS_ERROR_UNEXPECTED); - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_UNEXPECTED; } nsresult NumberFunctionCall::getNameAtom(nsIAtom** aAtom) diff --git a/mozilla/extensions/transformiix/source/xpath/NumberResult.cpp b/mozilla/extensions/transformiix/source/xpath/NumberResult.cpp index b0e3696322e..1f09ca07faf 100644 --- a/mozilla/extensions/transformiix/source/xpath/NumberResult.cpp +++ b/mozilla/extensions/transformiix/source/xpath/NumberResult.cpp @@ -34,29 +34,22 @@ /** * Default Constructor **/ -NumberResult::NumberResult() { - value = 0.0; -} //-- NumberResult /** * Creates a new NumberResult with the value of the given double parameter * @param dbl the double to use for initialization of this NumberResult's value **/ -NumberResult::NumberResult(double dbl) { - this->value = dbl; +NumberResult::NumberResult(double aValue, txResultRecycler* aRecycler) + : txAExprResult(aRecycler), value(aValue) +{ } //-- NumberResult /* * Virtual Methods from ExprResult */ -ExprResult* NumberResult::clone() -{ - return new NumberResult(value); -} - short NumberResult::getResultType() { - return ExprResult::NUMBER; + return txAExprResult::NUMBER; } //-- getResultType void NumberResult::stringValue(nsAString& str) { diff --git a/mozilla/extensions/transformiix/source/xpath/PathExpr.cpp b/mozilla/extensions/transformiix/source/xpath/PathExpr.cpp index c528e78971e..27c6fc538d6 100644 --- a/mozilla/extensions/transformiix/source/xpath/PathExpr.cpp +++ b/mozilla/extensions/transformiix/source/xpath/PathExpr.cpp @@ -94,77 +94,93 @@ void PathExpr::addExpr(Expr* expr, PathOperator pathOp) * for evaluation * @return the result of the evaluation **/ -ExprResult* PathExpr::evaluate(txIEvalContext* aContext) +nsresult +PathExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult) { - if (!aContext || (expressions.getLength() == 0)) { - NS_ASSERTION(0, "internal error"); - return new StringResult(NS_LITERAL_STRING("error")); - } + *aResult = nsnull; - NodeSet* nodes = new NodeSet(aContext->getContextNode()); - if (!nodes) { - // XXX ErrorReport: out of memory - NS_ASSERTION(0, "out of memory"); - return 0; - } + nsRefPtr nodes; + nsresult rv = aContext->recycler()->getNodeSet(aContext->getContextNode(), + getter_AddRefs(nodes)); + NS_ENSURE_SUCCESS(rv, rv); txListIterator iter(&expressions); PathExprItem* pxi; - while ((pxi = (PathExprItem*)iter.next())) { - NodeSet* tmpNodes = 0; + nsRefPtr tmpNodes; txNodeSetContext eContext(nodes, aContext); while (eContext.hasNext()) { eContext.next(); Node* node = eContext.getContextNode(); - NodeSet* resNodes; + nsRefPtr resNodes; if (pxi->pathOp == DESCENDANT_OP) { - resNodes = new NodeSet; - evalDescendants(pxi->expr, node, &eContext, resNodes); + rv = aContext->recycler()->getNodeSet(getter_AddRefs(resNodes)); + NS_ENSURE_SUCCESS(rv, rv); + + rv = evalDescendants(pxi->expr, node, &eContext, resNodes); + NS_ENSURE_SUCCESS(rv, rv); } else { - ExprResult *res = pxi->expr->evaluate(&eContext); - if (!res || (res->getResultType() != ExprResult::NODESET)) { + nsRefPtr res; + rv = pxi->expr->evaluate(&eContext, getter_AddRefs(res)); + NS_ENSURE_SUCCESS(rv, rv); + + if (res->getResultType() != txAExprResult::NODESET) { //XXX ErrorReport: report nonnodeset error - delete res; - res = new NodeSet; + return NS_ERROR_XSLT_NODESET_EXPECTED; } - resNodes = (NodeSet*)res; + resNodes = NS_STATIC_CAST(NodeSet*, + NS_STATIC_CAST(txAExprResult*, + res)); } if (tmpNodes) { - tmpNodes->add(resNodes); - delete resNodes; - } - else - tmpNodes = resNodes; + if (!resNodes->isEmpty()) { + nsRefPtr oldSet; + oldSet.swap(tmpNodes); + rv = aContext->recycler()-> + getNonSharedNodeSet(oldSet, getter_AddRefs(tmpNodes)); + NS_ENSURE_SUCCESS(rv, rv); + tmpNodes->add(resNodes); + } + } + else { + tmpNodes = resNodes; + } } - delete nodes; nodes = tmpNodes; - if (!nodes || (nodes->size() == 0)) break; + if (nodes->isEmpty()) { + break; + } } - return nodes; + + *aResult = nodes; + NS_ADDREF(*aResult); + + return NS_OK; } //-- evaluate /** * Selects from the descendants of the context node * all nodes that match the Expr **/ -void PathExpr::evalDescendants (Expr* aStep, Node* aNode, - txIMatchContext* aContext, - NodeSet* resNodes) +nsresult +PathExpr::evalDescendants(Expr* aStep, Node* aNode, txIMatchContext* aContext, + NodeSet* resNodes) { txSingleNodeContext eContext(aNode, aContext); - ExprResult *res = aStep->evaluate(&eContext); - if (!res || (res->getResultType() != ExprResult::NODESET)) { + nsRefPtr res; + nsresult rv = aStep->evaluate(&eContext, getter_AddRefs(res)); + NS_ENSURE_SUCCESS(rv, rv); + + if (res->getResultType() != txAExprResult::NODESET) { //XXX ErrorReport: report nonnodeset error + return NS_ERROR_XSLT_NODESET_EXPECTED; } - else { - resNodes->add((NodeSet*)res); - } - delete res; + resNodes->add(NS_STATIC_CAST(NodeSet*, NS_STATIC_CAST(txAExprResult*, + res))); MBool filterWS = aContext->isStripSpaceAllowed(aNode); @@ -173,10 +189,14 @@ void PathExpr::evalDescendants (Expr* aStep, Node* aNode, if (!(filterWS && (child->getNodeType() == Node::TEXT_NODE || child->getNodeType() == Node::CDATA_SECTION_NODE) && - XMLUtils::isWhitespace(child))) - evalDescendants(aStep, child, aContext, resNodes); + XMLUtils::isWhitespace(child))) { + rv = evalDescendants(aStep, child, aContext, resNodes); + NS_ENSURE_SUCCESS(rv, rv); + } child = child->getNextSibling(); } + + return NS_OK; } //-- evalDescendants /** diff --git a/mozilla/extensions/transformiix/source/xpath/PredicateList.cpp b/mozilla/extensions/transformiix/source/xpath/PredicateList.cpp index d9eab35347d..51e92963e95 100644 --- a/mozilla/extensions/transformiix/source/xpath/PredicateList.cpp +++ b/mozilla/extensions/transformiix/source/xpath/PredicateList.cpp @@ -56,14 +56,15 @@ void PredicateList::add(Expr* expr) predicates.add(expr); } // add -void PredicateList::evaluatePredicates(NodeSet* nodes, - txIMatchContext* aContext) +nsresult +PredicateList::evaluatePredicates(NodeSet* nodes, + txIMatchContext* aContext) { NS_ASSERTION(nodes, "called evaluatePredicates with NULL NodeSet"); - if (!nodes) - return; - - NodeSet newNodes; + nsRefPtr newNodes; + nsresult rv = aContext->recycler()->getNodeSet(getter_AddRefs(newNodes)); + NS_ENSURE_SUCCESS(rv, rv); + txListIterator iter(&predicates); while (iter.hasNext() && !nodes->isEmpty()) { Expr* expr = (Expr*)iter.next(); @@ -73,30 +74,32 @@ void PredicateList::evaluatePredicates(NodeSet* nodes, * or, if the result is a number, add the node with the right * position */ - newNodes.clear(); + newNodes->clear(); while (predContext.hasNext()) { predContext.next(); - ExprResult* exprResult = expr->evaluate(&predContext); - if (!exprResult) - break; + nsRefPtr exprResult; + rv = expr->evaluate(&predContext, getter_AddRefs(exprResult)); + NS_ENSURE_SUCCESS(rv, rv); + switch(exprResult->getResultType()) { - case ExprResult::NUMBER : + case txAExprResult::NUMBER: // handle default, [position() == numberValue()] if ((double)predContext.position() == exprResult->numberValue()) - newNodes.append(predContext.getContextNode()); + newNodes->append(predContext.getContextNode()); break; default: if (exprResult->booleanValue()) - newNodes.append(predContext.getContextNode()); + newNodes->append(predContext.getContextNode()); break; } - delete exprResult; } // Move new NodeSet to the current one nodes->clear(); - nodes->append(&newNodes); + nodes->append(newNodes); } + + return NS_OK; } /* diff --git a/mozilla/extensions/transformiix/source/xpath/RelationalExpr.cpp b/mozilla/extensions/transformiix/source/xpath/RelationalExpr.cpp index 413bc42ae35..1f45fbdf7a2 100644 --- a/mozilla/extensions/transformiix/source/xpath/RelationalExpr.cpp +++ b/mozilla/extensions/transformiix/source/xpath/RelationalExpr.cpp @@ -30,6 +30,7 @@ #include "Expr.h" #include "NodeSet.h" #include "XMLDOMUtils.h" +#include "txIXPathContext.h" RelationalExpr::RelationalExpr(Expr* aLeftExpr, Expr* aRightExpr, RelationalExprType aOp) @@ -41,26 +42,31 @@ RelationalExpr::RelationalExpr(Expr* aLeftExpr, Expr* aRightExpr, * Compares the two ExprResults based on XPath 1.0 Recommendation (section 3.4) */ PRBool -RelationalExpr::compareResults(ExprResult* aLeft, ExprResult* aRight) +RelationalExpr::compareResults(txIEvalContext* aContext, txAExprResult* aLeft, + txAExprResult* aRight) { short ltype = aLeft->getResultType(); short rtype = aRight->getResultType(); + nsresult rv = NS_OK; // Handle case for just Left NodeSet or Both NodeSets - if (ltype == ExprResult::NODESET) { - if (rtype == ExprResult::BOOLEAN) { + if (ltype == txAExprResult::NODESET) { + if (rtype == txAExprResult::BOOLEAN) { BooleanResult leftBool(aLeft->booleanValue()); - return compareResults(&leftBool, aRight); + return compareResults(aContext, &leftBool, aRight); } NodeSet* nodeSet = NS_STATIC_CAST(NodeSet*, aLeft); - StringResult strResult; + nsRefPtr strResult; + rv = aContext->recycler()->getStringResult(getter_AddRefs(strResult)); + NS_ENSURE_SUCCESS(rv, rv); + int i; for (i = 0; i < nodeSet->size(); ++i) { Node* node = nodeSet->get(i); - strResult.mValue.Truncate(); - XMLDOMUtils::getNodeValue(node, strResult.mValue); - if (compareResults(&strResult, aRight)) { + strResult->mValue.Truncate(); + XMLDOMUtils::getNodeValue(node, strResult->mValue); + if (compareResults(aContext, strResult, aRight)) { return PR_TRUE; } } @@ -69,20 +75,23 @@ RelationalExpr::compareResults(ExprResult* aLeft, ExprResult* aRight) } // Handle case for Just Right NodeSet - if (rtype == ExprResult::NODESET) { - if (ltype == ExprResult::BOOLEAN) { + if (rtype == txAExprResult::NODESET) { + if (ltype == txAExprResult::BOOLEAN) { BooleanResult rightBool(aRight->booleanValue()); - return compareResults(aLeft, &rightBool); + return compareResults(aContext, aLeft, &rightBool); } NodeSet* nodeSet = NS_STATIC_CAST(NodeSet*, aRight); - StringResult strResult; + nsRefPtr strResult; + rv = aContext->recycler()->getStringResult(getter_AddRefs(strResult)); + NS_ENSURE_SUCCESS(rv, rv); + int i; for (i = 0; i < nodeSet->size(); ++i) { Node* node = nodeSet->get(i); - strResult.mValue.Truncate(); - XMLDOMUtils::getNodeValue(node, strResult.mValue); - if (compareResults(aLeft, &strResult)) { + strResult->mValue.Truncate(); + XMLDOMUtils::getNodeValue(node, strResult->mValue); + if (compareResults(aContext, aLeft, strResult)) { return PR_TRUE; } } @@ -96,12 +105,14 @@ RelationalExpr::compareResults(ExprResult* aLeft, ExprResult* aRight) nsAString *lString, *rString; // If either is a bool, compare as bools. - if (ltype == ExprResult::BOOLEAN || rtype == ExprResult::BOOLEAN) { + if (ltype == txAExprResult::BOOLEAN || + rtype == txAExprResult::BOOLEAN) { result = aLeft->booleanValue() == aRight->booleanValue(); } // If either is a number, compare as numbers. - else if (ltype == ExprResult::NUMBER || rtype == ExprResult::NUMBER) { + else if (ltype == txAExprResult::NUMBER || + rtype == txAExprResult::NUMBER) { double lval = aLeft->numberValue(); double rval = aRight->numberValue(); #if defined(XP_WIN) || defined(XP_OS2) @@ -167,16 +178,22 @@ RelationalExpr::compareResults(ExprResult* aLeft, ExprResult* aRight) return PR_FALSE; } -ExprResult* -RelationalExpr::evaluate(txIEvalContext* aContext) +nsresult +RelationalExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult) { - nsAutoPtr lResult(mLeftExpr->evaluate(aContext)); - NS_ENSURE_TRUE(lResult, nsnull); + *aResult = nsnull; + nsRefPtr lResult; + nsresult rv = mLeftExpr->evaluate(aContext, getter_AddRefs(lResult)); + NS_ENSURE_SUCCESS(rv, rv); - nsAutoPtr rResult(mRightExpr->evaluate(aContext)); - NS_ENSURE_TRUE(rResult, nsnull); + nsRefPtr rResult; + rv = mRightExpr->evaluate(aContext, getter_AddRefs(rResult)); + NS_ENSURE_SUCCESS(rv, rv); + + aContext->recycler()-> + getBoolResult(compareResults(aContext, lResult, rResult), aResult); - return new BooleanResult(compareResults(lResult, rResult)); + return NS_OK; } void diff --git a/mozilla/extensions/transformiix/source/xpath/RootExpr.cpp b/mozilla/extensions/transformiix/source/xpath/RootExpr.cpp index 47aaf4e0d6a..a211beb5a4c 100644 --- a/mozilla/extensions/transformiix/source/xpath/RootExpr.cpp +++ b/mozilla/extensions/transformiix/source/xpath/RootExpr.cpp @@ -42,17 +42,15 @@ RootExpr::RootExpr(MBool aSerialize) { * for evaluation * @return the result of the evaluation **/ -ExprResult* RootExpr::evaluate(txIEvalContext* aContext) +nsresult +RootExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult) { - Node* context; - if (!aContext || !(context = aContext->getContextNode())) { - NS_ASSERTION(0, "internal error"); - return 0; + Node* context = aContext->getContextNode(); + if (context->getNodeType() != Node::DOCUMENT_NODE) { + context = context->getOwnerDocument(); } - if (context->getNodeType() != Node::DOCUMENT_NODE) - return new NodeSet(context->getOwnerDocument()); - return new NodeSet(context); + return aContext->recycler()->getNodeSet(context, aResult); } //-- evaluate /** diff --git a/mozilla/extensions/transformiix/source/xpath/StringExpr.cpp b/mozilla/extensions/transformiix/source/xpath/StringExpr.cpp deleted file mode 100644 index fb0f6fe08bc..00000000000 --- a/mozilla/extensions/transformiix/source/xpath/StringExpr.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is TransforMiiX XSLT processor. - * - * The Initial Developer of the Original Code is The MITRE Corporation. - * Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation. - * - * Portions created by Keith Visco as a Non MITRE employee, - * (C) 1999 Keith Visco. All Rights Reserved. - * - * Contributor(s): - * Keith Visco, kvisco@ziplink.net - * -- original author. - * - */ - -#include "Expr.h" -#include "ExprResult.h" - -/** - * StringExpr -**/ - -/** - * Creates a new StringExpr -**/ -StringExpr::StringExpr(const nsAString& value) { - //-- copy value - this->value.Append(value); -} //-- StringExpr - -/** - * Evaluates this Expr based on the given context node and processor state - * @param context the context node for evaluation of this Expr - * @param ps the ContextState containing the stack information needed - * for evaluation - * @return the result of the evaluation -**/ -ExprResult* StringExpr::evaluate(txIEvalContext* aContext) -{ - return new StringResult(value); -} //-- evaluate - -/** - * Returns the String representation of this Expr. - * @param dest the String to use when creating the String - * representation. The String representation will be appended to - * any data in the destination String, to allow cascading calls to - * other #toString() methods for Expressions. - * @return the String representation of this Expr. -**/ -void StringExpr::toString(nsAString& str) { - PRUnichar ch = '\''; - if (value.FindChar(ch) != kNotFound) - ch = '\"'; - str.Append(ch); - str.Append(value); - str.Append(ch); -} //-- toString - diff --git a/mozilla/extensions/transformiix/source/xpath/StringFunctionCall.cpp b/mozilla/extensions/transformiix/source/xpath/StringFunctionCall.cpp index d19c279ef70..28fb55f91aa 100644 --- a/mozilla/extensions/transformiix/source/xpath/StringFunctionCall.cpp +++ b/mozilla/extensions/transformiix/source/xpath/StringFunctionCall.cpp @@ -36,6 +36,7 @@ #include "XMLDOMUtils.h" #include "XMLUtils.h" #include +#include "nsReadableUtils.h" /** * Creates a StringFunctionCall of the given type @@ -51,39 +52,54 @@ StringFunctionCall::StringFunctionCall(StringFunctions aType) : mType(aType) * for evaluation * @return the result of the evaluation **/ -ExprResult* StringFunctionCall::evaluate(txIEvalContext* aContext) +nsresult +StringFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult) { + *aResult = nsnull; + + nsresult rv = NS_OK; txListIterator iter(¶ms); switch (mType) { case CONCAT: { if (!requireParams(2, -1, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; - nsAutoString resultStr; + nsRefPtr strRes; + rv = aContext->recycler()->getStringResult(getter_AddRefs(strRes)); + NS_ENSURE_SUCCESS(rv, rv); + while (iter.hasNext()) { - evaluateToString((Expr*)iter.next(), aContext, resultStr); + evaluateToString((Expr*)iter.next(), aContext, strRes->mValue); } - return new StringResult(resultStr); + *aResult = strRes; + NS_ADDREF(*aResult); + + return NS_OK; } case CONTAINS: { if (!requireParams(2, 2, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; nsAutoString arg1, arg2; Expr* arg1Expr = (Expr*)iter.next(); evaluateToString((Expr*)iter.next(), aContext, arg2); - if (arg2.IsEmpty()) - return new BooleanResult(PR_TRUE); + if (arg2.IsEmpty()) { + aContext->recycler()->getBoolResult(PR_TRUE, aResult); + } + else { + evaluateToString(arg1Expr, aContext, arg1); + aContext->recycler()->getBoolResult(arg1.Find(arg2) >= 0, + aResult); + } - evaluateToString(arg1Expr, aContext, arg1); - return new BooleanResult(arg1.Find(arg2) >= 0); + return NS_OK; } case NORMALIZE_SPACE: { if (!requireParams(0, 1, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; nsAutoString resultStr; if (iter.hasNext()) @@ -92,10 +108,13 @@ ExprResult* StringFunctionCall::evaluate(txIEvalContext* aContext) XMLDOMUtils::getNodeValue(aContext->getContextNode(), resultStr); + nsRefPtr strRes; + rv = aContext->recycler()->getStringResult(getter_AddRefs(strRes)); + NS_ENSURE_SUCCESS(rv, rv); + MBool addSpace = MB_FALSE; MBool first = MB_TRUE; - nsAutoString normed; - normed.SetCapacity(resultStr.Length()); + strRes->mValue.SetCapacity(resultStr.Length()); PRUnichar c; PRUint32 src; for (src = 0; src < resultStr.Length(); src++) { @@ -105,33 +124,41 @@ ExprResult* StringFunctionCall::evaluate(txIEvalContext* aContext) } else { if (addSpace && !first) - normed.Append(PRUnichar(' ')); + strRes->mValue.Append(PRUnichar(' ')); - normed.Append(c); + strRes->mValue.Append(c); addSpace = MB_FALSE; first = MB_FALSE; } } - return new StringResult(normed); + *aResult = strRes; + NS_ADDREF(*aResult); + + return NS_OK; } case STARTS_WITH: { if (!requireParams(2, 2, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; nsAutoString arg1, arg2; Expr* arg1Expr = (Expr*)iter.next(); evaluateToString((Expr*)iter.next(), aContext, arg2); - if (arg2.IsEmpty()) - return new BooleanResult(PR_TRUE); + if (arg2.IsEmpty()) { + aContext->recycler()->getBoolResult(PR_TRUE, aResult); + } + else { + evaluateToString(arg1Expr, aContext, arg1); + aContext->recycler()->getBoolResult( + StringBeginsWith(arg1, arg2), aResult); + } - evaluateToString(arg1Expr, aContext, arg1); - return new BooleanResult(arg1.Find(arg2) == 0); + return NS_OK; } case STRING_LENGTH: { if (!requireParams(0, 1, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; nsAutoString resultStr; if (iter.hasNext()) @@ -139,12 +166,16 @@ ExprResult* StringFunctionCall::evaluate(txIEvalContext* aContext) else XMLDOMUtils::getNodeValue(aContext->getContextNode(), resultStr); - return new NumberResult(resultStr.Length()); + rv = aContext->recycler()->getNumberResult(resultStr.Length(), + aResult); + NS_ENSURE_SUCCESS(rv, rv); + + return NS_OK; } case SUBSTRING: { if (!requireParams(2, 3, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; nsAutoString src; double start, end; @@ -154,15 +185,21 @@ ExprResult* StringFunctionCall::evaluate(txIEvalContext* aContext) // check for NaN or +/-Inf if (Double::isNaN(start) || Double::isInfinite(start) || - start >= src.Length() + 0.5) - return new StringResult(); + start >= src.Length() + 0.5) { + aContext->recycler()->getEmptyStringResult(aResult); + + return NS_OK; + } start = floor(start + 0.5) - 1; if (iter.hasNext()) { end = start + evaluateToNumber((Expr*)iter.next(), aContext); - if (Double::isNaN(end) || end < 0) - return new StringResult(); + if (Double::isNaN(end) || end < 0) { + aContext->recycler()->getEmptyStringResult(aResult); + + return NS_OK; + } if (end > src.Length()) end = src.Length(); @@ -176,61 +213,79 @@ ExprResult* StringFunctionCall::evaluate(txIEvalContext* aContext) if (start < 0) start = 0; - if (start > end) - return new StringResult(); - - return new StringResult(Substring(src, (PRUint32)start, - (PRUint32)end - (PRUint32)start)); + if (start > end) { + aContext->recycler()->getEmptyStringResult(aResult); + + return NS_OK; + } + + return aContext->recycler()->getStringResult( + Substring(src, (PRUint32)start, (PRUint32)(end - start)), + aResult); } case SUBSTRING_AFTER: { if (!requireParams(2, 2, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; nsAutoString arg1, arg2; evaluateToString((Expr*)iter.next(), aContext, arg1); evaluateToString((Expr*)iter.next(), aContext, arg2); - if (arg2.IsEmpty()) - return new StringResult(arg1); + if (arg2.IsEmpty()) { + return aContext->recycler()->getStringResult(arg1, aResult); + } PRInt32 idx = arg1.Find(arg2); - if (idx != kNotFound) { - PRUint32 len = arg2.Length(); - return new StringResult(Substring(arg1, idx + len, - arg1.Length() - (idx + len))); + if (idx == kNotFound) { + aContext->recycler()->getEmptyStringResult(aResult); + + return NS_OK; } - return new StringResult(); + + PRUint32 len = arg2.Length(); + return aContext->recycler()->getStringResult( + Substring(arg1, idx + len, arg1.Length() - (idx + len)), + aResult); } case SUBSTRING_BEFORE: { if (!requireParams(2, 2, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; nsAutoString arg1, arg2; Expr* arg1Expr = (Expr*)iter.next(); evaluateToString((Expr*)iter.next(), aContext, arg2); - if (arg2.IsEmpty()) - return new StringResult(); + if (arg2.IsEmpty()) { + aContext->recycler()->getEmptyStringResult(aResult); + + return NS_OK; + } evaluateToString(arg1Expr, aContext, arg1); PRInt32 idx = arg1.Find(arg2); - if (idx != kNotFound) { - return new StringResult(Substring(arg1, 0, idx)); + if (idx == kNotFound) { + aContext->recycler()->getEmptyStringResult(aResult); + + return NS_OK; } - return new StringResult(); + + return aContext->recycler()-> + getStringResult(Substring(arg1, 0, idx), aResult); } case TRANSLATE: { if (!requireParams(3, 3, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; + + nsRefPtr strRes; + rv = aContext->recycler()->getStringResult(getter_AddRefs(strRes)); + NS_ENSURE_SUCCESS(rv, rv); nsAutoString src; evaluateToString((Expr*)iter.next(), aContext, src); - if (src.IsEmpty()) - return new StringResult(); - - nsAutoString oldChars, newChars, dest; + strRes->mValue.SetCapacity(src.Length()); + nsAutoString oldChars, newChars; evaluateToString((Expr*)iter.next(), aContext, oldChars); evaluateToString((Expr*)iter.next(), aContext, newChars); PRUint32 i; @@ -239,32 +294,41 @@ ExprResult* StringFunctionCall::evaluate(txIEvalContext* aContext) PRInt32 idx = oldChars.FindChar(src.CharAt(i)); if (idx != kNotFound) { if (idx < newCharsLength) - dest.Append(newChars.CharAt((PRUint32)idx)); + strRes->mValue.Append(newChars.CharAt((PRUint32)idx)); } else { - dest.Append(src.CharAt(i)); + strRes->mValue.Append(src.CharAt(i)); } } - return new StringResult(dest); + *aResult = strRes; + NS_ADDREF(*aResult); + + return NS_OK; } case STRING: { if (!requireParams(0, 1, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; + + nsRefPtr strRes; + rv = aContext->recycler()->getStringResult(getter_AddRefs(strRes)); + NS_ENSURE_SUCCESS(rv, rv); - nsAutoString resultStr; if (iter.hasNext()) - evaluateToString((Expr*)iter.next(), aContext, resultStr); + evaluateToString((Expr*)iter.next(), aContext, strRes->mValue); else XMLDOMUtils::getNodeValue(aContext->getContextNode(), - resultStr); - return new StringResult(resultStr); + strRes->mValue); + *aResult = strRes; + NS_ADDREF(*aResult); + + return NS_OK; } } aContext->receiveError(NS_LITERAL_STRING("Internal error"), NS_ERROR_UNEXPECTED); - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_UNEXPECTED; } nsresult StringFunctionCall::getNameAtom(nsIAtom** aAtom) diff --git a/mozilla/extensions/transformiix/source/xpath/StringResult.cpp b/mozilla/extensions/transformiix/source/xpath/StringResult.cpp index 251bb941f0b..095f1e3e877 100644 --- a/mozilla/extensions/transformiix/source/xpath/StringResult.cpp +++ b/mozilla/extensions/transformiix/source/xpath/StringResult.cpp @@ -33,14 +33,17 @@ /** * Default Constructor **/ -StringResult::StringResult() { -} //-- StringResult +StringResult::StringResult(txResultRecycler* aRecycler) + : txAExprResult(aRecycler) +{ +} /** * Creates a new StringResult with the value of the given String parameter * @param str the String to use for initialization of this StringResult's value **/ -StringResult::StringResult(const nsAString& str) : mValue(str) +StringResult::StringResult(const nsAString& aValue, txResultRecycler* aRecycler) + : txAExprResult(aRecycler), mValue(aValue) { } @@ -48,13 +51,8 @@ StringResult::StringResult(const nsAString& str) : mValue(str) * Virtual Methods from ExprResult */ -ExprResult* StringResult::clone() -{ - return new StringResult(mValue); -} - short StringResult::getResultType() { - return ExprResult::STRING; + return txAExprResult::STRING; } //-- getResultType void StringResult::stringValue(nsAString& str) { diff --git a/mozilla/extensions/transformiix/source/xpath/UnaryExpr.cpp b/mozilla/extensions/transformiix/source/xpath/UnaryExpr.cpp index b548b69d545..2b659847233 100644 --- a/mozilla/extensions/transformiix/source/xpath/UnaryExpr.cpp +++ b/mozilla/extensions/transformiix/source/xpath/UnaryExpr.cpp @@ -25,6 +25,7 @@ #include "Expr.h" #include "ExprResult.h" +#include "txIXPathContext.h" UnaryExpr::UnaryExpr(Expr* expr) { @@ -43,20 +44,25 @@ UnaryExpr::~UnaryExpr() * for evaluation. * @return the result of the evaluation. */ -ExprResult* UnaryExpr::evaluate(txIEvalContext* aContext) +nsresult +UnaryExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult) { - ExprResult* exprRes = expr->evaluate(aContext); + *aResult = nsnull; + + nsRefPtr exprRes; + nsresult rv = expr->evaluate(aContext, getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); + double value = exprRes->numberValue(); - delete exprRes; #ifdef HPUX /* * Negation of a zero doesn't produce a negative * zero on HPUX. Perform the operation by multiplying with * -1. */ - return new NumberResult(-1 * value); + return aContext->recycler()->getNumberResult(-1 * value, aResult); #else - return new NumberResult(-value); + return aContext->recycler()->getNumberResult(-value, aResult); #endif } diff --git a/mozilla/extensions/transformiix/source/xpath/UnionExpr.cpp b/mozilla/extensions/transformiix/source/xpath/UnionExpr.cpp index 2e52e758849..12153e62529 100644 --- a/mozilla/extensions/transformiix/source/xpath/UnionExpr.cpp +++ b/mozilla/extensions/transformiix/source/xpath/UnionExpr.cpp @@ -25,6 +25,7 @@ #include "Expr.h" #include "NodeSet.h" +#include "txIXPathContext.h" //-------------/ //- UnionExpr -/ @@ -68,29 +69,34 @@ void UnionExpr::addExpr(Expr* expr) { * for evaluation * @return the result of the evaluation **/ -ExprResult* UnionExpr::evaluate(txIEvalContext* aContext) +nsresult +UnionExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult) { - NodeSet* nodes = new NodeSet(); - - if (!aContext || (expressions.getLength() == 0) || !nodes) - return nodes; + *aResult = nsnull; + nsRefPtr nodes; + nsresult rv = aContext->recycler()->getNodeSet(getter_AddRefs(nodes)); + NS_ENSURE_SUCCESS(rv, rv); txListIterator iter(&expressions); - while (iter.hasNext()) { Expr* expr = (Expr*)iter.next(); - ExprResult* exprResult = expr->evaluate(aContext); - if (!exprResult || - exprResult->getResultType() != ExprResult::NODESET) { - delete exprResult; - delete nodes; - return new StringResult(NS_LITERAL_STRING("error")); + nsRefPtr exprResult; + rv = expr->evaluate(aContext, getter_AddRefs(exprResult)); + NS_ENSURE_SUCCESS(rv, rv); + + if (exprResult->getResultType() != txAExprResult::NODESET) { + //XXX ErrorReport: report nonnodeset error + return NS_ERROR_XSLT_NODESET_EXPECTED; } - nodes->add((NodeSet*)exprResult); - delete exprResult; + rv = nodes->add(NS_STATIC_CAST(NodeSet*, NS_STATIC_CAST(txAExprResult*, + exprResult))); + NS_ENSURE_SUCCESS(rv, rv); } - return nodes; + *aResult = nodes; + NS_ADDREF(*aResult); + + return NS_OK; } //-- evaluate /** diff --git a/mozilla/extensions/transformiix/source/xpath/VariableRefExpr.cpp b/mozilla/extensions/transformiix/source/xpath/VariableRefExpr.cpp index 8339a1a345b..828f9da1974 100644 --- a/mozilla/extensions/transformiix/source/xpath/VariableRefExpr.cpp +++ b/mozilla/extensions/transformiix/source/xpath/VariableRefExpr.cpp @@ -58,15 +58,15 @@ VariableRefExpr::~VariableRefExpr() * for evaluation * @return the result of the evaluation **/ -ExprResult* VariableRefExpr::evaluate(txIEvalContext* aContext) +nsresult +VariableRefExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult) { - ExprResult* exprResult = 0; - nsresult rv = aContext->getVariable(mNamespace, mLocalName, exprResult); + nsresult rv = aContext->getVariable(mNamespace, mLocalName, *aResult); if (NS_FAILED(rv)) { // XXX report error, undefined variable - return new StringResult(NS_LITERAL_STRING("error")); + return rv; } - return exprResult->clone(); + return NS_OK; } /** diff --git a/mozilla/extensions/transformiix/source/xpath/nsXPathEvaluator.cpp b/mozilla/extensions/transformiix/source/xpath/nsXPathEvaluator.cpp index 59fbf4d071d..97549b64d20 100644 --- a/mozilla/extensions/transformiix/source/xpath/nsXPathEvaluator.cpp +++ b/mozilla/extensions/transformiix/source/xpath/nsXPathEvaluator.cpp @@ -76,6 +76,17 @@ nsXPathEvaluator::CreateExpression(const nsAString & aExpression, nsIDOMXPathNSResolver *aResolver, nsIDOMXPathExpression **aResult) { + nsresult rv = NS_OK; + if (!mRecycler) { + nsRefPtr recycler = new txResultRecycler; + NS_ENSURE_TRUE(recycler, NS_ERROR_OUT_OF_MEMORY); + + rv = recycler->init(); + NS_ENSURE_SUCCESS(rv, rv); + + mRecycler = recycler; + } + nsCOMPtr doc = do_QueryReferent(mDocument); ParseContextImpl pContext(aResolver, !doc || doc->IsCaseSensitive()); Expr* expression = ExprParser::createExpr(PromiseFlatString(aExpression), @@ -83,7 +94,7 @@ nsXPathEvaluator::CreateExpression(const nsAString & aExpression, if (!expression) return NS_ERROR_DOM_INVALID_EXPRESSION_ERR; - *aResult = new nsXPathExpression(expression); + *aResult = new nsXPathExpression(expression, mRecycler); if (!*aResult) { delete expression; return NS_ERROR_OUT_OF_MEMORY; diff --git a/mozilla/extensions/transformiix/source/xpath/nsXPathEvaluator.h b/mozilla/extensions/transformiix/source/xpath/nsXPathEvaluator.h index 189960c1614..479e074639a 100644 --- a/mozilla/extensions/transformiix/source/xpath/nsXPathEvaluator.h +++ b/mozilla/extensions/transformiix/source/xpath/nsXPathEvaluator.h @@ -44,6 +44,8 @@ #include "txIXPathContext.h" #include "nsIXPathEvaluatorInternal.h" #include "nsIWeakReference.h" +#include "nsAutoPtr.h" +#include "txResultRecycler.h" class nsIDOMDocument; @@ -100,6 +102,7 @@ private: }; nsWeakPtr mDocument; + nsRefPtr mRecycler; }; /* d0a75e02-b5e7-11d5-a7f2-df109fb8a1fc */ diff --git a/mozilla/extensions/transformiix/source/xpath/nsXPathExpression.cpp b/mozilla/extensions/transformiix/source/xpath/nsXPathExpression.cpp index ebfb5b59340..9f0e46d5647 100644 --- a/mozilla/extensions/transformiix/source/xpath/nsXPathExpression.cpp +++ b/mozilla/extensions/transformiix/source/xpath/nsXPathExpression.cpp @@ -58,7 +58,10 @@ NS_INTERFACE_MAP_BEGIN(nsXPathExpression) NS_INTERFACE_MAP_ENTRY_EXTERNAL_DOM_CLASSINFO(XPathExpression) NS_INTERFACE_MAP_END -nsXPathExpression::nsXPathExpression(Expr* aExpression) : mExpression(aExpression) +nsXPathExpression::nsXPathExpression(Expr* aExpression, + txResultRecycler* aRecycler) + : mExpression(aExpression), + mRecycler(aRecycler) { } @@ -119,29 +122,29 @@ nsXPathExpression::Evaluate(nsIDOMNode *aContextNode, Document document(ownerDOMDocument); Node* node = document.createWrapper(aContextNode); - EvalContextImpl eContext(node); - ExprResult* exprResult = mExpression->evaluate(&eContext); - NS_ENSURE_TRUE(exprResult, NS_ERROR_OUT_OF_MEMORY); + EvalContextImpl eContext(node, mRecycler); + nsRefPtr exprResult; + rv = mExpression->evaluate(&eContext, getter_AddRefs(exprResult)); + NS_ENSURE_SUCCESS(rv, rv); PRUint16 resultType = aType; if (aType == nsIDOMXPathResult::ANY_TYPE) { short exprResultType = exprResult->getResultType(); switch (exprResultType) { - case ExprResult::NUMBER: + case txAExprResult::NUMBER: resultType = nsIDOMXPathResult::NUMBER_TYPE; break; - case ExprResult::STRING: + case txAExprResult::STRING: resultType = nsIDOMXPathResult::STRING_TYPE; break; - case ExprResult::BOOLEAN: + case txAExprResult::BOOLEAN: resultType = nsIDOMXPathResult::BOOLEAN_TYPE; break; - case ExprResult::NODESET: + case txAExprResult::NODESET: resultType = nsIDOMXPathResult::UNORDERED_NODE_ITERATOR_TYPE; break; - case ExprResult::RESULT_TREE_FRAGMENT: + case txAExprResult::RESULT_TREE_FRAGMENT: NS_ERROR("Can't return a tree fragment!"); - delete exprResult; return NS_ERROR_FAILURE; } } @@ -154,7 +157,6 @@ nsXPathExpression::Evaluate(nsIDOMNode *aContextNode, NS_ENSURE_TRUE(xpathResult, NS_ERROR_OUT_OF_MEMORY); } rv = xpathResult->SetExprResult(exprResult, resultType); - delete exprResult; NS_ENSURE_SUCCESS(rv, rv); return CallQueryInterface(xpathResult, aResult); @@ -165,9 +167,10 @@ nsXPathExpression::Evaluate(nsIDOMNode *aContextNode, * EvalContextImpl bases on only one context node and no variables */ -nsresult nsXPathExpression::EvalContextImpl::getVariable(PRInt32 aNamespace, - nsIAtom* aLName, - ExprResult*& aResult) +nsresult +nsXPathExpression::EvalContextImpl::getVariable(PRInt32 aNamespace, + nsIAtom* aLName, + txAExprResult*& aResult) { aResult = 0; return NS_ERROR_INVALID_ARG; @@ -184,6 +187,11 @@ void* nsXPathExpression::EvalContextImpl::getPrivateContext() return nsnull; } +txResultRecycler* nsXPathExpression::EvalContextImpl::recycler() +{ + return mRecycler; +} + void nsXPathExpression::EvalContextImpl::receiveError(const nsAString& aMsg, nsresult aRes) { diff --git a/mozilla/extensions/transformiix/source/xpath/nsXPathExpression.h b/mozilla/extensions/transformiix/source/xpath/nsXPathExpression.h index 00faa19f2cc..9e8604d262f 100644 --- a/mozilla/extensions/transformiix/source/xpath/nsXPathExpression.h +++ b/mozilla/extensions/transformiix/source/xpath/nsXPathExpression.h @@ -42,6 +42,8 @@ #include "nsIDOMXPathExpression.h" #include "txIXPathContext.h" +#include "txResultRecycler.h" +#include "nsAutoPtr.h" class Expr; @@ -51,7 +53,7 @@ class Expr; class nsXPathExpression : public nsIDOMXPathExpression { public: - nsXPathExpression(Expr* aExpression); + nsXPathExpression(Expr* aExpression, txResultRecycler* aRecycler); virtual ~nsXPathExpression(); // nsISupports interface @@ -62,12 +64,13 @@ public: private: Expr* mExpression; + nsRefPtr mRecycler; class EvalContextImpl : public txIEvalContext { public: - EvalContextImpl(Node* aContextNode) - :mNode(aContextNode), mLastError(NS_OK) + EvalContextImpl(Node* aContextNode, txResultRecycler* aRecycler) + : mNode(aContextNode), mLastError(NS_OK), mRecycler(aRecycler) { } @@ -84,6 +87,7 @@ private: private: Node* mNode; nsresult mLastError; + nsRefPtr mRecycler; }; }; diff --git a/mozilla/extensions/transformiix/source/xpath/nsXPathResult.cpp b/mozilla/extensions/transformiix/source/xpath/nsXPathResult.cpp index 679c9a38eb3..77a84e5413c 100644 --- a/mozilla/extensions/transformiix/source/xpath/nsXPathResult.cpp +++ b/mozilla/extensions/transformiix/source/xpath/nsXPathResult.cpp @@ -264,7 +264,7 @@ nsXPathResult::ContentRemoved(nsIDocument* aDocument, } NS_IMETHODIMP -nsXPathResult::SetExprResult(ExprResult* aExprResult, PRUint16 aResultType) +nsXPathResult::SetExprResult(txAExprResult* aExprResult, PRUint16 aResultType) { Reset(); @@ -287,7 +287,7 @@ nsXPathResult::SetExprResult(ExprResult* aExprResult, PRUint16 aResultType) return NS_OK; } - if (aExprResult->getResultType() == ExprResult::NODESET) { + if (aExprResult->getResultType() == txAExprResult::NODESET) { nsresult rv = NS_OK; NodeSet* nodeSet = (NodeSet*)aExprResult; diff --git a/mozilla/extensions/transformiix/source/xpath/nsXPathResult.h b/mozilla/extensions/transformiix/source/xpath/nsXPathResult.h index bc42250cf2e..e90ff0ee062 100644 --- a/mozilla/extensions/transformiix/source/xpath/nsXPathResult.h +++ b/mozilla/extensions/transformiix/source/xpath/nsXPathResult.h @@ -46,7 +46,7 @@ #include "nsCOMPtr.h" #include "nsCOMArray.h" -class ExprResult; +class txAExprResult; // {15b9b301-2012-11d6-a7f2-e6d0a678995c} #define NS_IXPATHRESULT_IID \ @@ -56,7 +56,7 @@ class nsIXPathResult : public nsISupports { public: NS_DEFINE_STATIC_IID_ACCESSOR(NS_IXPATHRESULT_IID) - NS_IMETHOD SetExprResult(ExprResult* aExprResult, + NS_IMETHOD SetExprResult(txAExprResult* aExprResult, PRUint16 aResultType) = 0; }; @@ -81,7 +81,7 @@ public: NS_DECL_NSIDOCUMENTOBSERVER // nsIXPathResult interface - NS_IMETHOD SetExprResult(ExprResult* aExprResult, + NS_IMETHOD SetExprResult(txAExprResult* aExprResult, PRUint16 aResultType); private: void Invalidate(); diff --git a/mozilla/extensions/transformiix/source/xpath/txForwardContext.cpp b/mozilla/extensions/transformiix/source/xpath/txForwardContext.cpp index 843ac913f30..6f51d23dbed 100644 --- a/mozilla/extensions/transformiix/source/xpath/txForwardContext.cpp +++ b/mozilla/extensions/transformiix/source/xpath/txForwardContext.cpp @@ -57,7 +57,7 @@ PRUint32 txForwardContext::position() } nsresult txForwardContext::getVariable(PRInt32 aNamespace, nsIAtom* aLName, - ExprResult*& aResult) + txAExprResult*& aResult) { NS_ASSERTION(mInner, "mInner is null!!!"); return mInner->getVariable(aNamespace, aLName, aResult); @@ -75,6 +75,12 @@ void* txForwardContext::getPrivateContext() return mInner->getPrivateContext(); } +txResultRecycler* txForwardContext::recycler() +{ + NS_ASSERTION(mInner, "mInner is null!!!"); + return mInner->recycler(); +} + void txForwardContext::receiveError(const nsAString& aMsg, nsresult aRes) { NS_ASSERTION(mInner, "mInner is null!!!"); diff --git a/mozilla/extensions/transformiix/source/xpath/txForwardContext.h b/mozilla/extensions/transformiix/source/xpath/txForwardContext.h index a68d7c67589..700226a1283 100644 --- a/mozilla/extensions/transformiix/source/xpath/txForwardContext.h +++ b/mozilla/extensions/transformiix/source/xpath/txForwardContext.h @@ -40,6 +40,7 @@ #define __TX_XPATH_CONTEXT #include "txIXPathContext.h" +#include "nsAutoPtr.h" class NodeSet; @@ -58,7 +59,7 @@ public: private: Node* mContext; - NodeSet* mContextSet; + nsRefPtr mContextSet; txIMatchContext* mInner; }; diff --git a/mozilla/extensions/transformiix/source/xpath/txIXPathContext.h b/mozilla/extensions/transformiix/source/xpath/txIXPathContext.h index 06a96981415..7b4804afbd1 100644 --- a/mozilla/extensions/transformiix/source/xpath/txIXPathContext.h +++ b/mozilla/extensions/transformiix/source/xpath/txIXPathContext.h @@ -43,9 +43,10 @@ #include "nsIAtom.h" #include "txError.h" -class ExprResult; +class txAExprResult; class FunctionCall; class Node; +class txResultRecycler; /* * txIParseContext @@ -107,7 +108,7 @@ public: * given namespace and local name. */ virtual nsresult getVariable(PRInt32 aNamespace, nsIAtom* aLName, - ExprResult*& aResult) = 0; + txAExprResult*& aResult) = 0; /* * Is whitespace stripping allowed for the given node? @@ -120,6 +121,8 @@ public: */ virtual void* getPrivateContext() = 0; + virtual txResultRecycler* recycler() = 0; + /* * Callback to be used by the expression/pattern if errors are detected. */ @@ -128,9 +131,10 @@ public: #define TX_DECL_MATCH_CONTEXT \ nsresult getVariable(PRInt32 aNamespace, nsIAtom* aLName, \ - ExprResult*& aResult); \ + txAExprResult*& aResult); \ MBool isStripSpaceAllowed(Node* aNode); \ void* getPrivateContext(); \ + txResultRecycler* recycler(); \ void receiveError(const nsAString& aMsg, nsresult aRes) class txIEvalContext : public txIMatchContext diff --git a/mozilla/extensions/transformiix/source/xpath/txLiteralExpr.cpp b/mozilla/extensions/transformiix/source/xpath/txLiteralExpr.cpp new file mode 100644 index 00000000000..6f697498228 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xpath/txLiteralExpr.cpp @@ -0,0 +1,86 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is TransforMiiX XSLT processor. + * + * The Initial Developer of the Original Code is + * IBM Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * IBM Corporation. All Rights Reserved. + * + * Contributor(s): + * IBM Corporation + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "Expr.h" + +txLiteralExpr::txLiteralExpr(double aDbl) + : mValue(new NumberResult(aDbl, nsnull)) +{ +} + +txLiteralExpr::txLiteralExpr(const nsAString& aStr) + : mValue(new StringResult(aStr, nsnull)) +{ +} + +nsresult +txLiteralExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult) +{ + NS_ENSURE_TRUE(mValue, NS_ERROR_OUT_OF_MEMORY); + + *aResult = mValue; + NS_ADDREF(*aResult); + + return NS_OK; +} + +void +txLiteralExpr::toString(nsAString& aStr) +{ + switch (mValue->getResultType()) { + case txAExprResult::NUMBER: + { + Double::toString(mValue->numberValue(), aStr); + return; + } + case txAExprResult::STRING: + { + StringResult* strRes = + NS_STATIC_CAST(StringResult*, NS_STATIC_CAST(txAExprResult*, + mValue)); + PRUnichar ch = '\''; + if (strRes->mValue.FindChar(ch) != kNotFound) { + ch = '\"'; + } + aStr.Append(ch); + aStr.Append(strRes->mValue); + aStr.Append(ch); + return; + } + } +} diff --git a/mozilla/extensions/transformiix/source/xpath/txNodeSetContext.cpp b/mozilla/extensions/transformiix/source/xpath/txNodeSetContext.cpp index dcb6d8c9939..489ab585bba 100644 --- a/mozilla/extensions/transformiix/source/xpath/txNodeSetContext.cpp +++ b/mozilla/extensions/transformiix/source/xpath/txNodeSetContext.cpp @@ -56,7 +56,7 @@ PRUint32 txNodeSetContext::position() } nsresult txNodeSetContext::getVariable(PRInt32 aNamespace, nsIAtom* aLName, - ExprResult*& aResult) + txAExprResult*& aResult) { NS_ASSERTION(mInner, "mInner is null!!!"); return mInner->getVariable(aNamespace, aLName, aResult); @@ -74,6 +74,12 @@ void* txNodeSetContext::getPrivateContext() return mInner->getPrivateContext(); } +txResultRecycler* txNodeSetContext::recycler() +{ + NS_ASSERTION(mInner, "mInner is null!!!"); + return mInner->recycler(); +} + void txNodeSetContext::receiveError(const nsAString& aMsg, nsresult aRes) { NS_ASSERTION(mInner, "mInner is null!!!"); diff --git a/mozilla/extensions/transformiix/source/xpath/txNodeSetContext.h b/mozilla/extensions/transformiix/source/xpath/txNodeSetContext.h index d5d065afc31..6bda676997b 100644 --- a/mozilla/extensions/transformiix/source/xpath/txNodeSetContext.h +++ b/mozilla/extensions/transformiix/source/xpath/txNodeSetContext.h @@ -41,6 +41,7 @@ #include "txIXPathContext.h" #include "NodeSet.h" +#include "nsAutoPtr.h" class txNodeSetContext : public txIEvalContext { @@ -67,22 +68,9 @@ public: TX_DECL_EVAL_CONTEXT; protected: - NodeSet* mContextSet; + nsRefPtr mContextSet; PRUint32 mPosition; txIMatchContext* mInner; }; -class txOwningNodeSetContext : public txNodeSetContext -{ -public: - txOwningNodeSetContext(NodeSet* aContextNodeSet, txIMatchContext* aContext) - : txNodeSetContext(aContextNodeSet, aContext) - { - } - virtual ~txOwningNodeSetContext() - { - delete mContextSet; - } -}; - #endif // __TX_XPATH_SET_CONTEXT diff --git a/mozilla/extensions/transformiix/source/xpath/txResultRecycler.cpp b/mozilla/extensions/transformiix/source/xpath/txResultRecycler.cpp new file mode 100644 index 00000000000..af0da5de033 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xpath/txResultRecycler.cpp @@ -0,0 +1,288 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is TransforMiiX XSLT processor. + * + * The Initial Developer of the Original Code is + * IBM Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * IBM Corporation. All Rights Reserved. + * + * Contributor(s): + * IBM Corporation + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "txResultRecycler.h" +#include "ExprResult.h" +#include "NodeSet.h" + +txResultRecycler::txResultRecycler() + : mEmptyStringResult(nsnull), + mTrueResult(nsnull), + mFalseResult(nsnull) +{ +} + +txResultRecycler::~txResultRecycler() +{ + txStackIterator stringIter(&mStringResults); + while (stringIter.hasNext()) { + delete NS_STATIC_CAST(StringResult*, stringIter.next()); + } + txStackIterator nodesetIter(&mNodeSetResults); + while (nodesetIter.hasNext()) { + delete NS_STATIC_CAST(NodeSet*, nodesetIter.next()); + } + txStackIterator numberIter(&mNumberResults); + while (numberIter.hasNext()) { + delete NS_STATIC_CAST(NumberResult*, numberIter.next()); + } + + NS_IF_RELEASE(mEmptyStringResult); + NS_IF_RELEASE(mTrueResult); + NS_IF_RELEASE(mFalseResult); +} + + +nsresult +txResultRecycler::init() +{ + NS_ASSERTION(!mEmptyStringResult && !mTrueResult && !mFalseResult, + "Already inited"); + mEmptyStringResult = new StringResult(nsnull); + NS_ENSURE_TRUE(mEmptyStringResult, NS_ERROR_OUT_OF_MEMORY); + + NS_ADDREF(mEmptyStringResult); + + mTrueResult = new BooleanResult(PR_TRUE); + NS_ENSURE_TRUE(mTrueResult, NS_ERROR_OUT_OF_MEMORY); + + NS_ADDREF(mTrueResult); + + mFalseResult = new BooleanResult(PR_FALSE); + NS_ENSURE_TRUE(mFalseResult, NS_ERROR_OUT_OF_MEMORY); + + NS_ADDREF(mFalseResult); + + return NS_OK; +} + + +void +txResultRecycler::recycle(txAExprResult* aResult) +{ + NS_ASSERTION(aResult->mRefCnt == 0, "In-use txAExprResult recycled"); + nsRefPtr kungFuDeathGrip; + aResult->mRecycler.swap(kungFuDeathGrip); + + nsresult rv = NS_OK; + switch (aResult->getResultType()) { + case txAExprResult::STRING: + { + rv = mStringResults.push(NS_STATIC_CAST(StringResult*, aResult)); + if (NS_FAILED(rv)) { + delete aResult; + } + return; + } + case txAExprResult::NODESET: + { + rv = mNodeSetResults.push(NS_STATIC_CAST(NodeSet*, aResult)); + if (NS_FAILED(rv)) { + delete aResult; + } + return; + } + case txAExprResult::NUMBER: + { + rv = mNumberResults.push(NS_STATIC_CAST(NumberResult*, aResult)); + if (NS_FAILED(rv)) { + delete aResult; + } + return; + } + default: + { + delete aResult; + } + } +} + +nsresult +txResultRecycler::getStringResult(StringResult** aResult) +{ + if (mStringResults.isEmpty()) { + *aResult = new StringResult(this); + NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY); + } + else { + *aResult = NS_STATIC_CAST(StringResult*, mStringResults.pop()); + (*aResult)->mValue.Truncate(); + (*aResult)->mRecycler = this; + } + NS_ADDREF(*aResult); + + return NS_OK; +} + +nsresult +txResultRecycler::getStringResult(const nsAString& aValue, + txAExprResult** aResult) +{ + if (mStringResults.isEmpty()) { + *aResult = new StringResult(aValue, this); + NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY); + } + else { + StringResult* strRes = + NS_STATIC_CAST(StringResult*, mStringResults.pop()); + strRes->mValue = aValue; + strRes->mRecycler = this; + *aResult = strRes; + } + NS_ADDREF(*aResult); + + return NS_OK; +} + +void +txResultRecycler::getEmptyStringResult(txAExprResult** aResult) +{ + *aResult = mEmptyStringResult; + NS_ADDREF(*aResult); +} + +nsresult +txResultRecycler::getNodeSet(NodeSet** aResult) +{ + if (mNodeSetResults.isEmpty()) { + *aResult = new NodeSet(this); + NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY); + } + else { + *aResult = NS_STATIC_CAST(NodeSet*, mNodeSetResults.pop()); + (*aResult)->clear(); + (*aResult)->mRecycler = this; + } + NS_ADDREF(*aResult); + + return NS_OK; +} + +nsresult +txResultRecycler::getNodeSet(NodeSet* aNodeSet, NodeSet** aResult) +{ + if (mNodeSetResults.isEmpty()) { + *aResult = new NodeSet(*aNodeSet, this); + NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY); + } + else { + *aResult = NS_STATIC_CAST(NodeSet*, mNodeSetResults.pop()); + (*aResult)->clear(); + (*aResult)->append(aNodeSet); + (*aResult)->mRecycler = this; + } + NS_ADDREF(*aResult); + + return NS_OK; +} + +nsresult +txResultRecycler::getNodeSet(Node* aNode, txAExprResult** aResult) +{ + if (mNodeSetResults.isEmpty()) { + *aResult = new NodeSet(aNode, this); + NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY); + } + else { + NodeSet* nodes = NS_STATIC_CAST(NodeSet*, mNodeSetResults.pop()); + nodes->clear(); + nodes->append(aNode); + nodes->mRecycler = this; + *aResult = nodes; + } + NS_ADDREF(*aResult); + + return NS_OK; +} + +nsresult +txResultRecycler::getNodeSet(Node* aNode, NodeSet** aResult) +{ + if (mNodeSetResults.isEmpty()) { + *aResult = new NodeSet(aNode, this); + NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY); + } + else { + *aResult = NS_STATIC_CAST(NodeSet*, mNodeSetResults.pop()); + (*aResult)->clear(); + (*aResult)->append(aNode); + (*aResult)->mRecycler = this; + } + NS_ADDREF(*aResult); + + return NS_OK; +} + +nsresult +txResultRecycler::getNumberResult(double aValue, txAExprResult** aResult) +{ + if (mNumberResults.isEmpty()) { + *aResult = new NumberResult(aValue, this); + NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY); + } + else { + NumberResult* numRes = + NS_STATIC_CAST(NumberResult*, mNumberResults.pop()); + numRes->value = aValue; + numRes->mRecycler = this; + *aResult = numRes; + } + NS_ADDREF(*aResult); + + return NS_OK; +} + +void +txResultRecycler::getBoolResult(PRBool aValue, txAExprResult** aResult) +{ + *aResult = aValue ? mTrueResult : mFalseResult; + NS_ADDREF(*aResult); +} + +nsresult +txResultRecycler::getNonSharedNodeSet(NodeSet* aNodeSet, NodeSet** aResult) +{ + if (aNodeSet->mRefCnt > 1) { + return getNodeSet(aNodeSet, aResult); + } + + *aResult = aNodeSet; + NS_ADDREF(*aResult); + + return NS_OK; +} diff --git a/mozilla/extensions/transformiix/source/xpath/txResultRecycler.h b/mozilla/extensions/transformiix/source/xpath/txResultRecycler.h new file mode 100644 index 00000000000..cdd8941f7b2 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xpath/txResultRecycler.h @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is TransforMiiX XSLT processor. + * + * The Initial Developer of the Original Code is + * IBM Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * IBM Corporation. All Rights Reserved. + * + * Contributor(s): + * IBM Corporation + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef txResultRecycler_h__ +#define txResultRecycler_h__ + +#include "nsCOMPtr.h" +#include "txStack.h" + +class txAExprResult; +class StringResult; +class NodeSet; +class Node; +class NumberResult; +class BooleanResult; + +class txResultRecycler +{ +public: + txResultRecycler(); + ~txResultRecycler(); + nsresult init(); + + void AddRef() + { + ++mRefCnt; + } + void Release() + { + if (--mRefCnt == 0) { + mRefCnt = 1; //stabilize + delete this; + } + } + + /** + * Returns an txAExprResult to this recycler for reuse. + * @param aResult result to recycle + */ + void recycle(txAExprResult* aResult); + + /** + * Functions to return results that will be fully used by the caller. + * Returns nsnull on out-of-memory and an inited result otherwise. + */ + nsresult getStringResult(StringResult** aResult); + nsresult getStringResult(const nsAString& aValue, txAExprResult** aResult); + nsresult getNodeSet(NodeSet** aResult); + nsresult getNodeSet(NodeSet* aNodeSet, NodeSet** aResult); + nsresult getNodeSet(Node* aNode, txAExprResult** aResult); + nsresult getNodeSet(Node* aNode, NodeSet** aResult); + nsresult getNumberResult(double aValue, txAExprResult** aResult); + + /** + * Functions to return a txAExprResult that is shared across several + * clients and must not be modified. Never returns nsnull. + */ + void getEmptyStringResult(txAExprResult** aResult); + void getBoolResult(PRBool aValue, txAExprResult** aResult); + + /** + * Functions that return non-shared resultsobjects + */ + nsresult getNonSharedNodeSet(NodeSet* aNodeSet, NodeSet** aResult); + +private: + nsAutoRefCnt mRefCnt; + txStack mStringResults; + txStack mNodeSetResults; + txStack mNumberResults; + StringResult* mEmptyStringResult; + BooleanResult* mTrueResult; + BooleanResult* mFalseResult; +}; + +#endif //txResultRecycler_h__ \ No newline at end of file diff --git a/mozilla/extensions/transformiix/source/xpath/txSingleNodeContext.h b/mozilla/extensions/transformiix/source/xpath/txSingleNodeContext.h index 7f6ed2f67b9..8ad834271d3 100644 --- a/mozilla/extensions/transformiix/source/xpath/txSingleNodeContext.h +++ b/mozilla/extensions/transformiix/source/xpath/txSingleNodeContext.h @@ -54,7 +54,7 @@ public: {} nsresult getVariable(PRInt32 aNamespace, nsIAtom* aLName, - ExprResult*& aResult) + txAExprResult*& aResult) { NS_ASSERTION(mInner, "mInner is null!!!"); return mInner->getVariable(aNamespace, aLName, aResult); @@ -72,6 +72,12 @@ public: return mInner->getPrivateContext(); } + txResultRecycler* recycler() + { + NS_ASSERTION(mInner, "mInner is null!!!"); + return mInner->recycler(); + } + void receiveError(const nsAString& aMsg, nsresult aRes) { NS_ASSERTION(mInner, "mInner is null!!!"); diff --git a/mozilla/extensions/transformiix/source/xslt/functions/CurrentFunctionCall.cpp b/mozilla/extensions/transformiix/source/xslt/functions/CurrentFunctionCall.cpp index 58de21ff130..d2db52d26b5 100644 --- a/mozilla/extensions/transformiix/source/xslt/functions/CurrentFunctionCall.cpp +++ b/mozilla/extensions/transformiix/source/xslt/functions/CurrentFunctionCall.cpp @@ -19,18 +19,23 @@ CurrentFunctionCall::CurrentFunctionCall() * @return NodeSet containing the context node used for the complete * Expr or Pattern. */ -ExprResult* CurrentFunctionCall::evaluate(txIEvalContext* aContext) +nsresult +CurrentFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult) { + *aResult = nsnull; + + if (!requireParams(0, 0, aContext)) + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; + txExecutionState* es = NS_STATIC_CAST(txExecutionState*, aContext->getPrivateContext()); if (!es) { NS_ASSERTION(0, "called xslt extension function \"current\" with wrong context"); - // Just return an empty nodeset, this at least has the right - // result type. - return new NodeSet(); + return NS_ERROR_UNEXPECTED; } - return new NodeSet(es->getEvalContext()->getContextNode()); + return aContext->recycler()->getNodeSet( + es->getEvalContext()->getContextNode(), aResult); } nsresult CurrentFunctionCall::getNameAtom(nsIAtom** aAtom) diff --git a/mozilla/extensions/transformiix/source/xslt/functions/DocumentFunctionCall.cpp b/mozilla/extensions/transformiix/source/xslt/functions/DocumentFunctionCall.cpp index 52bb753583c..17c26a59b94 100644 --- a/mozilla/extensions/transformiix/source/xslt/functions/DocumentFunctionCall.cpp +++ b/mozilla/extensions/transformiix/source/xslt/functions/DocumentFunctionCall.cpp @@ -57,81 +57,86 @@ DocumentFunctionCall::DocumentFunctionCall(const nsAString& aBaseURI) * @param context the context node for evaluation of this Expr * @return the result of the evaluation */ -ExprResult* DocumentFunctionCall::evaluate(txIEvalContext* aContext) +nsresult +DocumentFunctionCall::evaluate(txIEvalContext* aContext, + txAExprResult** aResult) { + *aResult = nsnull; txExecutionState* es = NS_STATIC_CAST(txExecutionState*, aContext->getPrivateContext()); - NodeSet* nodeSet = new NodeSet(); - NS_ENSURE_TRUE(nodeSet, nsnull); + nsRefPtr nodeSet; + nsresult rv = aContext->recycler()->getNodeSet(getter_AddRefs(nodeSet)); + NS_ENSURE_SUCCESS(rv, rv); // document(object, node-set?) - if (requireParams(1, 2, aContext)) { - txListIterator iter(¶ms); - Expr* param1 = (Expr*)iter.next(); - ExprResult* exprResult1 = param1->evaluate(aContext); - nsAutoString baseURI; - MBool baseURISet = MB_FALSE; + if (!requireParams(1, 2, aContext)) { + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; + } - if (iter.hasNext()) { - // We have 2 arguments, get baseURI from the first node - // in the resulting nodeset - Expr* param2 = (Expr*)iter.next(); - ExprResult* exprResult2 = param2->evaluate(aContext); - if (exprResult2->getResultType() != ExprResult::NODESET) { - nsAutoString err(NS_LITERAL_STRING("node-set expected as second argument to document(): ")); - toString(err); - aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG); - delete exprResult1; - delete exprResult2; - return nodeSet; - } + txListIterator iter(¶ms); + Expr* param1 = (Expr*)iter.next(); + nsRefPtr exprResult1; + rv = param1->evaluate(aContext, getter_AddRefs(exprResult1)); + NS_ENSURE_SUCCESS(rv, rv); - // Make this true, even if nodeSet2 is empty. For relative URLs, - // we'll fail to load the document with an empty base URI, and for - // absolute URLs, the base URI doesn't matter - baseURISet = MB_TRUE; + nsAutoString baseURI; + MBool baseURISet = MB_FALSE; - NodeSet* nodeSet2 = (NodeSet*) exprResult2; - if (!nodeSet2->isEmpty()) { - nodeSet2->get(0)->getBaseURI(baseURI); - } - delete exprResult2; + if (iter.hasNext()) { + // We have 2 arguments, get baseURI from the first node + // in the resulting nodeset + nsRefPtr nodeSet2; + rv = evaluateToNodeSet(NS_STATIC_CAST(Expr*, iter.next()), + aContext, getter_AddRefs(nodeSet2)); + NS_ENSURE_SUCCESS(rv, rv); + + // Make this true, even if nodeSet2 is empty. For relative URLs, + // we'll fail to load the document with an empty base URI, and for + // absolute URLs, the base URI doesn't matter + baseURISet = MB_TRUE; + + if (!nodeSet2->isEmpty()) { + nodeSet2->get(0)->getBaseURI(baseURI); } + } - if (exprResult1->getResultType() == ExprResult::NODESET) { - // The first argument is a NodeSet, iterate on its nodes - NodeSet* nodeSet1 = (NodeSet*) exprResult1; - int i; - for (i = 0; i < nodeSet1->size(); i++) { - Node* node = nodeSet1->get(i); - nsAutoString uriStr; - XMLDOMUtils::getNodeValue(node, uriStr); - if (!baseURISet) { - // if the second argument wasn't specified, use - // the baseUri of node itself - node->getBaseURI(baseURI); - } - Node* loadNode = es->retrieveDocument(uriStr, baseURI); - if (loadNode) { - nodeSet->add(loadNode); - } - } - } - else { - // The first argument is not a NodeSet + if (exprResult1->getResultType() == txAExprResult::NODESET) { + // The first argument is a NodeSet, iterate on its nodes + NodeSet* nodeSet1 = NS_STATIC_CAST(NodeSet*, + NS_STATIC_CAST(txAExprResult*, + exprResult1)); + int i; + for (i = 0; i < nodeSet1->size(); i++) { + Node* node = nodeSet1->get(i); nsAutoString uriStr; - exprResult1->stringValue(uriStr); - nsAString* base = baseURISet ? &baseURI : &mBaseURI; - Node* loadNode = es->retrieveDocument(uriStr, *base); + XMLDOMUtils::getNodeValue(node, uriStr); + if (!baseURISet) { + // if the second argument wasn't specified, use + // the baseUri of node itself + node->getBaseURI(baseURI); + } + Node* loadNode = es->retrieveDocument(uriStr, baseURI); if (loadNode) { nodeSet->add(loadNode); } } - delete exprResult1; + } + else { + // The first argument is not a NodeSet + nsAutoString uriStr; + exprResult1->stringValue(uriStr); + nsAString* base = baseURISet ? &baseURI : &mBaseURI; + Node* loadNode = es->retrieveDocument(uriStr, *base); + if (loadNode) { + nodeSet->add(loadNode); + } } - return nodeSet; + *aResult = nodeSet; + NS_ADDREF(*aResult); + + return NS_OK; } nsresult DocumentFunctionCall::getNameAtom(nsIAtom** aAtom) diff --git a/mozilla/extensions/transformiix/source/xslt/functions/ElementAvailableFnCall.cpp b/mozilla/extensions/transformiix/source/xslt/functions/ElementAvailableFnCall.cpp index fbe9ec05506..2037dadc3ce 100644 --- a/mozilla/extensions/transformiix/source/xslt/functions/ElementAvailableFnCall.cpp +++ b/mozilla/extensions/transformiix/source/xslt/functions/ElementAvailableFnCall.cpp @@ -66,73 +66,70 @@ ElementAvailableFunctionCall::ElementAvailableFunctionCall(txNamespaceMap* aMapp * @return the result of the evaluation * @see FunctionCall.h **/ -ExprResult* ElementAvailableFunctionCall::evaluate(txIEvalContext* aContext) +nsresult +ElementAvailableFunctionCall::evaluate(txIEvalContext* aContext, + txAExprResult** aResult) { - ExprResult* result = nsnull; - - if (requireParams(1, 1, aContext)) { - txListIterator iter(¶ms); - Expr* param = (Expr*) iter.next(); - ExprResult* exprResult = param->evaluate(aContext); - if (exprResult && - exprResult->getResultType() == ExprResult::STRING) { - nsAutoString property; - exprResult->stringValue(property); - txExpandedName qname; - nsresult rv = qname.init(property, mMappings, MB_TRUE); - if (NS_SUCCEEDED(rv) && - qname.mNamespaceID == kNameSpaceID_XSLT && - (qname.mLocalName == txXSLTAtoms::applyImports || - qname.mLocalName == txXSLTAtoms::applyTemplates || - qname.mLocalName == txXSLTAtoms::attribute || - qname.mLocalName == txXSLTAtoms::attributeSet || - qname.mLocalName == txXSLTAtoms::callTemplate || - qname.mLocalName == txXSLTAtoms::choose || - qname.mLocalName == txXSLTAtoms::comment || - qname.mLocalName == txXSLTAtoms::copy || - qname.mLocalName == txXSLTAtoms::copyOf || - qname.mLocalName == txXSLTAtoms::decimalFormat || - qname.mLocalName == txXSLTAtoms::element || -// qname.mLocalName == txXSLTAtoms::fallback || - qname.mLocalName == txXSLTAtoms::forEach || - qname.mLocalName == txXSLTAtoms::_if || - qname.mLocalName == txXSLTAtoms::import || - qname.mLocalName == txXSLTAtoms::include || - qname.mLocalName == txXSLTAtoms::key || - qname.mLocalName == txXSLTAtoms::message || -// qname.mLocalName == txXSLTAtoms::namespaceAlias || - qname.mLocalName == txXSLTAtoms::number || - qname.mLocalName == txXSLTAtoms::otherwise || - qname.mLocalName == txXSLTAtoms::output || - qname.mLocalName == txXSLTAtoms::param || - qname.mLocalName == txXSLTAtoms::preserveSpace || - qname.mLocalName == txXSLTAtoms::processingInstruction || - qname.mLocalName == txXSLTAtoms::sort || - qname.mLocalName == txXSLTAtoms::stripSpace || - qname.mLocalName == txXSLTAtoms::stylesheet || - qname.mLocalName == txXSLTAtoms::_template || - qname.mLocalName == txXSLTAtoms::text || - qname.mLocalName == txXSLTAtoms::transform || - qname.mLocalName == txXSLTAtoms::valueOf || - qname.mLocalName == txXSLTAtoms::variable || - qname.mLocalName == txXSLTAtoms::when || - qname.mLocalName == txXSLTAtoms::withParam)) { - result = new BooleanResult(MB_TRUE); - } - } - else { - NS_NAMED_LITERAL_STRING(err, "Invalid argument passed to element-available(), expecting String"); - aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG); - result = new StringResult(err); - } - delete exprResult; + *aResult = nsnull; + if (!requireParams(1, 1, aContext)) { + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; } - if (!result) { - result = new BooleanResult(MB_FALSE); - } - return result; + + txListIterator iter(¶ms); + Expr* param = (Expr*) iter.next(); + + nsRefPtr exprResult; + nsresult rv = param->evaluate(aContext, getter_AddRefs(exprResult)); + NS_ENSURE_SUCCESS(rv, rv); + + nsAutoString property; + exprResult->stringValue(property); + txExpandedName qname; + rv = qname.init(property, mMappings, MB_TRUE); + NS_ENSURE_SUCCESS(rv, rv); + + PRBool val = qname.mNamespaceID == kNameSpaceID_XSLT && + (qname.mLocalName == txXSLTAtoms::applyImports || + qname.mLocalName == txXSLTAtoms::applyTemplates || + qname.mLocalName == txXSLTAtoms::attribute || + qname.mLocalName == txXSLTAtoms::attributeSet || + qname.mLocalName == txXSLTAtoms::callTemplate || + qname.mLocalName == txXSLTAtoms::choose || + qname.mLocalName == txXSLTAtoms::comment || + qname.mLocalName == txXSLTAtoms::copy || + qname.mLocalName == txXSLTAtoms::copyOf || + qname.mLocalName == txXSLTAtoms::decimalFormat || + qname.mLocalName == txXSLTAtoms::element || + //qname.mLocalName == txXSLTAtoms::fallback || + qname.mLocalName == txXSLTAtoms::forEach || + qname.mLocalName == txXSLTAtoms::_if || + qname.mLocalName == txXSLTAtoms::import || + qname.mLocalName == txXSLTAtoms::include || + qname.mLocalName == txXSLTAtoms::key || + qname.mLocalName == txXSLTAtoms::message || + //qname.mLocalName == txXSLTAtoms::namespaceAlias || + qname.mLocalName == txXSLTAtoms::number || + qname.mLocalName == txXSLTAtoms::otherwise || + qname.mLocalName == txXSLTAtoms::output || + qname.mLocalName == txXSLTAtoms::param || + qname.mLocalName == txXSLTAtoms::preserveSpace || + qname.mLocalName == txXSLTAtoms::processingInstruction || + qname.mLocalName == txXSLTAtoms::sort || + qname.mLocalName == txXSLTAtoms::stripSpace || + qname.mLocalName == txXSLTAtoms::stylesheet || + qname.mLocalName == txXSLTAtoms::_template || + qname.mLocalName == txXSLTAtoms::text || + qname.mLocalName == txXSLTAtoms::transform || + qname.mLocalName == txXSLTAtoms::valueOf || + qname.mLocalName == txXSLTAtoms::variable || + qname.mLocalName == txXSLTAtoms::when || + qname.mLocalName == txXSLTAtoms::withParam); + + aContext->recycler()->getBoolResult(val, aResult); + + return NS_OK; } nsresult ElementAvailableFunctionCall::getNameAtom(nsIAtom** aAtom) diff --git a/mozilla/extensions/transformiix/source/xslt/functions/FunctionAvailableFnCall.cpp b/mozilla/extensions/transformiix/source/xslt/functions/FunctionAvailableFnCall.cpp index 5b744da751f..bcdf930a10b 100644 --- a/mozilla/extensions/transformiix/source/xslt/functions/FunctionAvailableFnCall.cpp +++ b/mozilla/extensions/transformiix/source/xslt/functions/FunctionAvailableFnCall.cpp @@ -64,74 +64,69 @@ FunctionAvailableFunctionCall::FunctionAvailableFunctionCall(txNamespaceMap* aMa * @return the result of the evaluation * @see FunctionCall.h **/ -ExprResult* FunctionAvailableFunctionCall::evaluate(txIEvalContext* aContext) +nsresult +FunctionAvailableFunctionCall::evaluate(txIEvalContext* aContext, + txAExprResult** aResult) { - ExprResult* result = nsnull; - - if (requireParams(1, 1, aContext)) { - txListIterator iter(¶ms); - Expr* param = (Expr*)iter.next(); - ExprResult* exprResult = param->evaluate(aContext); - if (exprResult && - exprResult->getResultType() == ExprResult::STRING) { - nsAutoString property; - exprResult->stringValue(property); - txExpandedName qname; - nsresult rv = qname.init(property, mMappings, MB_FALSE); - if (NS_SUCCEEDED(rv) && - qname.mNamespaceID == kNameSpaceID_None && - (qname.mLocalName == txXPathAtoms::boolean || - qname.mLocalName == txXPathAtoms::ceiling || - qname.mLocalName == txXPathAtoms::concat || - qname.mLocalName == txXPathAtoms::contains || - qname.mLocalName == txXPathAtoms::count || - qname.mLocalName == txXPathAtoms::_false || - qname.mLocalName == txXPathAtoms::floor || - qname.mLocalName == txXPathAtoms::id || - qname.mLocalName == txXPathAtoms::lang || - qname.mLocalName == txXPathAtoms::last || - qname.mLocalName == txXPathAtoms::localName || - qname.mLocalName == txXPathAtoms::name || - qname.mLocalName == txXPathAtoms::namespaceUri || - qname.mLocalName == txXPathAtoms::normalizeSpace || - qname.mLocalName == txXPathAtoms::_not || - qname.mLocalName == txXPathAtoms::number || - qname.mLocalName == txXPathAtoms::position || - qname.mLocalName == txXPathAtoms::round || - qname.mLocalName == txXPathAtoms::startsWith || - qname.mLocalName == txXPathAtoms::string || - qname.mLocalName == txXPathAtoms::stringLength || - qname.mLocalName == txXPathAtoms::substring || - qname.mLocalName == txXPathAtoms::substringAfter || - qname.mLocalName == txXPathAtoms::substringBefore || - qname.mLocalName == txXPathAtoms::sum || - qname.mLocalName == txXPathAtoms::translate || - qname.mLocalName == txXPathAtoms::_true || - qname.mLocalName == txXSLTAtoms::current || - qname.mLocalName == txXSLTAtoms::document || - qname.mLocalName == txXSLTAtoms::elementAvailable || - qname.mLocalName == txXSLTAtoms::formatNumber || - qname.mLocalName == txXSLTAtoms::functionAvailable || - qname.mLocalName == txXSLTAtoms::generateId || - qname.mLocalName == txXSLTAtoms::key || -// qname.mLocalName == txXSLTAtoms::unparsedEntityUri || - qname.mLocalName == txXSLTAtoms::systemProperty)) { - result = new BooleanResult(MB_TRUE); - } - } - else { - NS_NAMED_LITERAL_STRING(err, "Invalid argument passed to function-available, expecting String"); - aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG); - result = new StringResult(err); - } - delete exprResult; + *aResult = nsnull; + if (!requireParams(1, 1, aContext)) { + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; } - if (!result) { - result = new BooleanResult(MB_FALSE); - } + txListIterator iter(¶ms); + Expr* param = (Expr*)iter.next(); + nsRefPtr exprResult; + nsresult rv = param->evaluate(aContext, getter_AddRefs(exprResult)); + NS_ENSURE_SUCCESS(rv, rv); + + nsAutoString property; + exprResult->stringValue(property); + txExpandedName qname; + rv = qname.init(property, mMappings, MB_FALSE); + NS_ENSURE_SUCCESS(rv, rv); + + PRBool val = qname.mNamespaceID == kNameSpaceID_None && + (qname.mLocalName == txXPathAtoms::boolean || + qname.mLocalName == txXPathAtoms::ceiling || + qname.mLocalName == txXPathAtoms::concat || + qname.mLocalName == txXPathAtoms::contains || + qname.mLocalName == txXPathAtoms::count || + qname.mLocalName == txXPathAtoms::_false || + qname.mLocalName == txXPathAtoms::floor || + qname.mLocalName == txXPathAtoms::id || + qname.mLocalName == txXPathAtoms::lang || + qname.mLocalName == txXPathAtoms::last || + qname.mLocalName == txXPathAtoms::localName || + qname.mLocalName == txXPathAtoms::name || + qname.mLocalName == txXPathAtoms::namespaceUri || + qname.mLocalName == txXPathAtoms::normalizeSpace || + qname.mLocalName == txXPathAtoms::_not || + qname.mLocalName == txXPathAtoms::number || + qname.mLocalName == txXPathAtoms::position || + qname.mLocalName == txXPathAtoms::round || + qname.mLocalName == txXPathAtoms::startsWith || + qname.mLocalName == txXPathAtoms::string || + qname.mLocalName == txXPathAtoms::stringLength || + qname.mLocalName == txXPathAtoms::substring || + qname.mLocalName == txXPathAtoms::substringAfter || + qname.mLocalName == txXPathAtoms::substringBefore || + qname.mLocalName == txXPathAtoms::sum || + qname.mLocalName == txXPathAtoms::translate || + qname.mLocalName == txXPathAtoms::_true || + qname.mLocalName == txXSLTAtoms::current || + qname.mLocalName == txXSLTAtoms::document || + qname.mLocalName == txXSLTAtoms::elementAvailable || + qname.mLocalName == txXSLTAtoms::formatNumber || + qname.mLocalName == txXSLTAtoms::functionAvailable || + qname.mLocalName == txXSLTAtoms::generateId || + qname.mLocalName == txXSLTAtoms::key || + //qname.mLocalName == txXSLTAtoms::unparsedEntityUri || + qname.mLocalName == txXSLTAtoms::systemProperty); + + aContext->recycler()->getBoolResult(val, aResult); + + return NS_OK; - return result; } nsresult FunctionAvailableFunctionCall::getNameAtom(nsIAtom** aAtom) diff --git a/mozilla/extensions/transformiix/source/xslt/functions/GenerateIdFunctionCall.cpp b/mozilla/extensions/transformiix/source/xslt/functions/GenerateIdFunctionCall.cpp index 2d23c5f929e..6584bf99f9c 100644 --- a/mozilla/extensions/transformiix/source/xslt/functions/GenerateIdFunctionCall.cpp +++ b/mozilla/extensions/transformiix/source/xslt/functions/GenerateIdFunctionCall.cpp @@ -53,10 +53,13 @@ GenerateIdFunctionCall::GenerateIdFunctionCall() * @return the result of the evaluation * @see FunctionCall.h **/ -ExprResult* GenerateIdFunctionCall::evaluate(txIEvalContext* aContext) +nsresult +GenerateIdFunctionCall::evaluate(txIEvalContext* aContext, + txAExprResult** aResult) { + *aResult = nsnull; if (!requireParams(0, 1, aContext)) - return new StringResult(); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; Node* node = 0; @@ -65,24 +68,26 @@ ExprResult* GenerateIdFunctionCall::evaluate(txIEvalContext* aContext) txListIterator iter(¶ms); Expr* param = (Expr*)iter.next(); - ExprResult* exprResult = param->evaluate(aContext); - if (!exprResult) - return 0; + nsRefPtr exprResult; + nsresult rv = param->evaluate(aContext, getter_AddRefs(exprResult)); + NS_ENSURE_SUCCESS(rv, rv); - if (exprResult->getResultType() != ExprResult::NODESET) { + if (exprResult->getResultType() != txAExprResult::NODESET) { NS_NAMED_LITERAL_STRING(err, "Invalid argument passed to generate-id(), expecting NodeSet"); - aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG); - delete exprResult; - return new StringResult(err); + aContext->receiveError(err, NS_ERROR_XSLT_NODESET_EXPECTED); + return NS_ERROR_XSLT_NODESET_EXPECTED; } - NodeSet* nodes = (NodeSet*) exprResult; - if (nodes->isEmpty()) - return new StringResult(); + NodeSet* nodes = NS_STATIC_CAST(NodeSet*, + NS_STATIC_CAST(txAExprResult*, + exprResult)); + if (nodes->isEmpty()) { + aContext->recycler()->getEmptyStringResult(aResult); + + return NS_OK; + } node = nodes->get(0); - - delete exprResult; } else { node = aContext->getContextNode(); @@ -91,7 +96,8 @@ ExprResult* GenerateIdFunctionCall::evaluate(txIEvalContext* aContext) // generate id for selected node char buf[22]; PR_snprintf(buf, 21, printfFmt, node); - return new StringResult(NS_ConvertASCIItoUCS2(buf)); + return aContext->recycler()->getStringResult(NS_ConvertASCIItoUCS2(buf), + aResult); } nsresult GenerateIdFunctionCall::getNameAtom(nsIAtom** aAtom) diff --git a/mozilla/extensions/transformiix/source/xslt/functions/SystemPropertyFunctionCall.cpp b/mozilla/extensions/transformiix/source/xslt/functions/SystemPropertyFunctionCall.cpp index 3232362a254..6b759aa2627 100644 --- a/mozilla/extensions/transformiix/source/xslt/functions/SystemPropertyFunctionCall.cpp +++ b/mozilla/extensions/transformiix/source/xslt/functions/SystemPropertyFunctionCall.cpp @@ -27,43 +27,46 @@ SystemPropertyFunctionCall::SystemPropertyFunctionCall(txNamespaceMap* aMappings * @return the result of the evaluation * @see FunctionCall.h **/ -ExprResult* SystemPropertyFunctionCall::evaluate(txIEvalContext* aContext) +nsresult +SystemPropertyFunctionCall::evaluate(txIEvalContext* aContext, + txAExprResult** aResult) { - ExprResult* result = nsnull; + *aResult = nsnull; - if (requireParams(1, 1, aContext)) { - txListIterator iter(¶ms); - Expr* param = (Expr*)iter.next(); - ExprResult* exprResult = param->evaluate(aContext); - if (exprResult->getResultType() == ExprResult::STRING) { - nsAutoString property; - exprResult->stringValue(property); - txExpandedName qname; - nsresult rv = qname.init(property, mMappings, MB_TRUE); - if (NS_SUCCEEDED(rv) && - qname.mNamespaceID == kNameSpaceID_XSLT) { - if (qname.mLocalName == txXSLTAtoms::version) { - result = new NumberResult(1.0); - } - else if (qname.mLocalName == txXSLTAtoms::vendor) { - result = new StringResult(NS_LITERAL_STRING("Transformiix")); - } - else if (qname.mLocalName == txXSLTAtoms::vendorUrl) { - result = new StringResult(NS_LITERAL_STRING("http://www.mozilla.org/projects/xslt/")); - } - } - } - else { - NS_NAMED_LITERAL_STRING(err, "Invalid argument passed to system-property(), expecting String"); - aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG); - result = new StringResult(err); - } + if (!requireParams(1, 1, aContext)) { + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; } - if (!result) { - result = new StringResult(); + txListIterator iter(¶ms); + Expr* param = (Expr*)iter.next(); + nsRefPtr exprResult; + nsresult rv = param->evaluate(aContext, getter_AddRefs(exprResult)); + NS_ENSURE_SUCCESS(rv, rv); + + nsAutoString property; + exprResult->stringValue(property); + txExpandedName qname; + rv = qname.init(property, mMappings, MB_TRUE); + NS_ENSURE_SUCCESS(rv, rv); + + if (qname.mNamespaceID == kNameSpaceID_XSLT) { + if (qname.mLocalName == txXSLTAtoms::version) { + return aContext->recycler()->getNumberResult(1.0, aResult); + } + if (qname.mLocalName == txXSLTAtoms::vendor) { + return aContext->recycler()->getStringResult( + NS_LITERAL_STRING("Transformiix"), aResult); + } + if (qname.mLocalName == txXSLTAtoms::vendorUrl) { + return aContext->recycler()->getStringResult( + NS_LITERAL_STRING("http://www.mozilla.org/projects/xslt/"), + aResult); + } } - return result; + aContext->recycler()->getEmptyStringResult(aResult); + + return NS_OK; + } nsresult SystemPropertyFunctionCall::getNameAtom(nsIAtom** aAtom) diff --git a/mozilla/extensions/transformiix/source/xslt/functions/txFormatNumberFunctionCall.cpp b/mozilla/extensions/transformiix/source/xslt/functions/txFormatNumberFunctionCall.cpp index c94c1f8eb58..edeb651faa0 100644 --- a/mozilla/extensions/transformiix/source/xslt/functions/txFormatNumberFunctionCall.cpp +++ b/mozilla/extensions/transformiix/source/xslt/functions/txFormatNumberFunctionCall.cpp @@ -74,11 +74,14 @@ txFormatNumberFunctionCall::txFormatNumberFunctionCall(txStylesheet* aStylesheet * for evaluation * @return the result of the evaluation */ -ExprResult* txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext) +nsresult +txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext, + txAExprResult** aResult) { nsresult rv = NS_OK; + *aResult = nsnull; if (!requireParams(2, 3, aContext)) - return new StringResult(); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; // Get number and format txListIterator iter(¶ms); @@ -93,8 +96,7 @@ ExprResult* txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext) nsAutoString formatQName; evaluateToString((Expr*)iter.next(), aContext, formatQName); rv = formatName.init(formatQName, mMappings, MB_FALSE); - if (NS_FAILED(rv)) - formatName.mNamespaceID = kNameSpaceID_Unknown; + NS_ENSURE_SUCCESS(rv, rv); } txDecimalFormat* format = mStylesheet->getDecimalFormat(formatName); @@ -102,21 +104,24 @@ ExprResult* txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext) nsAutoString err(NS_LITERAL_STRING("unknown decimal format for: ")); toString(err); aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG); - return new StringResult(err); + return NS_ERROR_XPATH_INVALID_ARG; } // Special cases - if (Double::isNaN(value)) - return new StringResult(format->mNaN); + if (Double::isNaN(value)) { + return aContext->recycler()->getStringResult(format->mNaN, aResult); + } - if (value == Double::POSITIVE_INFINITY) - return new StringResult(format->mInfinity); + if (value == Double::POSITIVE_INFINITY) { + return aContext->recycler()->getStringResult(format->mInfinity, + aResult); + } if (value == Double::NEGATIVE_INFINITY) { nsAutoString res; res.Append(format->mMinusSign); res.Append(format->mInfinity); - return new StringResult(res); + return aContext->recycler()->getStringResult(res, aResult); } // Value is a normal finite number @@ -172,7 +177,7 @@ ExprResult* txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext) toString(err); aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG); - return new StringResult(err); + return NS_ERROR_XPATH_INVALID_ARG; } } else if (c == format->mPerMille) { @@ -183,7 +188,7 @@ ExprResult* txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext) toString(err); aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG); - return new StringResult(err); + return NS_ERROR_XPATH_INVALID_ARG; } } else if (c == format->mDecimalSeparator || @@ -266,9 +271,8 @@ ExprResult* txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext) groupSize == 0) { nsAutoString err(INVALID_PARAM_VALUE); toString(err); - aContext->receiveError(err, - NS_ERROR_XPATH_INVALID_ARG); - return new StringResult(err); + aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG); + return NS_ERROR_XPATH_INVALID_ARG; } @@ -289,10 +293,7 @@ ExprResult* txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext) bufsize = 1 + 30; char* buf = new char[bufsize]; - if (!buf) { - //XXX ErrorReport: out of memory - return new StringResult; - } + NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY); PRIntn bufIntDigits, sign; char* endp; @@ -391,7 +392,7 @@ ExprResult* txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext) // Build suffix res.Append(suffix); - return new StringResult(res); + return aContext->recycler()->getStringResult(res, aResult); } //-- evaluate nsresult txFormatNumberFunctionCall::getNameAtom(nsIAtom** aAtom) diff --git a/mozilla/extensions/transformiix/source/xslt/functions/txKey.h b/mozilla/extensions/transformiix/source/xslt/functions/txKey.h index a2d3906a028..0c5b95f2e35 100644 --- a/mozilla/extensions/transformiix/source/xslt/functions/txKey.h +++ b/mozilla/extensions/transformiix/source/xslt/functions/txKey.h @@ -69,7 +69,8 @@ public: struct txKeyValueHashEntry : public PLDHashEntryHdr { txKeyValueHashEntry(const void* aKey) - : mKey(*NS_STATIC_CAST(const txKeyValueHashKey*, aKey)) + : mKey(*NS_STATIC_CAST(const txKeyValueHashKey*, aKey)), + mNodeSet(new NodeSet(nsnull)) { } @@ -79,7 +80,7 @@ struct txKeyValueHashEntry : public PLDHashEntryHdr static PLDHashNumber HashKey(const void* aKey); txKeyValueHashKey mKey; - NodeSet mNodeSet; + nsRefPtr mNodeSet; }; DECL_DHASH_WRAPPER(txKeyValueHash, txKeyValueHashEntry, txKeyValueHashKey&); @@ -206,7 +207,7 @@ public: const nsAString& aKeyValue, PRBool aIndexIfNotFound, txExecutionState& aEs, - const NodeSet** aResult); + NodeSet** aResult); private: // Hash of all indexed key-values @@ -217,6 +218,9 @@ private: // Map of txXSLKeys const txExpandedNameMap& mKeys; + + // Empty nodeset returned if no key is found + nsRefPtr mEmptyNodeSet; }; diff --git a/mozilla/extensions/transformiix/source/xslt/functions/txKeyFunctionCall.cpp b/mozilla/extensions/transformiix/source/xslt/functions/txKeyFunctionCall.cpp index 3465c473efa..fd6b4a24b5a 100644 --- a/mozilla/extensions/transformiix/source/xslt/functions/txKeyFunctionCall.cpp +++ b/mozilla/extensions/transformiix/source/xslt/functions/txKeyFunctionCall.cpp @@ -49,34 +49,26 @@ txKeyFunctionCall::txKeyFunctionCall(txNamespaceMap* aMappings) * for evaluation * @return the result of the evaluation */ -ExprResult* txKeyFunctionCall::evaluate(txIEvalContext* aContext) +nsresult +txKeyFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult) { if (!aContext || !requireParams(2, 2, aContext)) - return new StringResult(NS_LITERAL_STRING("error")); + return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; txExecutionState* es = NS_STATIC_CAST(txExecutionState*, aContext->getPrivateContext()); - NodeSet* res = new NodeSet; - if (!res) { - // ErrorReport: out of memory - return 0; - } - txListIterator iter(¶ms); nsAutoString keyQName; evaluateToString((Expr*)iter.next(), aContext, keyQName); txExpandedName keyName; nsresult rv = keyName.init(keyQName, mMappings, PR_FALSE); - if (NS_FAILED(rv)) { - delete res; - return new StringResult(NS_LITERAL_STRING("error")); - } + NS_ENSURE_SUCCESS(rv, rv); - ExprResult* exprResult = ((Expr*)iter.next())->evaluate(aContext); - if (!exprResult) - return res; + nsRefPtr exprResult; + rv = ((Expr*)iter.next())->evaluate(aContext, getter_AddRefs(exprResult)); + NS_ENSURE_SUCCESS(rv, rv); Document* contextDoc; Node* contextNode = aContext->getContextNode(); @@ -85,40 +77,40 @@ ExprResult* txKeyFunctionCall::evaluate(txIEvalContext* aContext) else contextDoc = contextNode->getOwnerDocument(); - if (exprResult->getResultType() == ExprResult::NODESET) { - NodeSet* nodeSet = (NodeSet*) exprResult; + nsRefPtr res; + NodeSet* nodeSet; + if (exprResult->getResultType() == txAExprResult::NODESET && + (nodeSet = NS_STATIC_CAST(NodeSet*, + NS_STATIC_CAST(txAExprResult*, + exprResult)))->size() > 1) { + rv = aContext->recycler()->getNodeSet(getter_AddRefs(res)); + NS_ENSURE_SUCCESS(rv, rv); + int i; for (i = 0; i < nodeSet->size(); ++i) { nsAutoString val; XMLDOMUtils::getNodeValue(nodeSet->get(i), val); - const NodeSet* nodes = 0; - rv = es->getKeyNodes(keyName, contextDoc, val, i == 0, &nodes); - if (NS_FAILED(rv)) { - delete res; - delete exprResult; - return new StringResult(NS_LITERAL_STRING("error")); - } - if (nodes) { - res->add(nodes); - } + nsRefPtr nodes; + rv = es->getKeyNodes(keyName, contextDoc, val, i == 0, + getter_AddRefs(nodes)); + NS_ENSURE_SUCCESS(rv, rv); + + res->add(nodes); } } else { nsAutoString val; exprResult->stringValue(val); const NodeSet* nodes = 0; - rv = es->getKeyNodes(keyName, contextDoc, val, PR_TRUE, &nodes); - if (NS_FAILED(rv)) { - delete res; - delete exprResult; - return new StringResult(NS_LITERAL_STRING("error")); - } - if (nodes) { - res->append(nodes); - } + rv = es->getKeyNodes(keyName, contextDoc, val, PR_TRUE, + getter_AddRefs(res)); + NS_ENSURE_SUCCESS(rv, rv); } - delete exprResult; - return res; + + *aResult = res; + NS_ADDREF(*aResult); + + return NS_OK; } nsresult txKeyFunctionCall::getNameAtom(nsIAtom** aAtom) @@ -201,7 +193,7 @@ txKeyHash::getKeyNodes(const txExpandedName& aKeyName, const nsAString& aKeyValue, PRBool aIndexIfNotFound, txExecutionState& aEs, - const NodeSet** aResult) + NodeSet** aResult) { NS_ENSURE_TRUE(mKeyValues.mHashTable.ops && mIndexedKeys.mHashTable.ops, NS_ERROR_OUT_OF_MEMORY); @@ -210,7 +202,8 @@ txKeyHash::getKeyNodes(const txExpandedName& aKeyName, txKeyValueHashKey valueKey(aKeyName, aDocument, aKeyValue); txKeyValueHashEntry* valueEntry = mKeyValues.GetEntry(valueKey); if (valueEntry) { - *aResult = &valueEntry->mNodeSet; + *aResult = valueEntry->mNodeSet; + NS_ADDREF(*aResult); return NS_OK; } @@ -221,6 +214,8 @@ txKeyHash::getKeyNodes(const txExpandedName& aKeyName, if (!aIndexIfNotFound) { // If aIndexIfNotFound is set then the caller knows this key is // indexed, so don't bother investigating. + *aResult = mEmptyNodeSet; + NS_ADDREF(*aResult); return NS_OK; } @@ -230,8 +225,9 @@ txKeyHash::getKeyNodes(const txExpandedName& aKeyName, if (indexEntry->mIndexed) { // The key was indexed and apparently didn't contain this value so - // return null. - + // return the empty nodeset. + *aResult = mEmptyNodeSet; + NS_ADDREF(*aResult); return NS_OK; } @@ -250,7 +246,12 @@ txKeyHash::getKeyNodes(const txExpandedName& aKeyName, // Now that the key is indexed we can get its value. valueEntry = mKeyValues.GetEntry(valueKey); if (valueEntry) { - *aResult = &valueEntry->mNodeSet; + *aResult = valueEntry->mNodeSet; + NS_ADDREF(*aResult); + } + else { + *aResult = mEmptyNodeSet; + NS_ADDREF(*aResult); } return NS_OK; @@ -262,7 +263,13 @@ txKeyHash::init() nsresult rv = mKeyValues.Init(8); NS_ENSURE_SUCCESS(rv, rv); - return mIndexedKeys.Init(1); + rv = mIndexedKeys.Init(1); + NS_ENSURE_SUCCESS(rv, rv); + + mEmptyNodeSet = new NodeSet(nsnull); + NS_ENSURE_TRUE(mEmptyNodeSet, NS_ERROR_OUT_OF_MEMORY); + + return NS_OK; } /** @@ -374,23 +381,30 @@ nsresult txXSLKey::testNode(Node* aNode, txKeyValueHashKey& aKey, rv = aEs.pushEvalContext(&evalContext); NS_ENSURE_SUCCESS(rv, rv); - ExprResult* exprResult = key->useExpr->evaluate(&evalContext); + nsRefPtr exprResult; + rv = key->useExpr->evaluate(&evalContext, + getter_AddRefs(exprResult)); + NS_ENSURE_SUCCESS(rv, rv); + aEs.popEvalContext(); - if (exprResult->getResultType() == ExprResult::NODESET) { - NodeSet* res = (NodeSet*)exprResult; + if (exprResult->getResultType() == txAExprResult::NODESET) { + NodeSet* res = NS_STATIC_CAST(NodeSet*, + NS_STATIC_CAST(txAExprResult*, + exprResult)); for (int i=0; isize(); i++) { val.Truncate(); XMLDOMUtils::getNodeValue(res->get(i), val); aKey.mKeyValue.Assign(val); txKeyValueHashEntry* entry = aKeyValueHash.AddEntry(aKey); - NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY); + NS_ENSURE_TRUE(entry && entry->mNodeSet, + NS_ERROR_OUT_OF_MEMORY); - if (entry->mNodeSet.isEmpty() || - entry->mNodeSet.get(entry->mNodeSet.size() - 1) != + if (entry->mNodeSet->isEmpty() || + entry->mNodeSet->get(entry->mNodeSet->size() - 1) != aNode) { - entry->mNodeSet.append(aNode); + entry->mNodeSet->append(aNode); } } } @@ -399,15 +413,15 @@ nsresult txXSLKey::testNode(Node* aNode, txKeyValueHashKey& aKey, aKey.mKeyValue.Assign(val); txKeyValueHashEntry* entry = aKeyValueHash.AddEntry(aKey); - NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY); + NS_ENSURE_TRUE(entry && entry->mNodeSet, + NS_ERROR_OUT_OF_MEMORY); - if (entry->mNodeSet.isEmpty() || - entry->mNodeSet.get(entry->mNodeSet.size()-1) != + if (entry->mNodeSet->isEmpty() || + entry->mNodeSet->get(entry->mNodeSet->size() - 1) != aNode) { - entry->mNodeSet.append(aNode); + entry->mNodeSet->append(aNode); } } - delete exprResult; } } diff --git a/mozilla/extensions/transformiix/source/xslt/txBufferingHandler.h b/mozilla/extensions/transformiix/source/xslt/txBufferingHandler.h index 6b5bc96672d..0340681a4d3 100644 --- a/mozilla/extensions/transformiix/source/xslt/txBufferingHandler.h +++ b/mozilla/extensions/transformiix/source/xslt/txBufferingHandler.h @@ -53,20 +53,6 @@ class txResultBuffer public: ~txResultBuffer(); - nsrefcnt AddRef() - { - return ++mRefCnt; - } - nsrefcnt Release() - { - if (--mRefCnt == 0) { - mRefCnt = 1; //stabilize - delete this; - return 0; - } - return mRefCnt; - } - nsresult addTransaction(txOutputTransaction* aTransaction); nsresult flushToHandler(txAXMLEventHandler* aHandler); txOutputTransaction* getLastTransaction(); @@ -75,7 +61,6 @@ public: private: nsVoidArray mTransactions; - nsAutoRefCnt mRefCnt; }; class txBufferingHandler : public txAXMLEventHandler @@ -87,7 +72,7 @@ public: TX_DECL_TXAXMLEVENTHANDLER protected: - nsRefPtr mBuffer; + nsAutoPtr mBuffer; PRPackedBool mCanAddAttribute; }; diff --git a/mozilla/extensions/transformiix/source/xslt/txExecutionState.cpp b/mozilla/extensions/transformiix/source/xslt/txExecutionState.cpp index 07d86a56319..414b9685b48 100644 --- a/mozilla/extensions/transformiix/source/xslt/txExecutionState.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txExecutionState.cpp @@ -103,8 +103,7 @@ Document* txLoadedDocumentsHash::Get(const nsAString& aURI) } txExecutionState::txExecutionState(txStylesheet* aStylesheet) - : mTemplateParams(nsnull), - mStylesheet(aStylesheet), + : mStylesheet(aStylesheet), mNextInstruction(nsnull), mLocalVariables(nsnull), mRecursionDepth(0), @@ -125,7 +124,6 @@ txExecutionState::~txExecutionState() delete mLocalVariables; delete mEvalContext; delete mRTFDocument; - delete mTemplateParams; PRInt32 i; for (i = 0; i < mTemplateRuleCount; ++i) { @@ -205,9 +203,15 @@ txExecutionState::init(Node* aNode, rv = mKeyHash.init(); NS_ENSURE_SUCCESS(rv, rv); + mRecycler = new txResultRecycler; + NS_ENSURE_TRUE(mRecycler, NS_ERROR_OUT_OF_MEMORY); + + rv = mRecycler->init(); + NS_ENSURE_SUCCESS(rv, rv); + // The actual value here doesn't really matter since noone should use this // value. But lets put something errorlike in just in case - mGlobalVarPlaceholderValue = new StringResult(NS_LITERAL_STRING("Error")); + mGlobalVarPlaceholderValue = new StringResult(NS_LITERAL_STRING("Error"), nsnull); NS_ENSURE_TRUE(mGlobalVarPlaceholderValue, NS_ERROR_OUT_OF_MEMORY); return NS_OK; @@ -226,25 +230,25 @@ txExecutionState::end() nsresult txExecutionState::getVariable(PRInt32 aNamespace, nsIAtom* aLName, - ExprResult*& aResult) + txAExprResult*& aResult) { nsresult rv = NS_OK; txExpandedName name(aNamespace, aLName); // look for a local variable if (mLocalVariables) { - aResult = mLocalVariables->getVariable(name); + mLocalVariables->getVariable(name, &aResult); if (aResult) { return NS_OK; } } // look for an evaluated global variable - aResult = mGlobalVariableValues.getVariable(name); + mGlobalVariableValues.getVariable(name, &aResult); if (aResult) { if (aResult == mGlobalVarPlaceholderValue) { // XXX ErrorReport: cyclic variable-value - aResult = nsnull; + NS_RELEASE(aResult); return NS_ERROR_XSLT_BAD_RECURSION; } return NS_OK; @@ -269,9 +273,9 @@ txExecutionState::getVariable(PRInt32 aNamespace, nsIAtom* aLName, rv = param->getValue(&aResult); NS_ENSURE_SUCCESS(rv, rv); - rv = mGlobalVariableValues.bindVariable(name, aResult, PR_FALSE); + rv = mGlobalVariableValues.bindVariable(name, aResult); if (NS_FAILED(rv)) { - aResult = nsnull; + NS_RELEASE(aResult); return rv; } @@ -280,8 +284,7 @@ txExecutionState::getVariable(PRInt32 aNamespace, nsIAtom* aLName, } // Insert a placeholdervalue to protect against recursion - rv = mGlobalVariableValues.bindVariable(name, mGlobalVarPlaceholderValue, - PR_FALSE); + rv = mGlobalVariableValues.bindVariable(name, mGlobalVarPlaceholderValue); NS_ENSURE_SUCCESS(rv, rv); // evaluate the global variable @@ -289,8 +292,8 @@ txExecutionState::getVariable(PRInt32 aNamespace, nsIAtom* aLName, if (var->mExpr) { txVariableMap* oldVars = mLocalVariables; mLocalVariables = nsnull; - aResult = var->mExpr->evaluate(getEvalContext()); - NS_ENSURE_TRUE(aResult, NS_ERROR_FAILURE); + rv = var->mExpr->evaluate(getEvalContext(), &aResult); + NS_ENSURE_SUCCESS(rv, rv); mLocalVariables = oldVars; } @@ -319,17 +322,17 @@ txExecutionState::getVariable(PRInt32 aNamespace, nsIAtom* aLName, mNextInstruction = prevInstr; rtfHandler = (txRtfHandler*)popResultHandler(); - aResult = rtfHandler->createRTF(); - NS_ENSURE_TRUE(aResult, NS_ERROR_OUT_OF_MEMORY); + rv = rtfHandler->getAsRTF(&aResult); + NS_ENSURE_SUCCESS(rv, rv); } popEvalContext(); // Remove the placeholder and insert the calculated value mGlobalVariableValues.removeVariable(name); - rv = mGlobalVariableValues.bindVariable(name, aResult, PR_TRUE); + rv = mGlobalVariableValues.bindVariable(name, aResult); if (NS_FAILED(rv)) { - delete aResult; - aResult = nsnull; + NS_RELEASE(aResult); + return rv; } @@ -348,6 +351,12 @@ txExecutionState::getPrivateContext() return this; } +txResultRecycler* +txExecutionState::recycler() +{ + return mRecycler; +} + void txExecutionState::receiveError(const nsAString& aMsg, nsresult aRes) { @@ -428,7 +437,7 @@ txExecutionState::popResultHandler() nsresult txExecutionState::pushTemplateRule(txStylesheet::ImportFrame* aFrame, const txExpandedName& aMode, - txExpandedNameMap* aParams) + txVariableMap* aParams) { if (mTemplateRuleCount == mTemplateRulesBufferSize) { PRInt32 newSize = @@ -467,12 +476,6 @@ txExecutionState::getEvalContext() return mEvalContext; } -txExpandedNameMap* -txExecutionState::getParamMap() -{ - return mTemplateParams; -} - Node* txExecutionState::retrieveDocument(const nsAString& uri, const nsAString& baseUri) @@ -538,7 +541,7 @@ txExecutionState::getKeyNodes(const txExpandedName& aKeyName, Document* aDocument, const nsAString& aKeyValue, PRBool aIndexIfNotFound, - const NodeSet** aResult) + NodeSet** aResult) { return mKeyHash.getKeyNodes(aKeyName, aDocument, aKeyValue, aIndexIfNotFound, *this, aResult); @@ -598,13 +601,13 @@ txExecutionState::returnFromTemplate() nsresult txExecutionState::bindVariable(const txExpandedName& aName, - ExprResult* aValue, MBool aOwned) + txAExprResult* aValue) { if (!mLocalVariables) { mLocalVariables = new txVariableMap; NS_ENSURE_TRUE(mLocalVariables, NS_ERROR_OUT_OF_MEMORY); } - return mLocalVariables->bindVariable(aName, aValue, aOwned); + return mLocalVariables->bindVariable(aName, aValue); } void @@ -614,21 +617,22 @@ txExecutionState::removeVariable(const txExpandedName& aName) } nsresult -txExecutionState::pushParamMap(txExpandedNameMap* aParams) +txExecutionState::pushParamMap(txVariableMap* aParams) { nsresult rv = mParamStack.push(mTemplateParams); NS_ENSURE_SUCCESS(rv, rv); + mTemplateParams.forget(); mTemplateParams = aParams; return NS_OK; } -txExpandedNameMap* +txVariableMap* txExecutionState::popParamMap() { - txExpandedNameMap* oldParams = mTemplateParams; - mTemplateParams = (txExpandedNameMap*)mParamStack.pop(); + txVariableMap* oldParams = mTemplateParams.forget(); + mTemplateParams = (txVariableMap*)mParamStack.pop(); return oldParams; } diff --git a/mozilla/extensions/transformiix/source/xslt/txExecutionState.h b/mozilla/extensions/transformiix/source/xslt/txExecutionState.h index ea3c54548ad..147e2acba34 100644 --- a/mozilla/extensions/transformiix/source/xslt/txExecutionState.h +++ b/mozilla/extensions/transformiix/source/xslt/txExecutionState.h @@ -101,7 +101,7 @@ public: txStylesheet::ImportFrame* mFrame; PRInt32 mModeNsId; nsIAtom* mModeLocalName; - txExpandedNameMap* mParams; + txVariableMap* mParams; }; // Stack functions @@ -115,10 +115,10 @@ public: txAXMLEventHandler* popResultHandler(); nsresult pushTemplateRule(txStylesheet::ImportFrame* aFrame, const txExpandedName& aMode, - txExpandedNameMap* aParams); + txVariableMap* aParams); void popTemplateRule(); - nsresult pushParamMap(txExpandedNameMap* aParams); - txExpandedNameMap* popParamMap(); + nsresult pushParamMap(txVariableMap* aParams); + txVariableMap* popParamMap(); // state-getting functions txIEvalContext* getEvalContext(); @@ -126,7 +126,7 @@ public: Node* retrieveDocument(const nsAString& uri, const nsAString& baseUri); nsresult getKeyNodes(const txExpandedName& aKeyName, Document* aDocument, const nsAString& aKeyValue, PRBool aIndexIfNotFound, - const NodeSet** aResult); + NodeSet** aResult); TemplateRule* getCurrentTemplateRule(); // state-modification functions @@ -137,14 +137,14 @@ public: void gotoInstruction(txInstruction* aNext); void returnFromTemplate(); nsresult bindVariable(const txExpandedName& aName, - ExprResult* aValue, MBool aOwned); + txAExprResult* aValue); void removeVariable(const txExpandedName& aName); txAXMLEventHandler* mOutputHandler; txAXMLEventHandler* mResultHandler; txAOutputHandlerFactory* mOutputHandlerFactory; - txExpandedNameMap* mTemplateParams; + nsAutoPtr mTemplateParams; nsRefPtr mStylesheet; @@ -159,7 +159,7 @@ private: txInstruction* mNextInstruction; txVariableMap* mLocalVariables; txVariableMap mGlobalVariableValues; - nsAutoPtr mGlobalVarPlaceholderValue; + nsRefPtr mGlobalVarPlaceholderValue; PRInt32 mRecursionDepth; TemplateRule* mTemplateRules; @@ -173,6 +173,7 @@ private: txLoadedDocumentsHash mLoadedDocuments; txKeyHash mKeyHash; + nsRefPtr mRecycler; static const PRInt32 kMaxRecursionDepth; }; diff --git a/mozilla/extensions/transformiix/source/xslt/txInstructions.cpp b/mozilla/extensions/transformiix/source/xslt/txInstructions.cpp index a267b06aa1e..1118cd325ed 100644 --- a/mozilla/extensions/transformiix/source/xslt/txInstructions.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txInstructions.cpp @@ -134,14 +134,13 @@ txAttribute::txAttribute(nsAutoPtr aName, nsAutoPtr aNamespace, nsresult txAttribute::execute(txExecutionState& aEs) { - nsresult rv = NS_OK; - - ExprResult* exprRes = mName->evaluate(aEs.getEvalContext()); - NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE); + nsRefPtr exprRes; + nsresult rv = mName->evaluate(aEs.getEvalContext(), + getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); nsAutoString name; exprRes->stringValue(name); - delete exprRes; if (!XMLUtils::isValidQName(name) || TX_StringEqualsAtom(name, txXMLAtoms::xmlns)) { @@ -155,12 +154,12 @@ txAttribute::execute(txExecutionState& aEs) PRInt32 nsId = kNameSpaceID_None; if (!name.IsEmpty()) { if (mNamespace) { - exprRes = mNamespace->evaluate(aEs.getEvalContext()); - NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE); + rv = mNamespace->evaluate(aEs.getEvalContext(), + getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); nsAutoString nspace; exprRes->stringValue(nspace); - delete exprRes; if (!nspace.IsEmpty()) { #ifdef TX_EXE @@ -186,13 +185,12 @@ txAttribute::execute(txExecutionState& aEs) name.Cut(0, 6); } - txTextHandler* handler = - NS_STATIC_CAST(txTextHandler*, aEs.popResultHandler()); + nsAutoPtr handler( + NS_STATIC_CAST(txTextHandler*, aEs.popResultHandler())); if (!name.IsEmpty()) { // add attribute if everything was ok aEs.mResultHandler->attribute(name, nsId, handler->mValue); } - delete handler; return NS_OK; } @@ -224,10 +222,10 @@ txCheckParam::execute(txExecutionState& aEs) { nsresult rv = NS_OK; if (aEs.mTemplateParams) { - ExprResult* exprRes = - NS_STATIC_CAST(ExprResult*, aEs.mTemplateParams->get(mName)); + nsRefPtr exprRes; + aEs.mTemplateParams->getVariable(mName, getter_AddRefs(exprRes)); if (exprRes) { - rv = aEs.bindVariable(mName, exprRes, MB_FALSE); + rv = aEs.bindVariable(mName, exprRes); NS_ENSURE_SUCCESS(rv, rv); aEs.gotoInstruction(mBailTarget); @@ -247,13 +245,14 @@ txConditionalGoto::txConditionalGoto(nsAutoPtr aCondition, nsresult txConditionalGoto::execute(txExecutionState& aEs) { - ExprResult* exprRes = mCondition->evaluate(aEs.getEvalContext()); - NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE); + nsRefPtr exprRes; + nsresult rv = mCondition->evaluate(aEs.getEvalContext(), + getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); if (!exprRes->booleanValue()) { aEs.gotoInstruction(mTarget); } - delete exprRes; return NS_OK; } @@ -261,8 +260,8 @@ txConditionalGoto::execute(txExecutionState& aEs) nsresult txComment::execute(txExecutionState& aEs) { - txTextHandler* handler = - NS_STATIC_CAST(txTextHandler*, aEs.popResultHandler()); + nsAutoPtr handler( + NS_STATIC_CAST(txTextHandler*, aEs.popResultHandler())); PRUint32 length = handler->mValue.Length(); PRInt32 pos = 0; while ((pos = handler->mValue.FindChar('-', (PRUint32)pos)) != kNotFound) { @@ -274,7 +273,6 @@ txComment::execute(txExecutionState& aEs) } aEs.mResultHandler->comment(handler->mValue); - delete handler; return NS_OK; } @@ -428,34 +426,33 @@ txCopyOf::txCopyOf(nsAutoPtr aSelect) nsresult txCopyOf::execute(txExecutionState& aEs) { - nsresult rv = NS_OK; - ExprResult* exprRes = mSelect->evaluate(aEs.getEvalContext()); - NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE); + nsRefPtr exprRes; + nsresult rv = mSelect->evaluate(aEs.getEvalContext(), + getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); switch (exprRes->getResultType()) { - case ExprResult::NODESET: + case txAExprResult::NODESET: { - NodeSet* nodes = NS_STATIC_CAST(NodeSet*, exprRes); + NodeSet* nodes = NS_STATIC_CAST(NodeSet*, + NS_STATIC_CAST(txAExprResult*, + exprRes)); int i; for (i = 0; i < nodes->size(); ++i) { Node* node = nodes->get(i); rv = copyNode(node, aEs); - if (NS_FAILED(rv)) { - delete exprRes; - return rv; - } + NS_ENSURE_SUCCESS(rv, rv); } break; } - case ExprResult::RESULT_TREE_FRAGMENT: + case txAExprResult::RESULT_TREE_FRAGMENT: { - txResultTreeFragment* rtf = NS_STATIC_CAST(txResultTreeFragment*, - exprRes); + txResultTreeFragment* rtf = + NS_STATIC_CAST(txResultTreeFragment*, + NS_STATIC_CAST(txAExprResult*, exprRes)); rv = rtf->flushToHandler(aEs.mResultHandler); - if (NS_FAILED(rv)) { - delete exprRes; - return rv; - } + NS_ENSURE_SUCCESS(rv, rv); + break; } default: @@ -469,8 +466,6 @@ txCopyOf::execute(txExecutionState& aEs) } } - delete exprRes; - return NS_OK; } @@ -575,8 +570,10 @@ txLREAttribute::execute(txExecutionState& aEs) mLocalName->ToString(nodeName); } - nsAutoPtr exprRes(mValue->evaluate(aEs.getEvalContext())); - NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE); + nsRefPtr exprRes; + nsresult rv = mValue->evaluate(aEs.getEvalContext(), + getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); nsAString* value = exprRes->stringValuePointer(); if (value) { @@ -599,8 +596,8 @@ txMessage::txMessage(PRBool aTerminate) nsresult txMessage::execute(txExecutionState& aEs) { - txTextHandler* handler = - NS_STATIC_CAST(txTextHandler*, aEs.popResultHandler()); + nsAutoPtr handler( + NS_STATIC_CAST(txTextHandler*, aEs.popResultHandler())); nsCOMPtr consoleSvc = do_GetService("@mozilla.org/consoleservice;1"); @@ -609,7 +606,6 @@ txMessage::execute(txExecutionState& aEs) logString.Append(handler->mValue); consoleSvc->LogStringMessage(logString.get()); } - delete handler; return mTerminate ? NS_ERROR_XSLT_ABORTED : NS_OK; } @@ -655,22 +651,22 @@ txProcessingInstruction::txProcessingInstruction(nsAutoPtr aName) nsresult txProcessingInstruction::execute(txExecutionState& aEs) { - txTextHandler* handler = - NS_STATIC_CAST(txTextHandler*, aEs.popResultHandler()); + nsAutoPtr handler( + NS_STATIC_CAST(txTextHandler*, aEs.popResultHandler())); XMLUtils::normalizePIValue(handler->mValue); - ExprResult* exprRes = mName->evaluate(aEs.getEvalContext()); - NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE); + nsRefPtr exprRes; + nsresult rv = mName->evaluate(aEs.getEvalContext(), + getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); nsAutoString name; exprRes->stringValue(name); - delete exprRes; // Check name validity (must be valid NCName and a PITarget) // XXX Need to check for NCName and PITarget if (!XMLUtils::isValidQName(name)) { // XXX ErrorReport: bad PI-target - delete handler; return NS_ERROR_FAILURE; } @@ -696,17 +692,18 @@ txPushNewContext::~txPushNewContext() nsresult txPushNewContext::execute(txExecutionState& aEs) { - nsresult rv = NS_OK; - ExprResult* exprRes = mSelect->evaluate(aEs.getEvalContext()); - NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE); + nsRefPtr exprRes; + nsresult rv = mSelect->evaluate(aEs.getEvalContext(), + getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); - if (exprRes->getResultType() != ExprResult::NODESET) { - delete exprRes; + if (exprRes->getResultType() != txAExprResult::NODESET) { // XXX ErrorReport: nodeset expected return NS_ERROR_XSLT_NODESET_EXPECTED; } - NodeSet* nodes = NS_STATIC_CAST(NodeSet*, exprRes); + NodeSet* nodes = + NS_STATIC_CAST(NodeSet*, NS_STATIC_CAST(txAExprResult*, exprRes)); if (nodes->isEmpty()) { aEs.gotoInstruction(mBailTarget); @@ -727,11 +724,8 @@ txPushNewContext::execute(txExecutionState& aEs) rv = sorter.sortNodeSet(nodes, &aEs); NS_ENSURE_SUCCESS(rv, rv); - txNodeSetContext* context = new txOwningNodeSetContext(nodes, &aEs); - if (!context) { - delete exprRes; - return NS_ERROR_OUT_OF_MEMORY; - } + txNodeSetContext* context = new txNodeSetContext(nodes, &aEs); + NS_ENSURE_TRUE(context, NS_ERROR_OUT_OF_MEMORY); context->next(); @@ -851,29 +845,27 @@ txSetParam::txSetParam(const txExpandedName& aName, nsAutoPtr aValue) nsresult txSetParam::execute(txExecutionState& aEs) { + nsresult rv = NS_OK; if (!aEs.mTemplateParams) { - aEs.mTemplateParams = new txExpandedNameMap(PR_TRUE); + aEs.mTemplateParams = new txVariableMap; NS_ENSURE_TRUE(aEs.mTemplateParams, NS_ERROR_OUT_OF_MEMORY); } - ExprResult* exprRes; + nsRefPtr exprRes; if (mValue) { - exprRes = mValue->evaluate(aEs.getEvalContext()); - NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE); + rv = mValue->evaluate(aEs.getEvalContext(), + getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); } else { - txRtfHandler* rtfHandler = - NS_STATIC_CAST(txRtfHandler*, aEs.popResultHandler()); - exprRes = rtfHandler->createRTF(); - delete rtfHandler; - NS_ENSURE_TRUE(exprRes, NS_ERROR_OUT_OF_MEMORY); + nsAutoPtr rtfHandler( + NS_STATIC_CAST(txRtfHandler*, aEs.popResultHandler())); + rv = rtfHandler->getAsRTF(getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); } - nsresult rv = aEs.mTemplateParams->add(mName, exprRes); - if (NS_FAILED(rv)) { - delete exprRes; - return rv; - } + rv = aEs.mTemplateParams->bindVariable(mName, exprRes); + NS_ENSURE_SUCCESS(rv, rv); return NS_OK; } @@ -887,26 +879,20 @@ txSetVariable::txSetVariable(const txExpandedName& aName, nsresult txSetVariable::execute(txExecutionState& aEs) { - ExprResult* exprRes; + nsresult rv = NS_OK; + nsRefPtr exprRes; if (mValue) { - exprRes = mValue->evaluate(aEs.getEvalContext()); - NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE); + rv = mValue->evaluate(aEs.getEvalContext(), getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); } else { - txRtfHandler* rtfHandler = - NS_STATIC_CAST(txRtfHandler*, aEs.popResultHandler()); - exprRes = rtfHandler->createRTF(); - delete rtfHandler; - NS_ENSURE_TRUE(exprRes, NS_ERROR_OUT_OF_MEMORY); + nsAutoPtr rtfHandler( + NS_STATIC_CAST(txRtfHandler*, aEs.popResultHandler())); + rv = rtfHandler->getAsRTF(getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); } - nsresult rv = aEs.bindVariable(mName, exprRes, MB_TRUE); - if (NS_FAILED(rv)) { - delete exprRes; - return rv; - } - - return NS_OK; + return aEs.bindVariable(mName, exprRes); } txStartElement::txStartElement(nsAutoPtr aName, @@ -921,14 +907,13 @@ txStartElement::txStartElement(nsAutoPtr aName, nsresult txStartElement::execute(txExecutionState& aEs) { - nsresult rv = NS_OK; - - ExprResult* exprRes = mName->evaluate(aEs.getEvalContext()); - NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE); + nsRefPtr exprRes; + nsresult rv = mName->evaluate(aEs.getEvalContext(), + getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); nsAutoString name; exprRes->stringValue(name); - delete exprRes; if (!XMLUtils::isValidQName(name)) { // tunkate name to indicate failure @@ -938,12 +923,12 @@ txStartElement::execute(txExecutionState& aEs) PRInt32 nsId = kNameSpaceID_None; if (!name.IsEmpty()) { if (mNamespace) { - exprRes = mNamespace->evaluate(aEs.getEvalContext()); - NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE); + rv = mNamespace->evaluate(aEs.getEvalContext(), + getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); nsAutoString nspace; exprRes->stringValue(nspace); - delete exprRes; if (!nspace.IsEmpty()) { #ifdef TX_EXE @@ -1044,8 +1029,10 @@ txValueOf::txValueOf(nsAutoPtr aExpr, PRBool aDOE) nsresult txValueOf::execute(txExecutionState& aEs) { - nsAutoPtr exprRes(mExpr->evaluate(aEs.getEvalContext())); - NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE); + nsRefPtr exprRes; + nsresult rv = mExpr->evaluate(aEs.getEvalContext(), + getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); nsAString* value = exprRes->stringValuePointer(); if (value) { @@ -1061,6 +1048,5 @@ txValueOf::execute(txExecutionState& aEs) } } - return NS_OK; } diff --git a/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp b/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp index aeb634b29fe..184fa972920 100644 --- a/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp @@ -938,7 +938,7 @@ txMozillaXSLTProcessor::ContentRemoved(nsIDocument* aDocument, /* static*/ nsresult -txVariable::Convert(nsIVariant *aValue, ExprResult** aResult) +txVariable::Convert(nsIVariant *aValue, txAExprResult** aResult) { *aResult = nsnull; @@ -961,8 +961,10 @@ txVariable::Convert(nsIVariant *aValue, ExprResult** aResult) nsresult rv = aValue->GetAsDouble(&value); NS_ENSURE_SUCCESS(rv, rv); - *aResult = new NumberResult(value); - NS_ENSURE_TRUE(aResult, NS_ERROR_OUT_OF_MEMORY); + *aResult = new NumberResult(value, nsnull); + NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY); + + NS_ADDREF(*aResult); return NS_OK; } @@ -975,7 +977,9 @@ txVariable::Convert(nsIVariant *aValue, ExprResult** aResult) NS_ENSURE_SUCCESS(rv, rv); *aResult = new BooleanResult(value); - NS_ENSURE_TRUE(aResult, NS_ERROR_OUT_OF_MEMORY); + NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY); + + NS_ADDREF(*aResult); return NS_OK; } @@ -996,8 +1000,10 @@ txVariable::Convert(nsIVariant *aValue, ExprResult** aResult) nsresult rv = aValue->GetAsAString(value); NS_ENSURE_SUCCESS(rv, rv); - *aResult = new StringResult(value); - NS_ENSURE_TRUE(aResult, NS_ERROR_OUT_OF_MEMORY); + *aResult = new StringResult(value, nsnull); + NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY); + + NS_ADDREF(*aResult); return NS_OK; } diff --git a/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.h b/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.h index 9366693e668..4fad1fdf902 100644 --- a/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.h +++ b/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.h @@ -74,20 +74,17 @@ public: mTxValue(nsnull) { } - ~txVariable() - { - delete mTxValue; - } - nsresult getValue(ExprResult** aValue) + nsresult getValue(txAExprResult** aValue) { NS_ASSERTION(mValue, "variablevalue is null"); if (!mTxValue) { - nsresult rv = Convert(mValue, &mTxValue); + nsresult rv = Convert(mValue, getter_AddRefs(mTxValue)); NS_ENSURE_SUCCESS(rv, rv); } *aValue = mTxValue; + NS_ADDREF(*aValue); return NS_OK; } @@ -101,15 +98,14 @@ public: { NS_ASSERTION(aValue, "setting variablevalue to null"); mValue = aValue; - delete mTxValue; mTxValue = nsnull; } private: - static nsresult Convert(nsIVariant *aValue, ExprResult** aResult); + static nsresult Convert(nsIVariant *aValue, txAExprResult** aResult); nsCOMPtr mValue; - ExprResult* mTxValue; + nsRefPtr mTxValue; }; /** diff --git a/mozilla/extensions/transformiix/source/xslt/txRtfHandler.cpp b/mozilla/extensions/transformiix/source/xslt/txRtfHandler.cpp index e75a2de0bb7..8ebb15fb599 100644 --- a/mozilla/extensions/transformiix/source/xslt/txRtfHandler.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txRtfHandler.cpp @@ -39,8 +39,8 @@ #include "txRtfHandler.h" -txResultTreeFragment::txResultTreeFragment(txResultBuffer* aBuffer) - : mBuffer(aBuffer) +txResultTreeFragment::txResultTreeFragment(nsAutoPtr& aBuffer) + : txAExprResult(nsnull), mBuffer(aBuffer) { } @@ -48,11 +48,6 @@ txResultTreeFragment::~txResultTreeFragment() { } -ExprResult* txResultTreeFragment::clone() -{ - return new txResultTreeFragment(mBuffer); -} - short txResultTreeFragment::getResultType() { return RESULT_TREE_FRAGMENT; @@ -103,9 +98,15 @@ txRtfHandler::~txRtfHandler() { } -txResultTreeFragment* txRtfHandler::createRTF() +nsresult +txRtfHandler::getAsRTF(txAExprResult** aResult) { - return new txResultTreeFragment(mBuffer); + *aResult = new txResultTreeFragment(mBuffer); + NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY); + + NS_ADDREF(*aResult); + + return NS_OK; } void txRtfHandler::endDocument() diff --git a/mozilla/extensions/transformiix/source/xslt/txRtfHandler.h b/mozilla/extensions/transformiix/source/xslt/txRtfHandler.h index 6ef8d3aa85d..f8a9868a715 100644 --- a/mozilla/extensions/transformiix/source/xslt/txRtfHandler.h +++ b/mozilla/extensions/transformiix/source/xslt/txRtfHandler.h @@ -43,10 +43,10 @@ #include "txBufferingHandler.h" #include "ExprResult.h" -class txResultTreeFragment : public ExprResult +class txResultTreeFragment : public txAExprResult { public: - txResultTreeFragment(txResultBuffer* aBuffer); + txResultTreeFragment(nsAutoPtr& aBuffer); ~txResultTreeFragment(); TX_DECL_EXPRRESULT @@ -54,7 +54,7 @@ public: nsresult flushToHandler(txAXMLEventHandler* aHandler); private: - nsRefPtr mBuffer; + nsAutoPtr mBuffer; }; class txRtfHandler : public txBufferingHandler @@ -63,7 +63,7 @@ public: txRtfHandler(); virtual ~txRtfHandler(); - txResultTreeFragment* createRTF(); + nsresult getAsRTF(txAExprResult** aResult); void endDocument(); void startDocument(); diff --git a/mozilla/extensions/transformiix/source/xslt/txStylesheet.h b/mozilla/extensions/transformiix/source/xslt/txStylesheet.h index 24d5b3eb56c..65fd2ab3773 100644 --- a/mozilla/extensions/transformiix/source/xslt/txStylesheet.h +++ b/mozilla/extensions/transformiix/source/xslt/txStylesheet.h @@ -240,7 +240,7 @@ protected: class txIGlobalParameter : public TxObject { public: - virtual nsresult getValue(ExprResult** aValue) = 0; + virtual nsresult getValue(txAExprResult** aValue) = 0; }; diff --git a/mozilla/extensions/transformiix/source/xslt/txStylesheetCompileHandlers.cpp b/mozilla/extensions/transformiix/source/xslt/txStylesheetCompileHandlers.cpp index 34a67fa0f89..869cd1a2c33 100644 --- a/mozilla/extensions/transformiix/source/xslt/txStylesheetCompileHandlers.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txStylesheetCompileHandlers.cpp @@ -1131,7 +1131,7 @@ txFnEndTopVariable(txStylesheetCompilerState& aState) // No children were found. NS_ASSERTION(!var->mValue, "There shouldn't be a select-expression here"); - var->mValue = new StringExpr(NS_LITERAL_STRING("")); + var->mValue = new txLiteralExpr(NS_LITERAL_STRING("")); NS_ENSURE_TRUE(var->mValue, NS_ERROR_OUT_OF_MEMORY); } else if (!var->mValue) { @@ -2126,7 +2126,7 @@ txFnEndParam(txStylesheetCompilerState& aState) // No children were found. NS_ASSERTION(!var->mValue, "There shouldn't be a select-expression here"); - var->mValue = new StringExpr(NS_LITERAL_STRING("")); + var->mValue = new txLiteralExpr(NS_LITERAL_STRING("")); NS_ENSURE_TRUE(var->mValue, NS_ERROR_OUT_OF_MEMORY); } @@ -2404,7 +2404,7 @@ txFnEndVariable(txStylesheetCompilerState& aState) // No children were found. NS_ASSERTION(!var->mValue, "There shouldn't be a select-expression here"); - var->mValue = new StringExpr(NS_LITERAL_STRING("")); + var->mValue = new txLiteralExpr(NS_LITERAL_STRING("")); NS_ENSURE_TRUE(var->mValue, NS_ERROR_OUT_OF_MEMORY); } @@ -2567,7 +2567,7 @@ txFnEndWithParam(txStylesheetCompilerState& aState) // No children were found. NS_ASSERTION(!var->mValue, "There shouldn't be a select-expression here"); - var->mValue = new StringExpr(NS_LITERAL_STRING("")); + var->mValue = new txLiteralExpr(NS_LITERAL_STRING("")); NS_ENSURE_TRUE(var->mValue, NS_ERROR_OUT_OF_MEMORY); } diff --git a/mozilla/extensions/transformiix/source/xslt/txVariableMap.h b/mozilla/extensions/transformiix/source/xslt/txVariableMap.h index f77c098fd8b..aec2dcc8683 100644 --- a/mozilla/extensions/transformiix/source/xslt/txVariableMap.h +++ b/mozilla/extensions/transformiix/source/xslt/txVariableMap.h @@ -47,59 +47,60 @@ class txVariableMap { public: txVariableMap(); + ~txVariableMap(); - nsresult bindVariable(const txExpandedName& aName, - ExprResult* aValue, MBool aOwned); + nsresult bindVariable(const txExpandedName& aName, txAExprResult* aValue); - ExprResult* getVariable(const txExpandedName& aName); + void getVariable(const txExpandedName& aName, txAExprResult** aResult); void removeVariable(const txExpandedName& aName); private: - // Map with owned variables - txExpandedNameMap mOwnedVariables; - - // Map with non-owned variables - txExpandedNameMap mNonOwnedVariables; + txExpandedNameMap mMap; }; -inline txVariableMap::txVariableMap() - : mOwnedVariables(MB_TRUE), - mNonOwnedVariables(MB_FALSE) +inline +txVariableMap::txVariableMap() + : mMap(MB_FALSE) { } -inline nsresult txVariableMap::bindVariable(const txExpandedName& aName, - ExprResult* aValue, MBool aOwned) +inline +txVariableMap::~txVariableMap() { - nsresult rv = NS_ERROR_FAILURE; - if (aOwned) { - if (!mNonOwnedVariables.get(aName)) { - rv = mOwnedVariables.add(aName, aValue); - } + txExpandedNameMap::iterator iter(mMap); + while (iter.next()) { + txAExprResult* res = NS_STATIC_CAST(txAExprResult*, iter.value()); + NS_RELEASE(res); } - else { - if (!mOwnedVariables.get(aName)) { - rv = mNonOwnedVariables.add(aName, aValue); - } +} + +inline nsresult +txVariableMap::bindVariable(const txExpandedName& aName, txAExprResult* aValue) +{ + NS_ASSERTION(aValue, "can't add null-variables to a txVariableMap"); + nsresult rv = mMap.add(aName, aValue); + if (NS_SUCCEEDED(rv)) { + NS_ADDREF(aValue); } return rv; } -inline ExprResult* txVariableMap::getVariable(const txExpandedName& aName) +inline void +txVariableMap::getVariable(const txExpandedName& aName, txAExprResult** aResult) { - ExprResult* var = (ExprResult*)mOwnedVariables.get(aName); - if (!var) { - var = (ExprResult*)mNonOwnedVariables.get(aName); + *aResult = NS_STATIC_CAST(txAExprResult*, mMap.get(aName)); + if (*aResult) { + NS_ADDREF(*aResult); } - return var; } -inline void txVariableMap::removeVariable(const txExpandedName& aName) +inline void +txVariableMap::removeVariable(const txExpandedName& aName) { - mOwnedVariables.remove(aName); - mNonOwnedVariables.remove(aName); + txAExprResult* var = NS_STATIC_CAST(txAExprResult*, mMap.remove(aName)); + NS_IF_RELEASE(var); } #endif //TRANSFRMX_VARIABLEMAP_H diff --git a/mozilla/extensions/transformiix/source/xslt/txXSLTNumber.cpp b/mozilla/extensions/transformiix/source/xslt/txXSLTNumber.cpp index fc754dd5f40..87940361a7d 100644 --- a/mozilla/extensions/transformiix/source/xslt/txXSLTNumber.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txXSLTNumber.cpp @@ -114,14 +114,15 @@ txXSLTNumber::getValueList(Expr* aValueExpr, txPattern* aCountPattern, nsAString& aValueString) { aValueString.Truncate(); - + nsresult rv = NS_OK; + // If the value attribute exists then use that if (aValueExpr) { - ExprResult* result = aValueExpr->evaluate(aContext); - NS_ENSURE_TRUE(result, NS_ERROR_FAILURE); + nsRefPtr result; + rv = aValueExpr->evaluate(aContext, getter_AddRefs(result)); + NS_ENSURE_SUCCESS(rv, rv); double value = result->numberValue(); - delete result; if (Double::isInfinite(value) || Double::isNaN(value) || value < 0.5) { @@ -319,12 +320,12 @@ txXSLTNumber::getCounters(Expr* aGroupSize, Expr* aGroupSeparator, nsAutoString groupSeparator; PRInt32 groupSize = 0; if (aGroupSize && aGroupSeparator) { - ExprResult* sizeRes = aGroupSize->evaluate(aContext); - NS_ENSURE_TRUE(sizeRes, NS_ERROR_FAILURE); + nsRefPtr exprRes; + rv = aGroupSize->evaluate(aContext, getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); nsAutoString sizeStr; - sizeRes->stringValue(sizeStr); - delete sizeRes; + exprRes->stringValue(sizeStr); double size = Double::toDouble(sizeStr); groupSize = (PRInt32)size; @@ -332,20 +333,19 @@ txXSLTNumber::getCounters(Expr* aGroupSize, Expr* aGroupSeparator, groupSize = 0; } - ExprResult* sepRes = aGroupSeparator->evaluate(aContext); - NS_ENSURE_TRUE(sepRes, NS_ERROR_FAILURE); + rv = aGroupSeparator->evaluate(aContext, getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); - sepRes->stringValue(groupSeparator); - delete sepRes; + exprRes->stringValue(groupSeparator); } nsAutoString format; if (aFormat) { - ExprResult* formatRes = aFormat->evaluate(aContext); - NS_ENSURE_TRUE(formatRes, NS_ERROR_FAILURE); + nsRefPtr formatRes; + rv = aFormat->evaluate(aContext, getter_AddRefs(formatRes)); + NS_ENSURE_SUCCESS(rv, rv); formatRes->stringValue(format); - delete formatRes; } PRUint32 formatLen = format.Length(); PRUint32 formatPos = 0; diff --git a/mozilla/extensions/transformiix/source/xslt/txXSLTPatterns.cpp b/mozilla/extensions/transformiix/source/xslt/txXSLTPatterns.cpp index dad7142c8a2..62067d1be0e 100644 --- a/mozilla/extensions/transformiix/source/xslt/txXSLTPatterns.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txXSLTPatterns.cpp @@ -418,12 +418,12 @@ MBool txKeyPattern::matches(Node* aNode, txIMatchContext* aContext) contextDoc = (Document*)aNode; else contextDoc = aNode->getOwnerDocument(); - const NodeSet* nodes = 0; - nsresult rv = es->getKeyNodes(mName, contextDoc, mValue, PR_TRUE, &nodes); - if (NS_FAILED(rv) || !nodes) - return MB_FALSE; - MBool isTrue = nodes->contains(aNode); - return isTrue; + nsRefPtr nodes; + nsresult rv = es->getKeyNodes(mName, contextDoc, mValue, PR_TRUE, + getter_AddRefs(nodes)); + NS_ENSURE_SUCCESS(rv, PR_FALSE); + + return nodes->contains(aNode); } double txKeyPattern::getDefaultPriority() @@ -498,7 +498,10 @@ MBool txStepPattern::matches(Node* aNode, txIMatchContext* aContext) */ // Create the context node set for evaluating the predicates - NodeSet nodes; + nsRefPtr nodes; + nsresult rv = aContext->recycler()->getNodeSet(getter_AddRefs(nodes)); + NS_ENSURE_SUCCESS(rv, rv); + Node* parent = aNode->getXPathParent(); if (mIsAttr) { NamedNodeMap* atts = parent->getAttributes(); @@ -507,7 +510,7 @@ MBool txStepPattern::matches(Node* aNode, txIMatchContext* aContext) for (i = 0; i < atts->getLength(); i++) { Node* attr = atts->item(i); if (mNodeTest->matches(attr, aContext)) - nodes.append(attr); + nodes->append(attr); } } } @@ -515,33 +518,36 @@ MBool txStepPattern::matches(Node* aNode, txIMatchContext* aContext) Node* tmpNode = parent->getFirstChild(); while (tmpNode) { if (mNodeTest->matches(tmpNode, aContext)) - nodes.append(tmpNode); + nodes->append(tmpNode); tmpNode = tmpNode->getNextSibling(); } } txListIterator iter(&predicates); Expr* predicate = (Expr*)iter.next(); - NodeSet newNodes; + nsRefPtr newNodes; + rv = aContext->recycler()->getNodeSet(getter_AddRefs(newNodes)); + NS_ENSURE_SUCCESS(rv, rv); while (iter.hasNext()) { - newNodes.clear(); + newNodes->clear(); MBool contextIsInPredicate = MB_FALSE; - txNodeSetContext predContext(&nodes, aContext); + txNodeSetContext predContext(nodes, aContext); while (predContext.hasNext()) { predContext.next(); - ExprResult* exprResult = predicate->evaluate(&predContext); - if (!exprResult) - break; + nsRefPtr exprResult; + rv = predicate->evaluate(&predContext, getter_AddRefs(exprResult)); + NS_ENSURE_SUCCESS(rv, PR_FALSE); + switch(exprResult->getResultType()) { - case ExprResult::NUMBER : + case txAExprResult::NUMBER: // handle default, [position() == numberValue()] if ((double)predContext.position() == exprResult->numberValue()) { Node* tmp = predContext.getContextNode(); if (tmp == aNode) contextIsInPredicate = MB_TRUE; - newNodes.append(tmp); + newNodes->append(tmp); } break; default: @@ -549,25 +555,25 @@ MBool txStepPattern::matches(Node* aNode, txIMatchContext* aContext) Node* tmp = predContext.getContextNode(); if (tmp == aNode) contextIsInPredicate = MB_TRUE; - newNodes.append(tmp); + newNodes->append(tmp); } break; } - delete exprResult; } // Move new NodeSet to the current one - nodes.clear(); - nodes.append(&newNodes); + nodes->clear(); + nodes->append(newNodes); if (!contextIsInPredicate) { return MB_FALSE; } predicate = (Expr*)iter.next(); } - txForwardContext evalContext(aContext, aNode, &nodes); - ExprResult* exprResult = predicate->evaluate(&evalContext); - if (!exprResult) - return MB_FALSE; - if (exprResult->getResultType() == ExprResult::NUMBER) + txForwardContext evalContext(aContext, aNode, nodes); + nsRefPtr exprResult; + rv = predicate->evaluate(&evalContext, getter_AddRefs(exprResult)); + NS_ENSURE_SUCCESS(rv, PR_FALSE); + + if (exprResult->getResultType() == txAExprResult::NUMBER) // handle default, [position() == numberValue()] return ((double)evalContext.position() == exprResult->numberValue()); diff --git a/mozilla/extensions/transformiix/source/xslt/txXSLTProcessor.cpp b/mozilla/extensions/transformiix/source/xslt/txXSLTProcessor.cpp index 9730831d0ae..99be7a80b1c 100644 --- a/mozilla/extensions/transformiix/source/xslt/txXSLTProcessor.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txXSLTProcessor.cpp @@ -42,6 +42,7 @@ #include "TxLog.h" #include "txStylesheetCompileHandlers.h" #include "txExecutionState.h" +#include "ExprResult.h" #ifdef TX_EXE #include "txHTMLOutput.h" #endif diff --git a/mozilla/extensions/transformiix/source/xslt/util/txNodeSorter.cpp b/mozilla/extensions/transformiix/source/xslt/util/txNodeSorter.cpp index 390e0bbda84..dbb4c87d337 100644 --- a/mozilla/extensions/transformiix/source/xslt/util/txNodeSorter.cpp +++ b/mozilla/extensions/transformiix/source/xslt/util/txNodeSorter.cpp @@ -72,6 +72,7 @@ txNodeSorter::addSortElement(Expr* aSelectExpr, Expr* aLangExpr, { SortKey* key = new SortKey; NS_ENSURE_TRUE(key, NS_ERROR_OUT_OF_MEMORY); + nsresult rv = NS_OK; // Select key->mExpr = aSelectExpr; @@ -79,12 +80,12 @@ txNodeSorter::addSortElement(Expr* aSelectExpr, Expr* aLangExpr, // Order MBool ascending = MB_TRUE; if (aOrderExpr) { - ExprResult* exprRes = aOrderExpr->evaluate(aContext); - NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE); + nsRefPtr exprRes; + rv = aOrderExpr->evaluate(aContext, getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); nsAutoString attrValue; exprRes->stringValue(attrValue); - delete exprRes; if (TX_StringEqualsAtom(attrValue, txXSLTAtoms::descending)) { ascending = MB_FALSE; @@ -100,11 +101,11 @@ txNodeSorter::addSortElement(Expr* aSelectExpr, Expr* aLangExpr, // Create comparator depending on datatype nsAutoString dataType; if (aDataTypeExpr) { - ExprResult* exprRes = aDataTypeExpr->evaluate(aContext); - NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE); + nsRefPtr exprRes; + rv = aDataTypeExpr->evaluate(aContext, getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); exprRes->stringValue(dataType); - delete exprRes; } if (!aDataTypeExpr || TX_StringEqualsAtom(dataType, txXSLTAtoms::text)) { @@ -113,22 +114,22 @@ txNodeSorter::addSortElement(Expr* aSelectExpr, Expr* aLangExpr, // Language nsAutoString lang; if (aLangExpr) { - ExprResult* exprRes = aLangExpr->evaluate(aContext); - NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE); + nsRefPtr exprRes; + rv = aLangExpr->evaluate(aContext, getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); exprRes->stringValue(lang); - delete exprRes; } // Case-order MBool upperFirst = PR_FALSE; if (aCaseOrderExpr) { - ExprResult* exprRes = aCaseOrderExpr->evaluate(aContext); - NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE); + nsRefPtr exprRes; + rv = aCaseOrderExpr->evaluate(aContext, getter_AddRefs(exprRes)); + NS_ENSURE_SUCCESS(rv, rv); nsAutoString attrValue; exprRes->stringValue(attrValue); - delete exprRes; if (TX_StringEqualsAtom(attrValue, txXSLTAtoms::upperFirst)) { upperFirst = PR_TRUE; @@ -218,6 +219,7 @@ int txNodeSorter::compareNodes(SortableNode* aSNode1, txExecutionState* aEs) { txListIterator iter(&mSortKeys); + nsresult rv = NS_OK; int i; // Step through each key until a difference is found @@ -227,34 +229,30 @@ int txNodeSorter::compareNodes(SortableNode* aSNode1, if (!aSNode1->mSortValues[i]) { txForwardContext evalContext(aEs->getEvalContext(), aSNode1->mNode, aNodes); aEs->pushEvalContext(&evalContext); - ExprResult* res = key->mExpr->evaluate(&evalContext); + nsRefPtr res; + rv = key->mExpr->evaluate(&evalContext, getter_AddRefs(res)); + NS_ENSURE_SUCCESS(rv, -1); + aEs->popEvalContext(); - if (!res) { - // XXX ErrorReport - return -1; - } aSNode1->mSortValues[i] = key->mComparator->createSortableValue(res); if (!aSNode1->mSortValues[i]) { // XXX ErrorReport return -1; } - delete res; } if (!aSNode2->mSortValues[i]) { txForwardContext evalContext(aEs->getEvalContext(), aSNode2->mNode, aNodes); aEs->pushEvalContext(&evalContext); - ExprResult* res = key->mExpr->evaluate(&evalContext); + nsRefPtr res; + rv = key->mExpr->evaluate(&evalContext, getter_AddRefs(res)); + NS_ENSURE_SUCCESS(rv, -1); + aEs->popEvalContext(); - if (!res) { - // XXX ErrorReport - return -1; - } aSNode2->mSortValues[i] = key->mComparator->createSortableValue(res); if (!aSNode2->mSortValues[i]) { // XXX ErrorReport return -1; } - delete res; } // Compare node values diff --git a/mozilla/extensions/transformiix/source/xslt/util/txXPathResultComparator.cpp b/mozilla/extensions/transformiix/source/xslt/util/txXPathResultComparator.cpp index 060695cd298..a4931aca245 100644 --- a/mozilla/extensions/transformiix/source/xslt/util/txXPathResultComparator.cpp +++ b/mozilla/extensions/transformiix/source/xslt/util/txXPathResultComparator.cpp @@ -107,7 +107,7 @@ nsresult txResultStringComparator::init(const nsAFlatString& aLanguage) } #endif -TxObject* txResultStringComparator::createSortableValue(ExprResult* aExprRes) +TxObject* txResultStringComparator::createSortableValue(txAExprResult* aExprRes) { StringValue* val = new StringValue; @@ -279,7 +279,7 @@ txResultNumberComparator::~txResultNumberComparator() { } -TxObject* txResultNumberComparator::createSortableValue(ExprResult* aExprRes) +TxObject* txResultNumberComparator::createSortableValue(txAExprResult* aExprRes) { NumberValue* numval = new NumberValue; if (numval) diff --git a/mozilla/extensions/transformiix/source/xslt/util/txXPathResultComparator.h b/mozilla/extensions/transformiix/source/xslt/util/txXPathResultComparator.h index ec230773db3..45153f10768 100644 --- a/mozilla/extensions/transformiix/source/xslt/util/txXPathResultComparator.h +++ b/mozilla/extensions/transformiix/source/xslt/util/txXPathResultComparator.h @@ -48,7 +48,7 @@ #include "nsString.h" #endif -class ExprResult; +class txAExprResult; /* * Result comparators @@ -69,7 +69,7 @@ public: /* * Create a sortable value. */ - virtual TxObject* createSortableValue(ExprResult* exprRes) = 0; + virtual TxObject* createSortableValue(txAExprResult* exprRes) = 0; }; /* @@ -83,7 +83,7 @@ public: virtual ~txResultStringComparator(); int compareValues(TxObject* aVal1, TxObject* aVal2); - TxObject* createSortableValue(ExprResult* aExprRes); + TxObject* createSortableValue(txAExprResult* aExprRes); private: #ifndef TX_EXE nsCOMPtr mCollation; @@ -121,7 +121,7 @@ public: virtual ~txResultNumberComparator(); int compareValues(TxObject* aVal1, TxObject* aVal2); - TxObject* createSortableValue(ExprResult* aExprRes); + TxObject* createSortableValue(txAExprResult* aExprRes); private: int mAscending;