Code

Corrected initialization order.
[inkscape.git] / src / dom / xpathtoken.h
1 #ifndef __XPATHTOKEN_H__
2 #define __XPATHTOKEN_H__
4 /**
5  * Phoebe DOM Implementation.
6  *
7  * This is a C++ approximation of the W3C DOM model, which follows
8  * fairly closely the specifications in the various .idl files, copies of
9  * which are provided for reference.  Most important is this one:
10  *
11  * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html
12  *
13  * Authors:
14  *   Bob Jamison
15  *
16  * Copyright (C) 2006 Bob Jamison
17  *
18  *  This library is free software; you can redistribute it and/or
19  *  modify it under the terms of the GNU Lesser General Public
20  *  License as published by the Free Software Foundation; either
21  *  version 2.1 of the License, or (at your option) any later version.
22  *
23  *  This library is distributed in the hope that it will be useful,
24  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
25  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
26  *  Lesser General Public License for more details.
27  *
28  *  You should have received a copy of the GNU Lesser General Public
29  *  License along with this library; if not, write to the Free Software
30  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
31  */
34 #include "dom.h"
36 #include <math.h>
38 #include <vector>
40 namespace org
41 {
42 namespace w3c
43 {
44 namespace dom
45 {
46 namespace xpath
47 {
49 typedef org::w3c::dom::DOMString DOMString;
52 class TokenExecutor;
55 //########################################################################
56 //# S T A C K    I T E M
57 //########################################################################
60 /**
61  * This represents a single value on the evaluation stack
62  */
63 class StackItem
64 {
65 public:
67     /**
68      *  Constructor
69      */
70     StackItem()
71         { init(); }
73     /**
74      *  Copy constructor
75      */
76     StackItem(const StackItem &other)
77         { assign(other); }
79     /**
80      *  Destructor
81      */
82     virtual ~StackItem()
83         {}
85     /**
86      *
87      */
88     StackItem &operator=(const StackItem &other)
89         { assign(other); return *this; }
91     //treat the stack item like an union of string, integer, and double
93     /**
94      * String value
95      */
96     DOMString sval;
98     /**
99      * Integer value
100      */
101     long      ival;
103     /**
104      * Double value;
105      */
106     double    dval;
109 private:
111     void init()
112         {
113         sval = "";
114         ival = 0;
115         dval = 0.0;
116         }
118     void assign(const StackItem &other)
119         {
120         sval = other.sval; 
121         ival = other.ival;
122         dval = other.dval;
123         }
125 };
129 //########################################################################
130 //# X P A T H    T O K E N
131 //########################################################################
133 class Token;
134 class Stack;
136 typedef bool (*TokenFunc)(Token &tok, Stack &stack);
139 /**
140  *  This is a pseudocode-type class that executes itself on a stack,
141  *  much like stack-oriented languages such as FORTH or Postscript.
142  *  Each token can pop zero or more tokens off the stack, and push
143  *  zero or one token back onto it.  When a list of tokens is completed,
144  *  a single stack value should be left on the stack.
145  */
146 class Token
148 public:
150     /**
151      * Token types.  Look in xpathtoken.cpp's function table
152      * to see how these types map to their respective
153      * functionalities
154      */
155     typedef enum
156         {
157         //primitives
158         TOK_NOP = 0,
159         TOK_STR,
160         TOK_INT,
161         TOK_FLOAT,
162         //operators
163         TOK_AND,
164         TOK_OR,
165         TOK_MOD,
166         TOK_DIV,
167         TOK_MUL,
168         TOK_DOUBLE_SLASH,
169         TOK_SLASH,
170         TOK_PIPE,
171         TOK_PLUS,
172         TOK_MINUS,
173         TOK_NEG,
174         TOK_EQUALS,
175         TOK_NOT_EQUALS,
176         TOK_LESS_THAN_EQUALS,
177         TOK_LESS_THAN,
178         TOK_GREATER_THAN_EQUALS,
179         TOK_GREATER_THAN,
180         //path types
181         TOK_ABSOLUTE,
182         TOK_RELATIVE,
183         TOK_STEP,
184         TOK_NAME_TEST,
185         TOK_EXPR,
186         TOK_UNION,
187         //axis types
188         TOK_AXIS_ANCESTOR_OR_SELF,
189         TOK_AXIS_ANCESTOR,
190         TOK_AXIS_ATTRIBUTE,
191         TOK_AXIS_CHILD,
192         TOK_AXIS_DESCENDANT_OR_SELF,
193         TOK_AXIS_DESCENDANT,
194         TOK_AXIS_FOLLOWING_SIBLING,
195         TOK_AXIS_FOLLOWING,
196         TOK_AXIS_NAMESPACE,
197         TOK_AXIS_PARENT,
198         TOK_AXIS_PRECEDING_SIBLING,
199         TOK_AXIS_PRECEDING,
200         TOK_AXIS_SELF,
201         //function types
202         TOK_FUNC_LAST,
203         TOK_FUNC_POSITION,
204         TOK_FUNC_COUNT,
205         TOK_FUNC_ID,
206         TOK_FUNC_LOCAL_NAME,
207         TOK_FUNC_NAMESPACE_URI,
208         TOK_FUNC_NAME,
209         TOK_FUNC_STRING,
210         TOK_FUNC_CONCAT,
211         TOK_FUNC_STARTS_WITH,
212         TOK_FUNC_CONTAINS,
213         TOK_FUNC_SUBSTRING_BEFORE,
214         TOK_FUNC_SUBSTRING_AFTER,
215         TOK_FUNC_SUBSTRING,
216         TOK_FUNC_STRING_LENGTH,
217         TOK_FUNC_NORMALIZE_SPACE,
218         TOK_FUNC_TRANSLATE,
219         TOK_FUNC_BOOLEAN,
220         TOK_FUNC_NOT,
221         TOK_FUNC_TRUE,
222         TOK_FUNC_FALSE,
223         TOK_FUNC_LANG,
224         TOK_FUNC_NUMBER,
225         TOK_FUNC_SUM,
226         TOK_FUNC_FLOOR,
227         TOK_FUNC_CEILING,
228         TOK_FUNC_ROUND,
229         } TokenType;
234     /**
235      *  Constructor with a NOP default type
236      */
237     Token()
238         { init(); }
240     /**
241      *  Constructor with a NOP default type
242      */
243     Token(int typeArg)
244         { init(); type = typeArg; }
246     /**
247      *  Constructor with a NOP default type
248      */
249     Token(int typeArg, 
250           long ivalArg, double dvalArg, const DOMString &svalArg)
251         { 
252         init();
253         type = typeArg,
254         ival = ivalArg;
255         dval = dvalArg;
256         sval = svalArg;
257         }
259     /**
260      * Copy constructor
261      */
262     Token(const Token &other)
263         { assign(other); }
265     /**
266      * Assignment
267      */
268     Token &operator=(const Token &other)
269         { assign(other); return *this; }
271     /**
272      * Destructor
273      */
274     virtual ~Token()
275         {}
277     /**
278      *  Return the enumerated TokenType of this token
279      */
280     virtual int getType()
281         { return type; }
283     /**
284      *  Return true if the type is one of the Axis types
285      *  above;
286      */
287     virtual bool isAxis()
288         {
289         return type>=TOK_AXIS_ANCESTOR_OR_SELF &&
290                  type <= TOK_AXIS_SELF;
291         }
292     /**
293      *  Return the string TokenType of this token
294      */
295     virtual DOMString getTypeString();
297     /**
298      *  Let this token execute itself on the given stack,
299      *  possibly adding Nodes to the node list.
300      */
301     virtual bool execute(Stack &stack)
302         {
303         if (tokenFunc)
304             return tokenFunc(*this, stack);
305         return false;
306         }
308     /**
309      *  Print the contents of this token
310      */
311     virtual void dump()
312         {
313         printf("%s %s %f %ld\n",
314             getTypeString().c_str(), sval.c_str(), dval, ival);
315         }
317     //treat the token like an union of string, integer, and double
319     /**
320      * String value
321      */
322     DOMString sval;
324     /**
325      * Integer value
326      */
327     long ival;
329     /**
330      * Double value;
331      */
332     double dval;
334     /**
335      *
336      */
337     static Token create(int type, long ival,
338               double dval, const DOMString &sval);
340     /**
341      *
342      */
343     static Token create(int type)
344         { return create(type, 0, 0.0, ""); }
346     /**
347      *
348      */
349     static Token create(int type, long val)
350         { return create(type, val, 0.0, ""); }
352     /**
353      *
354      */
355     static Token create(int type, double val)
356         { return create(type, 0, val, ""); }
358     /**
359      *
360      */
361     static Token create(int type, const DOMString &val)
362         { return create(type, 0, 0.0, val); }
366 protected:
368     /**
369      * The enmerated token type
370      */
371     int type;
373     /**
374      * The function that defines the behaviour of this token
375      */
376     TokenFunc tokenFunc;
379 private:
381     void init()
382         {
383         tokenFunc = NULL;
384         type      = TOK_NOP;
385         ival      = 0L;
386         dval      = 0.0;
387         //sval      = ""; //not necessary
388         }
390     void assign(const Token &other)
391         {
392         tokenFunc = other.tokenFunc;
393         type      = other.type;
394         sval      = other.sval;
395         ival      = other.ival;
396         dval      = other.dval;
397         }
400 };
403 //########################################################################
404 //# S T A C K
405 //########################################################################
407 /**
408  *
409  */
410 class Stack
412 public:
414     //# From 2.3, principal type of child axes
415     typedef enum
416         {
417         AXIS_ATTRIBUTE,
418         AXIS_NAMESPACE,
419         AXIS_ELEMENT
420         } PrincipalNodeType;
422     /**
423      *  Constructor
424      */
425     Stack(TokenExecutor &par) : parent(par)
426         { clear(); }
428     /**
429      *  Copy constructor
430      */
431     Stack(const Stack &other) : parent(other.parent)
432         { assign(other); }
434     /**
435      *  Destructor
436      */
437     virtual ~Stack()
438         {}
440     /**
441      *
442      */
443     Stack &operator=(const Stack &other)
444         { assign(other); return *this; }
446     /**
447      *
448      */
449     void push(StackItem &item)
450         { return stackItems.push_back(item); }
452     /**
453      *
454      */
455     StackItem pop()
456         {
457         if (stackItems.size() < 1)
458             {
459             //TODO: error here
460             StackItem item;
461             return item;
462             }
463         std::vector<StackItem>::iterator iter =
464                    stackItems.end() - 1;
465         StackItem item = *iter;
466         stackItems.erase(iter);
467         return item;
468         }
470     /**
471      *
472      */
473     virtual void clear()
474         {
475         stackItems.clear();
476         principalNodeType = AXIS_ELEMENT;
477         }
479 private:
481     void assign(const Stack &other)
482         {
483         principalNodeType = other.principalNodeType;
484         stackItems        = other.stackItems;
485         }
487     int principalNodeType;
489     std::vector<StackItem> stackItems;
491     TokenExecutor &parent;
493 };
498 //########################################################################
499 //# T O K E N    L I S T
500 //########################################################################
502 /**
503  *
504  */
505 class TokenList
507 public:
509     /**
510      *
511      */
512     TokenList()
513         { init(); }
515     /**
516      *
517      */
518     TokenList(const TokenList &other)
519         { assign(other); }
521     /**
522      *
523      */
524     TokenList &operator=(const TokenList &other)
525         { assign(other); return *this; }
527     /**
528      *
529      */
530     virtual ~TokenList()
531         { }
534     /**
535      *
536      */
537     virtual void add(const Token &token)
538         { tokens.push_back(token); }
540     /**
541      *
542      */
543     virtual std::vector<Token> &getTokens()
544         { return tokens; }
546     /**
547      *
548      */
549     virtual void dump()
550         {
551         for (unsigned int i=0 ; i<tokens.size() ; i++)
552             {
553             Token token = tokens[i];
554             token.dump();
555             }
556         }
558     /**
559      *
560      */
561     virtual void clear()
562        {
563        tokens.clear();
564        }
566 private:
569     void init()
570         {
571         clear();
572         }
574     void assign(const TokenList &other)
575         {
576         tokens = other.tokens;
577         }
579     std::vector<Token> tokens;
582 };
587 //########################################################################
588 //# T O K E N    E X E C U T O R
589 //########################################################################
592 /**
593  * A token evaluator, with stack and axis context
594  */
595 class TokenExecutor
597 public:
599     /**
600      * Constructor
601      */
602     TokenExecutor();
604     /**
605      * Copy constructor
606      */
607     TokenExecutor(const TokenExecutor &other);
609     /**
610      * Destructor
611      */
612     virtual ~TokenExecutor();
614     /**
615      *  Assign our values to those of the other
616      */
617     virtual void assign(const TokenExecutor &other);
619     /**
620      * Reset the stack to its original settings
621      */
622     virtual void reset();
624     /**
625      * Execute a list upon a given node.  For each Axis encountered,
626      * get the nodes encountered so far, and execute the rest of the
627      * list of tokens upon each of the nodes.
628      */
629     int execute(std::vector<Token> &tokens,
630                 int position,
631                 const NodePtr node,
632                 NodeList &nodeList);
634     /**
635      * Execute a token list on the stack
636      */
637     bool execute(TokenList &list,
638                  const NodePtr node,
639                  NodeList &result);
641 private:
643     /**
644      *
645      */
646     TokenList tokenList;
648     /**
649      *
650      */
651     NodeList nodeList;
654 };
659 } // namespace xpath
660 } // namespace dom
661 } // namespace w3c
662 } // namespace org
669 #endif  /* __XPATHTOKEN_H__ */
670 //########################################################################
671 //# E N D    O F    F I L E
672 //########################################################################