Bug 210528: Fix ownership models of some functioncalls in the XPath code and replace some txLists with owning nsTArrays. r/sr=peterv

This commit is contained in:
cvshook%sicking.cc 2006-12-12 21:20:15 +00:00
Родитель 1ecf0d0950
Коммит 2d6de8b4cb
25 изменённых файлов: 374 добавлений и 662 удалений

Просмотреть файл

@ -231,26 +231,6 @@ void txList::clear()
itemCount = 0;
}
void*
txList::replace(PRUint32 aIndex, void* aObjPtr)
{
PRUint32 i = 0;
ListItem* item = firstItem;
while (i < aIndex && item) {
item = item->nextItem;
++i;
}
if (!item) {
return nsnull;
}
void* oldObj = item->objPtr;
item->objPtr = aObjPtr;
return oldObj;
}
//------------------------------------/
//- Implementation of txListIterator -/
//------------------------------------/

Просмотреть файл

@ -102,15 +102,6 @@ public:
*/
void clear();
/**
* Replaces the Object at the given index with a new Object.
* If the given index is outside the list null is returned.
* @param aIndex index of Object to replace.
* @param aObjPtr new Object to put in the list.
* @return the old Object pointer
*/
void* replace(PRUint32 aIndex, void* aObjPtr);
protected:
struct ListItem {

Просмотреть файл

@ -0,0 +1,66 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** 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 Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jonas Sicking <jonas@sicking.cc>
*
* 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 txOwningArray_h__
#define txOwningArray_h__
#include "nsTPtrArray.h"
// Class acting like a nsTPtrArray except that it deletes its objects
// on destruction. It does not however delete its objects on operations
// like RemoveElementsAt or on |array[i] = bar|.
template<class E>
class txOwningArray : public nsTPtrArray<E>
{
public:
typedef nsTPtrArray<E> base_type;
typedef typename base_type::elem_type elem_type;
~txOwningArray()
{
elem_type* iter = base_type::Elements();
elem_type* end = iter + base_type::Length();
for (; iter < end; ++iter) {
delete *iter;
}
}
};
#endif // txOwningArray_h__

Просмотреть файл

@ -110,13 +110,11 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
}
nsresult rv = NS_OK;
txListIterator iter(&params);
switch (mType) {
case COUNT:
{
nsRefPtr<txNodeSet> nodes;
rv = evaluateToNodeSet((Expr*)iter.next(), aContext,
rv = evaluateToNodeSet(mParams[0], aContext,
getter_AddRefs(nodes));
NS_ENSURE_SUCCESS(rv, rv);
@ -126,8 +124,7 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
case ID:
{
nsRefPtr<txAExprResult> exprResult;
rv = ((Expr*)iter.next())->evaluate(aContext,
getter_AddRefs(exprResult));
rv = mParams[0]->evaluate(aContext, getter_AddRefs(exprResult));
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<txNodeSet> resultSet;
@ -179,8 +176,8 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
{
// Check for optional arg
nsRefPtr<txNodeSet> nodes;
if (iter.hasNext()) {
rv = evaluateToNodeSet((Expr*)iter.next(), aContext,
if (!mParams.IsEmpty()) {
rv = evaluateToNodeSet(mParams[0], aContext,
getter_AddRefs(nodes));
NS_ENSURE_SUCCESS(rv, rv);
@ -255,9 +252,9 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
rv = aContext->recycler()->getStringResult(getter_AddRefs(strRes));
NS_ENSURE_SUCCESS(rv, rv);
while (iter.hasNext()) {
Expr* param = NS_STATIC_CAST(Expr*, iter.next());
rv = param->evaluateToString(aContext, strRes->mValue);
PRUint32 i, len = mParams.Length();
for (i = 0; i < len; ++i) {
rv = mParams[i]->evaluateToString(aContext, strRes->mValue);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -267,11 +264,8 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
}
case CONTAINS:
{
Expr* arg1Expr = NS_STATIC_CAST(Expr*, iter.next());
Expr* arg2Expr = NS_STATIC_CAST(Expr*, iter.next());
nsAutoString arg2;
rv = arg2Expr->evaluateToString(aContext, arg2);
rv = mParams[1]->evaluateToString(aContext, arg2);
NS_ENSURE_SUCCESS(rv, rv);
if (arg2.IsEmpty()) {
@ -279,7 +273,7 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
}
else {
nsAutoString arg1;
rv = arg1Expr->evaluateToString(aContext, arg1);
rv = mParams[0]->evaluateToString(aContext, arg1);
NS_ENSURE_SUCCESS(rv, rv);
aContext->recycler()->getBoolResult(FindInReadable(arg2, arg1),
@ -291,9 +285,8 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
case NORMALIZE_SPACE:
{
nsAutoString resultStr;
if (iter.hasNext()) {
Expr* param = NS_STATIC_CAST(Expr*, iter.next());
rv = param->evaluateToString(aContext, resultStr);
if (!mParams.IsEmpty()) {
rv = mParams[0]->evaluateToString(aContext, resultStr);
NS_ENSURE_SUCCESS(rv, rv);
}
else {
@ -331,11 +324,8 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
}
case STARTS_WITH:
{
Expr* arg1Expr = NS_STATIC_CAST(Expr*, iter.next());
Expr* arg2Expr = NS_STATIC_CAST(Expr*, iter.next());
nsAutoString arg2;
rv = arg2Expr->evaluateToString(aContext, arg2);
rv = mParams[1]->evaluateToString(aContext, arg2);
NS_ENSURE_SUCCESS(rv, rv);
PRBool result;
@ -344,7 +334,7 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
}
else {
nsAutoString arg1;
rv = arg1Expr->evaluateToString(aContext, arg1);
rv = mParams[0]->evaluateToString(aContext, arg1);
NS_ENSURE_SUCCESS(rv, rv);
result = StringBeginsWith(arg1, arg2);
@ -360,9 +350,8 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
rv = aContext->recycler()->getStringResult(getter_AddRefs(strRes));
NS_ENSURE_SUCCESS(rv, rv);
if (iter.hasNext()) {
Expr* param = NS_STATIC_CAST(Expr*, iter.next());
rv = param->evaluateToString(aContext, strRes->mValue);
if (!mParams.IsEmpty()) {
rv = mParams[0]->evaluateToString(aContext, strRes->mValue);
NS_ENSURE_SUCCESS(rv, rv);
}
else {
@ -377,9 +366,8 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
case STRING_LENGTH:
{
nsAutoString resultStr;
if (iter.hasNext()) {
Expr* arg1Expr = NS_STATIC_CAST(Expr*, iter.next());
rv = arg1Expr->evaluateToString(aContext, resultStr);
if (!mParams.IsEmpty()) {
rv = mParams[0]->evaluateToString(aContext, resultStr);
NS_ENSURE_SUCCESS(rv, rv);
}
else {
@ -394,14 +382,11 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
}
case SUBSTRING:
{
Expr* param = NS_STATIC_CAST(Expr*, iter.next());
nsAutoString src;
rv = param->evaluateToString(aContext, src);
rv = mParams[0]->evaluateToString(aContext, src);
NS_ENSURE_SUCCESS(rv, rv);
double start = evaluateToNumber(NS_STATIC_CAST(Expr*, iter.next()),
aContext);
double start = evaluateToNumber(mParams[1], aContext);
// check for NaN or +/-Inf
if (Double::isNaN(start) ||
@ -415,8 +400,8 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
start = floor(start + 0.5) - 1;
double end;
if (iter.hasNext()) {
end = start + evaluateToNumber((Expr*)iter.next(),
if (mParams.Length() == 3) {
end = start + evaluateToNumber(mParams[2],
aContext);
if (Double::isNaN(end) || end < 0) {
aContext->recycler()->getEmptyStringResult(aResult);
@ -448,14 +433,12 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
}
case SUBSTRING_AFTER:
{
Expr* arg1Expr = NS_STATIC_CAST(Expr*, iter.next());
nsAutoString arg1;
rv = arg1Expr->evaluateToString(aContext, arg1);
rv = mParams[0]->evaluateToString(aContext, arg1);
NS_ENSURE_SUCCESS(rv, rv);
Expr* arg2Expr = NS_STATIC_CAST(Expr*, iter.next());
nsAutoString arg2;
rv = arg2Expr->evaluateToString(aContext, arg2);
rv = mParams[1]->evaluateToString(aContext, arg2);
NS_ENSURE_SUCCESS(rv, rv);
if (arg2.IsEmpty()) {
@ -474,11 +457,8 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
}
case SUBSTRING_BEFORE:
{
Expr* arg1Expr = NS_STATIC_CAST(Expr*, iter.next());
Expr* arg2Expr = NS_STATIC_CAST(Expr*, iter.next());
nsAutoString arg2;
rv = arg2Expr->evaluateToString(aContext, arg2);
rv = mParams[1]->evaluateToString(aContext, arg2);
NS_ENSURE_SUCCESS(rv, rv);
if (arg2.IsEmpty()) {
@ -488,7 +468,7 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
}
nsAutoString arg1;
rv = arg1Expr->evaluateToString(aContext, arg1);
rv = mParams[0]->evaluateToString(aContext, arg1);
NS_ENSURE_SUCCESS(rv, rv);
PRInt32 idx = arg1.Find(arg2);
@ -503,10 +483,8 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
}
case TRANSLATE:
{
Expr* arg1Expr = NS_STATIC_CAST(Expr*, iter.next());
nsAutoString src;
rv = arg1Expr->evaluateToString(aContext, src);
rv = mParams[0]->evaluateToString(aContext, src);
NS_ENSURE_SUCCESS(rv, rv);
if (src.IsEmpty()) {
@ -521,14 +499,11 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
strRes->mValue.SetCapacity(src.Length());
Expr* arg2Expr = NS_STATIC_CAST(Expr*, iter.next());
Expr* arg3Expr = NS_STATIC_CAST(Expr*, iter.next());
nsAutoString oldChars, newChars;
rv = arg2Expr->evaluateToString(aContext, oldChars);
rv = mParams[1]->evaluateToString(aContext, oldChars);
NS_ENSURE_SUCCESS(rv, rv);
rv = arg3Expr->evaluateToString(aContext, newChars);
rv = mParams[2]->evaluateToString(aContext, newChars);
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 i;
@ -554,8 +529,8 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
case NUMBER:
{
double res;
if (iter.hasNext()) {
res = evaluateToNumber((Expr*)iter.next(), aContext);
if (!mParams.IsEmpty()) {
res = evaluateToNumber(mParams[0], aContext);
}
else {
nsAutoString resultStr;
@ -567,7 +542,7 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
}
case ROUND:
{
double dbl = evaluateToNumber((Expr*)iter.next(), aContext);
double dbl = evaluateToNumber(mParams[0], aContext);
if (!Double::isNaN(dbl) && !Double::isInfinite(dbl)) {
if (Double::isNeg(dbl) && dbl >= -0.5) {
dbl *= 0;
@ -581,7 +556,7 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
}
case FLOOR:
{
double dbl = evaluateToNumber((Expr*)iter.next(), aContext);
double dbl = evaluateToNumber(mParams[0], aContext);
if (!Double::isNaN(dbl) &&
!Double::isInfinite(dbl) &&
!(dbl == 0 && Double::isNeg(dbl))) {
@ -592,7 +567,7 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
}
case CEILING:
{
double dbl = evaluateToNumber((Expr*)iter.next(), aContext);
double dbl = evaluateToNumber(mParams[0], aContext);
if (!Double::isNaN(dbl) && !Double::isInfinite(dbl)) {
if (Double::isNeg(dbl) && dbl > -1) {
dbl *= 0;
@ -607,7 +582,7 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
case SUM:
{
nsRefPtr<txNodeSet> nodes;
nsresult rv = evaluateToNodeSet((Expr*)iter.next(), aContext,
nsresult rv = evaluateToNodeSet(mParams[0], aContext,
getter_AddRefs(nodes));
NS_ENSURE_SUCCESS(rv, rv);
@ -625,9 +600,8 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
case BOOLEAN:
{
Expr* param = NS_STATIC_CAST(Expr*, iter.next());
PRBool result;
nsresult rv = param->evaluateToBool(aContext, result);
nsresult rv = mParams[0]->evaluateToBool(aContext, result);
NS_ENSURE_SUCCESS(rv, rv);
aContext->recycler()->getBoolResult(result, aResult);
@ -658,8 +632,7 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
}
nsAutoString arg;
Expr* param = NS_STATIC_CAST(Expr*, iter.next());
nsresult rv = param->evaluateToString(aContext, arg);
rv = mParams[0]->evaluateToString(aContext, arg);
NS_ENSURE_SUCCESS(rv, rv);
PRBool result =
@ -674,9 +647,8 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
}
case _NOT:
{
Expr* param = NS_STATIC_CAST(Expr*, iter.next());
PRBool result;
nsresult rv = param->evaluateToBool(aContext, result);
rv = mParams[0]->evaluateToBool(aContext, result);
NS_ENSURE_SUCCESS(rv, rv);
aContext->recycler()->getBoolResult(!result, aResult);
@ -742,7 +714,7 @@ txCoreFunctionCall::isSensitiveTo(ContextSensitivity aContext)
case STRING_LENGTH:
case NUMBER:
{
if (params.isEmpty()) {
if (mParams.IsEmpty()) {
return !!(aContext & NODE_CONTEXT);
}
return argsSensitiveTo(aContext);

Просмотреть файл

@ -41,12 +41,12 @@
#ifndef TRANSFRMX_EXPR_H
#define TRANSFRMX_EXPR_H
#include "txList.h"
#include "nsAutoPtr.h"
#include "txExprResult.h"
#include "txCore.h"
#include "nsString.h"
#include "nsTPtrArray.h"
#include "txOwningArray.h"
#include "nsIAtom.h"
#ifdef DEBUG
#define TX_TO_STRING
@ -70,14 +70,6 @@ class txXPathNode;
class Expr
{
public:
/**
* Virtual destructor, important for subclasses
**/
virtual ~Expr()
{
}
/**
* Evaluates this Expr based on the given context node and processor state
* @param context the context node for evaluation of this Expr
@ -272,14 +264,14 @@ TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \
Expr* \
_class::getSubExprAt(PRUint32 aPos) \
{ \
return NS_STATIC_CAST(Expr*, _ExprList.get(aPos)); \
return _ExprList.SafeElementAt(aPos); \
} \
void \
_class::setSubExprAt(PRUint32 aPos, Expr* aExpr) \
{ \
NS_ASSERTION(aPos < (PRUint32)_ExprList.getLength(), \
NS_ASSERTION(aPos < _ExprList.Length(), \
"setting bad subexpression index"); \
_ExprList.replace(aPos, aExpr); \
_ExprList[aPos] = aExpr; \
}
@ -290,8 +282,6 @@ _class::setSubExprAt(PRUint32 aPos, Expr* aExpr) \
class FunctionCall : public Expr
{
public:
virtual ~FunctionCall();
/**
* Adds the given parameter to this FunctionCall's parameter list.
* The ownership of the given Expr is passed over to the FunctionCall,
@ -299,7 +289,11 @@ public:
* @param aExpr the Expr to add to this FunctionCall's parameter list
* @return nsresult indicating out of memory
*/
nsresult addParam(Expr* aExpr);
nsresult addParam(Expr* aExpr)
{
return mParams.AppendElement(aExpr) ?
NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
/**
* Check if the number of parameters falls within a range.
@ -322,7 +316,7 @@ public:
protected:
txList params;
txOwningArray<Expr> mParams;
/*
* Evaluates the given Expression and converts its result to a number.
@ -492,12 +486,18 @@ public:
/*
* Creates a new txNodeTypeTest of the given type
*/
txNodeTypeTest(NodeType aNodeType);
txNodeTypeTest(NodeType aNodeType)
: mNodeType(aNodeType)
{
}
/*
* Sets the name of the node to match. Only availible for pi nodes
*/
void setNodeName(const nsAString& aName);
void setNodeName(const nsAString& aName)
{
mNodeName = do_GetAtom(aName);
}
NodeType getNodeTestType()
{
@ -533,19 +533,7 @@ private:
* for use with Step and Filter Expressions
**/
class PredicateList {
public:
/**
* Creates a new PredicateList
**/
PredicateList();
/**
* Destructor, will delete all Expressions in the list, so remove
* any you may need
**/
virtual ~PredicateList();
/**
* Adds the given Expr to the list.
* The ownership of the given Expr is passed over the PredicateList,
@ -553,19 +541,30 @@ public:
* @param aExpr the Expr to add to the list
* @return nsresult indicating out of memory
*/
nsresult add(Expr* aExpr);
nsresult add(Expr* aExpr)
{
NS_ASSERTION(aExpr, "missing expression");
return mPredicates.AppendElement(aExpr) ?
NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
nsresult evaluatePredicates(txNodeSet* aNodes, txIMatchContext* aContext);
/**
* Drops the first predicate without deleting it.
*/
void dropFirst();
void dropFirst()
{
mPredicates.RemoveElementAt(0);
}
/**
* returns true if this predicate list is empty
**/
MBool isEmpty();
PRBool isEmpty()
{
return mPredicates.IsEmpty();
}
#ifdef TX_TO_STRING
/**
@ -576,20 +575,28 @@ public:
* other #toString() methods for Expressions.
* @return the String representation of this PredicateList.
**/
virtual void toString(nsAString& dest);
void toString(nsAString& dest);
#endif
protected:
PRBool isSensitiveTo(Expr::ContextSensitivity aContext);
Expr* getSubExprAt(PRUint32 aPos);
void setSubExprAt(PRUint32 aPos, Expr* aExpr);
Expr* getSubExprAt(PRUint32 aPos)
{
return mPredicates.SafeElementAt(aPos);
}
void setSubExprAt(PRUint32 aPos, Expr* aExpr)
{
NS_ASSERTION(aPos < mPredicates.Length(),
"setting bad subexpression index");
mPredicates[aPos] = aExpr;
}
//-- list of predicates
List predicates;
txOwningArray<Expr> mPredicates;
}; //-- PredicateList
class LocationStep : public PredicateList,
public Expr
class LocationStep : public Expr,
public PredicateList
{
public:
enum LocationStepType {
@ -613,7 +620,7 @@ public:
* @param nodeExpr the NodeExpr to use when matching Nodes
* @param axisIdentifier the Axis Identifier in which to search for nodes
**/
LocationStep(nsAutoPtr<txNodeTest>& aNodeTest,
LocationStep(txNodeTest* aNodeTest,
LocationStepType aAxisIdentifier)
: mNodeTest(aNodeTest),
mAxisIdentifier(aAxisIdentifier)
@ -650,15 +657,16 @@ private:
LocationStepType mAxisIdentifier;
};
class FilterExpr : public PredicateList, public Expr {
class FilterExpr : public Expr,
public PredicateList
{
public:
/**
* Creates a new FilterExpr using the given Expr
* @param expr the Expr to use for evaluation
*/
FilterExpr(nsAutoPtr<Expr>& aExpr)
FilterExpr(Expr* aExpr)
: expr(aExpr)
{
}
@ -673,10 +681,16 @@ private:
class txLiteralExpr : public Expr {
public:
txLiteralExpr(double aDbl);
txLiteralExpr(const nsAString& aStr);
txLiteralExpr(double aDbl)
: mValue(new NumberResult(aDbl, nsnull))
{
}
txLiteralExpr(const nsAString& aStr)
: mValue(new StringResult(aStr, nsnull))
{
}
txLiteralExpr(txAExprResult* aValue)
: mValue(aValue)
: mValue(aValue)
{
}
@ -686,35 +700,6 @@ private:
nsRefPtr<txAExprResult> mValue;
};
/**
* Represents an AdditiveExpr, a binary expression that
* performs an additive operation between it's lvalue and rvalue:
* + : add
* - : subtract
**/
class AdditiveExpr : public Expr {
public:
//-- AdditiveExpr Types
//-- LF, changed from static const short to enum
enum _AdditiveExprType { ADDITION = 1, SUBTRACTION };
AdditiveExpr(nsAutoPtr<Expr>& aLeftExpr, nsAutoPtr<Expr>& aRightExpr,
short aOp)
: op(aOp),
leftExpr(aLeftExpr),
rightExpr(aRightExpr)
{
}
TX_DECL_EXPR
private:
short op;
nsAutoPtr<Expr> leftExpr, rightExpr;
}; //-- AdditiveExpr
/**
* Represents an UnaryExpr. Returns the negative value of it's expr.
**/
@ -722,7 +707,7 @@ class UnaryExpr : public Expr {
public:
UnaryExpr(nsAutoPtr<Expr>& aExpr)
UnaryExpr(Expr* aExpr)
: expr(aExpr)
{
}
@ -737,15 +722,14 @@ private:
* Represents a BooleanExpr, a binary expression that
* performs a boolean operation between it's lvalue and rvalue.
**/
class BooleanExpr : public Expr {
class BooleanExpr : public Expr
{
public:
//-- BooleanExpr Types
enum _BooleanExprType { AND = 1, OR };
BooleanExpr(nsAutoPtr<Expr>& aLeftExpr, nsAutoPtr<Expr>& aRightExpr,
short aOp)
BooleanExpr(Expr* aLeftExpr, Expr* aRightExpr, short aOp)
: leftExpr(aLeftExpr),
rightExpr(aRightExpr),
op(aOp)
@ -767,15 +751,13 @@ private:
* div : divide
*
**/
class txNumberExpr : public Expr {
class txNumberExpr : public Expr
{
public:
enum eOp { ADD, SUBTRACT, DIVIDE, MULTIPLY, MODULUS };
txNumberExpr(nsAutoPtr<Expr>& aLeftExpr,
nsAutoPtr<Expr>& aRightExpr,
eOp aOp)
txNumberExpr(Expr* aLeftExpr, Expr* aRightExpr, eOp aOp)
: mLeftExpr(aLeftExpr),
mRightExpr(aRightExpr),
mOp(aOp)
@ -799,8 +781,8 @@ private:
* >= : greater than or equal to
*
**/
class RelationalExpr : public Expr {
class RelationalExpr : public Expr
{
public:
enum RelationalExprType {
EQUAL,
@ -811,8 +793,7 @@ public:
GREATER_OR_EQUAL
};
RelationalExpr(nsAutoPtr<Expr>& aLeftExpr, nsAutoPtr<Expr>& aRightExpr,
RelationalExprType aOp)
RelationalExpr(Expr* aLeftExpr, Expr* aRightExpr, RelationalExprType aOp)
: mLeftExpr(aLeftExpr),
mRightExpr(aRightExpr),
mOp(aOp)
@ -873,7 +854,12 @@ public:
/**
* Removes and deletes the expression at the given index.
*/
void deleteExprAt(PRUint32 aPos);
void deleteExprAt(PRUint32 aPos)
{
NS_ASSERTION(aPos < mItems.Length(),
"killing bad expression index");
mItems.RemoveElementAt(aPos);
}
TX_DECL_OPTIMIZABLE_EXPR
@ -940,19 +926,7 @@ private:
* Represents a UnionExpr
**/
class UnionExpr : public Expr {
public:
/**
* Creates a new UnionExpr
**/
UnionExpr();
/**
* Destructor, will delete all Path Expressions
**/
virtual ~UnionExpr();
/**
* Adds the PathExpr to this UnionExpr
* The ownership of the given Expr is passed over the UnionExpr,
@ -960,18 +934,29 @@ public:
* @param aExpr the Expr to add to this UnionExpr
* @return nsresult indicating out of memory
*/
nsresult addExpr(Expr* aExpr);
nsresult addExpr(Expr* aExpr)
{
return mExpressions.AppendElement(aExpr) ?
NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
/**
* Removes and deletes the expression at the given index.
*/
void deleteExprAt(PRUint32 aPos);
void deleteExprAt(PRUint32 aPos)
{
NS_ASSERTION(aPos < mExpressions.Length(),
"killing bad expression index");
delete mExpressions[aPos];
mExpressions.RemoveElementAt(aPos);
}
TX_DECL_OPTIMIZABLE_EXPR
private:
List expressions;
txOwningArray<Expr> mExpressions;
}; //-- UnionExpr
@ -999,14 +984,16 @@ private:
class txUnionNodeTest : public txNodeTest
{
public:
~txUnionNodeTest();
nsresult addNodeTest(txNodeTest* aNodeTest);
nsresult addNodeTest(txNodeTest* aNodeTest)
{
return mNodeTests.AppendElement(aNodeTest) ?
NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
TX_DECL_NODE_TEST
private:
nsTPtrArray<txNodeTest> mNodeTests;
txOwningArray<txNodeTest> mNodeTests;
};
/**

Просмотреть файл

@ -289,6 +289,9 @@ txExprParser::createBinaryExpr(nsAutoPtr<Expr>& left, nsAutoPtr<Expr>& right,
}
NS_ENSURE_TRUE(expr, NS_ERROR_OUT_OF_MEMORY);
left.forget();
right.forget();
*aResult = expr;
return NS_OK;
}
@ -322,11 +325,14 @@ txExprParser::createExpr(txExprLexer& lexer, txIParseContext* aContext,
}
if (unary) {
expr = new UnaryExpr(expr);
if (!expr) {
Expr* unaryExpr = new UnaryExpr(expr);
if (!unaryExpr) {
rv = NS_ERROR_OUT_OF_MEMORY;
break;
}
expr.forget();
expr = unaryExpr;
}
Token* tok = lexer.nextToken();
@ -426,6 +432,8 @@ txExprParser::createFilterOrStep(txExprLexer& lexer, txIParseContext* aContext,
nsAutoPtr<FilterExpr> filterExpr(new FilterExpr(expr));
NS_ENSURE_TRUE(filterExpr, NS_ERROR_OUT_OF_MEMORY);
expr.forget();
//-- handle predicates
rv = parsePredicates(filterExpr, lexer, aContext);
NS_ENSURE_SUCCESS(rv, rv);
@ -608,6 +616,8 @@ txExprParser::createLocationStep(txExprLexer& lexer, txIParseContext* aContext,
nsAutoPtr<LocationStep> lstep(new LocationStep(nodeTest, axisIdentifier));
NS_ENSURE_TRUE(lstep, NS_ERROR_OUT_OF_MEMORY);
nodeTest.forget();
//-- handle predicates
rv = parsePredicates(lstep, lexer, aContext);
NS_ENSURE_SUCCESS(rv, rv);
@ -714,9 +724,11 @@ txExprParser::createPathExpr(txExprLexer& lexer, txIParseContext* aContext,
nsAutoPtr<PathExpr> pathExpr(new PathExpr());
NS_ENSURE_TRUE(pathExpr, NS_ERROR_OUT_OF_MEMORY);
rv = pathExpr->addExpr(expr.forget(), PathExpr::RELATIVE_OP);
rv = pathExpr->addExpr(expr, PathExpr::RELATIVE_OP);
NS_ENSURE_SUCCESS(rv, rv);
expr.forget();
// this is ugly
while (1) {
PathExpr::PathOperator pathOp;
@ -737,8 +749,10 @@ txExprParser::createPathExpr(txExprLexer& lexer, txIParseContext* aContext,
rv = createLocationStep(lexer, aContext, getter_Transfers(expr));
NS_ENSURE_SUCCESS(rv, rv);
rv = pathExpr->addExpr(expr.forget(), pathOp);
rv = pathExpr->addExpr(expr, pathOp);
NS_ENSURE_SUCCESS(rv, rv);
expr.forget();
}
NS_NOTREACHED("internal xpath parser error");
return NS_ERROR_UNEXPECTED;
@ -766,9 +780,11 @@ txExprParser::createUnionExpr(txExprLexer& lexer, txIParseContext* aContext,
nsAutoPtr<UnionExpr> unionExpr(new UnionExpr());
NS_ENSURE_TRUE(unionExpr, NS_ERROR_OUT_OF_MEMORY);
rv = unionExpr->addExpr(expr.forget());
rv = unionExpr->addExpr(expr);
NS_ENSURE_SUCCESS(rv, rv);
expr.forget();
while (lexer.peek()->mType == Token::UNION_OP) {
lexer.nextToken(); //-- eat token
@ -819,9 +835,11 @@ txExprParser::parsePredicates(PredicateList* aPredicateList,
rv = createExpr(lexer, aContext, getter_Transfers(expr));
NS_ENSURE_SUCCESS(rv, rv);
rv = aPredicateList->add(expr.forget());
rv = aPredicateList->add(expr);
NS_ENSURE_SUCCESS(rv, rv);
expr.forget();
if (lexer.nextToken()->mType != Token::R_BRACKET) {
lexer.pushBack();
return NS_ERROR_XPATH_BRACKET_EXPECTED;

Просмотреть файл

@ -45,36 +45,10 @@
* This class represents a FunctionCall as defined by the XSL Working Draft
**/
/**
* Destructor
**/
FunctionCall::~FunctionCall()
{
txListIterator iter(&params);
while (iter.hasNext()) {
delete (Expr*)iter.next();
}
} //-- ~FunctionCall
//------------------/
//- Public Methods -/
//------------------/
/**
* Adds the given parameter to this FunctionCall's parameter list
* @param expr the Expr to add to this FunctionCall's parameter list
*/
nsresult
FunctionCall::addParam(Expr* aExpr)
{
NS_ASSERTION(aExpr, "missing expression");
nsresult rv = params.add(aExpr);
if (NS_FAILED(rv)) {
delete aExpr;
}
return rv;
} //-- addParam
/*
* Evaluates the given Expression and converts its result to a number.
*/
@ -120,7 +94,7 @@ PRBool FunctionCall::requireParams(PRInt32 aParamCountMin,
PRInt32 aParamCountMax,
txIEvalContext* aContext)
{
PRInt32 argc = params.getLength();
PRInt32 argc = mParams.Length();
if (argc < aParamCountMin ||
(aParamCountMax > -1 && argc > aParamCountMax)) {
nsAutoString err(NS_LITERAL_STRING("invalid number of parameters for function"));
@ -139,23 +113,23 @@ PRBool FunctionCall::requireParams(PRInt32 aParamCountMin,
Expr*
FunctionCall::getSubExprAt(PRUint32 aPos)
{
return NS_STATIC_CAST(Expr*, params.get(aPos));
return mParams.SafeElementAt(aPos);
}
void
FunctionCall::setSubExprAt(PRUint32 aPos, Expr* aExpr)
{
NS_ASSERTION(aPos < (PRUint32)params.getLength(),
NS_ASSERTION(aPos < mParams.Length(),
"setting bad subexpression index");
params.replace(aPos, aExpr);
mParams[aPos] = aExpr;
}
PRBool
FunctionCall::argsSensitiveTo(ContextSensitivity aContext)
{
txListIterator iter(&params);
while (iter.hasNext()) {
if (NS_STATIC_CAST(Expr*, iter.next())->isSensitiveTo(aContext)) {
PRUint32 i, len = mParams.Length();
for (i = 0; i < len; ++i) {
if (mParams[i]->isSensitiveTo(aContext)) {
return PR_TRUE;
}
}
@ -177,15 +151,11 @@ FunctionCall::toString(nsAString& aDest)
aDest.Append(functionName);
aDest.Append(PRUnichar('('));
txListIterator iter(&params);
MBool addComma = MB_FALSE;
while (iter.hasNext()) {
if (addComma) {
for (PRUint32 i = 0; i < mParams.Length(); ++i) {
if (i != 0) {
aDest.Append(PRUnichar(','));
}
addComma = MB_TRUE;
Expr* expr = (Expr*)iter.next();
expr->toString(aDest);
mParams[i]->toString(aDest);
}
aDest.Append(PRUnichar(')'));
}

Просмотреть файл

@ -38,16 +38,6 @@
#include "txExpr.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)
{

Просмотреть файл

@ -41,19 +41,6 @@
#include "txIXPathContext.h"
#include "txXPathTreeWalker.h"
/*
* Creates a new txNodeTypeTest of the given type
*/
txNodeTypeTest::txNodeTypeTest(NodeType aNodeType)
: mNodeType(aNodeType)
{
}
void txNodeTypeTest::setNodeName(const nsAString& aName)
{
mNodeName = do_GetAtom(aName);
}
PRBool txNodeTypeTest::matches(const txXPathNode& aNode,
txIMatchContext* aContext)
{

Просмотреть файл

@ -58,7 +58,6 @@ PathExpr::addExpr(Expr* aExpr, PathOperator aPathOp)
"First step has to be relative in PathExpr");
PathExprItem* pxi = mItems.AppendElement();
if (!pxi) {
delete aExpr;
return NS_ERROR_OUT_OF_MEMORY;
}
pxi->expr = aExpr;
@ -67,15 +66,6 @@ PathExpr::addExpr(Expr* aExpr, PathOperator aPathOp)
return NS_OK;
}
void
PathExpr::deleteExprAt(PRUint32 aPos)
{
NS_ASSERTION(aPos < mItems.Length(),
"killing bad expression index");
mItems.RemoveElementAt(aPos);
}
//-----------------------------/
//- Virtual methods from Expr -/
//-----------------------------/

Просмотреть файл

@ -45,36 +45,6 @@
* for use with Step and Filter Expressions
*/
PredicateList::PredicateList()
{
} // PredicateList
/*
* Destructor, will delete all Expressions in the list
*/
PredicateList::~PredicateList()
{
txListIterator iter(&predicates);
while (iter.hasNext()) {
delete (Expr*)iter.next();
}
} // ~PredicateList
/*
* Adds the given Expr to the list
* @param expr the Expr to add to the list
*/
nsresult
PredicateList::add(Expr* aExpr)
{
NS_ASSERTION(aExpr, "missing expression");
nsresult rv = predicates.add(aExpr);
if (NS_FAILED(rv)) {
delete aExpr;
}
return rv;
} // add
nsresult
PredicateList::evaluatePredicates(txNodeSet* nodes,
txIMatchContext* aContext)
@ -82,9 +52,8 @@ PredicateList::evaluatePredicates(txNodeSet* nodes,
NS_ASSERTION(nodes, "called evaluatePredicates with NULL NodeSet");
nsresult rv = NS_OK;
txListIterator iter(&predicates);
while (iter.hasNext() && !nodes->isEmpty()) {
Expr* expr = (Expr*)iter.next();
PRUint32 i, len = mPredicates.Length();
for (i = 0; i < len && !nodes->isEmpty(); ++i) {
txNodeSetContext predContext(nodes, aContext);
/*
* add nodes to newNodes that match the expression
@ -95,7 +64,8 @@ PredicateList::evaluatePredicates(txNodeSet* nodes,
while (predContext.hasNext()) {
predContext.next();
nsRefPtr<txAExprResult> exprResult;
rv = expr->evaluate(&predContext, getter_AddRefs(exprResult));
rv = mPredicates[i]->evaluate(&predContext,
getter_AddRefs(exprResult));
NS_ENSURE_SUCCESS(rv, rv);
// handle default, [position() == numberValue()]
@ -116,34 +86,6 @@ PredicateList::evaluatePredicates(txNodeSet* nodes,
return NS_OK;
}
void
PredicateList::dropFirst()
{
predicates.remove(predicates.get(0));
}
/*
* returns true if this predicate list is empty
*/
MBool PredicateList::isEmpty()
{
return (MBool)(predicates.getLength() == 0);
} // isEmpty
Expr*
PredicateList::getSubExprAt(PRUint32 aPos)
{
return NS_STATIC_CAST(Expr*, predicates.get(aPos));
}
void
PredicateList::setSubExprAt(PRUint32 aPos, Expr* aExpr)
{
NS_ASSERTION(aPos < (PRUint32)predicates.getLength(),
"setting bad subexpression index");
predicates.replace(aPos, aExpr);
}
PRBool
PredicateList::isSensitiveTo(Expr::ContextSensitivity aContext)
{
@ -154,9 +96,9 @@ PredicateList::isSensitiveTo(Expr::ContextSensitivity aContext)
return PR_FALSE;
}
txListIterator iter(&predicates);
while (iter.hasNext()) {
if (NS_STATIC_CAST(Expr*, iter.next())->isSensitiveTo(context)) {
PRUint32 i, len = mPredicates.Length();
for (i = 0; i < len; ++i) {
if (mPredicates[i]->isSensitiveTo(context)) {
return PR_TRUE;
}
}
@ -167,11 +109,9 @@ PredicateList::isSensitiveTo(Expr::ContextSensitivity aContext)
#ifdef TX_TO_STRING
void PredicateList::toString(nsAString& dest)
{
txListIterator iter(&predicates);
while (iter.hasNext()) {
Expr* expr = (Expr*) iter.next();
for (PRUint32 i = 0; i < mPredicates.Length(); ++i) {
dest.Append(PRUnichar('['));
expr->toString(dest);
mPredicates[i]->toString(dest);
dest.Append(PRUnichar(']'));
}
}

Просмотреть файл

@ -44,48 +44,6 @@
//- UnionExpr -/
//-------------/
/**
* Creates a new UnionExpr
**/
UnionExpr::UnionExpr() {
//-- do nothing
}
/**
* Destructor, will delete all Path Expressions
**/
UnionExpr::~UnionExpr() {
txListIterator iter(&expressions);
while (iter.hasNext()) {
delete (Expr*)iter.next();
}
} //-- ~UnionExpr
/**
* Adds the Expr to this UnionExpr
* @param expr the Expr to add to this UnionExpr
**/
nsresult
UnionExpr::addExpr(Expr* aExpr)
{
nsresult rv = expressions.add(aExpr);
if (NS_FAILED(rv)) {
delete aExpr;
}
return rv;
} //-- addExpr
void
UnionExpr::deleteExprAt(PRUint32 aPos)
{
NS_ASSERTION(aPos < (PRUint32)expressions.getLength(),
"killing bad expression index");
// This isn't very efficient. We should switch to nsTArray.
expressions.remove(expressions.get((int)aPos));
}
//-----------------------------/
//- Virtual methods from Expr -/
//-----------------------------/
@ -105,11 +63,10 @@ UnionExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
nsresult rv = aContext->recycler()->getNodeSet(getter_AddRefs(nodes));
NS_ENSURE_SUCCESS(rv, rv);
txListIterator iter(&expressions);
while (iter.hasNext()) {
Expr* expr = (Expr*)iter.next();
PRUint32 i, len = mExpressions.Length();
for (i = 0; i < len; ++i) {
nsRefPtr<txAExprResult> exprResult;
rv = expr->evaluate(aContext, getter_AddRefs(exprResult));
rv = mExpressions[i]->evaluate(aContext, getter_AddRefs(exprResult));
NS_ENSURE_SUCCESS(rv, rv);
if (exprResult->getResultType() != txAExprResult::NODESET) {
@ -141,14 +98,14 @@ UnionExpr::getType()
return UNION_EXPR;
}
TX_IMPL_EXPR_STUBS_LIST(UnionExpr, NODESET_RESULT, expressions)
TX_IMPL_EXPR_STUBS_LIST(UnionExpr, NODESET_RESULT, mExpressions)
PRBool
UnionExpr::isSensitiveTo(ContextSensitivity aContext)
{
txListIterator iter(&expressions);
while (iter.hasNext()) {
if (NS_STATIC_CAST(Expr*, iter.next())->isSensitiveTo(aContext)) {
PRUint32 i, len = mExpressions.Length();
for (i = 0; i < len; ++i) {
if (mExpressions[i]->isSensitiveTo(aContext)) {
return PR_TRUE;
}
}
@ -160,15 +117,11 @@ UnionExpr::isSensitiveTo(ContextSensitivity aContext)
void
UnionExpr::toString(nsAString& dest)
{
txListIterator iter(&expressions);
short count = 0;
while (iter.hasNext()) {
//-- set operator
if (count > 0)
PRUint32 i;
for (i = 0; i < mExpressions.Length(); ++i) {
if (i > 0)
dest.AppendLiteral(" | ");
((Expr*)iter.next())->toString(dest);
++count;
mExpressions[i]->toString(dest);
}
}
#endif

Просмотреть файл

@ -40,25 +40,6 @@
#include "txExprResult.h"
#include "txSingleNodeContext.h"
txUnionNodeTest::~txUnionNodeTest()
{
PRUint32 i, len = mNodeTests.Length();
for (i = 0; i < len; ++i) {
delete mNodeTests[i];
}
}
nsresult
txUnionNodeTest::addNodeTest(txNodeTest* aNodeTest)
{
if (!mNodeTests.AppendElement(aNodeTest)) {
delete aNodeTest;
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
PRBool
txUnionNodeTest::matches(const txXPathNode& aNode,
txIMatchContext* aContext)

Просмотреть файл

@ -395,7 +395,7 @@ txXPCOMExtensionFunctionCall::evaluate(txIEvalContext* aContext,
}
txFunctionEvaluationContext *context;
PRUint8 i = 0;
PRUint32 paramStart = 0;
if (type == CONTEXT) {
if (paramInfo.IsOut()) {
// We don't support out values.
@ -414,20 +414,20 @@ txXPCOMExtensionFunctionCall::evaluate(txIEvalContext* aContext,
NS_ADDREF((txIFunctionEvaluationContext*&)invokeParam.val.p = context);
// Skip first argument, since it's the context.
++i;
paramStart = 1;
}
else {
context = nsnull;
}
// XXX varargs
if (!requireParams(inArgs - i, inArgs - i, aContext)) {
if (!requireParams(inArgs - paramStart, inArgs - paramStart, aContext)) {
return NS_ERROR_FAILURE;
}
txListIterator iter(&params);
for (; i < inArgs; ++i) {
Expr* expr = NS_STATIC_CAST(Expr*, iter.next());
PRUint32 i;
for (i = paramStart; i < inArgs; ++i) {
Expr* expr = mParams[i - paramStart];
const nsXPTParamInfo &paramInfo = methodInfo->GetParam(i);
txArgumentType type = GetParamType(paramInfo, info);

Просмотреть файл

@ -298,19 +298,22 @@ txXPathOptimizer::optimizeUnion(Expr* aInExpr, Expr** aOutExpr)
// Create a txUnionNodeTest if needed
if (!unionTest) {
unionTest = new txUnionNodeTest;
nsAutoPtr<txNodeTest> owner(unionTest = new txUnionNodeTest);
NS_ENSURE_TRUE(unionTest, NS_ERROR_OUT_OF_MEMORY);
rv = unionTest->addNodeTest(currentStep->getNodeTest());
currentStep->setNodeTest(unionTest);
NS_ENSURE_SUCCESS(rv, rv);
currentStep->setNodeTest(unionTest);
owner.forget();
}
// Merge the nodetest into the union
rv = unionTest->addNodeTest(step->getNodeTest());
step->setNodeTest(nsnull);
NS_ENSURE_SUCCESS(rv, rv);
step->setNodeTest(nsnull);
// Remove the step from the UnionExpr
uni->deleteExprAt(i);
--i;

Просмотреть файл

@ -116,20 +116,18 @@ DocumentFunctionCall::evaluate(txIEvalContext* aContext,
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
}
txListIterator iter(&params);
Expr* param1 = (Expr*)iter.next();
nsRefPtr<txAExprResult> exprResult1;
rv = param1->evaluate(aContext, getter_AddRefs(exprResult1));
rv = mParams[0]->evaluate(aContext, getter_AddRefs(exprResult1));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString baseURI;
MBool baseURISet = MB_FALSE;
if (iter.hasNext()) {
if (mParams.Length() == 2) {
// We have 2 arguments, get baseURI from the first node
// in the resulting nodeset
nsRefPtr<txNodeSet> nodeSet2;
rv = evaluateToNodeSet(NS_STATIC_CAST(Expr*, iter.next()),
rv = evaluateToNodeSet(mParams[1],
aContext, getter_AddRefs(nodeSet2));
NS_ENSURE_SUCCESS(rv, rv);

Просмотреть файл

@ -149,11 +149,8 @@ txEXSLTNodeSetFunctionCall::evaluate(txIEvalContext *aContext,
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
}
txListIterator iter(&params);
Expr* param1 = NS_STATIC_CAST(Expr*, iter.next());
nsRefPtr<txAExprResult> exprResult;
nsresult rv = param1->evaluate(aContext, getter_AddRefs(exprResult));
nsresult rv = mParams[0]->evaluate(aContext, getter_AddRefs(exprResult));
NS_ENSURE_SUCCESS(rv, rv);
if (exprResult->getResultType() == txAExprResult::NODESET) {
@ -244,11 +241,8 @@ txEXSLTObjectTypeFunctionCall::evaluate(txIEvalContext *aContext,
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
}
txListIterator iter(&params);
Expr* param1 = NS_STATIC_CAST(Expr*, iter.next());
nsRefPtr<txAExprResult> exprResult;
nsresult rv = param1->evaluate(aContext, getter_AddRefs(exprResult));
nsresult rv = mParams[0]->evaluate(aContext, getter_AddRefs(exprResult));
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<StringResult> strRes;

Просмотреть файл

@ -81,22 +81,18 @@ txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext,
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
// Get number and format
txListIterator iter(&params);
double value;
txExpandedName formatName;
value = evaluateToNumber((Expr*)iter.next(), aContext);
value = evaluateToNumber(mParams[0], aContext);
nsAutoString formatStr;
Expr* param = NS_STATIC_CAST(Expr*, iter.next());
nsresult rv = param->evaluateToString(aContext, formatStr);
nsresult rv = mParams[1]->evaluateToString(aContext, formatStr);
NS_ENSURE_SUCCESS(rv, rv);
if (iter.hasNext()) {
if (mParams.Length() == 3) {
nsAutoString formatQName;
param = NS_STATIC_CAST(Expr*, iter.next());
rv = param->evaluateToString(aContext, formatQName);
rv = mParams[2]->evaluateToString(aContext, formatQName);
NS_ENSURE_SUCCESS(rv, rv);
rv = formatName.init(formatQName, mMappings, MB_FALSE);

Просмотреть файл

@ -69,7 +69,7 @@ GenerateIdFunctionCall::evaluate(txIEvalContext* aContext,
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
nsresult rv = NS_OK;
if (params.getLength() != 1) {
if (mParams.IsEmpty()) {
StringResult* strRes;
rv = aContext->recycler()->getStringResult(&strRes);
NS_ENSURE_SUCCESS(rv, rv);
@ -82,9 +82,8 @@ GenerateIdFunctionCall::evaluate(txIEvalContext* aContext,
return NS_OK;
}
txListIterator iter(&params);
nsRefPtr<txNodeSet> nodes;
rv = evaluateToNodeSet(NS_STATIC_CAST(Expr*, iter.next()), aContext,
rv = evaluateToNodeSet(mParams[0], aContext,
getter_AddRefs(nodes));
NS_ENSURE_SUCCESS(rv, rv);
@ -114,7 +113,7 @@ GenerateIdFunctionCall::getReturnType()
PRBool
GenerateIdFunctionCall::isSensitiveTo(ContextSensitivity aContext)
{
if (params.isEmpty()) {
if (mParams.IsEmpty()) {
return !!(aContext & NODE_CONTEXT);
}

Просмотреть файл

@ -75,11 +75,8 @@ txKeyFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
txExecutionState* es =
NS_STATIC_CAST(txExecutionState*, aContext->getPrivateContext());
txListIterator iter(&params);
nsAutoString keyQName;
Expr* param = NS_STATIC_CAST(Expr*, iter.next());
nsresult rv = param->evaluateToString(aContext, keyQName);
nsresult rv = mParams[0]->evaluateToString(aContext, keyQName);
NS_ENSURE_SUCCESS(rv, rv);
txExpandedName keyName;
@ -87,7 +84,7 @@ txKeyFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<txAExprResult> exprResult;
rv = ((Expr*)iter.next())->evaluate(aContext, getter_AddRefs(exprResult));
rv = mParams[1]->evaluate(aContext, getter_AddRefs(exprResult));
NS_ENSURE_SUCCESS(rv, rv);
txXPathTreeWalker walker(aContext->getContextNode());

Просмотреть файл

@ -68,6 +68,8 @@ txStylesheet::init()
nsAutoPtr<Expr> nodeExpr(new LocationStep(nt, LocationStep::CHILD_AXIS));
NS_ENSURE_TRUE(nodeExpr, NS_ERROR_OUT_OF_MEMORY);
nt.forget();
txPushNewContext* pushContext = new txPushNewContext(nodeExpr);
mContainerTemplate->mNext = pushContext;
NS_ENSURE_TRUE(pushContext, NS_ERROR_OUT_OF_MEMORY);
@ -95,6 +97,8 @@ txStylesheet::init()
nodeExpr = new LocationStep(nt, LocationStep::SELF_AXIS);
NS_ENSURE_TRUE(nodeExpr, NS_ERROR_OUT_OF_MEMORY);
nt.forget();
mCharactersTemplate = new txValueOf(nodeExpr, PR_FALSE);
NS_ENSURE_TRUE(mCharactersTemplate, NS_ERROR_OUT_OF_MEMORY);
@ -427,16 +431,16 @@ txStylesheet::addTemplate(txTemplateItem* aTemplate,
// Add the simple patterns to the list of matchable templates, according
// to default priority
txList simpleMatches;
rv = aTemplate->mMatch->getSimplePatterns(simpleMatches);
if (simpleMatches.get(0) == aTemplate->mMatch) {
aTemplate->mMatch.forget();
nsAutoPtr<txPattern> simple = aTemplate->mMatch;
nsAutoPtr<txPattern> unionPattern;
if (simple->getType() == txPattern::UNION_PATTERN) {
unionPattern = simple;
simple = unionPattern->getSubPatternAt(0);
unionPattern->setSubPatternAt(0, nsnull);
}
txListIterator simples(&simpleMatches);
while (simples.hasNext()) {
// XXX if we fail in this loop, we leak the remaining simple patterns
nsAutoPtr<txPattern> simple(NS_STATIC_CAST(txPattern*, simples.next()));
PRUint32 unionPos = 1; // only used when unionPattern is set
while (simple) {
double priority = aTemplate->mPrio;
if (Double::isNaN(priority)) {
priority = simple->getDefaultPriority();
@ -457,6 +461,14 @@ txStylesheet::addTemplate(txTemplateItem* aTemplate,
nt->mFirstInstruction = instr;
nt->mMatch = simple;
nt->mPriority = priority;
if (unionPattern) {
simple = unionPattern->getSubPatternAt(unionPos);
if (simple) {
unionPattern->setSubPatternAt(unionPos, nsnull);
}
++unionPos;
}
}
return NS_OK;

Просмотреть файл

@ -1457,6 +1457,8 @@ txFnStartApplyTemplates(PRInt32 aNamespaceID,
select = new LocationStep(nt, LocationStep::CHILD_AXIS);
NS_ENSURE_TRUE(select, NS_ERROR_OUT_OF_MEMORY);
nt.forget();
}
nsAutoPtr<txPushNewContext> pushcontext(new txPushNewContext(select));
@ -2336,6 +2338,8 @@ txFnStartSort(PRInt32 aNamespaceID,
select = new LocationStep(nt, LocationStep::SELF_AXIS);
NS_ENSURE_TRUE(select, NS_ERROR_OUT_OF_MEMORY);
nt.forget();
}
nsAutoPtr<Expr> lang;

Просмотреть файл

@ -54,11 +54,8 @@ txXSLTEnvironmentFunctionCall::evaluate(txIEvalContext* aContext,
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
}
txListIterator iter(&params);
Expr* param = (Expr*)iter.next();
nsAutoString property;
nsresult rv = param->evaluateToString(aContext, property);
nsresult rv = mParams[0]->evaluateToString(aContext, property);
NS_ENSURE_SUCCESS(rv, rv);
txExpandedName qname;

Просмотреть файл

@ -48,49 +48,6 @@
#include "nsIContent.h"
#endif
/*
* txPattern
*
* Base class of all patterns
* Implements only a default getSimplePatterns
*/
nsresult txPattern::getSimplePatterns(txList& aList)
{
aList.add(this);
return NS_OK;
}
txPattern::~txPattern()
{
}
/*
* txUnionPattern
*
* This pattern is returned by the parser for "foo | bar" constructs.
* |xsl:template|s should use the simple patterns
*/
/*
* Destructor, deletes all LocationPathPatterns
*/
txUnionPattern::~txUnionPattern()
{
txListIterator iter(&mLocPathPatterns);
while (iter.hasNext()) {
delete (txPattern*)iter.next();
}
}
nsresult txUnionPattern::addPattern(txPattern* aPattern)
{
if (!aPattern)
return NS_ERROR_NULL_POINTER;
mLocPathPatterns.add(aPattern);
return NS_OK;
}
/*
* Returns the default priority of this Pattern.
* UnionPatterns don't like this.
@ -110,39 +67,34 @@ double txUnionPattern::getDefaultPriority()
*/
MBool txUnionPattern::matches(const txXPathNode& aNode, txIMatchContext* aContext)
{
txListIterator iter(&mLocPathPatterns);
while (iter.hasNext()) {
txPattern* p = (txPattern*)iter.next();
if (p->matches(aNode, aContext)) {
PRUint32 i, len = mLocPathPatterns.Length();
for (i = 0; i < len; ++i) {
if (mLocPathPatterns[i]->matches(aNode, aContext)) {
return MB_TRUE;
}
}
return MB_FALSE;
}
nsresult txUnionPattern::getSimplePatterns(txList& aList)
txPattern::Type
txUnionPattern::getType()
{
txListIterator iter(&mLocPathPatterns);
while (iter.hasNext()) {
aList.add(iter.next());
iter.remove();
}
return NS_OK;
return UNION_PATTERN;
}
TX_IMPL_PATTERN_STUBS_NO_SUB_EXPR(txUnionPattern)
txPattern*
txUnionPattern::getSubPatternAt(PRUint32 aPos)
{
return NS_STATIC_CAST(txPattern*, mLocPathPatterns.get(aPos));
return mLocPathPatterns.SafeElementAt(aPos);
}
void
txUnionPattern::setSubPatternAt(PRUint32 aPos, txPattern* aPattern)
{
NS_ASSERTION(aPos < (PRUint32)mLocPathPatterns.getLength(),
NS_ASSERTION(aPos < mLocPathPatterns.Length(),
"setting bad subexpression index");
mLocPathPatterns.replace(aPos, aPattern);
mLocPathPatterns[aPos] = aPattern;
}
@ -153,12 +105,10 @@ txUnionPattern::toString(nsAString& aDest)
#ifdef DEBUG
aDest.AppendLiteral("txUnionPattern{");
#endif
txListIterator iter(&mLocPathPatterns);
if (iter.hasNext())
((txPattern*)iter.next())->toString(aDest);
while (iter.hasNext()) {
aDest.AppendLiteral(" | ");
((txPattern*)iter.next())->toString(aDest);
for (PRUint32 i = 0; i < mLocPathPatterns.Length(); ++i) {
if (i != 0)
aDest.AppendLiteral(" | ");
mLocPathPatterns[i]->toString(aDest);
}
#ifdef DEBUG
aDest.Append(PRUnichar('}'));
@ -174,31 +124,21 @@ txUnionPattern::toString(nsAString& aDest)
* (dealt with by the parser)
*/
/*
* Destructor, deletes all PathPatterns
*/
txLocPathPattern::~txLocPathPattern()
nsresult txLocPathPattern::addStep(txPattern* aPattern, PRBool isChild)
{
txListIterator iter(&mSteps);
while (iter.hasNext()) {
delete (Step*)iter.next();
}
}
nsresult txLocPathPattern::addStep(txPattern* aPattern, MBool isChild)
{
if (!aPattern)
return NS_ERROR_NULL_POINTER;
Step* step = new Step(aPattern, isChild);
Step* step = mSteps.AppendElement();
if (!step)
return NS_ERROR_OUT_OF_MEMORY;
mSteps.add(step);
step->pattern = aPattern;
step->isChild = isChild;
return NS_OK;
}
MBool txLocPathPattern::matches(const txXPathNode& aNode, txIMatchContext* aContext)
{
NS_ASSERTION(mSteps.getLength(), "Internal error");
NS_ASSERTION(mSteps.Length() > 1, "Internal error");
/*
* The idea is to split up a path into blocks separated by descendant
@ -212,11 +152,8 @@ MBool txLocPathPattern::matches(const txXPathNode& aNode, txIMatchContext* aCont
* tree.
*/
txListIterator iter(&mSteps);
iter.resetToEnd();
Step* step;
step = (Step*)iter.previous();
PRUint32 pos = mSteps.Length();
Step* step = &mSteps[--pos];
if (!step->pattern->matches(aNode, aContext))
return MB_FALSE;
@ -224,9 +161,9 @@ MBool txLocPathPattern::matches(const txXPathNode& aNode, txIMatchContext* aCont
PRBool hasParent = walker.moveToParent();
while (step->isChild) {
step = (Step*)iter.previous();
if (!step)
if (!pos)
return MB_TRUE; // all steps matched
step = &mSteps[--pos];
if (!hasParent || !step->pattern->matches(walker.getCurrentPosition(), aContext))
return MB_FALSE; // no more ancestors or no match
@ -235,25 +172,26 @@ MBool txLocPathPattern::matches(const txXPathNode& aNode, txIMatchContext* aCont
// We have at least one // path separator
txXPathTreeWalker blockWalker(walker);
txListIterator blockIter(iter);
PRUint32 blockPos = pos;
while ((step = (Step*)iter.previous())) {
while (pos) {
if (!hasParent)
return MB_FALSE; // There are more steps in the current block
// than ancestors of the tested node
step = &mSteps[--pos];
if (!step->pattern->matches(walker.getCurrentPosition(), aContext)) {
// Didn't match. We restart at beginning of block using a new
// start node
iter = blockIter;
pos = blockPos;
hasParent = blockWalker.moveToParent();
walker.moveTo(blockWalker);
}
else {
hasParent = walker.moveToParent();
if (!step->isChild) {
// We've matched an entire block. Set new start iter and start node
blockIter = iter;
// We've matched an entire block. Set new start pos and start node
blockPos = pos;
blockWalker.moveTo(walker);
}
}
@ -264,28 +202,23 @@ MBool txLocPathPattern::matches(const txXPathNode& aNode, txIMatchContext* aCont
double txLocPathPattern::getDefaultPriority()
{
if (mSteps.getLength() > 1) {
return 0.5;
}
NS_ASSERTION(mSteps.Length() > 1, "Internal error");
return ((Step*)mSteps.get(0))->pattern->getDefaultPriority();
return 0.5;
}
TX_IMPL_PATTERN_STUBS_NO_SUB_EXPR(txLocPathPattern)
txPattern*
txLocPathPattern::getSubPatternAt(PRUint32 aPos)
{
Step* step = NS_STATIC_CAST(Step*, mSteps.get(aPos));
return step ? step->pattern.get() : nsnull;
return aPos < mSteps.Length() ? mSteps[aPos].pattern.get() : nsnull;
}
void
txLocPathPattern::setSubPatternAt(PRUint32 aPos, txPattern* aPattern)
{
NS_ASSERTION(aPos < (PRUint32)mSteps.getLength(),
"setting bad subexpression index");
Step* step = NS_STATIC_CAST(Step*, mSteps.get(aPos));
NS_ASSERTION(aPos < mSteps.Length(), "setting bad subexpression index");
Step* step = &mSteps[aPos];
step->pattern.forget();
step->pattern = aPattern;
}
@ -294,21 +227,17 @@ txLocPathPattern::setSubPatternAt(PRUint32 aPos, txPattern* aPattern)
void
txLocPathPattern::toString(nsAString& aDest)
{
txListIterator iter(&mSteps);
#ifdef DEBUG
aDest.AppendLiteral("txLocPathPattern{");
#endif
Step* step;
step = (Step*)iter.next();
if (step) {
step->pattern->toString(aDest);
}
while ((step = (Step*)iter.next())) {
if (step->isChild)
aDest.Append(PRUnichar('/'));
else
aDest.AppendLiteral("//");
step->pattern->toString(aDest);
for (PRUint32 i = 0; i < mSteps.Length(); ++i) {
if (i != 0) {
if (mSteps[i].isChild)
aDest.Append(PRUnichar('/'));
else
aDest.AppendLiteral("//");
}
mSteps[i].pattern->toString(aDest);
}
#ifdef DEBUG
aDest.Append(PRUnichar('}'));
@ -322,10 +251,6 @@ txLocPathPattern::toString(nsAString& aDest)
* a txPattern matching the document node, or '/'
*/
txRootPattern::~txRootPattern()
{
}
MBool txRootPattern::matches(const txXPathNode& aNode, txIMatchContext* aContext)
{
return txXPathNodeUtils::isRoot(aNode);
@ -372,10 +297,6 @@ txIdPattern::txIdPattern(const nsSubstring& aString)
}
}
txIdPattern::~txIdPattern()
{
}
MBool txIdPattern::matches(const txXPathNode& aNode, txIMatchContext* aContext)
{
if (!txXPathNodeUtils::isElement(aNode)) {
@ -444,10 +365,6 @@ txIdPattern::toString(nsAString& aDest)
* argument.
*/
txKeyPattern::~txKeyPattern()
{
}
MBool txKeyPattern::matches(const txXPathNode& aNode, txIMatchContext* aContext)
{
txExecutionState* es = (txExecutionState*)aContext->getPrivateContext();
@ -551,13 +468,13 @@ MBool txStepPattern::matches(const txXPathNode& aNode, txIMatchContext* aContext
walker.moveToNextSibling();
}
txListIterator iter(&predicates);
Expr* predicate = (Expr*)iter.next();
Expr* predicate = mPredicates[0];
nsRefPtr<txNodeSet> newNodes;
rv = aContext->recycler()->getNodeSet(getter_AddRefs(newNodes));
NS_ENSURE_SUCCESS(rv, rv);
while (iter.hasNext()) {
PRUint32 i, predLen = mPredicates.Length();
for (i = 1; i < predLen; ++i) {
newNodes->clear();
MBool contextIsInPredicate = MB_FALSE;
txNodeSetContext predContext(nodes, aContext);
@ -594,7 +511,7 @@ MBool txStepPattern::matches(const txXPathNode& aNode, txIMatchContext* aContext
if (!contextIsInPredicate) {
return MB_FALSE;
}
predicate = (Expr*)iter.next();
predicate = mPredicates[i];
}
txForwardContext evalContext(aContext, aNode, nodes);
nsRefPtr<txAExprResult> exprResult;

Просмотреть файл

@ -48,8 +48,6 @@ class ProcessorState;
class txPattern
{
public:
virtual ~txPattern();
/*
* Determines whether this Pattern matches the given node.
*/
@ -64,21 +62,12 @@ public:
*/
virtual double getDefaultPriority() = 0;
/*
* Adds the simple Patterns to the List.
* For union patterns, add all sub patterns,
* all other (simple) patterns just add themselves.
* This cuts the ownership of the union pattern and it's
* simple patterns, leaving union patterns empty after a call
* to this function.
*/
virtual nsresult getSimplePatterns(txList &aList);
/**
* Returns the type of this pattern.
*/
enum Type {
STEP_PATTERN,
UNION_PATTERN,
OTHER_PATTERN
};
virtual Type getType()
@ -137,10 +126,6 @@ public:
void toString(nsAString& aDest)
#endif
#define TX_DECL_PATTERN2 \
TX_DECL_PATTERN; \
nsresult getSimplePatterns(txList &aList)
#define TX_IMPL_PATTERN_STUBS_NO_SUB_EXPR(_class) \
Expr* \
_class::getSubExprAt(PRUint32 aPos) \
@ -168,59 +153,45 @@ _class::setSubPatternAt(PRUint32 aPos, txPattern* aPattern) \
class txUnionPattern : public txPattern
{
public:
txUnionPattern()
nsresult addPattern(txPattern* aPattern)
{
return mLocPathPatterns.AppendElement(aPattern) ?
NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
~txUnionPattern();
nsresult addPattern(txPattern* aPattern);
TX_DECL_PATTERN2;
TX_DECL_PATTERN;
Type getType();
private:
txList mLocPathPatterns;
txOwningArray<txPattern> mLocPathPatterns;
};
class txLocPathPattern : public txPattern
{
public:
txLocPathPattern()
{
}
~txLocPathPattern();
nsresult addStep(txPattern* aPattern, MBool isChild);
nsresult addStep(txPattern* aPattern, PRBool isChild);
TX_DECL_PATTERN;
private:
class Step {
public:
Step(txPattern* aPattern, MBool aIsChild)
: pattern(aPattern), isChild(aIsChild)
{
}
nsAutoPtr<txPattern> pattern;
MBool isChild;
PRBool isChild;
};
txList mSteps;
nsTArray<Step> mSteps;
};
class txRootPattern : public txPattern
{
public:
txRootPattern()
#ifdef TX_TO_STRING
txRootPattern()
: mSerialize(PR_TRUE)
#endif
{
}
~txRootPattern();
#endif
TX_DECL_PATTERN;
@ -242,8 +213,6 @@ class txIdPattern : public txPattern
public:
txIdPattern(const nsSubstring& aString);
~txIdPattern();
TX_DECL_PATTERN;
private:
@ -259,21 +228,22 @@ public:
{
}
~txKeyPattern();
TX_DECL_PATTERN;
private:
txExpandedName mName;
nsIAtom* mPrefix;
#ifdef TX_TO_STRING
nsCOMPtr<nsIAtom> mPrefix;
#endif
nsString mValue;
};
class txStepPattern : public PredicateList, public txPattern
class txStepPattern : public txPattern,
public PredicateList
{
public:
txStepPattern(txNodeTest* aNodeTest, MBool isAttr)
:mNodeTest(aNodeTest), mIsAttr(isAttr)
txStepPattern(txNodeTest* aNodeTest, PRBool isAttr)
: mNodeTest(aNodeTest), mIsAttr(isAttr)
{
}
@ -292,7 +262,7 @@ public:
private:
nsAutoPtr<txNodeTest> mNodeTest;
MBool mIsAttr;
PRBool mIsAttr;
};
#endif // TX_XSLT_PATTERNS_H