1 /**\r
2 * Phoebe DOM Implementation.\r
3 *\r
4 * This is a C++ approximation of the W3C DOM model, which follows\r
5 * fairly closely the specifications in the various .idl files, copies of\r
6 * which are provided for reference. Most important is this one:\r
7 *\r
8 * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html\r
9 *\r
10 * Authors:\r
11 * Bob Jamison\r
12 *\r
13 * Copyright (C) 2006 Bob Jamison\r
14 *\r
15 * This library is free software; you can redistribute it and/or\r
16 * modify it under the terms of the GNU Lesser General Public\r
17 * License as published by the Free Software Foundation; either\r
18 * version 2.1 of the License, or (at your option) any later version.\r
19 *\r
20 * This library is distributed in the hope that it will be useful,\r
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
23 * Lesser General Public License for more details.\r
24 *\r
25 * You should have received a copy of the GNU Lesser General Public\r
26 * License along with this library; if not, write to the Free Software\r
27 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\r
28 */\r
29 \r
30 \r
31 #include "xpathtoken.h"\r
32 #include <stdio.h>\r
33 \r
34 \r
35 \r
36 namespace org\r
37 {\r
38 namespace w3c\r
39 {\r
40 namespace dom\r
41 {\r
42 namespace xpath\r
43 {\r
44 \r
45 //########################################################################\r
46 //# X P A T H T O K E N\r
47 //########################################################################\r
48 \r
49 typedef struct\r
50 {\r
51 int ival;\r
52 char *sval;\r
53 } TokenStringPair;\r
54 \r
55 static TokenStringPair tokenStrings[] =\r
56 {\r
57 //primitives\r
58 { Token::TOK_NOP, "nop" },\r
59 { Token::TOK_STR, "str" },\r
60 { Token::TOK_INT, "int" },\r
61 { Token::TOK_FLOAT, "float" },\r
62 //operators\r
63 { Token::TOK_AND, "and" },\r
64 { Token::TOK_OR, "or" },\r
65 { Token::TOK_MOD, "mod" },\r
66 { Token::TOK_DIV, "div" },\r
67 { Token::TOK_MULTIPLY, "multiply" },\r
68 { Token::TOK_DOUBLE_SLASH, "double-slash" },\r
69 { Token::TOK_SLASH, "slash" },\r
70 { Token::TOK_PIPE, "pipe" },\r
71 { Token::TOK_PLUS, "plus" },\r
72 { Token::TOK_MINUS, "minus" },\r
73 { Token::TOK_NEG, "neg" },\r
74 { Token::TOK_EQUALS, "equals" },\r
75 { Token::TOK_NOT_EQUALS, "not-equals" },\r
76 { Token::TOK_LESS_THAN_EQUALS, "less-than-equals" },\r
77 { Token::TOK_LESS_THAN, "less-than" },\r
78 { Token::TOK_GREATER_THAN_EQUALS, "greater-than-equals" },\r
79 { Token::TOK_GREATER_THAN, "greater-than" },\r
80 //path types\r
81 { Token::TOK_ABSOLUTE, "absolute" },\r
82 { Token::TOK_RELATIVE, "relative" },\r
83 { Token::TOK_STEP, "step" },\r
84 { Token::TOK_NAME_TEST, "name-test" },\r
85 { Token::TOK_EXPR, "expr" },\r
86 { Token::TOK_UNION, "union" },\r
87 //axis types\r
88 { Token::TOK_AXIS_ANCESTOR_OR_SELF, "axis-ancestor-or-self" },\r
89 { Token::TOK_AXIS_ANCESTOR, "axis-ancestor" },\r
90 { Token::TOK_AXIS_ATTRIBUTE, "axis-attribute" },\r
91 { Token::TOK_AXIS_CHILD, "axis-child" },\r
92 { Token::TOK_AXIS_DESCENDANT_OR_SELF, "axis-descendant-or-self" },\r
93 { Token::TOK_AXIS_DESCENDANT, "axis-descendant" },\r
94 { Token::TOK_AXIS_FOLLOWING_SIBLING, "axis-following-sibling" },\r
95 { Token::TOK_AXIS_FOLLOWING, "axis-following" },\r
96 { Token::TOK_AXIS_NAMESPACE, "axis-namespace" },\r
97 { Token::TOK_AXIS_PARENT, "axis-parent" },\r
98 { Token::TOK_AXIS_PRECEDING_SIBLING, "axis-preceding-sibling" },\r
99 { Token::TOK_AXIS_PRECEDING, "axis-preceding" },\r
100 { Token::TOK_AXIS_SELF, "axis-self" },\r
101 //function types\r
102 { Token::TOK_FUNC_LAST, "func-last" },\r
103 { Token::TOK_FUNC_POSITION, "func-position" },\r
104 { Token::TOK_FUNC_COUNT, "func-count" },\r
105 { Token::TOK_FUNC_ID, "func-id" },\r
106 { Token::TOK_FUNC_LOCAL_NAME, "func-local-name" },\r
107 { Token::TOK_FUNC_NAMESPACE_URI, "func-namespace-uri" },\r
108 { Token::TOK_FUNC_NAME, "func-name" },\r
109 { Token::TOK_FUNC_STRING, "func-string" },\r
110 { Token::TOK_FUNC_CONCAT, "func-concat" },\r
111 { Token::TOK_FUNC_STARTS_WITH, "func-starts-with" },\r
112 { Token::TOK_FUNC_CONTAINS, "func-contains" },\r
113 { Token::TOK_FUNC_SUBSTRING_BEFORE, "func-substring-before" },\r
114 { Token::TOK_FUNC_SUBSTRING_AFTER, "func-substring-after" },\r
115 { Token::TOK_FUNC_SUBSTRING, "func-substring" },\r
116 { Token::TOK_FUNC_STRING_LENGTH, "func-string-length" },\r
117 { Token::TOK_FUNC_NORMALIZE_SPACE, "func-normalize-space" },\r
118 { Token::TOK_FUNC_TRANSLATE, "func-translate" },\r
119 { Token::TOK_FUNC_BOOLEAN, "func-boolean" },\r
120 { Token::TOK_FUNC_NOT, "func-not" },\r
121 { Token::TOK_FUNC_TRUE, "func-true" },\r
122 { Token::TOK_FUNC_FALSE, "func-false" },\r
123 { Token::TOK_FUNC_LANG, "func-lang" },\r
124 { Token::TOK_FUNC_NUMBER, "func-number" },\r
125 { Token::TOK_FUNC_SUM, "func-sum" },\r
126 { Token::TOK_FUNC_FLOOR, "func-floor" },\r
127 { Token::TOK_FUNC_CEILING, "func-ceiling" },\r
128 { Token::TOK_FUNC_ROUND, "func-round" },\r
129 { -1, (char *)0 }\r
130 };\r
131 \r
132 \r
133 /**\r
134 * Return the string TokenType of this token\r
135 * (in the .cpp file)\r
136 */\r
137 DOMString Token::getTypeString()\r
138 {\r
139 DOMString ret = "unknown";\r
140 for (TokenStringPair *pair = tokenStrings ; pair->sval ; pair++)\r
141 {\r
142 if (pair->ival == type)\r
143 {\r
144 ret = pair->sval;\r
145 break;\r
146 }\r
147 }\r
148 return ret;\r
149 }\r
150 \r
151 \r
152 \r
153 //########################################################################\r
154 //# X P A T H A X I S\r
155 //########################################################################\r
156 \r
157 /**\r
158 *\r
159 */\r
160 Axis::Axis()\r
161 {\r
162 init();\r
163 }\r
164 \r
165 \r
166 /**\r
167 *\r
168 */\r
169 Axis::Axis(int tokPos)\r
170 {\r
171 init();\r
172 tokenPosition = tokPos;\r
173 }\r
174 \r
175 \r
176 /**\r
177 *\r
178 */\r
179 Axis::Axis(const Axis &other)\r
180 {\r
181 init();\r
182 assign(other);\r
183 }\r
184 \r
185 \r
186 /**\r
187 *\r
188 */\r
189 Axis::~Axis()\r
190 {\r
191 }\r
192 \r
193 \r
194 /**\r
195 *\r
196 */\r
197 Axis &Axis::operator=(const Axis &other)\r
198 {\r
199 assign(other);\r
200 return *this;\r
201 }\r
202 \r
203 /**\r
204 *\r
205 */\r
206 void Axis::init()\r
207 {\r
208 tokenPosition = 0;\r
209 }\r
210 \r
211 /**\r
212 *\r
213 */\r
214 void Axis::assign(const Axis &other)\r
215 {\r
216 tokenPosition = other.tokenPosition;\r
217 }\r
218 \r
219 /**\r
220 *\r
221 */\r
222 void Axis::setPosition(unsigned int val)\r
223 {\r
224 tokenPosition = val;\r
225 }\r
226 \r
227 /**\r
228 *\r
229 */\r
230 unsigned int Axis::getPosition()\r
231 {\r
232 return tokenPosition;\r
233 }\r
234 \r
235 /**\r
236 *\r
237 */\r
238 void Axis::setNode(const Node *val)\r
239 {\r
240 node = (Node *)val;\r
241 }\r
242 \r
243 /**\r
244 *\r
245 */\r
246 Node *Axis::getNode()\r
247 {\r
248 return node;\r
249 }\r
250 \r
251 //########################################################################\r
252 //# X P A T H S T A C K I T E M\r
253 //########################################################################\r
254 \r
255 /**\r
256 *\r
257 */\r
258 StackItem::StackItem()\r
259 {\r
260 ival = 0L;\r
261 dval = 0.0;\r
262 }\r
263 \r
264 \r
265 /**\r
266 *\r
267 */\r
268 StackItem::StackItem(const StackItem &other)\r
269 {\r
270 assign(other);\r
271 }\r
272 \r
273 \r
274 /**\r
275 *\r
276 */\r
277 StackItem::~StackItem()\r
278 {\r
279 }\r
280 \r
281 \r
282 /**\r
283 *\r
284 */\r
285 StackItem &StackItem::operator=(const StackItem &other)\r
286 {\r
287 assign(other);\r
288 return *this;\r
289 }\r
290 \r
291 /**\r
292 *\r
293 */\r
294 void StackItem::assign(const StackItem &other)\r
295 {\r
296 sval = other.sval;\r
297 ival = other.ival;\r
298 dval = other.dval;\r
299 }\r
300 \r
301 \r
302 //########################################################################\r
303 //# T O K E N L I S T\r
304 //########################################################################\r
305 \r
306 /**\r
307 *\r
308 */\r
309 TokenList::TokenList()\r
310 {\r
311 }\r
312 \r
313 \r
314 /**\r
315 *\r
316 */\r
317 TokenList::TokenList(const TokenList &other)\r
318 {\r
319 assign(other);\r
320 }\r
321 \r
322 /**\r
323 *\r
324 */\r
325 TokenList &TokenList::operator=(const TokenList &other)\r
326 {\r
327 assign(other);\r
328 return *this;\r
329 }\r
330 \r
331 /**\r
332 *\r
333 */\r
334 void TokenList::assign(const TokenList &other)\r
335 {\r
336 tokens = other.tokens;\r
337 }\r
338 \r
339 /**\r
340 *\r
341 */\r
342 TokenList::~TokenList()\r
343 {\r
344 clear();\r
345 }\r
346 \r
347 /**\r
348 *\r
349 */\r
350 void TokenList::clear()\r
351 {\r
352 std::vector<Token *>::iterator iter;\r
353 for (iter = tokens.begin() ; iter!= tokens.end() ; iter++)\r
354 {\r
355 delete (*iter);\r
356 }\r
357 tokens.clear();\r
358 }\r
359 \r
360 /**\r
361 *\r
362 */\r
363 void TokenList::add(Token *tok)\r
364 {\r
365 tokens.push_back(tok);\r
366 }\r
367 \r
368 \r
369 /**\r
370 *\r
371 */\r
372 unsigned int TokenList::size() const\r
373 {\r
374 return (unsigned int)tokens.size();\r
375 }\r
376 \r
377 \r
378 /**\r
379 *\r
380 */\r
381 void TokenList::dump()\r
382 {\r
383 std::vector<Token *>::iterator iter;\r
384 printf("############# TOKENS\n");\r
385 for (iter = tokens.begin() ; iter != tokens.end() ; iter++)\r
386 {\r
387 Token *tok = *iter;\r
388 tok->dump();\r
389 }\r
390 }\r
391 \r
392 \r
393 //########################################################################\r
394 //# X P A T H E X E C U T O R\r
395 //########################################################################\r
396 \r
397 /**\r
398 *\r
399 */\r
400 TokenExecutor::TokenExecutor()\r
401 {\r
402 reset();\r
403 }\r
404 \r
405 \r
406 /**\r
407 *\r
408 */\r
409 TokenExecutor::TokenExecutor(const TokenExecutor &other)\r
410 {\r
411 reset();\r
412 assign(other);\r
413 }\r
414 \r
415 \r
416 /**\r
417 *\r
418 */\r
419 TokenExecutor::~TokenExecutor()\r
420 {\r
421 }\r
422 \r
423 \r
424 /**\r
425 *\r
426 */\r
427 void TokenExecutor::assign(const TokenExecutor &other)\r
428 {\r
429 axis = other.axis;\r
430 axisStack = other.axisStack;\r
431 stackSize = other.stackSize;\r
432 for (int i=0 ; i<stackSize ; i++)\r
433 stack[i] = other.stack[i];\r
434 }\r
435 \r
436 \r
437 /**\r
438 *\r
439 */\r
440 void TokenExecutor::reset()\r
441 {\r
442 axis.setPosition(0);\r
443 axis.setNode(NULL);\r
444 stackSize = 0;\r
445 }\r
446 \r
447 \r
448 \r
449 \r
450 /**\r
451 * Set the root node\r
452 */\r
453 NodeList TokenExecutor::execute(const TokenList &tokens, const Node *node)\r
454 {\r
455 \r
456 axis.setPosition(0);\r
457 axis.setNode(node);\r
458 \r
459 nodeList.clear();\r
460 \r
461 while (axis.getPosition() < tokens.size())\r
462 {\r
463 }\r
464 \r
465 return nodeList;\r
466 }\r
467 \r
468 \r
469 \r
470 \r
471 \r
472 /**\r
473 *\r
474 */\r
475 void TokenExecutor::push(StackItem &item)\r
476 {\r
477 if (stackSize>=STACK_SIZE)\r
478 {\r
479 return;\r
480 }\r
481 stack[stackSize++] = item;\r
482 }\r
483 \r
484 /**\r
485 *\r
486 */\r
487 StackItem TokenExecutor::pop()\r
488 {\r
489 if (stackSize<1)\r
490 {\r
491 StackItem item;\r
492 return item;\r
493 }\r
494 return stack[--stackSize];\r
495 }\r
496 \r
497 \r
498 \r
499 \r
500 \r
501 \r
502 \r
503 \r
504 \r
505 \r
506 } // namespace xpath\r
507 } // namespace dom\r
508 } // namespace w3c\r
509 } // namespace org\r
510 //########################################################################\r
511 //# E N D O F F I L E\r
512 //########################################################################\r
513 \r
514 \r
515 \r