зеркало из https://github.com/mozilla/gecko-dev.git
Bug 205703: Refcount Expr-results, to avoid cloning, and recycle them, to avoid memorymanagement.
r=Pike sr=peterv
This commit is contained in:
Родитель
f69a5761ff
Коммит
c0f7dd27f1
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -76,6 +76,17 @@ nsXPathEvaluator::CreateExpression(const nsAString & aExpression,
|
|||
nsIDOMXPathNSResolver *aResolver,
|
||||
nsIDOMXPathExpression **aResult)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (!mRecycler) {
|
||||
nsRefPtr<txResultRecycler> recycler = new txResultRecycler;
|
||||
NS_ENSURE_TRUE(recycler, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = recycler->init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mRecycler = recycler;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> 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;
|
||||
|
|
|
@ -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<txResultRecycler> mRecycler;
|
||||
};
|
||||
|
||||
/* d0a75e02-b5e7-11d5-a7f2-df109fb8a1fc */
|
||||
|
|
|
@ -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<txAExprResult> 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)
|
||||
{
|
||||
|
|
|
@ -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<txResultRecycler> 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<txResultRecycler> mRecycler;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<txAExprResult> 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
|
||||
|
||||
/**
|
||||
|
|
|
@ -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<StringResult> 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<txAExprResult> 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
|
||||
|
||||
/**
|
||||
|
|
|
@ -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<txAExprResult> 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
|
||||
|
||||
/**
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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<txAExprResult> 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<Expr> mLeftExpr;
|
||||
nsAutoPtr<Expr> 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
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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<txResultRecycler> 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
|
||||
|
||||
|
|
|
@ -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<txAExprResult> 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<NodeSet> nodes =
|
||||
NS_STATIC_CAST(NodeSet*, NS_STATIC_CAST(txAExprResult*, exprRes));
|
||||
// null out exprRes so that we can test for shared-ness
|
||||
exprRes = nsnull;
|
||||
nsRefPtr<NodeSet> 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
|
||||
|
||||
/**
|
||||
|
|
|
@ -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!!!");
|
||||
|
|
|
@ -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<NodeSet> mContextSet;
|
||||
txIMatchContext* mInner;
|
||||
};
|
||||
|
||||
|
|
|
@ -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<txAExprResult> 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<txAExprResult> 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<txAExprResult> 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<txAExprResult> 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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -54,13 +54,15 @@ LocationStep::LocationStep(nsAutoPtr<txNodeTest> 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<NodeSet> 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,
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "ExprResult.h"
|
||||
#include <math.h>
|
||||
#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<txAExprResult> 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
|
||||
|
||||
/**
|
||||
|
|
|
@ -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!!!");
|
||||
|
|
|
@ -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<NodeSet> 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
|
||||
|
|
|
@ -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<NodeSet> 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<txAExprResult> 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<NodeSet> 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<NodeSet> 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<nsIAtom> 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<nsIDOMNode> 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)
|
||||
|
|
|
@ -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<NodeSet> 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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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<NodeSet> 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<NodeSet> tmpNodes;
|
||||
txNodeSetContext eContext(nodes, aContext);
|
||||
while (eContext.hasNext()) {
|
||||
eContext.next();
|
||||
Node* node = eContext.getContextNode();
|
||||
|
||||
NodeSet* resNodes;
|
||||
nsRefPtr<NodeSet> 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<txAExprResult> 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<NodeSet> 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<txAExprResult> 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
|
||||
|
||||
/**
|
||||
|
|
|
@ -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<NodeSet> 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<txAExprResult> 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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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<StringResult> 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<StringResult> 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<ExprResult> lResult(mLeftExpr->evaluate(aContext));
|
||||
NS_ENSURE_TRUE(lResult, nsnull);
|
||||
*aResult = nsnull;
|
||||
nsRefPtr<txAExprResult> lResult;
|
||||
nsresult rv = mLeftExpr->evaluate(aContext, getter_AddRefs(lResult));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<ExprResult> rResult(mRightExpr->evaluate(aContext));
|
||||
NS_ENSURE_TRUE(rResult, nsnull);
|
||||
nsRefPtr<txAExprResult> 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
|
||||
|
|
|
@ -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<txResultRecycler> 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;
|
||||
}
|
|
@ -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__
|
|
@ -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
|
||||
|
||||
/**
|
||||
|
|
|
@ -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!!!");
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "XMLDOMUtils.h"
|
||||
#include "XMLUtils.h"
|
||||
#include <math.h>
|
||||
#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<StringResult> 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<StringResult> 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<StringResult> 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<StringResult> 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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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<txAExprResult> 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
|
||||
}
|
||||
|
||||
|
|
|
@ -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<NodeSet> 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<txAExprResult> 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
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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<txResultBuffer> mBuffer;
|
||||
nsAutoPtr<txResultBuffer> mBuffer;
|
||||
PRPackedBool mCanAddAttribute;
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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> 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<txAExprResult> 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<NodeSet> 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)
|
||||
|
|
|
@ -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<txAExprResult> 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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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<txVariableMap> mTemplateParams;
|
||||
|
||||
nsRefPtr<txStylesheet> mStylesheet;
|
||||
|
||||
|
@ -159,7 +159,7 @@ private:
|
|||
txInstruction* mNextInstruction;
|
||||
txVariableMap* mLocalVariables;
|
||||
txVariableMap mGlobalVariableValues;
|
||||
nsAutoPtr<ExprResult> mGlobalVarPlaceholderValue;
|
||||
nsRefPtr<txAExprResult> mGlobalVarPlaceholderValue;
|
||||
PRInt32 mRecursionDepth;
|
||||
|
||||
TemplateRule* mTemplateRules;
|
||||
|
@ -173,6 +173,7 @@ private:
|
|||
|
||||
txLoadedDocumentsHash mLoadedDocuments;
|
||||
txKeyHash mKeyHash;
|
||||
nsRefPtr<txResultRecycler> mRecycler;
|
||||
|
||||
static const PRInt32 kMaxRecursionDepth;
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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<txAExprResult> 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)
|
||||
|
|
|
@ -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<txAExprResult> 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)
|
||||
|
|
|
@ -134,14 +134,13 @@ txAttribute::txAttribute(nsAutoPtr<Expr> aName, nsAutoPtr<Expr> aNamespace,
|
|||
nsresult
|
||||
txAttribute::execute(txExecutionState& aEs)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
ExprResult* exprRes = mName->evaluate(aEs.getEvalContext());
|
||||
NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE);
|
||||
nsRefPtr<txAExprResult> 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<txTextHandler> 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<txAExprResult> 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<Expr> aCondition,
|
|||
nsresult
|
||||
txConditionalGoto::execute(txExecutionState& aEs)
|
||||
{
|
||||
ExprResult* exprRes = mCondition->evaluate(aEs.getEvalContext());
|
||||
NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE);
|
||||
nsRefPtr<txAExprResult> 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<txTextHandler> 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<Expr> aSelect)
|
|||
nsresult
|
||||
txCopyOf::execute(txExecutionState& aEs)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
ExprResult* exprRes = mSelect->evaluate(aEs.getEvalContext());
|
||||
NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE);
|
||||
nsRefPtr<txAExprResult> 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<ExprResult> exprRes(mValue->evaluate(aEs.getEvalContext()));
|
||||
NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE);
|
||||
nsRefPtr<txAExprResult> 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<txTextHandler> handler(
|
||||
NS_STATIC_CAST(txTextHandler*, aEs.popResultHandler()));
|
||||
|
||||
nsCOMPtr<nsIConsoleService> 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<Expr> aName)
|
|||
nsresult
|
||||
txProcessingInstruction::execute(txExecutionState& aEs)
|
||||
{
|
||||
txTextHandler* handler =
|
||||
NS_STATIC_CAST(txTextHandler*, aEs.popResultHandler());
|
||||
nsAutoPtr<txTextHandler> 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<txAExprResult> 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<txAExprResult> 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<Expr> 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<txAExprResult> 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<txRtfHandler> 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<txAExprResult> 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<txRtfHandler> 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<Expr> aName,
|
||||
|
@ -921,14 +907,13 @@ txStartElement::txStartElement(nsAutoPtr<Expr> aName,
|
|||
nsresult
|
||||
txStartElement::execute(txExecutionState& aEs)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
ExprResult* exprRes = mName->evaluate(aEs.getEvalContext());
|
||||
NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE);
|
||||
nsRefPtr<txAExprResult> 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<Expr> aExpr, PRBool aDOE)
|
|||
nsresult
|
||||
txValueOf::execute(txExecutionState& aEs)
|
||||
{
|
||||
nsAutoPtr<ExprResult> exprRes(mExpr->evaluate(aEs.getEvalContext()));
|
||||
NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE);
|
||||
nsRefPtr<txAExprResult> 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;
|
||||
}
|
||||
|
|
|
@ -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<NodeSet> 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<NodeSet> mEmptyNodeSet;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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<txAExprResult> 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<NodeSet> 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<NodeSet> 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<txAExprResult> 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; i<res->size(); 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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<nsIVariant> mValue;
|
||||
ExprResult* mTxValue;
|
||||
nsRefPtr<txAExprResult> mTxValue;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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<txAExprResult> 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<txAExprResult> 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<txAExprResult> 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<txAExprResult> 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<txAExprResult> 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<txAExprResult> 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
|
||||
|
|
|
@ -39,8 +39,8 @@
|
|||
|
||||
#include "txRtfHandler.h"
|
||||
|
||||
txResultTreeFragment::txResultTreeFragment(txResultBuffer* aBuffer)
|
||||
: mBuffer(aBuffer)
|
||||
txResultTreeFragment::txResultTreeFragment(nsAutoPtr<txResultBuffer>& 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()
|
||||
|
|
|
@ -43,10 +43,10 @@
|
|||
#include "txBufferingHandler.h"
|
||||
#include "ExprResult.h"
|
||||
|
||||
class txResultTreeFragment : public ExprResult
|
||||
class txResultTreeFragment : public txAExprResult
|
||||
{
|
||||
public:
|
||||
txResultTreeFragment(txResultBuffer* aBuffer);
|
||||
txResultTreeFragment(nsAutoPtr<txResultBuffer>& aBuffer);
|
||||
~txResultTreeFragment();
|
||||
|
||||
TX_DECL_EXPRRESULT
|
||||
|
@ -54,7 +54,7 @@ public:
|
|||
nsresult flushToHandler(txAXMLEventHandler* aHandler);
|
||||
|
||||
private:
|
||||
nsRefPtr<txResultBuffer> mBuffer;
|
||||
nsAutoPtr<txResultBuffer> mBuffer;
|
||||
};
|
||||
|
||||
class txRtfHandler : public txBufferingHandler
|
||||
|
@ -63,7 +63,7 @@ public:
|
|||
txRtfHandler();
|
||||
virtual ~txRtfHandler();
|
||||
|
||||
txResultTreeFragment* createRTF();
|
||||
nsresult getAsRTF(txAExprResult** aResult);
|
||||
|
||||
void endDocument();
|
||||
void startDocument();
|
||||
|
|
|
@ -240,7 +240,7 @@ protected:
|
|||
class txIGlobalParameter : public TxObject
|
||||
{
|
||||
public:
|
||||
virtual nsresult getValue(ExprResult** aValue) = 0;
|
||||
virtual nsresult getValue(txAExprResult** aValue) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<txAExprResult> 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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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<nsICollation> 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;
|
||||
|
|
|
@ -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<txAExprResult> 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<txAExprResult> 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<txAExprResult> 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;
|
||||
|
|
|
@ -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<NodeSet> 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<NodeSet> 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<NodeSet> 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<txAExprResult> 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<txAExprResult> 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());
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "TxLog.h"
|
||||
#include "txStylesheetCompileHandlers.h"
|
||||
#include "txExecutionState.h"
|
||||
#include "ExprResult.h"
|
||||
#ifdef TX_EXE
|
||||
#include "txHTMLOutput.h"
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче