//**************************************************************************************************************************
//* Blue Xml Extension
//* Copyright (c) 2002-2003 Josh Harler
//*
//* Blue - General Purpose C++ Library
//* Copyright (c) 2002-2003 Josh Harler
//*
//* This software is provided 'as-is', without any express or implied warranty. In no event
//* will the authors be held liable for any damages arising from the use of this software.
//*
//* Permission is granted to anyone to use this software for any purpose, including commercial
//* applications, and to alter it and redistribute it freely, subject to the following restrictions:
//*
//* 1. The origin of this software must not be misrepresented; you must not claim that you
//* wrote the original software. If you use this software in a product, an acknowledgment in the
//* product documentation would be appreciated but is not required.
//*
//* 2. Altered source versions must be plainly marked as such, and must not be misrepresented as
//* being the original software.
//*
//* 3. This notice may not be removed or altered from any source distribution.
//*
//* Modified by JCrane2 to support PugXML parser:
//* http://www.codeproject.com/soap/pugxml.asp
//* http://www.codeproject.com/soap/JCraneArticle.asp
//*
//* file PugXPathFunctions.h
//**
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_PUGXPATHFUNCTIONS_H__C26C32BB_0BCE_4ED3_8E62_57A61A18820A__INCLUDED_)
#define AFX_PUGXPATHFUNCTIONS_H__C26C32BB_0BCE_4ED3_8E62_57A61A18820A__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "PugXPathExpression.h"
// Include the Pug XML library.
#include "pugxml.h"
#include <sstream>
#include <io.h>
#include <sys\stat.h>
using namespace std;
using namespace pug;
namespace blue
{
namespace ext
{
namespace xml
{
/****
* Functions
*/
class PugXPathFunctionCount;
// class PugXPathFunctionId;
class PugXPathFunctionLast;
class PugXPathFunctionLocalName;
class PugXPathFunctionName;
// class PugXPathFunctionNamespaceUri;
class PugXPathFunctionPosition;
class PugXPathFunctionConcat;
class PugXPathFunctionContains;
class PugXPathFunctionNormalizeSpace;
class PugXPathFunctionStartsWith;
class PugXPathFunctionString;
class PugXPathFunctionStringLength;
class PugXPathFunctionSubstring;
class PugXPathFunctionSubstringAfter;
class PugXPathFunctionSubstringBefore;
class PugXPathFunctionTranslate;
class PugXPathFunctionCeiling;
class PugXPathFunctionFloor;
class PugXPathFunctionRound;
class PugXPathFunctionSum;
class PugXPathFunctionBoolean;
class PugXPathFunctionFalse;
// class PugXPathFunctionLang;
class PugXPathFunctionNot;
class PugXPathFunctionTrue;
/****
* Operators
*/
class PugXPathOperatorOr;
class PugXPathOperatorAnd;
class PugXPathOperatorNotEqual;
class PugXPathOperatorLessEqual;
class PugXPathOperatorLess;
class PugXPathOperatorGreatEqual;
class PugXPathOperatorGreat;
class PugXPathOperatorAdd;
class PugXPathOperatorSub;
class PugXPathOperatorMult;
class PugXPathOperatorDiv;
class PugXPathOperatorMod;
class PugXPathOperatorEqual;
/****
* \class PugXPathFunctionCount
*/
class PugXPathFunctionCount :public PugXPathFunction
{
public:
PugXPathFunctionCount() :PugXPathFunction("count", 1)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], PugXPathToken::NODESET);
return PugXPathToken(parms[0].getValueNodeSet(context).getSize());
}
};
/****
* \class PugXPathFunctionLast
*/
class PugXPathFunctionLast :public PugXPathFunction
{
public:
PugXPathFunctionLast() :PugXPathFunction("last", 0)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
return PugXPathToken(search.getSize());
}
};
/****
* \class PugXPathFunctionLocalName
*/
class PugXPathFunctionLocalName :public PugXPathFunction
{
public:
PugXPathFunctionLocalName() :PugXPathFunction("local-name", 0)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
BString name = context->name;
int posColon = name.findPos(":");
if (posColon != BString::npos)
{
name = name.stripFromLeft(posColon + 1);
}
return PugXPathToken(name);
}
};
/****
* \class PugXPathFunctionName
*/
class PugXPathFunctionName :public PugXPathFunction
{
public:
PugXPathFunctionName() :PugXPathFunction("name", 0)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
return PugXPathToken(BString(context->name));
}
};
/****
* \class PugXPathFunctionPosition
*/
class PugXPathFunctionPosition :public PugXPathFunction
{
public:
PugXPathFunctionPosition() :PugXPathFunction("position", 0)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
for (int i = 0; i < search.getSize(); ++i)
{
if (search[i] == context)
{
return PugXPathToken(i + 1);
}
}
return PugXPathToken(1);
}
};
/****
* \class PugXPathFunctionConcat
*/
class PugXPathFunctionConcat :public PugXPathFunction
{
public:
PugXPathFunctionConcat() :PugXPathFunction("concat", -1)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
BString result;
for (int i = 0; i < parms.getSize(); ++i)
{
validateParm(parms[0], PugXPathToken::STRING);
result += parms[0].getValue(context);
}
return PugXPathToken(result);
}
};
/****
* \class PugXPathFunctionContains
*/
class PugXPathFunctionContains :public PugXPathFunction
{
public:
PugXPathFunctionContains() :PugXPathFunction("contains", 2)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], PugXPathToken::STRING);
validateParm(parms[1], PugXPathToken::STRING);
return PugXPathToken(parms[0].getValue(context).findPos(parms[1].getValue(context)) != BString::npos);
}
};
/****
* \class PugXPathFunctionNormalizeSpace
*/
class PugXPathFunctionNormalizeSpace :public PugXPathFunction
{
public:
PugXPathFunctionNormalizeSpace() :PugXPathFunction("normalize-space", 1)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], PugXPathToken::STRING);
return PugXPathToken(parms[0].getValue(context).trim());
}
};
/****
* \class PugXPathFunctionStartsWith
*/
class PugXPathFunctionStartsWith :public PugXPathFunction
{
public:
PugXPathFunctionStartsWith() :PugXPathFunction("starts-with", 2)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], PugXPathToken::STRING);
validateParm(parms[1], PugXPathToken::STRING);
return PugXPathToken(parms[0].getValue(context).beginsWith(parms[1].getValue(context)));
}
};
/****
* \class PugXPathFunctionString
*/
class PugXPathFunctionString :public PugXPathFunction
{
public:
PugXPathFunctionString() :PugXPathFunction("string", 1)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
return PugXPathToken((parms[0].isCompatibleWith(PugXPathToken::STRING) ? parms[0].getValue(context) : BString::null));
}
};
/****
* \class PugXPathFunctionStringLength
*/
class PugXPathFunctionStringLength :public PugXPathFunction
{
public:
PugXPathFunctionStringLength() :PugXPathFunction("string-length", 1)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], PugXPathToken::STRING);
return PugXPathToken(parms[0].getValue(context).getLength());
}
};
/****
* \class PugXPathFunctionSubstring
*/
class PugXPathFunctionSubstring :public PugXPathFunction
{
public:
PugXPathFunctionSubstring() :PugXPathFunction("substring", 3)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], PugXPathToken::STRING);
validateParm(parms[1], PugXPathToken::NUMBER_INT);
validateParm(parms[2], PugXPathToken::NUMBER_INT);
return PugXPathToken(parms[0].getValue(context).subString(parms[1].getValueNumberInt(), parms[2].getValueNumberInt()));
}
};
/****
* \class PugXPathFunctionSubstringAfter
*/
class PugXPathFunctionSubstringAfter :public PugXPathFunction
{
public:
PugXPathFunctionSubstringAfter() :PugXPathFunction("substring-after", 2)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], PugXPathToken::STRING);
validateParm(parms[1], PugXPathToken::STRING);
BString value1 = parms[0].getValue(context);
BString value2 = parms[1].getValue(context);
return PugXPathToken(value1.subString(value1.findPos(value2)));
}
};
/****
* \class PugXPathFunctionSubstringBefore
*/
class PugXPathFunctionSubstringBefore :public PugXPathFunction
{
public:
PugXPathFunctionSubstringBefore() :PugXPathFunction("substring-before", 2)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], PugXPathToken::STRING);
validateParm(parms[1], PugXPathToken::STRING);
BString value1 = parms[0].getValue(context);
BString value2 = parms[1].getValue(context);
int pos = value1.findPos(value2);
if (pos == BString::npos)
{
pos = value1.getLength();
}
return PugXPathToken(value1.left(pos));
}
};
/****
* \class PugXPathFunctionTranslate
*/
class PugXPathFunctionTranslate :public PugXPathFunction
{
public:
PugXPathFunctionTranslate() :PugXPathFunction("translate", 3)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> , xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], PugXPathToken::STRING);
validateParm(parms[1], PugXPathToken::STRING);
validateParm(parms[2], PugXPathToken::STRING);
BString source = parms[0].getValue(context);
BString search = parms[1].getValue(context);
BString transl = parms[2].getValue(context);
BString result;
if (search.getLength() != transl.getLength())
{
throw PugXPathException("The second and third parameters to PugXPath function 'translate' must be the same length");
}
for (int i = 0; i < source.getLength(); ++i)
{
char ch = source[i];
for (int iS = 0; iS < search.getLength(); ++iS)
{
if (ch == search[iS])
{
ch = transl[iS];
}
}
result += ch;
}
return PugXPathToken(result);
}
};
/****
* \class PugXPathFunctionCeiling
*/
class PugXPathFunctionCeiling :public PugXPathFunction
{
public:
PugXPathFunctionCeiling() :PugXPathFunction("ceiling", 1)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], PugXPathToken::NUMBER_DBL);
double dblValue = parms[0].getValueNumberDouble();
int intValue = (int)dblValue;
if ((double)intValue < dblValue)
{
return PugXPathToken(intValue + 1);
}
else
{
return PugXPathToken(intValue);
}
}
};
/****
* \class PugXPathFunctionFloor
*/
class PugXPathFunctionFloor :public PugXPathFunction
{
public:
PugXPathFunctionFloor() :PugXPathFunction("floor", 1)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], PugXPathToken::NUMBER_DBL);
if (parms[0].getValue(context).isValidInt())
{
return PugXPathToken(parms[0].getValueNumberInt());
}
double dblValue = parms[0].getValueNumberDouble();
int intValue = (int)dblValue;
if ((double)(intValue + 1) > dblValue)
{
return PugXPathToken(intValue);
}
else
{
return PugXPathToken(intValue + 1);
}
}
};
/****
* \class PugXPathFunctionRound
*/
class PugXPathFunctionRound :public PugXPathFunction
{
public:
PugXPathFunctionRound() :PugXPathFunction("round", 1)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], PugXPathToken::NUMBER_DBL);
if (parms[0].getValue(context).isValidInt())
{
return PugXPathToken(parms[0].getValueNumberInt());
}
double dblValue = parms[0].getValueNumberDouble();
if (dblValue >= 0)
{
return PugXPathToken((int)(dblValue + .5));
}
else
{
return PugXPathToken((int)(dblValue - .5));
}
}
};
/****
* \class PugXPathFunctionSum
*/
class PugXPathFunctionSum :public PugXPathFunction
{
public:
PugXPathFunctionSum() :PugXPathFunction("sum", 1)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], PugXPathToken::NODESET);
Array<xml_node_struct*> nodes = parms[0].getValueNodeSet(context);
double total = 0;
for (int i = 0; i < nodes.getSize(); ++i)
{
BString value;
if (nodes[i]->type == node_pcdata)
nodes[i]->child[0]->value;
else
nodes[i]->value;
if (!PugXPathToken(value).isCompatibleWith(PugXPathToken::NUMBER_DBL))
{
throw PugXPathException("Node does not contain a valid numeric data for use with function 'sum'");
}
total += value.getAsDouble();
}
return PugXPathToken(total);
}
};
/****
* \class PugXPathFunctionBoolean
*/
class PugXPathFunctionBoolean :public PugXPathFunction
{
public:
PugXPathFunctionBoolean() :PugXPathFunction("boolean", 1)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
if (parms[0].isCompatibleWith(PugXPathToken::BOOLEAN))
{
return PugXPathToken(parms[0].getValueBool());
}
return PugXPathToken(false);
}
};
/****
* \class PugXPathFunctionFalse
*/
class PugXPathFunctionFalse :public PugXPathFunction
{
public:
PugXPathFunctionFalse() :PugXPathFunction("false", 0)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
return PugXPathToken(false);
}
};
/****
* \class PugXPathFunctionNot
*/
class PugXPathFunctionNot :public PugXPathFunction
{
public:
PugXPathFunctionNot() :PugXPathFunction("not", 1)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], PugXPathToken::BOOLEAN);
if (parms[0].getType() == PugXPathToken::NODESET)
{
Array<xml_node_struct*> results = parms[0].getValueNodeSet(context);
return PugXPathToken(results.getSize() == 0);
}
return PugXPathToken(!parms[0].getValueBool());
}
};
/****
* \class PugXPathFunctionTrue
*/
class PugXPathFunctionTrue :public PugXPathFunction
{
public:
PugXPathFunctionTrue() :PugXPathFunction("true", 0)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
return PugXPathToken(true);
}
};
/****
* \class PugXPathOperatorOr
*/
class PugXPathOperatorOr :public PugXPathFunction
{
public:
PugXPathOperatorOr() :PugXPathFunction("or", 2)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], PugXPathToken::BOOLEAN);
validateParm(parms[1], PugXPathToken::BOOLEAN);
return PugXPathToken(parms[0].getValueBool() || parms[1].getValueBool());
}
};
/****
* \class PugXPathOperatorAnd
*/
class PugXPathOperatorAnd :public PugXPathFunction
{
public:
PugXPathOperatorAnd() :PugXPathFunction("and", 2)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], PugXPathToken::BOOLEAN);
validateParm(parms[1], PugXPathToken::BOOLEAN);
return PugXPathToken(parms[0].getValueBool() && parms[1].getValueBool());
}
};
/****
* \class PugXPathOperatorNotEqual
*/
class PugXPathOperatorNotEqual :public PugXPathFunction
{
public:
PugXPathOperatorNotEqual() :PugXPathFunction("!=", 2)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], parms[1].getType());
if (parms[0].getType() == PugXPathToken::NUMBER_DBL || parms[1].getType() == PugXPathToken::NUMBER_DBL)
{
return PugXPathToken(parms[0].getValueNumberDouble() != parms[1].getValueNumberDouble());
}
if (parms[0].getType() == PugXPathToken::NUMBER_INT || parms[1].getType() == PugXPathToken::NUMBER_INT)
{
return PugXPathToken(parms[0].getValueNumberInt() != parms[1].getValueNumberInt());
}
return PugXPathToken(parms[0].getValue(context) != parms[1].getValue(context));
}
};
/****
* \class PugXPathOperatorLessEqual
*/
class PugXPathOperatorLessEqual :public PugXPathFunction
{
public:
PugXPathOperatorLessEqual() :PugXPathFunction("<=", 2)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], parms[1].getType());
if (parms[0].getType() == PugXPathToken::NUMBER_DBL || parms[1].getType() == PugXPathToken::NUMBER_DBL)
{
return PugXPathToken(parms[0].getValueNumberDouble() <= parms[1].getValueNumberDouble());
}
if (parms[0].getType() == PugXPathToken::NUMBER_INT || parms[1].getType() == PugXPathToken::NUMBER_INT)
{
return PugXPathToken(parms[0].getValueNumberInt() <= parms[1].getValueNumberInt());
}
return PugXPathToken(parms[0].getValue(context) <= parms[1].getValue(context));
}
};
/****
* \class PugXPathOperatorLess
*/
class PugXPathOperatorLess :public PugXPathFunction
{
public:
PugXPathOperatorLess() :PugXPathFunction("<", 2)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], parms[1].getType());
if (parms[0].getType() == PugXPathToken::NUMBER_DBL || parms[1].getType() == PugXPathToken::NUMBER_DBL)
{
return PugXPathToken(parms[0].getValueNumberDouble() < parms[1].getValueNumberDouble());
}
if (parms[0].getType() == PugXPathToken::NUMBER_INT || parms[1].getType() == PugXPathToken::NUMBER_INT)
{
return PugXPathToken(parms[0].getValueNumberInt() < parms[1].getValueNumberInt());
}
return PugXPathToken(parms[0].getValue(context) < parms[1].getValue(context));
}
};
/****
* \class PugXPathOperatorGreatEqual
*/
class PugXPathOperatorGreatEqual :public PugXPathFunction
{
public:
PugXPathOperatorGreatEqual() :PugXPathFunction(">=", 2)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], parms[1].getType());
if (parms[0].getType() == PugXPathToken::NUMBER_DBL || parms[1].getType() == PugXPathToken::NUMBER_DBL)
{
return PugXPathToken(parms[0].getValueNumberDouble() >= parms[1].getValueNumberDouble());
}
if (parms[0].getType() == PugXPathToken::NUMBER_INT || parms[1].getType() == PugXPathToken::NUMBER_INT)
{
return PugXPathToken(parms[0].getValueNumberInt() >= parms[1].getValueNumberInt());
}
return PugXPathToken(parms[0].getValue(context) >= parms[1].getValue(context));
}
};
/****
* \class PugXPathOperatorGreat
*/
class PugXPathOperatorGreat :public PugXPathFunction
{
public:
PugXPathOperatorGreat() :PugXPathFunction(">", 2)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], parms[1].getType());
if (parms[0].getType() == PugXPathToken::NUMBER_DBL || parms[1].getType() == PugXPathToken::NUMBER_DBL)
{
return PugXPathToken(parms[0].getValueNumberDouble() > parms[1].getValueNumberDouble());
}
if (parms[0].getType() == PugXPathToken::NUMBER_INT || parms[1].getType() == PugXPathToken::NUMBER_INT)
{
return PugXPathToken(parms[0].getValueNumberInt() > parms[1].getValueNumberInt());
}
return PugXPathToken(parms[0].getValue(context) > parms[1].getValue(context));
}
};
/****
* \class PugXPathOperatorAdd
*/
class PugXPathOperatorAdd :public PugXPathFunction
{
public:
PugXPathOperatorAdd() :PugXPathFunction("+", 2)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], parms[1].getType());
if (parms[0].getType() == PugXPathToken::NUMBER_DBL || parms[1].getType() == PugXPathToken::NUMBER_DBL)
{
return PugXPathToken(parms[0].getValueNumberDouble() + parms[1].getValueNumberDouble());
}
if (parms[0].getType() == PugXPathToken::NUMBER_INT || parms[1].getType() == PugXPathToken::NUMBER_INT)
{
return PugXPathToken(parms[0].getValueNumberInt() + parms[1].getValueNumberInt());
}
if (parms[0].getType() == PugXPathToken::STRING || parms[1].getType() == PugXPathToken::STRING)
{
return PugXPathToken(parms[0].getValue(context) + parms[1].getValue(context));
}
throw PugXPathException("Incompatible types for PugXPath operator '+'");
}
};
/****
* \class PugXPathOperatorSub
*/
class PugXPathOperatorSub :public PugXPathFunction
{
public:
PugXPathOperatorSub() :PugXPathFunction("-", 2)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], parms[1].getType());
if (parms[0].getType() == PugXPathToken::NUMBER_DBL || parms[1].getType() == PugXPathToken::NUMBER_DBL)
{
return PugXPathToken(parms[0].getValueNumberDouble() - parms[1].getValueNumberDouble());
}
if (parms[0].getType() == PugXPathToken::NUMBER_INT || parms[1].getType() == PugXPathToken::NUMBER_INT)
{
return PugXPathToken(parms[0].getValueNumberInt() - parms[1].getValueNumberInt());
}
throw PugXPathException("Incompatible types for PugXPath operator '-'");
}
};
/****
* \class PugXPathOperatorMult
*/
class PugXPathOperatorMult :public PugXPathFunction
{
public:
PugXPathOperatorMult() :PugXPathFunction("*", 2)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], parms[1].getType());
if (parms[0].getType() == PugXPathToken::NUMBER_DBL || parms[1].getType() == PugXPathToken::NUMBER_DBL)
{
return PugXPathToken(parms[0].getValueNumberDouble() * parms[1].getValueNumberDouble());
}
if (parms[0].getType() == PugXPathToken::NUMBER_INT || parms[1].getType() == PugXPathToken::NUMBER_INT)
{
return PugXPathToken(parms[0].getValueNumberInt() * parms[1].getValueNumberInt());
}
throw PugXPathException("Incompatible types for PugXPath operator '*'");
}
};
/****
* \class PugXPathOperatorDiv
*/
class PugXPathOperatorDiv :public PugXPathFunction
{
public:
PugXPathOperatorDiv() :PugXPathFunction("div", 2)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], parms[1].getType());
if (parms[0].getType() == PugXPathToken::NUMBER_DBL || parms[1].getType() == PugXPathToken::NUMBER_DBL)
{
if (parms[1].getValueNumberDouble() == 0.0)
{
throw PugXPathException("Divide by zero encountered in PugXPath expression");
}
return PugXPathToken(parms[0].getValueNumberDouble() / parms[1].getValueNumberDouble());
}
if (parms[0].getType() == PugXPathToken::NUMBER_INT || parms[1].getType() == PugXPathToken::NUMBER_INT)
{
if (parms[1].getValueNumberInt() == 0)
{
throw PugXPathException("Divide by zero encountered in PugXPath expression");
}
int parm0 = parms[0].getValueNumberInt();
int parm1 = parms[1].getValueNumberInt();
if (parm0 % parm1 == 0)
{
return PugXPathToken(parm0 / parm1);
}
else
{
return PugXPathToken(parms[0].getValueNumberDouble() / parms[1].getValueNumberDouble());
}
}
throw PugXPathException("Incompatible types for PugXPath operator 'div'");
}
};
/****
* \class PugXPathOperatorMod
*/
class PugXPathOperatorMod :public PugXPathFunction
{
public:
PugXPathOperatorMod() :PugXPathFunction("mod", 2)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], PugXPathToken::NUMBER_INT);
validateParm(parms[1], PugXPathToken::NUMBER_INT);
return PugXPathToken(parms[0].getValueNumberInt() % parms[1].getValueNumberInt());
}
};
/****
* \class PugXPathOperatorEqual
*/
class PugXPathOperatorEqual :public PugXPathFunction
{
public:
PugXPathOperatorEqual() :PugXPathFunction("=", 2)
{}
virtual PugXPathToken execute(Array<xml_node_struct*> search, xml_node_struct* context, Array<PugXPathToken> parms)
{
validateParm(parms[0], parms[1].getType());
if (parms[0].getType() == PugXPathToken::NUMBER_DBL || parms[1].getType() == PugXPathToken::NUMBER_DBL)
{
return PugXPathToken(parms[0].getValueNumberDouble() == parms[1].getValueNumberDouble());
}
if (parms[0].getType() == PugXPathToken::NUMBER_INT || parms[1].getType() == PugXPathToken::NUMBER_INT)
{
return PugXPathToken(parms[0].getValueNumberInt() == parms[1].getValueNumberInt());
}
if (parms[0].getType() == PugXPathToken::BOOLEAN || parms[1].getType() == PugXPathToken::BOOLEAN)
{
return PugXPathToken(parms[0].getValueBool() == parms[1].getValueBool());
}
if (parms[0].getType() == PugXPathToken::NODESET)
{
Array<xml_node_struct*> nodeset1 = parms[0].getValueNodeSet(context);
if (parms[1].getType() == PugXPathToken::NODESET)
{
Array<xml_node_struct*> nodeset2 = parms[1].getValueNodeSet(context);
if (nodeset1.getSize() != nodeset2.getSize())
{
return PugXPathToken(false);
}
for (int i = 0; i < nodeset1.getSize(); ++i)
{
if (nodeset1[0] != nodeset2[1])
{
return PugXPathToken(false);
}
}
return PugXPathToken(true);
}
if (nodeset1.getSize() > 0)
{
if (nodeset1[0]->type == node_pcdata)
return PugXPathToken(parms[1].getValue(context) == nodeset1[0]->value);
else
return PugXPathToken(parms[1].getValue(context) == nodeset1[0]->child[0]->value);
}
return PugXPathToken(false);
}
if (parms[1].getType() == PugXPathToken::NODESET)
{
Array<xml_node_struct*> nodeset1 = parms[1].getValueNodeSet(context);
if (parms[0].getType() == PugXPathToken::NODESET)
{
Array<xml_node_struct*> nodeset2 = parms[0].getValueNodeSet(context);
if (nodeset1.getSize() != nodeset2.getSize())
{
return PugXPathToken(false);
}
for (int i = 0; i < nodeset1.getSize(); ++i)
{
if (nodeset1[0] != nodeset2[1])
{
return PugXPathToken(false);
}
}
return PugXPathToken(true);
}
if (nodeset1.getSize() > 0)
{
if (nodeset1[0]->type == node_pcdata)
return PugXPathToken(parms[0].getValue(context) == nodeset1[0]->value);
else
return PugXPathToken(parms[0].getValue(context) == nodeset1[0]->child[0]->value);
}
return PugXPathToken(false);
}
return PugXPathToken(parms[0].getValue(context) == parms[1].getValue(context));
}
};
}
}
} // namespaces
#endif // !defined(AFX_PUGPugXPathFUNCTIONS_H__C26C32BB_0BCE_4ED3_8E62_57A61A18820A__INCLUDED_)