xpathtoken.h revision 4cb9ed4c3d183554e888e636844f8e3c2e666c40
#ifndef __XPATHTOKEN_H__
#define __XPATHTOKEN_H__
/**
* Phoebe DOM Implementation.
*
* This is a C++ approximation of the W3C DOM model, which follows
* fairly closely the specifications in the various .idl files, copies of
* which are provided for reference. Most important is this one:
*
* http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html
*
* Authors:
* Bob Jamison
*
* Copyright (C) 2006 Bob Jamison
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "dom.h"
#include <math.h>
#include <cstdio>
#include <vector>
namespace org
{
namespace w3c
{
namespace dom
{
namespace xpath
{
typedef org::w3c::dom::DOMString DOMString;
class TokenExecutor;
//########################################################################
//# S T A C K I T E M
//########################################################################
/**
* This represents a single value on the evaluation stack
*/
class StackItem
{
public:
/**
* Constructor
*/
StackItem()
{ init(); }
/**
* Copy constructor
*/
StackItem(const StackItem &other)
{ assign(other); }
/**
* Destructor
*/
virtual ~StackItem()
{}
/**
*
*/
StackItem &operator=(const StackItem &other)
{ assign(other); return *this; }
//treat the stack item like an union of string, integer, and double
/**
* String value
*/
DOMString sval;
/**
* Integer value
*/
long ival;
/**
* Double value;
*/
double dval;
private:
void init()
{
sval = "";
ival = 0;
dval = 0.0;
}
void assign(const StackItem &other)
{
sval = other.sval;
ival = other.ival;
dval = other.dval;
}
};
//########################################################################
//# X P A T H T O K E N
//########################################################################
class Token;
class Stack;
typedef bool (*TokenFunc)(Token &tok, Stack &stack);
/**
* This is a pseudocode-type class that executes itself on a stack,
* much like stack-oriented languages such as FORTH or Postscript.
* Each token can pop zero or more tokens off the stack, and push
* zero or one token back onto it. When a list of tokens is completed,
* a single stack value should be left on the stack.
*/
class Token
{
public:
/**
* Token types. Look in xpathtoken.cpp's function table
* to see how these types map to their respective
* functionalities
*/
typedef enum
{
//primitives
TOK_NOP = 0,
TOK_STR,
TOK_INT,
TOK_FLOAT,
//operators
TOK_AND,
TOK_OR,
TOK_MOD,
TOK_DIV,
TOK_MUL,
TOK_DOUBLE_SLASH,
TOK_SLASH,
TOK_PIPE,
TOK_PLUS,
TOK_MINUS,
TOK_NEG,
TOK_EQUALS,
TOK_NOT_EQUALS,
TOK_LESS_THAN_EQUALS,
TOK_LESS_THAN,
TOK_GREATER_THAN_EQUALS,
TOK_GREATER_THAN,
//path types
TOK_ABSOLUTE,
TOK_RELATIVE,
TOK_STEP,
TOK_NAME_TEST,
TOK_EXPR,
TOK_UNION,
//axis types
TOK_AXIS_ANCESTOR_OR_SELF,
TOK_AXIS_ANCESTOR,
TOK_AXIS_ATTRIBUTE,
TOK_AXIS_CHILD,
TOK_AXIS_DESCENDANT_OR_SELF,
TOK_AXIS_DESCENDANT,
TOK_AXIS_FOLLOWING_SIBLING,
TOK_AXIS_FOLLOWING,
TOK_AXIS_NAMESPACE,
TOK_AXIS_PARENT,
TOK_AXIS_PRECEDING_SIBLING,
TOK_AXIS_PRECEDING,
TOK_AXIS_SELF,
//function types
TOK_FUNC_LAST,
TOK_FUNC_POSITION,
TOK_FUNC_COUNT,
TOK_FUNC_ID,
TOK_FUNC_LOCAL_NAME,
TOK_FUNC_NAMESPACE_URI,
TOK_FUNC_NAME,
TOK_FUNC_STRING,
TOK_FUNC_CONCAT,
TOK_FUNC_STARTS_WITH,
TOK_FUNC_CONTAINS,
TOK_FUNC_SUBSTRING_BEFORE,
TOK_FUNC_SUBSTRING_AFTER,
TOK_FUNC_SUBSTRING,
TOK_FUNC_STRING_LENGTH,
TOK_FUNC_NORMALIZE_SPACE,
TOK_FUNC_TRANSLATE,
TOK_FUNC_BOOLEAN,
TOK_FUNC_NOT,
TOK_FUNC_TRUE,
TOK_FUNC_FALSE,
TOK_FUNC_LANG,
TOK_FUNC_NUMBER,
TOK_FUNC_SUM,
TOK_FUNC_FLOOR,
TOK_FUNC_CEILING,
TOK_FUNC_ROUND,
} TokenType;
/**
* Constructor with a NOP default type
*/
Token()
{ init(); }
/**
* Constructor with a NOP default type
*/
Token(int typeArg)
{ init(); type = typeArg; }
/**
* Constructor with a NOP default type
*/
Token(int typeArg,
long ivalArg, double dvalArg, const DOMString &svalArg)
{
init();
type = typeArg,
ival = ivalArg;
dval = dvalArg;
sval = svalArg;
}
/**
* Copy constructor
*/
Token(const Token &other)
{ assign(other); }
/**
* Assignment
*/
Token &operator=(const Token &other)
{ assign(other); return *this; }
/**
* Destructor
*/
virtual ~Token()
{}
/**
* Return the enumerated TokenType of this token
*/
virtual int getType()
{ return type; }
/**
* Return true if the type is one of the Axis types
* above;
*/
virtual bool isAxis()
{
return type>=TOK_AXIS_ANCESTOR_OR_SELF &&
type <= TOK_AXIS_SELF;
}
/**
* Return the string TokenType of this token
*/
virtual DOMString getTypeString();
/**
* Let this token execute itself on the given stack,
* possibly adding Nodes to the node list.
*/
virtual bool execute(Stack &stack)
{
if (tokenFunc)
return tokenFunc(*this, stack);
return false;
}
/**
* Print the contents of this token
*/
virtual void dump()
{
printf("%s %s %f %ld\n",
getTypeString().c_str(), sval.c_str(), dval, ival);
}
//treat the token like an union of string, integer, and double
/**
* String value
*/
DOMString sval;
/**
* Integer value
*/
long ival;
/**
* Double value;
*/
double dval;
/**
*
*/
static Token create(int type, long ival,
double dval, const DOMString &sval);
/**
*
*/
static Token create(int type)
{ return create(type, 0, 0.0, ""); }
/**
*
*/
static Token create(int type, long val)
{ return create(type, val, 0.0, ""); }
/**
*
*/
static Token create(int type, double val)
{ return create(type, 0, val, ""); }
/**
*
*/
static Token create(int type, const DOMString &val)
{ return create(type, 0, 0.0, val); }
protected:
/**
* The enmerated token type
*/
int type;
/**
* The function that defines the behaviour of this token
*/
TokenFunc tokenFunc;
private:
void init()
{
tokenFunc = NULL;
type = TOK_NOP;
ival = 0L;
dval = 0.0;
//sval = ""; //not necessary
}
void assign(const Token &other)
{
tokenFunc = other.tokenFunc;
type = other.type;
sval = other.sval;
ival = other.ival;
dval = other.dval;
}
};
//########################################################################
//# S T A C K
//########################################################################
/**
*
*/
class Stack
{
public:
//# From 2.3, principal type of child axes
typedef enum
{
AXIS_ATTRIBUTE,
AXIS_NAMESPACE,
AXIS_ELEMENT
} PrincipalNodeType;
/**
* Constructor
*/
Stack(TokenExecutor &par) : parent(par)
{ clear(); }
/**
* Copy constructor
*/
Stack(const Stack &other) : parent(other.parent)
{ assign(other); }
/**
* Destructor
*/
virtual ~Stack()
{}
/**
*
*/
Stack &operator=(const Stack &other)
{ assign(other); return *this; }
/**
*
*/
void push(StackItem &item)
{ return stackItems.push_back(item); }
/**
*
*/
StackItem pop()
{
if (stackItems.size() < 1)
{
//TODO: error here
StackItem item;
return item;
}
std::vector<StackItem>::iterator iter =
stackItems.end() - 1;
StackItem item = *iter;
stackItems.erase(iter);
return item;
}
/**
*
*/
virtual void clear()
{
stackItems.clear();
principalNodeType = AXIS_ELEMENT;
}
private:
void assign(const Stack &other)
{
principalNodeType = other.principalNodeType;
stackItems = other.stackItems;
}
int principalNodeType;
std::vector<StackItem> stackItems;
TokenExecutor &parent;
};
//########################################################################
//# T O K E N L I S T
//########################################################################
/**
*
*/
class TokenList
{
public:
/**
*
*/
TokenList()
{ init(); }
/**
*
*/
TokenList(const TokenList &other)
{ assign(other); }
/**
*
*/
TokenList &operator=(const TokenList &other)
{ assign(other); return *this; }
/**
*
*/
virtual ~TokenList()
{ }
/**
*
*/
virtual void add(const Token &token)
{ tokens.push_back(token); }
/**
*
*/
virtual std::vector<Token> &getTokens()
{ return tokens; }
/**
*
*/
virtual void dump()
{
for (unsigned int i=0 ; i<tokens.size() ; i++)
{
Token token = tokens[i];
token.dump();
}
}
/**
*
*/
virtual void clear()
{
tokens.clear();
}
private:
void init()
{
clear();
}
void assign(const TokenList &other)
{
tokens = other.tokens;
}
std::vector<Token> tokens;
};
//########################################################################
//# T O K E N E X E C U T O R
//########################################################################
/**
* A token evaluator, with stack and axis context
*/
class TokenExecutor
{
public:
/**
* Constructor
*/
TokenExecutor();
/**
* Copy constructor
*/
TokenExecutor(const TokenExecutor &other);
/**
* Destructor
*/
virtual ~TokenExecutor();
/**
* Assign our values to those of the other
*/
virtual void assign(const TokenExecutor &other);
/**
* Reset the stack to its original settings
*/
virtual void reset();
/**
* Execute a list upon a given node. For each Axis encountered,
* get the nodes encountered so far, and execute the rest of the
* list of tokens upon each of the nodes.
*/
int execute(std::vector<Token> &tokens,
int position,
const NodePtr node,
NodeList &nodeList);
/**
* Execute a token list on the stack
*/
bool execute(TokenList &list,
const NodePtr node,
NodeList &result);
private:
/**
*
*/
TokenList tokenList;
/**
*
*/
NodeList nodeList;
};
} // namespace xpath
} // namespace dom
} // namespace w3c
} // namespace org
#endif /* __XPATHTOKEN_H__ */
//########################################################################
//# E N D O F F I L E
//########################################################################