1 #ifndef __XPATHTOKEN_H__\r
2 #define __XPATHTOKEN_H__\r
3 \r
4 /**\r
5 * Phoebe DOM Implementation.\r
6 *\r
7 * This is a C++ approximation of the W3C DOM model, which follows\r
8 * fairly closely the specifications in the various .idl files, copies of\r
9 * which are provided for reference. Most important is this one:\r
10 *\r
11 * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html\r
12 *\r
13 * Authors:\r
14 * Bob Jamison\r
15 *\r
16 * Copyright (C) 2006 Bob Jamison\r
17 *\r
18 * This library is free software; you can redistribute it and/or\r
19 * modify it under the terms of the GNU Lesser General Public\r
20 * License as published by the Free Software Foundation; either\r
21 * version 2.1 of the License, or (at your option) any later version.\r
22 *\r
23 * This library is distributed in the hope that it will be useful,\r
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
26 * Lesser General Public License for more details.\r
27 *\r
28 * You should have received a copy of the GNU Lesser General Public\r
29 * License along with this library; if not, write to the Free Software\r
30 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\r
31 */\r
32 \r
33 \r
34 #include "dom.h"\r
35 \r
36 #include <math.h>\r
37 \r
38 #include <vector>\r
39 \r
40 namespace org\r
41 {\r
42 namespace w3c\r
43 {\r
44 namespace dom\r
45 {\r
46 namespace xpath\r
47 {\r
48 \r
49 typedef org::w3c::dom::DOMString DOMString;\r
50 \r
51 /**\r
52 * This represents a single value on the evaluation stack\r
53 */\r
54 class StackItem\r
55 {\r
56 public:\r
57 \r
58 /**\r
59 * Constructor\r
60 */\r
61 StackItem();\r
62 \r
63 /**\r
64 * Copy constructor\r
65 */\r
66 StackItem(const StackItem &other);\r
67 \r
68 /**\r
69 * Destructor\r
70 */\r
71 virtual ~StackItem();\r
72 \r
73 //treat the stack item like an union of string, integer, and double\r
74 \r
75 /**\r
76 * String value\r
77 */\r
78 DOMString sval;\r
79 \r
80 /**\r
81 * Integer value\r
82 */\r
83 long ival;\r
84 \r
85 /**\r
86 * Double value;\r
87 */\r
88 double dval;\r
89 \r
90 };\r
91 \r
92 #define STACK_SIZE 1024\r
93 \r
94 /**\r
95 * An evaluation stack\r
96 */\r
97 class Stack\r
98 {\r
99 public:\r
100 \r
101 /**\r
102 * Constructor\r
103 */\r
104 Stack();\r
105 \r
106 /**\r
107 * Copy constructor\r
108 */\r
109 Stack(const Stack &other);\r
110 \r
111 /**\r
112 * Destructor\r
113 */\r
114 virtual ~Stack();\r
115 \r
116 /**\r
117 * Assign our values to those of the other\r
118 */\r
119 virtual void assign(const Stack &other);\r
120 \r
121 /**\r
122 * Reset the stack to its original settings\r
123 */\r
124 virtual void reset();\r
125 \r
126 /**\r
127 * Push a stack item onto the stack\r
128 */\r
129 virtual void push(StackItem &item);\r
130 \r
131 /**\r
132 * Pop a stack item from the stack\r
133 */\r
134 virtual StackItem pop();\r
135 \r
136 /**\r
137 * Set the root node\r
138 */\r
139 virtual void setRootNode(const Node *node);\r
140 \r
141 /**\r
142 * Get the current node list;\r
143 */\r
144 virtual NodeList &getNodeList();\r
145 \r
146 \r
147 private:\r
148 \r
149 Node *root;\r
150 NodeList nodeList;\r
151 \r
152 StackItem items[STACK_SIZE];\r
153 int size;\r
154 };\r
155 \r
156 \r
157 \r
158 \r
159 /**\r
160 * This is a pseudocode-type class that executes itself on a stack,\r
161 * much like stack-oriented languages such as FORTH or Postscript.\r
162 * Each token can pop zero or more tokens off the stack, and push\r
163 * zero or one token back onto it. When a list of tokens is completed,\r
164 * a single stack value should be left on the stack.\r
165 */\r
166 class Token\r
167 {\r
168 public:\r
169 \r
170 /**\r
171 * Token types. Look in xpathtoken.cpp's function table\r
172 * to see how these types map to their respective\r
173 * functionalities\r
174 */\r
175 typedef enum\r
176 {\r
177 TOK_NOP = 0,\r
178 TOK_STR,\r
179 TOK_INT,\r
180 TOK_FLOAT,\r
181 //operators\r
182 TOK_AND,\r
183 TOK_OR,\r
184 TOK_MOD,\r
185 TOK_DIV,\r
186 TOK_MULTIPLY,\r
187 TOK_DOUBLE_SLASH,\r
188 TOK_SLASH,\r
189 TOK_PIPE,\r
190 TOK_PLUS,\r
191 TOK_MINUS,\r
192 TOK_NEG,\r
193 TOK_EQUALS,\r
194 TOK_NOT_EQUALS,\r
195 TOK_LESS_THAN_EQUALS,\r
196 TOK_LESS_THAN,\r
197 TOK_GREATER_THAN_EQUALS,\r
198 TOK_GREATER_THAN,\r
199 //path types\r
200 TOK_ABSOLUTE,\r
201 TOK_RELATIVE,\r
202 TOK_STEP,\r
203 TOK_EXPR,\r
204 TOK_UNION,\r
205 //function types\r
206 TOK_POSITION\r
207 } TokenType;\r
208 /**\r
209 * Constructor with a NOP default type\r
210 */\r
211 Token()\r
212 {\r
213 type = TOK_NOP;\r
214 stype = "nop";\r
215 ival = 0L;\r
216 dval = 0.0;\r
217 }\r
218 \r
219 /**\r
220 * Copy constructor\r
221 */\r
222 Token(const Token &other)\r
223 {\r
224 type = other.type;\r
225 stype = other.stype;\r
226 sval = other.sval;\r
227 ival = other.ival;\r
228 dval = other.dval;\r
229 }\r
230 \r
231 /**\r
232 * Destructor\r
233 */\r
234 virtual ~Token()\r
235 {}\r
236 \r
237 /**\r
238 * Return the enumerated TokenType of this token\r
239 */\r
240 virtual int getType()\r
241 { return type; }\r
242 \r
243 /**\r
244 * Let this token execute itself on the given stack,\r
245 * possibly adding Nodes to the node list.\r
246 */\r
247 virtual bool execute(Stack &stack)\r
248 { return true; }\r
249 \r
250 /**\r
251 * Print the contents of this token\r
252 */\r
253 virtual void dump()\r
254 {\r
255 printf("%s %s %f %ld\n", stype, sval.c_str(), dval, ival);\r
256 }\r
257 \r
258 //treat the token like an union of string, integer, and double\r
259 \r
260 /**\r
261 * String value\r
262 */\r
263 DOMString sval;\r
264 \r
265 /**\r
266 * Integer value\r
267 */\r
268 long ival;\r
269 \r
270 /**\r
271 * Double value;\r
272 */\r
273 double dval;\r
274 \r
275 protected:\r
276 \r
277 /**\r
278 * The enmerated token type\r
279 */\r
280 int type;\r
281 \r
282 /**\r
283 * String type\r
284 */\r
285 char *stype;\r
286 \r
287 private:\r
288 \r
289 \r
290 };\r
291 \r
292 \r
293 //########################################################################\r
294 //# X P A T H T O K E N\r
295 //########################################################################\r
296 \r
297 \r
298 \r
299 //###########################\r
300 //# V A L U E S\r
301 //###########################\r
302 \r
303 class TokStr : public Token\r
304 {\r
305 public:\r
306 TokStr(const DOMString &val)\r
307 {\r
308 type = TOK_STR;\r
309 stype = "str";\r
310 sval = val;\r
311 }\r
312 virtual bool execute(Stack &stack)\r
313 {\r
314 StackItem item;\r
315 item.sval = sval;\r
316 stack.push(item);\r
317 return true;\r
318 }\r
319 };\r
320 \r
321 class TokFloat : public Token\r
322 {\r
323 public:\r
324 TokFloat(double val)\r
325 {\r
326 type = TOK_FLOAT;\r
327 stype = "float";\r
328 dval = val;\r
329 }\r
330 virtual bool execute(Stack &stack)\r
331 {\r
332 StackItem item;\r
333 item.dval = dval;\r
334 stack.push(item);\r
335 return true;\r
336 }\r
337 };\r
338 \r
339 class TokInt : public Token\r
340 {\r
341 public:\r
342 TokInt(long val)\r
343 {\r
344 type = TOK_INT;\r
345 stype = "int";\r
346 ival = val;\r
347 }\r
348 virtual bool execute(Stack &stack)\r
349 {\r
350 StackItem item;\r
351 item.ival = ival;\r
352 stack.push(item);\r
353 return true;\r
354 }\r
355 };\r
356 \r
357 class TokAnd : public Token\r
358 {\r
359 public:\r
360 TokAnd()\r
361 {\r
362 type = TOK_AND;\r
363 stype = "and";\r
364 }\r
365 virtual bool execute(Stack &stack)\r
366 {\r
367 StackItem item1 = stack.pop();\r
368 StackItem item2 = stack.pop();\r
369 item1.ival = item1.ival && item2.ival;\r
370 stack.push(item1);\r
371 return true;\r
372 }\r
373 };\r
374 \r
375 class TokOr : public Token\r
376 {\r
377 public:\r
378 TokOr()\r
379 {\r
380 type = TOK_OR;\r
381 stype = "or";\r
382 }\r
383 virtual bool execute(Stack &stack)\r
384 {\r
385 StackItem item1 = stack.pop();\r
386 StackItem item2 = stack.pop();\r
387 item1.ival = item1.ival || item2.ival;\r
388 stack.push(item1);\r
389 return true;\r
390 }\r
391 };\r
392 \r
393 class TokMod : public Token\r
394 {\r
395 public:\r
396 TokMod()\r
397 {\r
398 type = TOK_MOD;\r
399 stype = "mod";\r
400 }\r
401 virtual bool execute(Stack &stack)\r
402 {\r
403 StackItem item1 = stack.pop();\r
404 StackItem item2 = stack.pop();\r
405 item1.dval = fmod(item1.dval, item2.dval);\r
406 stack.push(item1);\r
407 return true;\r
408 }\r
409 };\r
410 \r
411 class TokDiv : public Token\r
412 {\r
413 public:\r
414 TokDiv()\r
415 {\r
416 type = TOK_DIV;\r
417 stype = "div";\r
418 }\r
419 virtual bool execute(Stack &stack)\r
420 {\r
421 StackItem item1 = stack.pop();\r
422 StackItem item2 = stack.pop();\r
423 item1.dval /= item2.dval;\r
424 stack.push(item1);\r
425 return true;\r
426 }\r
427 };\r
428 \r
429 class TokMul : public Token\r
430 {\r
431 public:\r
432 TokMul()\r
433 {\r
434 type = TOK_MULTIPLY;\r
435 stype = "mul";\r
436 }\r
437 virtual bool execute(Stack &stack)\r
438 {\r
439 StackItem item1 = stack.pop();\r
440 StackItem item2 = stack.pop();\r
441 item1.dval *= item2.dval;\r
442 stack.push(item1);\r
443 return true;\r
444 }\r
445 };\r
446 \r
447 class TokPlus : public Token\r
448 {\r
449 public:\r
450 TokPlus()\r
451 {\r
452 type = TOK_PLUS;\r
453 stype = "plus";\r
454 }\r
455 virtual bool execute(Stack &stack)\r
456 {\r
457 StackItem item1 = stack.pop();\r
458 StackItem item2 = stack.pop();\r
459 item1.dval += item2.dval;\r
460 stack.push(item1);\r
461 return true;\r
462 }\r
463 };\r
464 \r
465 class TokMinus : public Token\r
466 {\r
467 public:\r
468 TokMinus()\r
469 {\r
470 type = TOK_MINUS;\r
471 stype = "minus";\r
472 }\r
473 virtual bool execute(Stack &stack)\r
474 {\r
475 StackItem item1 = stack.pop();\r
476 StackItem item2 = stack.pop();\r
477 item1.dval -= item2.dval;\r
478 stack.push(item1);\r
479 return true;\r
480 }\r
481 };\r
482 \r
483 class TokNeg : public Token\r
484 {\r
485 public:\r
486 TokNeg()\r
487 {\r
488 type = TOK_NEG;\r
489 stype = "neg";\r
490 }\r
491 virtual bool execute(Stack &stack)\r
492 {\r
493 StackItem item;\r
494 item.dval = -dval;\r
495 item.ival = -ival;\r
496 stack.push(item);\r
497 return true;\r
498 }\r
499 };\r
500 \r
501 class TokEquals : public Token\r
502 {\r
503 public:\r
504 TokEquals()\r
505 {\r
506 type = TOK_EQUALS;\r
507 stype = "equals";\r
508 }\r
509 virtual bool execute(Stack &stack)\r
510 {\r
511 StackItem item1 = stack.pop();\r
512 StackItem item2 = stack.pop();\r
513 item1.ival = (item1.dval == item2.dval);\r
514 stack.push(item1);\r
515 return true;\r
516 }\r
517 };\r
518 \r
519 class TokNotEquals : public Token\r
520 {\r
521 public:\r
522 TokNotEquals()\r
523 {\r
524 type = TOK_NOT_EQUALS;\r
525 stype = "neq";\r
526 }\r
527 virtual bool execute(Stack &stack)\r
528 {\r
529 StackItem item1 = stack.pop();\r
530 StackItem item2 = stack.pop();\r
531 item1.ival = (item1.dval != item2.dval);\r
532 stack.push(item1);\r
533 return true;\r
534 }\r
535 };\r
536 \r
537 class TokLessThanEquals : public Token\r
538 {\r
539 public:\r
540 TokLessThanEquals()\r
541 {\r
542 type = TOK_LESS_THAN_EQUALS;\r
543 stype = "lt_eq";\r
544 }\r
545 virtual bool execute(Stack &stack)\r
546 {\r
547 StackItem item1 = stack.pop();\r
548 StackItem item2 = stack.pop();\r
549 item1.ival = (item1.dval <= item2.dval);\r
550 stack.push(item1);\r
551 return true;\r
552 }\r
553 };\r
554 \r
555 class TokLessThan : public Token\r
556 {\r
557 public:\r
558 TokLessThan()\r
559 {\r
560 type = TOK_LESS_THAN;\r
561 stype = "lt";\r
562 }\r
563 virtual bool execute(Stack &stack)\r
564 {\r
565 StackItem item1 = stack.pop();\r
566 StackItem item2 = stack.pop();\r
567 item1.ival = (item1.dval < item2.dval);\r
568 stack.push(item1);\r
569 return true;\r
570 }\r
571 };\r
572 \r
573 class TokGreaterThanEquals : public Token\r
574 {\r
575 public:\r
576 TokGreaterThanEquals()\r
577 {\r
578 type = TOK_GREATER_THAN_EQUALS;\r
579 stype = "gt";\r
580 }\r
581 virtual bool execute(Stack &stack)\r
582 {\r
583 StackItem item1 = stack.pop();\r
584 StackItem item2 = stack.pop();\r
585 item1.ival = (item1.dval >= item2.dval);\r
586 stack.push(item1);\r
587 return true;\r
588 }\r
589 };\r
590 \r
591 class TokGreaterThan : public Token\r
592 {\r
593 public:\r
594 TokGreaterThan()\r
595 {\r
596 type = TOK_GREATER_THAN;\r
597 stype = "gt_eq";\r
598 }\r
599 virtual bool execute(Stack &stack)\r
600 {\r
601 StackItem item1 = stack.pop();\r
602 StackItem item2 = stack.pop();\r
603 item1.ival = (item1.dval > item2.dval);\r
604 stack.push(item1);\r
605 return true;\r
606 }\r
607 };\r
608 \r
609 \r
610 //###########################\r
611 //# X P A T H I T E M S\r
612 //###########################\r
613 \r
614 class TokAbsolute : public Token\r
615 {\r
616 public:\r
617 TokAbsolute()\r
618 {\r
619 type = TOK_ABSOLUTE;\r
620 stype = "absolute";\r
621 }\r
622 virtual bool execute(Stack &stack)\r
623 {\r
624 return true;\r
625 }\r
626 };\r
627 \r
628 class TokRelative : public Token\r
629 {\r
630 public:\r
631 TokRelative()\r
632 {\r
633 type = TOK_RELATIVE;\r
634 stype = "relative";\r
635 }\r
636 virtual bool execute(Stack &stack)\r
637 {\r
638 return true;\r
639 }\r
640 };\r
641 \r
642 class TokStep : public Token\r
643 {\r
644 public:\r
645 TokStep()\r
646 {\r
647 type = TOK_STEP;\r
648 stype = "step";\r
649 }\r
650 virtual bool execute(Stack &stack)\r
651 {\r
652 return true;\r
653 }\r
654 };\r
655 \r
656 class TokExpr : public Token\r
657 {\r
658 public:\r
659 TokExpr()\r
660 {\r
661 type = TOK_EXPR;\r
662 stype = "token";\r
663 }\r
664 virtual bool execute(Stack &stack)\r
665 {\r
666 return true;\r
667 }\r
668 };\r
669 \r
670 class TokUnion : public Token\r
671 {\r
672 public:\r
673 TokUnion()\r
674 {\r
675 type = TOK_UNION;\r
676 stype = "union";\r
677 }\r
678 virtual bool execute(Stack &stack)\r
679 {\r
680 return true;\r
681 }\r
682 };\r
683 \r
684 \r
685 \r
686 //###########################\r
687 //# F U N C T I O N S\r
688 //###########################\r
689 \r
690 class TokPosition : public Token\r
691 {\r
692 public:\r
693 TokPosition()\r
694 {\r
695 type = TOK_POSITION;\r
696 stype = "position";\r
697 }\r
698 virtual bool execute(Stack &stack)\r
699 {\r
700 return true;\r
701 }\r
702 };\r
703 \r
704 \r
705 \r
706 //########################################################################\r
707 //# T O K E N L I S T\r
708 //########################################################################\r
709 \r
710 /**\r
711 *\r
712 */\r
713 class TokenList\r
714 {\r
715 public:\r
716 \r
717 /**\r
718 *\r
719 */\r
720 TokenList();\r
721 \r
722 /**\r
723 *\r
724 */\r
725 virtual ~TokenList();\r
726 \r
727 /**\r
728 *\r
729 */\r
730 virtual void clear();\r
731 \r
732 /**\r
733 *\r
734 */\r
735 virtual void add(Token *tok);\r
736 \r
737 /**\r
738 * This method "executes" a list of Tokens in the context of a DOM root\r
739 * Node, returning a list of Nodes that match the xpath expression.\r
740 */\r
741 NodeList execute(const Node *root);\r
742 \r
743 /**\r
744 *\r
745 */\r
746 virtual void dump();\r
747 \r
748 private:\r
749 \r
750 \r
751 std::vector<Token *> tokens;\r
752 \r
753 };\r
754 \r
755 \r
756 \r
757 } // namespace xpath\r
758 } // namespace dom\r
759 } // namespace w3c\r
760 } // namespace org\r
761 \r
762 \r
763 \r
764 \r
765 \r
766 \r
767 #endif /* __XPATHTOKEN_H__ */\r
768 //########################################################################\r
769 //# E N D O F F I L E\r
770 //########################################################################\r
771 \r