зеркало из https://github.com/mozilla/pjs.git
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:
Родитель
f285d2acf6
Коммит
8c36ac1947
|
@ -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(¶ms);
|
||||
|
||||
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(¶ms);
|
||||
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(¶ms);
|
||||
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(¶ms);
|
||||
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(¶ms);
|
||||
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 ¶mInfo = 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(¶ms);
|
||||
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(¶ms);
|
||||
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(¶ms);
|
||||
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(¶ms);
|
||||
|
||||
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(¶ms);
|
||||
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(¶ms);
|
||||
|
||||
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(¶ms);
|
||||
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
|
||||
|
|
Загрузка…
Ссылка в новой задаче