#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 <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 */ 00063 class StackItem { public: /** * Constructor */ 00070 StackItem() { init(); } /** * Copy constructor */ 00076 StackItem(const StackItem &other) { assign(other); } /** * Destructor */ 00082 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 */ 00096 DOMString sval; /** * Integer value */ 00101 long ival; /** * Double value; */ 00106 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. */ 00146 class Token { public: /** * Token types. Look in xpathtoken.cpp's function table * to see how these types map to their respective * functionalities */ 00155 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 */ 00237 Token() { init(); } /** * Constructor with a NOP default type */ 00243 Token(int typeArg) { init(); type = typeArg; } /** * Constructor with a NOP default type */ 00249 Token(int typeArg, long ivalArg, double dvalArg, const DOMString &svalArg) { init(); type = typeArg, ival = ivalArg; dval = dvalArg; sval = svalArg; } /** * Copy constructor */ 00262 Token(const Token &other) { assign(other); } /** * Assignment */ 00268 Token &operator=(const Token &other) { assign(other); return *this; } /** * Destructor */ 00274 virtual ~Token() {} /** * Return the enumerated TokenType of this token */ 00280 virtual int getType() { return type; } /** * Return true if the type is one of the Axis types * above; */ 00287 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. */ 00301 virtual bool execute(Stack &stack) { if (tokenFunc) return tokenFunc(*this, stack); return false; } /** * Print the contents of this token */ 00311 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 */ 00322 DOMString sval; /** * Integer value */ 00327 long ival; /** * Double value; */ 00332 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 */ 00371 int type; /** * The function that defines the behaviour of this token */ 00376 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 */ 00595 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 //########################################################################