1 /*
2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2.1 of the License, or (at your option) any later version.
6 *
7 * As a special exception, you may use this file as part of a free
8 * software library without restriction. Specifically, if other files
9 * instantiate templates or use macros or inline functions from this
10 * file, or you compile this file and link it with other files to
11 * produce an executable, this file does not by itself cause the
12 * resulting executable to be covered by the GNU General Public
13 * License. This exception does not however invalidate any other
14 * reasons why the executable file might be covered by the GNU Library
15 * General Public License.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 */
26 #include "cxxtools/xml/xmlreader.h"
27 #include <cxxtools/xml/enddocument.h>
28 #include "cxxtools/xml/entityresolver.h"
29 #include <cxxtools/xml/doctypedeclaration.h>
30 #include "cxxtools/xml/startelement.h"
31 #include "cxxtools/xml/endelement.h"
32 #include "cxxtools/xml/characters.h"
33 #include "cxxtools/xml/processinginstruction.h"
34 #include "cxxtools/xml/comment.h"
35 #include "cxxtools/xml/xmlerror.h"
36 #include "cxxtools/textstream.h"
37 #include "cxxtools/utf8codec.h"
38 #include "cxxtools/log.h"
39 #include <stdexcept>
40 #include <iostream>
41 #include <sstream>
42
43 log_define("cxxtools.xml.reader")
44
45 namespace cxxtools {
46
47 namespace xml {
48
49 class XmlReaderImpl
50 {
51 struct State
52 {
~Statecxxtools::xml::XmlReaderImpl::State53 virtual ~State()
54 {}
55
onCharcxxtools::xml::XmlReaderImpl::State56 State* onChar(cxxtools::Char c, XmlReaderImpl& reader)
57 {
58 switch( c.value() )
59 {
60 case '\n':
61 case ' ':
62 case '\t':
63 case '\r':
64 return this->onSpace(c, reader);
65
66 case '<':
67 return this->onOpenBracket(c, reader);
68
69 case '>':
70 return this->onCloseBracket(c, reader);
71
72 case ':':
73 return this->onColon(c, reader);
74
75 case '/':
76 return this->onSlash(c, reader);
77
78 case '=':
79 return this->onEqual(c, reader);
80
81 case '"':
82 case '\'':
83 return this->onQuote(c, reader);
84
85 case '!':
86 return this->onExclam(c, reader);
87
88 case '?':
89 return this->onQuest(c, reader);
90
91 default:
92 return this->onAlpha(c, reader);
93 }
94
95 std::ostringstream msg;
96 msg << "unexpected char '" << c.narrow() << '\'';
97 syntaxError(msg.str().c_str(), reader.line());
98 return 0;
99 }
100
onSpacecxxtools::xml::XmlReaderImpl::State101 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
102 {
103 syntaxError("unexpected space", reader.line() );
104 return this;
105 }
106
onOpenBracketcxxtools::xml::XmlReaderImpl::State107 virtual State* onOpenBracket(cxxtools::Char c, XmlReaderImpl& reader)
108 {
109 syntaxError("unexpected open bracket", reader.line());
110 return this;
111 }
112
onCloseBracketcxxtools::xml::XmlReaderImpl::State113 virtual State* onCloseBracket(cxxtools::Char c, XmlReaderImpl& reader)
114 {
115 syntaxError("unexpected close bracket", reader.line());
116 return this;
117 }
118
onColoncxxtools::xml::XmlReaderImpl::State119 virtual State* onColon(cxxtools::Char c, XmlReaderImpl& reader)
120 {
121 syntaxError("unexpected colon", reader.line());
122 return this;
123 }
124
onSlashcxxtools::xml::XmlReaderImpl::State125 virtual State* onSlash(cxxtools::Char c, XmlReaderImpl& reader)
126 {
127 syntaxError("unexpected slash", reader.line());
128 return this;
129 }
130
onEqualcxxtools::xml::XmlReaderImpl::State131 virtual State* onEqual(cxxtools::Char c, XmlReaderImpl& reader)
132 {
133 syntaxError("unexpected equal", reader.line());
134 return this;
135 }
136
onQuotecxxtools::xml::XmlReaderImpl::State137 virtual State* onQuote(cxxtools::Char c, XmlReaderImpl& reader)
138 {
139 syntaxError("unexpected quote", reader.line());
140 return this;
141 }
142
onExclamcxxtools::xml::XmlReaderImpl::State143 virtual State* onExclam(cxxtools::Char c, XmlReaderImpl& reader)
144 {
145 syntaxError("unexpected exclamation mark", reader.line());
146 return this;
147 }
148
onQuestcxxtools::xml::XmlReaderImpl::State149 virtual State* onQuest(cxxtools::Char c, XmlReaderImpl& reader)
150 {
151 syntaxError("unexpected questionmark", reader.line());
152 return this;
153 }
154
onAlphacxxtools::xml::XmlReaderImpl::State155 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
156 {
157 std::ostringstream msg;
158 msg << "unexpected alpha '" << c.narrow() << '\'';
159 syntaxError(msg.str().c_str(), reader.line());
160 return this;
161 }
162
onEofcxxtools::xml::XmlReaderImpl::State163 virtual State* onEof(XmlReaderImpl& reader)
164 {
165 syntaxError("unexpected end of file", reader.line());
166 return this;
167 }
168
169 static void syntaxError(const char* msg, unsigned line);
170
171 };
172
173
174 struct OnCData : public State
175 {
onSpacecxxtools::xml::XmlReaderImpl::OnCData176 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
177 {
178 reader.appendContent(c);
179 return this;
180 }
181
onOpenBracketcxxtools::xml::XmlReaderImpl::OnCData182 virtual State* onOpenBracket(cxxtools::Char c, XmlReaderImpl& reader)
183 {
184 reader.appendContent(c);
185 return this;
186 }
187
onCloseBracketcxxtools::xml::XmlReaderImpl::OnCData188 virtual State* onCloseBracket(cxxtools::Char c, XmlReaderImpl& reader)
189 {
190
191 const String& content = reader._chars.content();
192 unsigned len = content.length();
193
194 if( len > 2 && content[len-2] == ']' &&
195 content[len-2] == ']')
196 {
197 reader._chars.content().resize(len-2);
198 return AfterTag::instance();
199 }
200
201 reader.appendContent(c);
202 return this;
203 }
204
onColoncxxtools::xml::XmlReaderImpl::OnCData205 virtual State* onColon(cxxtools::Char c, XmlReaderImpl& reader)
206 {
207 reader.appendContent(c);
208 return this;
209 }
210
onSlashcxxtools::xml::XmlReaderImpl::OnCData211 virtual State* onSlash(cxxtools::Char c, XmlReaderImpl& reader)
212 {
213 reader.appendContent(c);
214 return this;
215 }
216
onEqualcxxtools::xml::XmlReaderImpl::OnCData217 virtual State* onEqual(cxxtools::Char c, XmlReaderImpl& reader)
218 {
219 reader.appendContent(c);
220 return this;
221 }
222
onQuotecxxtools::xml::XmlReaderImpl::OnCData223 virtual State* onQuote(cxxtools::Char c, XmlReaderImpl& reader)
224 {
225 reader.appendContent(c);
226 return this;
227 }
228
onExclamcxxtools::xml::XmlReaderImpl::OnCData229 virtual State* onExclam(cxxtools::Char c, XmlReaderImpl& reader)
230 {
231 reader.appendContent(c);
232 return this;
233 }
234
onQuestcxxtools::xml::XmlReaderImpl::OnCData235 virtual State* onQuest(cxxtools::Char c, XmlReaderImpl& reader)
236 {
237 reader.appendContent(c);
238 return this;
239 }
240
onAlphacxxtools::xml::XmlReaderImpl::OnCData241 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
242 {
243 reader.appendContent(c);
244 return this;
245 }
246
instancecxxtools::xml::XmlReaderImpl::OnCData247 static State* instance()
248 {
249 static OnCData _state;
250 return &_state;
251 }
252 };
253
254
255 struct BeforeCData : public State
256 {
onAlphacxxtools::xml::XmlReaderImpl::BeforeCData257 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
258 {
259 String& token = reader._token;
260 token += c;
261
262 if(token.length() < 7)
263 return this;
264
265 if(token == L"[CDATA[")
266 {
267 token.clear();
268 return OnCData::instance();
269 }
270
271 syntaxError("CDATA expected", reader.line());
272 return this;
273 }
274
instancecxxtools::xml::XmlReaderImpl::BeforeCData275 static State* instance()
276 {
277 static BeforeCData _state;
278 return &_state;
279 }
280 };
281
282
283 struct OnEntityReference : public State
284 {
onAlphacxxtools::xml::XmlReaderImpl::OnEntityReference285 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
286 {
287 if(c == ';')
288 {
289 try
290 {
291 reader.resolveEntity(reader._token);
292 }
293 catch (const std::exception&)
294 {
295 throw XmlError("invalid entity " + reader._token.narrow(), reader.line());
296 }
297
298 reader._chars.content() += reader._token;
299 reader._token.clear();
300 return OnCharacters::instance();
301 }
302
303 reader._token += c;
304 return this;
305 }
306
instancecxxtools::xml::XmlReaderImpl::OnEntityReference307 static State* instance()
308 {
309 static OnEntityReference _state;
310 return &_state;
311 }
312 };
313
314
315 struct OnAttributeEntityReference : public State
316 {
onAlphacxxtools::xml::XmlReaderImpl::OnAttributeEntityReference317 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
318 {
319 if(c == ';')
320 {
321 reader.resolveEntity(reader._token);
322 reader._attr.value() += reader._token;
323 reader._token.clear();
324 return OnAttributeValue::instance();
325 }
326
327 reader._token += c;
328 return this;
329 }
330
instancecxxtools::xml::XmlReaderImpl::OnAttributeEntityReference331 static State* instance()
332 {
333 static OnAttributeEntityReference _state;
334 return &_state;
335 }
336 };
337
338
339 struct OnCharacters : public State
340 {
onSpacecxxtools::xml::XmlReaderImpl::OnCharacters341 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
342 {
343 reader.appendContent(c);
344 return this;
345 }
346
onColoncxxtools::xml::XmlReaderImpl::OnCharacters347 virtual State* onColon(cxxtools::Char c, XmlReaderImpl& reader)
348 {
349 reader.appendContent(c);
350 return this;
351 }
352
onOpenBracketcxxtools::xml::XmlReaderImpl::OnCharacters353 virtual State* onOpenBracket(cxxtools::Char c, XmlReaderImpl& reader)
354 {
355 return OnTag::instance();
356 }
357
onSlashcxxtools::xml::XmlReaderImpl::OnCharacters358 virtual State* onSlash(cxxtools::Char c, XmlReaderImpl& reader)
359 {
360 reader.appendContent(c);
361 return this;
362 }
363
onEqualcxxtools::xml::XmlReaderImpl::OnCharacters364 virtual State* onEqual(cxxtools::Char c, XmlReaderImpl& reader)
365 {
366 reader.appendContent(c);
367 return this;
368 }
369
onQuotecxxtools::xml::XmlReaderImpl::OnCharacters370 virtual State* onQuote(cxxtools::Char c, XmlReaderImpl& reader)
371 {
372 reader.appendContent(c);
373 return this;
374 }
375
onExclamcxxtools::xml::XmlReaderImpl::OnCharacters376 virtual State* onExclam(cxxtools::Char c, XmlReaderImpl& reader)
377 {
378 reader.appendContent(c);
379 return this;
380 }
381
onQuestcxxtools::xml::XmlReaderImpl::OnCharacters382 virtual State* onQuest(cxxtools::Char c, XmlReaderImpl& reader)
383 {
384 reader.appendContent(c);
385 return this;
386 }
387
onAlphacxxtools::xml::XmlReaderImpl::OnCharacters388 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
389 {
390 if(c == '&')
391 {
392 reader._token.clear();
393 return OnEntityReference::instance();
394 }
395
396 reader.appendContent(c);
397 return this;
398 }
399
instancecxxtools::xml::XmlReaderImpl::OnCharacters400 static State* instance()
401 {
402 static OnCharacters _state;
403 return &_state;
404 }
405 };
406
407
408 struct AfterEndElementName : public State
409 {
onSpacecxxtools::xml::XmlReaderImpl::AfterEndElementName410 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
411 {
412 return this;
413 }
414
onCloseBracketcxxtools::xml::XmlReaderImpl::AfterEndElementName415 virtual State* onCloseBracket(cxxtools::Char c, XmlReaderImpl& reader)
416 {
417 reader._chars.clear();
418 reader._current = &(reader._endElem);
419 reader._depth--;
420
421 if(reader.depth() == 0)
422 return OnEpilog::instance();
423
424 return AfterTag::instance();
425 }
426
instancecxxtools::xml::XmlReaderImpl::AfterEndElementName427 static State* instance()
428 {
429 static AfterEndElementName _state;
430 return &_state;
431 }
432 };
433
434
435 struct OnEndElementName : public State
436 {
onSpacecxxtools::xml::XmlReaderImpl::OnEndElementName437 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
438 {
439 return AfterEndElementName::instance();
440 }
441
onAlphacxxtools::xml::XmlReaderImpl::OnEndElementName442 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
443 {
444 reader._endElem.name() += c;
445 return this;
446 }
447
onCloseBracketcxxtools::xml::XmlReaderImpl::OnEndElementName448 virtual State* onCloseBracket(cxxtools::Char c, XmlReaderImpl& reader)
449 {
450 reader._chars.clear();
451 reader._current = &(reader._endElem);
452 reader._depth--;
453
454 if(reader.depth() == 0)
455 return OnEpilog::instance();
456
457 return AfterTag::instance();
458 }
459
instancecxxtools::xml::XmlReaderImpl::OnEndElementName460 static State* instance()
461 {
462 static OnEndElementName _state;
463 return &_state;
464 }
465 };
466
467
468 struct OnEndElement : public State
469 {
onAlphacxxtools::xml::XmlReaderImpl::OnEndElement470 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
471 {
472 reader._endElem.name() += c;
473 return OnEndElementName::instance();
474 }
475
instancecxxtools::xml::XmlReaderImpl::OnEndElement476 static State* instance()
477 {
478 static OnEndElement _state;
479 return &_state;
480 }
481 };
482
483
484 struct OnEmptyElement : public State
485 {
onSpacecxxtools::xml::XmlReaderImpl::OnEmptyElement486 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
487 {
488 return this;
489 }
490
onCloseBracketcxxtools::xml::XmlReaderImpl::OnEmptyElement491 virtual State* onCloseBracket(cxxtools::Char c, XmlReaderImpl& reader)
492 {
493 reader._endElem.name() = reader._startElem.name();
494 reader._current = &(reader._endElem);
495 reader._depth--;
496
497 if(reader.depth() == 0)
498 return OnEpilog::instance();
499
500 return AfterTag::instance();
501 }
502
instancecxxtools::xml::XmlReaderImpl::OnEmptyElement503 static State* instance()
504 {
505 static OnEmptyElement _state;
506 return &_state;
507 }
508 };
509
510
511 struct OnAttributeValue : public State
512 {
onQuotecxxtools::xml::XmlReaderImpl::OnAttributeValue513 virtual State* onQuote(cxxtools::Char c, XmlReaderImpl& reader)
514 {
515 reader._startElem.addAttribute(reader._attr);
516 return BeforeAttribute::instance();
517 }
518
onSpacecxxtools::xml::XmlReaderImpl::OnAttributeValue519 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
520 {
521 reader._attr.value() += c;
522 return this;
523 }
524
onOpenBracketcxxtools::xml::XmlReaderImpl::OnAttributeValue525 virtual State* onOpenBracket(cxxtools::Char c, XmlReaderImpl& reader)
526 {
527 reader._attr.value() += c;
528 return this;
529 }
530
onCloseBracketcxxtools::xml::XmlReaderImpl::OnAttributeValue531 virtual State* onCloseBracket(cxxtools::Char c, XmlReaderImpl& reader)
532 {
533 reader._attr.value() += c;
534 return this;
535 }
536
onColoncxxtools::xml::XmlReaderImpl::OnAttributeValue537 virtual State* onColon(cxxtools::Char c, XmlReaderImpl& reader)
538 {
539 reader._attr.value() += c;
540 return this;
541 }
542
onSlashcxxtools::xml::XmlReaderImpl::OnAttributeValue543 virtual State* onSlash(cxxtools::Char c, XmlReaderImpl& reader)
544 {
545 reader._attr.value() += c;
546 return this;
547 }
548
onEqualcxxtools::xml::XmlReaderImpl::OnAttributeValue549 virtual State* onEqual(cxxtools::Char c, XmlReaderImpl& reader)
550 {
551 reader._attr.value() += c;
552 return this;
553 }
554
onExclamcxxtools::xml::XmlReaderImpl::OnAttributeValue555 virtual State* onExclam(cxxtools::Char c, XmlReaderImpl& reader)
556 {
557 reader._attr.value() += c;
558 return this;
559 }
560
onQuestcxxtools::xml::XmlReaderImpl::OnAttributeValue561 virtual State* onQuest(cxxtools::Char c, XmlReaderImpl& reader)
562 {
563 reader._attr.value() += c;
564 return this;
565 }
566
onAlphacxxtools::xml::XmlReaderImpl::OnAttributeValue567 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
568 {
569 if (c == '&')
570 {
571 reader._token.clear();
572 return OnAttributeEntityReference::instance();
573 }
574
575 reader._attr.value() += c;
576 return this;
577 }
578
instancecxxtools::xml::XmlReaderImpl::OnAttributeValue579 static State* instance()
580 {
581 static OnAttributeValue _state;
582 return &_state;
583 }
584 };
585
586
587 struct BeforeAttributeValue : public State
588 {
onSpacecxxtools::xml::XmlReaderImpl::BeforeAttributeValue589 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
590 {
591 return this;
592 }
593
onQuotecxxtools::xml::XmlReaderImpl::BeforeAttributeValue594 virtual State* onQuote(cxxtools::Char c, XmlReaderImpl& reader)
595 {
596 return OnAttributeValue::instance();
597 }
598
instancecxxtools::xml::XmlReaderImpl::BeforeAttributeValue599 static State* instance()
600 {
601 static BeforeAttributeValue _state;
602 return &_state;
603 }
604 };
605
606
607 struct AfterAttributeName : public State
608 {
onSpacecxxtools::xml::XmlReaderImpl::AfterAttributeName609 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
610 {
611 return this;
612 }
613
onEqualcxxtools::xml::XmlReaderImpl::AfterAttributeName614 virtual State* onEqual(cxxtools::Char c, XmlReaderImpl& reader)
615 {
616 return BeforeAttributeValue::instance();
617 }
618
instancecxxtools::xml::XmlReaderImpl::AfterAttributeName619 static State* instance()
620 {
621 static AfterAttributeName _state;
622 return &_state;
623 }
624 };
625
626
627 struct OnAttributeName : public State
628 {
onSpacecxxtools::xml::XmlReaderImpl::OnAttributeName629 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
630 {
631 return AfterAttributeName::instance();
632 }
633
onEqualcxxtools::xml::XmlReaderImpl::OnAttributeName634 virtual State* onEqual(cxxtools::Char c, XmlReaderImpl& reader)
635 {
636 return BeforeAttributeValue::instance();
637 }
638
onAlphacxxtools::xml::XmlReaderImpl::OnAttributeName639 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
640 {
641 reader._attr.name() += c;
642 return this;
643 }
644
onColoncxxtools::xml::XmlReaderImpl::OnAttributeName645 virtual State* onColon(cxxtools::Char c, XmlReaderImpl& reader)
646 {
647 reader._attr.name() += c;
648 return this;
649 }
650
instancecxxtools::xml::XmlReaderImpl::OnAttributeName651 static State* instance()
652 {
653 static OnAttributeName _state;
654 return &_state;
655 }
656 };
657
658
659 struct BeforeAttribute : public State
660 {
onSpacecxxtools::xml::XmlReaderImpl::BeforeAttribute661 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
662 {
663 return this;
664 }
665
onSlashcxxtools::xml::XmlReaderImpl::BeforeAttribute666 virtual State* onSlash(cxxtools::Char c, XmlReaderImpl& reader)
667 {
668 reader._current = &(reader._startElem);
669 reader._depth++;
670 return OnEmptyElement::instance();
671 }
672
onAlphacxxtools::xml::XmlReaderImpl::BeforeAttribute673 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
674 {
675 reader._attr.clear();
676 reader._attr.name() += c;
677 return OnAttributeName::instance();
678 }
679
onCloseBracketcxxtools::xml::XmlReaderImpl::BeforeAttribute680 virtual State* onCloseBracket(cxxtools::Char c, XmlReaderImpl& reader)
681 {
682 reader._chars.clear();
683 reader._current = &(reader._startElem);
684 reader._depth++;
685 return AfterTag::instance();
686 }
687
instancecxxtools::xml::XmlReaderImpl::BeforeAttribute688 static State* instance()
689 {
690 static BeforeAttribute _state;
691 return &_state;
692 }
693 };
694
695
696 struct OnStartElement : public State
697 {
onSpacecxxtools::xml::XmlReaderImpl::OnStartElement698 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
699 {
700 return BeforeAttribute::instance();
701 }
702
onSlashcxxtools::xml::XmlReaderImpl::OnStartElement703 virtual State* onSlash(cxxtools::Char c, XmlReaderImpl& reader)
704 {
705 reader._chars.clear();
706 reader._current = &(reader._startElem);
707 reader._depth++;
708 return OnEmptyElement::instance();
709 }
710
onAlphacxxtools::xml::XmlReaderImpl::OnStartElement711 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
712 {
713 reader._startElem.name() += c;
714 return this;
715 }
716
onCloseBracketcxxtools::xml::XmlReaderImpl::OnStartElement717 virtual State* onCloseBracket(cxxtools::Char c, XmlReaderImpl& reader)
718 {
719 reader._chars.clear();
720 reader._current = &(reader._startElem);
721 reader._depth++;
722 return AfterTag::instance();
723 }
724
instancecxxtools::xml::XmlReaderImpl::OnStartElement725 static State* instance()
726 {
727 static OnStartElement _state;
728 return &_state;
729 }
730 };
731
732
733 struct OnCommentEnd : public State
734 {
onCloseBracketcxxtools::xml::XmlReaderImpl::OnCommentEnd735 virtual State* onCloseBracket(cxxtools::Char c, XmlReaderImpl& reader)
736 {
737 if(reader.depth() == 0)
738 return OnProlog::instance();
739
740 return AfterTag::instance();
741 }
742
instancecxxtools::xml::XmlReaderImpl::OnCommentEnd743 static State* instance()
744 {
745 static OnCommentEnd _state;
746 return &_state;
747 }
748 };
749
750
751 struct AfterComment : public State
752 {
onSpacecxxtools::xml::XmlReaderImpl::AfterComment753 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
754 {
755 return OnComment::instance();
756 }
757
onColoncxxtools::xml::XmlReaderImpl::AfterComment758 virtual State* onColon(cxxtools::Char c, XmlReaderImpl& reader)
759 {
760 return OnComment::instance();
761 }
762
onEqualcxxtools::xml::XmlReaderImpl::AfterComment763 virtual State* onEqual(cxxtools::Char c, XmlReaderImpl& reader)
764 {
765 return OnComment::instance();
766 }
767
onQuotecxxtools::xml::XmlReaderImpl::AfterComment768 virtual State* onQuote(cxxtools::Char c, XmlReaderImpl& reader)
769 {
770 return OnComment::instance();
771 }
772
onExclamcxxtools::xml::XmlReaderImpl::AfterComment773 virtual State* onExclam(cxxtools::Char c, XmlReaderImpl& reader)
774 {
775 return OnComment::instance();
776 }
777
onCloseBracketcxxtools::xml::XmlReaderImpl::AfterComment778 virtual State* onCloseBracket(cxxtools::Char c, XmlReaderImpl& reader)
779 {
780 return OnComment::instance();
781 }
782
onOpenBracketcxxtools::xml::XmlReaderImpl::AfterComment783 virtual State* onOpenBracket(cxxtools::Char c, XmlReaderImpl& reader)
784 {
785 return OnComment::instance();
786 }
787
onSlashcxxtools::xml::XmlReaderImpl::AfterComment788 virtual State* onSlash(cxxtools::Char c, XmlReaderImpl& reader)
789 {
790 return OnComment::instance();
791 }
792
onQuestcxxtools::xml::XmlReaderImpl::AfterComment793 virtual State* onQuest(cxxtools::Char c, XmlReaderImpl& reader)
794 {
795 return OnComment::instance();
796 }
797
onAlphacxxtools::xml::XmlReaderImpl::AfterComment798 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
799 {
800 if(c == '-')
801 return OnCommentEnd::instance();
802
803 return OnComment::instance();
804 }
805
instancecxxtools::xml::XmlReaderImpl::AfterComment806 static State* instance()
807 {
808 static AfterComment _state;
809 return &_state;
810 }
811 };
812
813
814 struct OnComment : public State
815 {
onSpacecxxtools::xml::XmlReaderImpl::OnComment816 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
817 {
818 return this;
819 }
820
onColoncxxtools::xml::XmlReaderImpl::OnComment821 virtual State* onColon(cxxtools::Char c, XmlReaderImpl& reader)
822 {
823 return this;
824 }
825
onEqualcxxtools::xml::XmlReaderImpl::OnComment826 virtual State* onEqual(cxxtools::Char c, XmlReaderImpl& reader)
827 {
828 return this;
829 }
830
onQuotecxxtools::xml::XmlReaderImpl::OnComment831 virtual State* onQuote(cxxtools::Char c, XmlReaderImpl& reader)
832 {
833 return this;
834 }
835
onExclamcxxtools::xml::XmlReaderImpl::OnComment836 virtual State* onExclam(cxxtools::Char c, XmlReaderImpl& reader)
837 {
838 return this;
839 }
840
onCloseBracketcxxtools::xml::XmlReaderImpl::OnComment841 virtual State* onCloseBracket(cxxtools::Char c, XmlReaderImpl& reader)
842 {
843 return this;
844 }
845
onOpenBracketcxxtools::xml::XmlReaderImpl::OnComment846 virtual State* onOpenBracket(cxxtools::Char c, XmlReaderImpl& reader)
847 {
848 return this;
849 }
850
onSlashcxxtools::xml::XmlReaderImpl::OnComment851 virtual State* onSlash(cxxtools::Char c, XmlReaderImpl& reader)
852 {
853 return this;
854 }
855
onQuestcxxtools::xml::XmlReaderImpl::OnComment856 virtual State* onQuest(cxxtools::Char c, XmlReaderImpl& reader)
857 {
858 return this;
859 }
860
onAlphacxxtools::xml::XmlReaderImpl::OnComment861 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
862 {
863 if(c == '-')
864 return AfterComment::instance();
865
866 return this;
867 }
868
instancecxxtools::xml::XmlReaderImpl::OnComment869 static State* instance()
870 {
871 static OnComment _state;
872 return &_state;
873 }
874 };
875
876
877 struct BeforeComment: public State
878 {
onAlphacxxtools::xml::XmlReaderImpl::BeforeComment879 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
880 {
881 if(c == '-')
882 return OnComment::instance();
883
884 State::onAlpha(c, reader); // throws syntax error // TODO DOCTYPE
885 return this;
886 }
887
instancecxxtools::xml::XmlReaderImpl::BeforeComment888 static State* instance()
889 {
890 static BeforeComment _state;
891 return &_state;
892 }
893 };
894
895
896 struct AfterTag : public OnCharacters
897 {
onSpacecxxtools::xml::XmlReaderImpl::AfterTag898 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
899 {
900 if(reader.depth() == 0)
901 return OnProlog::instance();
902
903 reader.appendContent(c);
904 return OnCharacters::instance();
905 }
906
onEofcxxtools::xml::XmlReaderImpl::AfterTag907 virtual State* onEof(XmlReaderImpl& reader)
908 {
909 if(reader.depth() > 0)
910 return State::onEof(reader); // throws exception
911
912 reader._current = &( reader._endDoc );
913 return this;
914 }
915
instancecxxtools::xml::XmlReaderImpl::AfterTag916 static State* instance()
917 {
918 static AfterTag _state;
919 return &_state;
920 }
921 };
922
923
924 struct OnDocType : public State
925 {
onSpacecxxtools::xml::XmlReaderImpl::OnDocType926 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
927 {
928 reader._docType.content() += c;
929 return this;
930 }
931
onQuestcxxtools::xml::XmlReaderImpl::OnDocType932 virtual State* onQuest(cxxtools::Char c, XmlReaderImpl& reader)
933 {
934 reader._docType.content() += c;
935 return this;
936 }
937
onColoncxxtools::xml::XmlReaderImpl::OnDocType938 virtual State* onColon(cxxtools::Char c, XmlReaderImpl& reader)
939 {
940 reader._docType.content() += c;
941 return this;
942 }
943
onSlashcxxtools::xml::XmlReaderImpl::OnDocType944 virtual State* onSlash(cxxtools::Char c, XmlReaderImpl& reader)
945 {
946 reader._docType.content() += c;
947 return this;
948 }
949
onExclamcxxtools::xml::XmlReaderImpl::OnDocType950 virtual State* onExclam(cxxtools::Char c, XmlReaderImpl& reader)
951 {
952 reader._docType.content() += c;
953 return this;
954 }
955
onEqualcxxtools::xml::XmlReaderImpl::OnDocType956 virtual State* onEqual(cxxtools::Char c, XmlReaderImpl& reader)
957 {
958 reader._docType.content() += c;
959 return this;
960 }
961
onQuotecxxtools::xml::XmlReaderImpl::OnDocType962 virtual State* onQuote(cxxtools::Char c, XmlReaderImpl& reader)
963 {
964 reader._docType.content() += c;
965 return this;
966 }
967
onCloseBracketcxxtools::xml::XmlReaderImpl::OnDocType968 virtual State* onCloseBracket(cxxtools::Char c, XmlReaderImpl& reader)
969 {
970 reader._current = &(reader._docType);
971 return OnProlog::instance();
972 }
973
onAlphacxxtools::xml::XmlReaderImpl::OnDocType974 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
975 {
976 reader._docType.content() += c;
977 return this;
978 }
979
instancecxxtools::xml::XmlReaderImpl::OnDocType980 static State* instance()
981 {
982 static OnDocType _state;
983 return &_state;
984 }
985 };
986
987
988 struct BeforeDocType : public State
989 {
onAlphacxxtools::xml::XmlReaderImpl::BeforeDocType990 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
991 {
992 String& token = reader._docType.content();
993 token += c;
994
995 if(token.length() < 7)
996 return this;
997
998 if(token == L"DOCTYPE")
999 {
1000 return OnDocType::instance();
1001 }
1002
1003 token.clear();
1004 syntaxError("DOCTYPE expected", reader.line());
1005 return this;
1006 }
1007
instancecxxtools::xml::XmlReaderImpl::BeforeDocType1008 static State* instance()
1009 {
1010 static BeforeDocType _state;
1011 return &_state;
1012 }
1013 };
1014
1015
1016 struct OnTagExclam : public State
1017 {
onAlphacxxtools::xml::XmlReaderImpl::OnTagExclam1018 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
1019 {
1020 if(c == '-')
1021 return BeforeComment::instance();
1022
1023 if(c == '[' && reader.depth() > 0)
1024 {
1025 reader._token.clear();
1026 reader._token += c;
1027 return BeforeCData::instance();
1028 }
1029
1030 if(c == 'D' && reader.depth() == 0)
1031 {
1032 reader._docType.clear();
1033 reader._docType.content() += c;
1034 return BeforeDocType::instance();
1035 }
1036
1037 return State::onAlpha(c, reader); // throws syntax error
1038 }
1039
instancecxxtools::xml::XmlReaderImpl::OnTagExclam1040 static State* instance()
1041 {
1042 static OnTagExclam _state;
1043 return &_state;
1044 }
1045 };
1046
1047
1048 struct OnTag : public State
1049 {
onQuestcxxtools::xml::XmlReaderImpl::OnTag1050 virtual State* onQuest(cxxtools::Char c, XmlReaderImpl& reader)
1051 {
1052 reader._procInstr.clear();
1053 return OnProcessingInstruction::instance();
1054 }
1055
onExclamcxxtools::xml::XmlReaderImpl::OnTag1056 virtual State* onExclam(cxxtools::Char c, XmlReaderImpl& reader)
1057 {
1058 return OnTagExclam::instance();
1059 }
1060
onSlashcxxtools::xml::XmlReaderImpl::OnTag1061 virtual State* onSlash(cxxtools::Char c, XmlReaderImpl& reader)
1062 {
1063 if( reader._chars.content().length() )
1064 {
1065 reader._current = &(reader._chars);
1066 }
1067
1068 reader._endElem.clear();
1069 return OnEndElement::instance();
1070 }
1071
onAlphacxxtools::xml::XmlReaderImpl::OnTag1072 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
1073 {
1074 if( reader._chars.content().length() )
1075 {
1076 reader._current = &(reader._chars);
1077 }
1078
1079 reader._startElem.clear();
1080 reader._startElem.name() += c;
1081 return OnStartElement::instance();
1082 }
1083
instancecxxtools::xml::XmlReaderImpl::OnTag1084 static State* instance()
1085 {
1086 static OnTag _state;
1087 return &_state;
1088 }
1089 };
1090
1091
1092 struct OnEpilog : public State
1093 {
onSpacecxxtools::xml::XmlReaderImpl::OnEpilog1094 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
1095 {
1096 return this;
1097 }
1098
onOpenBracketcxxtools::xml::XmlReaderImpl::OnEpilog1099 virtual State* onOpenBracket(cxxtools::Char c, XmlReaderImpl& reader)
1100 {
1101 return OnTag::instance();
1102 }
1103
onEofcxxtools::xml::XmlReaderImpl::OnEpilog1104 virtual State* onEof(XmlReaderImpl& reader)
1105 {
1106 reader._current = &( reader._endDoc );
1107 return this;
1108 }
1109
instancecxxtools::xml::XmlReaderImpl::OnEpilog1110 static State* instance()
1111 {
1112 static OnEpilog _state;
1113 return &_state;
1114 }
1115 };
1116
1117
1118 struct OnProlog : public State
1119 {
onSpacecxxtools::xml::XmlReaderImpl::OnProlog1120 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
1121 {
1122 return this;
1123 }
1124
onOpenBracketcxxtools::xml::XmlReaderImpl::OnProlog1125 virtual State* onOpenBracket(cxxtools::Char c, XmlReaderImpl& reader)
1126 {
1127 return OnTag::instance();
1128 }
1129
onEofcxxtools::xml::XmlReaderImpl::OnProlog1130 virtual State* onEof(XmlReaderImpl& reader)
1131 {
1132 reader._current = &( reader._endDoc );
1133 return this;
1134 }
1135
instancecxxtools::xml::XmlReaderImpl::OnProlog1136 static State* instance()
1137 {
1138 static OnProlog _state;
1139 return &_state;
1140 }
1141 };
1142
1143
1144 struct OnProcessingInstructionEnd : public State
1145 {
onCloseBracketcxxtools::xml::XmlReaderImpl::OnProcessingInstructionEnd1146 virtual State* onCloseBracket(cxxtools::Char c, XmlReaderImpl& reader)
1147 {
1148 reader._current = &(reader._procInstr);
1149 return AfterTag::instance();
1150 }
1151
instancecxxtools::xml::XmlReaderImpl::OnProcessingInstructionEnd1152 static State* instance()
1153 {
1154 static OnProcessingInstructionEnd _state;
1155 return &_state;
1156 }
1157 };
1158
1159
1160 struct OnProcessingInstructionData : public State
1161 {
onSpacecxxtools::xml::XmlReaderImpl::OnProcessingInstructionData1162 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
1163 {
1164 reader._procInstr.data() += c;
1165 return this;
1166 }
1167
onColoncxxtools::xml::XmlReaderImpl::OnProcessingInstructionData1168 virtual State* onColon(cxxtools::Char c, XmlReaderImpl& reader)
1169 {
1170 reader._procInstr.data() += c;
1171 return this;
1172 }
1173
onSlashcxxtools::xml::XmlReaderImpl::OnProcessingInstructionData1174 virtual State* onSlash(cxxtools::Char c, XmlReaderImpl& reader)
1175 {
1176 reader._procInstr.data() += c;
1177 return this;
1178 }
1179
onQuestcxxtools::xml::XmlReaderImpl::OnProcessingInstructionData1180 virtual State* onQuest(cxxtools::Char c, XmlReaderImpl& reader)
1181 {
1182 return OnProcessingInstructionEnd::instance();
1183 }
1184
onExclamcxxtools::xml::XmlReaderImpl::OnProcessingInstructionData1185 virtual State* onExclam(cxxtools::Char c, XmlReaderImpl& reader)
1186 {
1187 reader._procInstr.data() += c;
1188 return this;
1189 }
1190
onQuotecxxtools::xml::XmlReaderImpl::OnProcessingInstructionData1191 virtual State* onQuote(cxxtools::Char c, XmlReaderImpl& reader)
1192 {
1193 reader._procInstr.data() += c;
1194 return this;
1195 }
1196
onEqualcxxtools::xml::XmlReaderImpl::OnProcessingInstructionData1197 virtual State* onEqual(cxxtools::Char c, XmlReaderImpl& reader)
1198 {
1199 reader._procInstr.data() += c;
1200 return this;
1201 }
1202
onAlphacxxtools::xml::XmlReaderImpl::OnProcessingInstructionData1203 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
1204 {
1205 reader._procInstr.data() += c;
1206 return this;
1207 }
1208
instancecxxtools::xml::XmlReaderImpl::OnProcessingInstructionData1209 static State* instance()
1210 {
1211 static OnProcessingInstructionData _state;
1212 return &_state;
1213 }
1214 };
1215
1216
1217 struct OnProcessingInstruction : public State
1218 {
onSpacecxxtools::xml::XmlReaderImpl::OnProcessingInstruction1219 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
1220 {
1221 return OnProcessingInstructionData::instance();
1222 }
1223
onAlphacxxtools::xml::XmlReaderImpl::OnProcessingInstruction1224 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
1225 {
1226 reader._procInstr.target() += c;
1227 return this;
1228 }
1229
instancecxxtools::xml::XmlReaderImpl::OnProcessingInstruction1230 static State* instance()
1231 {
1232 static OnProcessingInstruction _state;
1233 return &_state;
1234 }
1235 };
1236
1237
1238 struct OnXmlDeclValue : public State
1239 {
onQuotecxxtools::xml::XmlReaderImpl::OnXmlDeclValue1240 virtual State* onQuote(cxxtools::Char c, XmlReaderImpl& reader)
1241 {
1242 if(reader._attr.name() == L"version")
1243 {
1244 reader._version = reader._attr.value();
1245 }
1246 else if(reader._attr.name() == L"encoding")
1247 {
1248 reader._encoding = reader._attr.value();
1249 }
1250 else if(reader._attr.name() == L"standalone")
1251 {
1252 if(reader._attr.value() == L"true")
1253 reader._standalone = true;
1254 }
1255
1256 return OnXmlDeclBeforeAttr::instance();
1257 }
1258
onAlphacxxtools::xml::XmlReaderImpl::OnXmlDeclValue1259 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
1260 {
1261 reader._attr.value() += c;
1262 return this;
1263 }
1264
instancecxxtools::xml::XmlReaderImpl::OnXmlDeclValue1265 static State* instance()
1266 {
1267 static OnXmlDeclValue _state;
1268 return &_state;
1269 }
1270 };
1271
1272
1273 struct OnXmlDeclBeforeValue : public State
1274 {
onSpacecxxtools::xml::XmlReaderImpl::OnXmlDeclBeforeValue1275 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
1276 {
1277 return this;
1278 }
1279
onQuotecxxtools::xml::XmlReaderImpl::OnXmlDeclBeforeValue1280 virtual State* onQuote(cxxtools::Char c, XmlReaderImpl& reader)
1281 {
1282 return OnXmlDeclValue::instance();
1283 }
1284
instancecxxtools::xml::XmlReaderImpl::OnXmlDeclBeforeValue1285 static State* instance()
1286 {
1287 static OnXmlDeclBeforeValue _state;
1288 return &_state;
1289 }
1290 };
1291
1292
1293 struct OnXmlDeclAfterName : public State
1294 {
onSpacecxxtools::xml::XmlReaderImpl::OnXmlDeclAfterName1295 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
1296 {
1297 return this;
1298 }
1299
onEqualcxxtools::xml::XmlReaderImpl::OnXmlDeclAfterName1300 virtual State* onEqual(cxxtools::Char c, XmlReaderImpl& reader)
1301 {
1302 return OnXmlDeclBeforeValue::instance();
1303 }
1304
instancecxxtools::xml::XmlReaderImpl::OnXmlDeclAfterName1305 static State* instance()
1306 {
1307 static OnXmlDeclAfterName _state;
1308 return &_state;
1309 }
1310 };
1311
1312
1313 struct OnXmlDeclAttr : public State
1314 {
onSpacecxxtools::xml::XmlReaderImpl::OnXmlDeclAttr1315 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
1316 {
1317 return OnXmlDeclAfterName::instance();
1318 }
1319
onEqualcxxtools::xml::XmlReaderImpl::OnXmlDeclAttr1320 virtual State* onEqual(cxxtools::Char c, XmlReaderImpl& reader)
1321 {
1322 return OnXmlDeclBeforeValue::instance();
1323 }
1324
onAlphacxxtools::xml::XmlReaderImpl::OnXmlDeclAttr1325 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
1326 {
1327 reader._attr.name() += c;
1328 return this;
1329 }
1330
instancecxxtools::xml::XmlReaderImpl::OnXmlDeclAttr1331 static State* instance()
1332 {
1333 static OnXmlDeclAttr _state;
1334 return &_state;
1335 }
1336 };
1337
1338
1339 struct OnXmlDeclEnd : public State
1340 {
onCloseBracketcxxtools::xml::XmlReaderImpl::OnXmlDeclEnd1341 virtual State* onCloseBracket(cxxtools::Char c, XmlReaderImpl& reader)
1342 {
1343 return OnProlog::instance();
1344 }
1345
instancecxxtools::xml::XmlReaderImpl::OnXmlDeclEnd1346 static State* instance()
1347 {
1348 static OnXmlDeclEnd _state;
1349 return &_state;
1350 }
1351 };
1352
1353
1354 struct OnXmlDeclBeforeAttr : public State
1355 {
onSpacecxxtools::xml::XmlReaderImpl::OnXmlDeclBeforeAttr1356 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
1357 {
1358 return this;
1359 }
1360
onAlphacxxtools::xml::XmlReaderImpl::OnXmlDeclBeforeAttr1361 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
1362 {
1363 reader._attr.clear();
1364 reader._attr.name() += c;
1365 return OnXmlDeclAttr::instance();
1366 }
1367
onQuestcxxtools::xml::XmlReaderImpl::OnXmlDeclBeforeAttr1368 virtual State* onQuest(cxxtools::Char c, XmlReaderImpl& reader)
1369 {
1370 return OnXmlDeclEnd::instance();
1371 }
1372
instancecxxtools::xml::XmlReaderImpl::OnXmlDeclBeforeAttr1373 static State* instance()
1374 {
1375 static OnXmlDeclBeforeAttr _state;
1376 return &_state;
1377 }
1378 };
1379
1380
1381 struct OnXmlDeclName : public State
1382 {
onSpacecxxtools::xml::XmlReaderImpl::OnXmlDeclName1383 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
1384 {
1385 if( reader._procInstr.target() == L"xml" )
1386 return OnXmlDeclBeforeAttr::instance();
1387
1388 return OnProcessingInstructionData::instance();
1389 }
1390
onColoncxxtools::xml::XmlReaderImpl::OnXmlDeclName1391 virtual State* onColon(cxxtools::Char c, XmlReaderImpl& reader)
1392 {
1393 reader._procInstr.target() += c;
1394 return this;
1395 }
1396
onAlphacxxtools::xml::XmlReaderImpl::OnXmlDeclName1397 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
1398 {
1399 reader._procInstr.target() += c;
1400 return this;
1401 }
1402
instancecxxtools::xml::XmlReaderImpl::OnXmlDeclName1403 static State* instance()
1404 {
1405 static OnXmlDeclName _state;
1406 return &_state;
1407 }
1408 };
1409
1410
1411 struct OnXmlDeclQMark : public State
1412 {
onAlphacxxtools::xml::XmlReaderImpl::OnXmlDeclQMark1413 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
1414 {
1415 reader._procInstr.clear();
1416 reader._procInstr.target() += c;
1417 return OnXmlDeclName::instance();
1418 }
1419
instancecxxtools::xml::XmlReaderImpl::OnXmlDeclQMark1420 static State* instance()
1421 {
1422 static OnXmlDeclQMark _state;
1423 return &_state;
1424 }
1425 };
1426
1427
1428 struct OnXmlDecl : public State
1429 {
onQuestcxxtools::xml::XmlReaderImpl::OnXmlDecl1430 virtual State* onQuest(cxxtools::Char c, XmlReaderImpl& reader)
1431 {
1432 return OnXmlDeclQMark::instance();
1433 }
1434
onExclamcxxtools::xml::XmlReaderImpl::OnXmlDecl1435 virtual State* onExclam(cxxtools::Char c, XmlReaderImpl& reader)
1436 {
1437 return OnTagExclam::instance();
1438 }
1439
onAlphacxxtools::xml::XmlReaderImpl::OnXmlDecl1440 virtual State* onAlpha(cxxtools::Char c, XmlReaderImpl& reader)
1441 {
1442 reader._startElem.clear();
1443 reader._startElem.name() += c;
1444 return OnStartElement::instance();
1445 }
1446
instancecxxtools::xml::XmlReaderImpl::OnXmlDecl1447 static State* instance()
1448 {
1449 static OnXmlDecl _state;
1450 return &_state;
1451 }
1452 };
1453
1454
1455 struct OnDocumentBegin : public State
1456 {
onSpacecxxtools::xml::XmlReaderImpl::OnDocumentBegin1457 virtual State* onSpace(cxxtools::Char c, XmlReaderImpl& reader)
1458 {
1459 return OnProlog::instance();
1460 }
1461
onOpenBracketcxxtools::xml::XmlReaderImpl::OnDocumentBegin1462 virtual State* onOpenBracket(cxxtools::Char c, XmlReaderImpl& reader)
1463 {
1464 return OnXmlDecl::instance();
1465 }
1466
instancecxxtools::xml::XmlReaderImpl::OnDocumentBegin1467 static State* instance()
1468 {
1469 static OnDocumentBegin _state;
1470 return &_state;
1471 }
1472 };
1473
1474
1475 public:
XmlReaderImpl(std::basic_istream<Char> & is,int flags)1476 XmlReaderImpl(std::basic_istream<Char>& is, int flags)
1477 : _textBuffer( is.rdbuf() )
1478 , _buffer(0)
1479 , _flags(flags)
1480 , _standalone(true)
1481 , _depth(0)
1482 , _line(1)
1483 , _state(0)
1484 , _current(0)
1485 {
1486 _state = XmlReaderImpl::OnDocumentBegin::instance();
1487 }
1488
XmlReaderImpl(std::istream & is,int flags)1489 XmlReaderImpl(std::istream& is, int flags)
1490 : _textBuffer(0)
1491 , _buffer(0)
1492 , _flags(flags)
1493 , _standalone(true)
1494 , _depth(0)
1495 , _line(1)
1496 , _state(0)
1497 , _current(0)
1498 {
1499 _state = XmlReaderImpl::OnDocumentBegin::instance();
1500 _buffer = new TextBuffer( &is, new cxxtools::Utf8Codec() );
1501 _textBuffer = _buffer;
1502 }
1503
~XmlReaderImpl()1504 ~XmlReaderImpl()
1505 {
1506 delete _buffer;
1507 }
1508
reset(std::basic_istream<Char> & is,int flags)1509 void reset(std::basic_istream<Char>& is, int flags)
1510 {
1511 delete _buffer;
1512 _buffer = 0;
1513 _textBuffer = is.rdbuf();
1514
1515 _state = XmlReaderImpl::OnDocumentBegin::instance();
1516 _flags = flags;
1517 _version.clear();
1518 _encoding.clear();
1519 _standalone = true;
1520 _depth = 0;
1521 _line = 1;
1522 _current = 0;
1523 }
1524
reset(std::istream & is,int flags)1525 void reset(std::istream& is, int flags)
1526 {
1527 delete _buffer;
1528 _buffer = new TextBuffer( &is, new cxxtools::Utf8Codec() );
1529 _textBuffer = _buffer;
1530
1531 _state = XmlReaderImpl::OnDocumentBegin::instance();
1532 _flags = flags;
1533 _version.clear();
1534 _encoding.clear();
1535 _standalone = true;
1536 _depth = 0;
1537 _line = 1;
1538 _current = 0;
1539 }
1540
version() const1541 const cxxtools::String& version() const
1542 { return _version; }
1543
encoding() const1544 const cxxtools::String& encoding() const
1545 { return _encoding; }
1546
standalone() const1547 bool standalone() const
1548 { return _standalone; }
1549
entityResolver()1550 EntityResolver& entityResolver()
1551 {
1552 return _resolver;
1553 }
1554
entityResolver() const1555 const EntityResolver& entityResolver() const
1556 {
1557 return _resolver;
1558 }
1559
depth() const1560 size_t depth() const
1561 {
1562 return _depth;
1563 }
1564
line() const1565 std::size_t line() const
1566 {
1567 return _line;
1568 }
1569
get()1570 const Node& get()
1571 {
1572 if( ! _current )
1573 {
1574 this->next();
1575 }
1576
1577 return *_current;
1578 }
1579
next()1580 const Node& next()
1581 {
1582 _current = 0;
1583 do
1584 {
1585 std::basic_streambuf<Char>::int_type c = _textBuffer->sbumpc();
1586 if (c == std::char_traits<Char>::eof())
1587 {
1588 _state = _state->onEof(*this);
1589 break;
1590 }
1591
1592 Char ch = std::char_traits<Char>::to_char_type(c);
1593 _state = _state->onChar(ch, *this);
1594
1595 if (ch == L'\n')
1596 {
1597 ++_line;
1598 }
1599 }
1600 while (!_current);
1601
1602 return *_current;
1603 }
1604
advance()1605 bool advance()
1606 {
1607 _current = 0;
1608 while( ! _current && _textBuffer->in_avail() > 0 )
1609 {
1610 Char ch = std::char_traits<Char>::to_char_type(_textBuffer->sbumpc());
1611 _state = _state->onChar(ch, *this);
1612
1613 if (ch == '\n')
1614 {
1615 ++_line;
1616 }
1617 }
1618
1619 return _current != 0;
1620 }
1621
resolveEntity(String & str)1622 void resolveEntity(String& str)
1623 {
1624 str = entityResolver().resolveEntity( str );
1625 }
1626
appendContent(cxxtools::Char c)1627 void appendContent(cxxtools::Char c)
1628 {
1629 String& content = _chars.content();
1630 if (content.capacity() <= content.size() + 20)
1631 {
1632 if (content.capacity() < 16)
1633 content.reserve(16);
1634 else
1635 content.reserve(content.capacity() + content.capacity() / 2);
1636 }
1637 content += c;
1638 }
1639
1640 private:
1641 std::basic_streambuf<Char>* _textBuffer;
1642 std::basic_streambuf<Char>* _buffer;
1643 int _flags;
1644 EntityResolver _resolver;
1645
1646 cxxtools::String _version;
1647 cxxtools::String _encoding;
1648 bool _standalone;
1649 size_t _depth;
1650 std::size_t _line;
1651
1652 State* _state;
1653 Node* _current;
1654 String _token;
1655 DocTypeDeclaration _docType;
1656 ProcessingInstruction _procInstr;
1657 StartElement _startElem;
1658 EndElement _endElem;
1659 Characters _chars;
1660 Attribute _attr;
1661 EndDocument _endDoc;
1662 };
1663
1664
syntaxError(const char * msg,unsigned line)1665 void XmlReaderImpl::State::syntaxError(const char* msg, unsigned line)
1666 {
1667 std::ostringstream s;
1668 s << msg << " while parsing xml in line " << line;
1669 log_warn(s.str());
1670 throw XmlError(s.str(), line);
1671 }
1672
1673
XmlReader(std::istream & is,int flags)1674 XmlReader::XmlReader(std::istream& is, int flags)
1675 : _impl(0)
1676 {
1677 _impl = new XmlReaderImpl(is, flags);
1678 }
1679
1680
XmlReader(std::basic_istream<Char> & is,int flags)1681 XmlReader::XmlReader(std::basic_istream<Char>& is, int flags)
1682 : _impl(0)
1683 {
1684 _impl = new XmlReaderImpl(is, flags);
1685 }
1686
1687
~XmlReader()1688 XmlReader::~XmlReader()
1689 {
1690 delete _impl;
1691 }
1692
1693
reset(std::basic_istream<Char> & is,int flags)1694 void XmlReader::reset(std::basic_istream<Char>& is, int flags)
1695 {
1696 _impl->reset(is, flags);
1697 }
1698
1699
reset(std::istream & is,int flags)1700 void XmlReader::reset(std::istream& is, int flags)
1701 {
1702 _impl->reset(is, flags);
1703 }
1704
1705
documentVersion() const1706 const cxxtools::String& XmlReader::documentVersion() const
1707 {
1708 return _impl->version();
1709 }
1710
1711
documentEncoding() const1712 const cxxtools::String& XmlReader::documentEncoding() const
1713 {
1714 return _impl->encoding();
1715 }
1716
1717
standaloneDocument() const1718 bool XmlReader::standaloneDocument() const
1719 {
1720 return _impl->standalone();
1721 }
1722
1723
entityResolver()1724 EntityResolver& XmlReader::entityResolver()
1725 {
1726 return _impl->entityResolver();
1727 }
1728
1729
entityResolver() const1730 const EntityResolver& XmlReader::entityResolver() const
1731 {
1732 return _impl->entityResolver();
1733 }
1734
1735
depth() const1736 size_t XmlReader::depth() const
1737 {
1738 return _impl->depth();
1739 }
1740
1741
line() const1742 std::size_t XmlReader::line() const
1743 {
1744 return _impl->line();
1745 }
1746
1747
get()1748 const Node& XmlReader::get()
1749 {
1750 return _impl->get();
1751 }
1752
1753
next()1754 const Node& XmlReader::next()
1755 {
1756 return _impl->next();
1757 }
1758
1759
advance()1760 bool XmlReader::advance()
1761 {
1762 return _impl->advance();
1763 }
1764
1765
nextElement()1766 const StartElement& XmlReader::nextElement()
1767 {
1768 bool found = false;
1769 while( !found )
1770 {
1771 const Node& node = this->next();
1772 switch( node.type() )
1773 {
1774 case Node::EndDocument:
1775 {
1776 throw std::logic_error("End of document");
1777 }
1778 case Node::StartElement:
1779 found = true;
1780 break;
1781
1782 default:
1783 break;
1784 }
1785
1786 }
1787
1788 return static_cast<const StartElement&>( this->get() );
1789 }
1790
1791
nextTag()1792 const Node& XmlReader::nextTag()
1793 {
1794 bool found = false;
1795 while( !found )
1796 {
1797 const Node& node = this->next();
1798 switch( node.type() )
1799 {
1800 case Node::EndDocument:
1801 {
1802 throw std::logic_error("End of document");
1803 }
1804 case Node::StartElement:
1805 case Node::EndElement:
1806 found = true;
1807 break;
1808
1809 default:
1810 break;
1811 }
1812
1813 }
1814
1815 return this->get();
1816 }
1817
1818 } // namespace xml
1819
1820 } // namespace cxxtools
1821