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