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) 2005 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 * Push a stack item onto the stack\r
118 */\r
119 virtual void push(StackItem &item);\r
120 \r
121 /**\r
122 * Pop a stack item from the stack\r
123 */\r
124 virtual StackItem pop();\r
125 \r
126 \r
127 private:\r
128 \r
129 StackItem items[STACK_SIZE];\r
130 int size;\r
131 };\r
132 \r
133 \r
134 \r
135 \r
136 /**\r
137 * This is a pseudocode-type class that executes itself on a stack,\r
138 * much like stack-oriented languages such as FORTH or Postscript.\r
139 * Each token can pop zero or more tokens off the stack, and push\r
140 * zero or one token back onto it. When a list of tokens is completed,\r
141 * a single stack value should be left on the stack.\r
142 */\r
143 class Token\r
144 {\r
145 public:\r
146 \r
147 /**\r
148 * Token types. Look in xpathtoken.cpp's function table\r
149 * to see how these types map to their respective\r
150 * functionalities\r
151 */\r
152 typedef enum\r
153 {\r
154 TOK_NOP = 0,\r
155 TOK_STR,\r
156 TOK_INT,\r
157 TOK_FLOAT,\r
158 //operators\r
159 TOK_AND,\r
160 TOK_OR,\r
161 TOK_MOD,\r
162 TOK_DIV,\r
163 TOK_MULTIPLY,\r
164 TOK_DOUBLE_SLASH,\r
165 TOK_SLASH,\r
166 TOK_PIPE,\r
167 TOK_PLUS,\r
168 TOK_MINUS,\r
169 TOK_NEG,\r
170 TOK_EQUALS,\r
171 TOK_NOT_EQUALS,\r
172 TOK_LESS_THAN_EQUALS,\r
173 TOK_LESS_THAN,\r
174 TOK_GREATER_THAN_EQUALS,\r
175 TOK_GREATER_THAN,\r
176 //path types\r
177 TOK_ABSOLUTE,\r
178 TOK_RELATIVE,\r
179 TOK_STEP,\r
180 TOK_EXPR,\r
181 TOK_UNION,\r
182 //function types\r
183 TOK_POSITION\r
184 } TokenType;\r
185 /**\r
186 * Constructor with a NOP default type\r
187 */\r
188 Token()\r
189 {\r
190 type = TOK_NOP;\r
191 stype = "nop";\r
192 ival = 0L;\r
193 dval = 0.0;\r
194 }\r
195 \r
196 /**\r
197 * Copy constructor\r
198 */\r
199 Token(const Token &other)\r
200 {\r
201 type = other.type;\r
202 stype = other.stype;\r
203 sval = other.sval;\r
204 ival = other.ival;\r
205 dval = other.dval;\r
206 }\r
207 \r
208 /**\r
209 * Destructor\r
210 */\r
211 virtual ~Token()\r
212 {}\r
213 \r
214 /**\r
215 * Return the enumerated TokenType of this token\r
216 */\r
217 virtual int getType()\r
218 { return type; }\r
219 \r
220 /**\r
221 * Let this token execute itself on the given stack,\r
222 * possibly adding Nodes to the node list.\r
223 */\r
224 virtual bool execute(Stack &stack, NodeList &list)\r
225 { return true; }\r
226 \r
227 /**\r
228 * Print the contents of this token\r
229 */\r
230 virtual void dump()\r
231 {\r
232 printf("%s %s %f %ld\n", stype, sval.c_str(), dval, ival);\r
233 }\r
234 \r
235 //treat the token like an union of string, integer, and double\r
236 \r
237 /**\r
238 * String value\r
239 */\r
240 DOMString sval;\r
241 \r
242 /**\r
243 * Integer value\r
244 */\r
245 long ival;\r
246 \r
247 /**\r
248 * Double value;\r
249 */\r
250 double dval;\r
251 \r
252 protected:\r
253 \r
254 /**\r
255 * The enmerated token type\r
256 */\r
257 int type;\r
258 \r
259 /**\r
260 * String type\r
261 */\r
262 char *stype;\r
263 \r
264 private:\r
265 \r
266 \r
267 };\r
268 \r
269 \r
270 //########################################################################\r
271 //# X P A T H T O K E N\r
272 //########################################################################\r
273 \r
274 \r
275 \r
276 //###########################\r
277 //# V A L U E S\r
278 //###########################\r
279 \r
280 class TokStr : public Token\r
281 {\r
282 public:\r
283 TokStr(const DOMString &val)\r
284 {\r
285 type = TOK_STR;\r
286 stype = "str";\r
287 sval = val;\r
288 }\r
289 virtual bool execute(Stack &stack, NodeList &list)\r
290 {\r
291 StackItem item;\r
292 item.sval = sval;\r
293 stack.push(item);\r
294 return true;\r
295 }\r
296 };\r
297 \r
298 class TokFloat : public Token\r
299 {\r
300 public:\r
301 TokFloat(double val)\r
302 {\r
303 type = TOK_FLOAT;\r
304 stype = "float";\r
305 dval = val;\r
306 }\r
307 virtual bool execute(Stack &stack, NodeList &list)\r
308 {\r
309 StackItem item;\r
310 item.dval = dval;\r
311 stack.push(item);\r
312 return true;\r
313 }\r
314 };\r
315 \r
316 class TokInt : public Token\r
317 {\r
318 public:\r
319 TokInt(long val)\r
320 {\r
321 type = TOK_INT;\r
322 stype = "int";\r
323 ival = val;\r
324 }\r
325 virtual bool execute(Stack &stack, NodeList &list)\r
326 {\r
327 StackItem item;\r
328 item.ival = ival;\r
329 stack.push(item);\r
330 return true;\r
331 }\r
332 };\r
333 \r
334 class TokAnd : public Token\r
335 {\r
336 public:\r
337 TokAnd()\r
338 {\r
339 type = TOK_AND;\r
340 stype = "and";\r
341 }\r
342 virtual bool execute(Stack &stack, NodeList &list)\r
343 {\r
344 StackItem item1 = stack.pop();\r
345 StackItem item2 = stack.pop();\r
346 item1.ival = item1.ival && item2.ival;\r
347 stack.push(item1);\r
348 return true;\r
349 }\r
350 };\r
351 \r
352 class TokOr : public Token\r
353 {\r
354 public:\r
355 TokOr()\r
356 {\r
357 type = TOK_OR;\r
358 stype = "or";\r
359 }\r
360 virtual bool execute(Stack &stack, NodeList &list)\r
361 {\r
362 StackItem item1 = stack.pop();\r
363 StackItem item2 = stack.pop();\r
364 item1.ival = item1.ival || item2.ival;\r
365 stack.push(item1);\r
366 return true;\r
367 }\r
368 };\r
369 \r
370 class TokMod : public Token\r
371 {\r
372 public:\r
373 TokMod()\r
374 {\r
375 type = TOK_MOD;\r
376 stype = "mod";\r
377 }\r
378 virtual bool execute(Stack &stack, NodeList &list)\r
379 {\r
380 StackItem item1 = stack.pop();\r
381 StackItem item2 = stack.pop();\r
382 item1.dval = fmod(item1.dval, item2.dval);\r
383 stack.push(item1);\r
384 return true;\r
385 }\r
386 };\r
387 \r
388 class TokDiv : public Token\r
389 {\r
390 public:\r
391 TokDiv()\r
392 {\r
393 type = TOK_DIV;\r
394 stype = "div";\r
395 }\r
396 virtual bool execute(Stack &stack, NodeList &list)\r
397 {\r
398 StackItem item1 = stack.pop();\r
399 StackItem item2 = stack.pop();\r
400 item1.dval /= item2.dval;\r
401 stack.push(item1);\r
402 return true;\r
403 }\r
404 };\r
405 \r
406 class TokMul : public Token\r
407 {\r
408 public:\r
409 TokMul()\r
410 {\r
411 type = TOK_MULTIPLY;\r
412 stype = "mul";\r
413 }\r
414 virtual bool execute(Stack &stack, NodeList &list)\r
415 {\r
416 StackItem item1 = stack.pop();\r
417 StackItem item2 = stack.pop();\r
418 item1.dval *= item2.dval;\r
419 stack.push(item1);\r
420 return true;\r
421 }\r
422 };\r
423 \r
424 class TokPlus : public Token\r
425 {\r
426 public:\r
427 TokPlus()\r
428 {\r
429 type = TOK_PLUS;\r
430 stype = "plus";\r
431 }\r
432 virtual bool execute(Stack &stack, NodeList &list)\r
433 {\r
434 StackItem item1 = stack.pop();\r
435 StackItem item2 = stack.pop();\r
436 item1.dval += item2.dval;\r
437 stack.push(item1);\r
438 return true;\r
439 }\r
440 };\r
441 \r
442 class TokMinus : public Token\r
443 {\r
444 public:\r
445 TokMinus()\r
446 {\r
447 type = TOK_MINUS;\r
448 stype = "minus";\r
449 }\r
450 virtual bool execute(Stack &stack, NodeList &list)\r
451 {\r
452 StackItem item1 = stack.pop();\r
453 StackItem item2 = stack.pop();\r
454 item1.dval -= item2.dval;\r
455 stack.push(item1);\r
456 return true;\r
457 }\r
458 };\r
459 \r
460 class TokNeg : public Token\r
461 {\r
462 public:\r
463 TokNeg()\r
464 {\r
465 type = TOK_NEG;\r
466 stype = "neg";\r
467 }\r
468 virtual bool execute(Stack &stack, NodeList &list)\r
469 {\r
470 StackItem item;\r
471 item.dval = -dval;\r
472 item.ival = -ival;\r
473 stack.push(item);\r
474 return true;\r
475 }\r
476 };\r
477 \r
478 class TokEquals : public Token\r
479 {\r
480 public:\r
481 TokEquals()\r
482 {\r
483 type = TOK_EQUALS;\r
484 stype = "equals";\r
485 }\r
486 virtual bool execute(Stack &stack, NodeList &list)\r
487 {\r
488 StackItem item1 = stack.pop();\r
489 StackItem item2 = stack.pop();\r
490 item1.ival = (item1.dval == item2.dval);\r
491 stack.push(item1);\r
492 return true;\r
493 }\r
494 };\r
495 \r
496 class TokNotEquals : public Token\r
497 {\r
498 public:\r
499 TokNotEquals()\r
500 {\r
501 type = TOK_NOT_EQUALS;\r
502 stype = "neq";\r
503 }\r
504 virtual bool execute(Stack &stack, NodeList &list)\r
505 {\r
506 StackItem item1 = stack.pop();\r
507 StackItem item2 = stack.pop();\r
508 item1.ival = (item1.dval != item2.dval);\r
509 stack.push(item1);\r
510 return true;\r
511 }\r
512 };\r
513 \r
514 class TokLessThanEquals : public Token\r
515 {\r
516 public:\r
517 TokLessThanEquals()\r
518 {\r
519 type = TOK_LESS_THAN_EQUALS;\r
520 stype = "lt_eq";\r
521 }\r
522 virtual bool execute(Stack &stack, NodeList &list)\r
523 {\r
524 StackItem item1 = stack.pop();\r
525 StackItem item2 = stack.pop();\r
526 item1.ival = (item1.dval <= item2.dval);\r
527 stack.push(item1);\r
528 return true;\r
529 }\r
530 };\r
531 \r
532 class TokLessThan : public Token\r
533 {\r
534 public:\r
535 TokLessThan()\r
536 {\r
537 type = TOK_LESS_THAN;\r
538 stype = "lt";\r
539 }\r
540 virtual bool execute(Stack &stack, NodeList &list)\r
541 {\r
542 StackItem item1 = stack.pop();\r
543 StackItem item2 = stack.pop();\r
544 item1.ival = (item1.dval < item2.dval);\r
545 stack.push(item1);\r
546 return true;\r
547 }\r
548 };\r
549 \r
550 class TokGreaterThanEquals : public Token\r
551 {\r
552 public:\r
553 TokGreaterThanEquals()\r
554 {\r
555 type = TOK_GREATER_THAN_EQUALS;\r
556 stype = "gt";\r
557 }\r
558 virtual bool execute(Stack &stack, NodeList &list)\r
559 {\r
560 StackItem item1 = stack.pop();\r
561 StackItem item2 = stack.pop();\r
562 item1.ival = (item1.dval >= item2.dval);\r
563 stack.push(item1);\r
564 return true;\r
565 }\r
566 };\r
567 \r
568 class TokGreaterThan : public Token\r
569 {\r
570 public:\r
571 TokGreaterThan()\r
572 {\r
573 type = TOK_GREATER_THAN;\r
574 stype = "gt_eq";\r
575 }\r
576 virtual bool execute(Stack &stack, NodeList &list)\r
577 {\r
578 StackItem item1 = stack.pop();\r
579 StackItem item2 = stack.pop();\r
580 item1.ival = (item1.dval > item2.dval);\r
581 stack.push(item1);\r
582 return true;\r
583 }\r
584 };\r
585 \r
586 \r
587 //###########################\r
588 //# X P A T H I T E M S\r
589 //###########################\r
590 \r
591 class TokAbsolute : public Token\r
592 {\r
593 public:\r
594 TokAbsolute()\r
595 {\r
596 type = TOK_ABSOLUTE;\r
597 stype = "absolute";\r
598 }\r
599 virtual bool execute(Stack &stack, NodeList &list)\r
600 {\r
601 return true;\r
602 }\r
603 };\r
604 \r
605 class TokRelative : public Token\r
606 {\r
607 public:\r
608 TokRelative()\r
609 {\r
610 type = TOK_RELATIVE;\r
611 stype = "relative";\r
612 }\r
613 virtual bool execute(Stack &stack, NodeList &list)\r
614 {\r
615 return true;\r
616 }\r
617 };\r
618 \r
619 class TokStep : public Token\r
620 {\r
621 public:\r
622 TokStep()\r
623 {\r
624 type = TOK_STEP;\r
625 stype = "step";\r
626 }\r
627 virtual bool execute(Stack &stack, NodeList &list)\r
628 {\r
629 return true;\r
630 }\r
631 };\r
632 \r
633 class TokExpr : public Token\r
634 {\r
635 public:\r
636 TokExpr()\r
637 {\r
638 type = TOK_EXPR;\r
639 stype = "token";\r
640 }\r
641 virtual bool execute(Stack &stack, NodeList &list)\r
642 {\r
643 return true;\r
644 }\r
645 };\r
646 \r
647 class TokUnion : public Token\r
648 {\r
649 public:\r
650 TokUnion()\r
651 {\r
652 type = TOK_UNION;\r
653 stype = "union";\r
654 }\r
655 virtual bool execute(Stack &stack, NodeList &list)\r
656 {\r
657 return true;\r
658 }\r
659 };\r
660 \r
661 \r
662 \r
663 //###########################\r
664 //# F U N C T I O N S\r
665 //###########################\r
666 \r
667 class TokPosition : public Token\r
668 {\r
669 public:\r
670 TokPosition()\r
671 {\r
672 type = TOK_POSITION;\r
673 stype = "position";\r
674 }\r
675 virtual bool execute(Stack &stack, NodeList &list)\r
676 {\r
677 return true;\r
678 }\r
679 };\r
680 \r
681 \r
682 \r
683 //########################################################################\r
684 //# T O K E N L I S T\r
685 //########################################################################\r
686 \r
687 /**\r
688 *\r
689 */\r
690 class TokenList\r
691 {\r
692 public:\r
693 \r
694 /**\r
695 *\r
696 */\r
697 TokenList();\r
698 \r
699 /**\r
700 *\r
701 */\r
702 virtual ~TokenList();\r
703 \r
704 /**\r
705 *\r
706 */\r
707 virtual void clear();\r
708 \r
709 /**\r
710 *\r
711 */\r
712 virtual void add(Token *tok);\r
713 \r
714 /**\r
715 * This method "executes" a list of Tokens in the context of a DOM root\r
716 * Node, returning a list of Nodes that match the xpath expression.\r
717 */\r
718 NodeList execute(const Node *root);\r
719 \r
720 /**\r
721 *\r
722 */\r
723 virtual void dump();\r
724 \r
725 private:\r
726 \r
727 \r
728 std::vector<Token *> tokens;\r
729 \r
730 };\r
731 \r
732 \r
733 \r
734 } // namespace xpath\r
735 } // namespace dom\r
736 } // namespace w3c\r
737 } // namespace org\r
738 \r
739 \r
740 \r
741 \r
742 \r
743 \r
744 #endif /* __XPATHTOKEN_H__ */\r
745 //########################################################################\r
746 //# E N D O F F I L E\r
747 //########################################################################\r
748 \r