ReactOS 0.4.15-dev-7788-g1ad9096
xmlstorage.cpp
Go to the documentation of this file.
1
2 //
3 // XML storage C++ classes version 1.3
4 //
5 // Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Martin Fuchs <martin-fuchs@gmx.net>
6 //
7
10
11
12/*
13
14 All rights reserved.
15
16 Redistribution and use in source and binary forms, with or without
17 modification, are permitted provided that the following conditions are met:
18
19 * Redistributions of source code must retain the above copyright
20 notice, this list of conditions and the following disclaimer.
21 * Redistributions in binary form must reproduce the above copyright
22 notice, this list of conditions and the following disclaimer in
23 the documentation and/or other materials provided with the
24 distribution.
25
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 POSSIBILITY OF SUCH DAMAGE.
37
38*/
39
40#include <precomp.h>
41
42#ifndef XS_NO_COMMENT
43#define XS_NO_COMMENT // no #pragma comment(lib, ...) statements in .lib files to enable static linking
44#endif
45
46//#include "xmlstorage.h"
47
48
49namespace XMLStorage {
50
51
52 // work around GCC's wide string constant bug
53#ifdef __GNUC__
59#endif
60
64
65
67static std::string unescape(const char* s, char b, char e)
68{
69 const char* end = s + strlen(s);
70
71// if (*s == b)
72// ++s;
73//
74// if (end>s && end[-1]==e)
75// --end;
76
77 if (*s == b)
78 if (end>s && end[-1]==e)
79 ++s, --end;
80
81 return std::string(s, end-s);
82}
83
84inline std::string unescape(const char* s)
85{
86 return unescape(s, '"', '"');
87}
88
90static std::string unescape(const char* s, size_t l, char b, char e)
91{
92 const char* end = s + l;
93
94// if (*s == b)
95// ++s;
96//
97// if (end>s && end[-1]==e)
98// --end;
99
100 if (*s == b)
101 if (end>s && end[-1]==e)
102 ++s, --end;
103
104 return std::string(s, end-s);
105}
106
107inline std::string unescape(const char* s, size_t l)
108{
109 return unescape(s, l, '"', '"');
110}
111
112
114bool XMLPos::go(const XPath& xpath)
115{
116 XMLNode* node = xpath._absolute? _root: _cur;
117
118 node = node->find_relative(xpath);
119
120 if (node) {
121 go_to(node);
122 return true;
123 } else
124 return false;
125}
126
128bool const_XMLPos::go(const XPath& xpath)
129{
130 const XMLNode* node = xpath._absolute? _root: _cur;
131
132 node = node->find_relative(xpath);
133
134 if (node) {
135 go_to(node);
136 return true;
137 } else
138 return false;
139}
140
141
142const char* XPathElement::parse(const char* path)
143{
144 const char* slash = strchr(path, '/');
145 if (slash == path)
146 return NULL;
147
148 size_t l = slash? slash-path: strlen(path);
149 std::string comp(path, l);
150 path += l;
151
152 // look for [n] and [@attr_name="attr_value"] expressions in path components
153 const char* bracket = strchr(comp.c_str(), '[');
154 l = bracket? bracket-comp.c_str(): comp.length();
155 _child_name.assign(comp.c_str(), l);
156
157 int n = 0;
158 if (bracket) {
159 std::string expr = unescape(bracket, '[', ']');
160 const char* p = expr.c_str();
161
162 n = atoi(p); // read index number
163
164 if (n)
165 _child_idx = n - 1; // convert into zero based index
166
167 const char* at = strchr(p, '@');
168
169 if (at) {
170 p = at + 1;
171 const char* equal = strchr(p, '=');
172
173 // read attribute name and value
174 if (equal) {
177 }
178 }
179 }
180
181 return path;
182}
183
185{
186 int n = 0;
187
188 for(XMLNode::Children::const_iterator it=node->_children.begin(); it!=node->_children.end(); ++it)
189 if (matches(**it, n))
190 return *it;
191
192 return NULL;
193}
194
196{
197 int n = 0;
198
199 for(XMLNode::Children::const_iterator it=node->_children.begin(); it!=node->_children.end(); ++it)
200 if (matches(**it, n))
201 return *it;
202
203 return NULL;
204}
205
206bool XPathElement::matches(const XMLNode& node, int& n) const
207{
208 if (node != _child_name)
209 if (_child_name != XS_TEXT("*")) // use asterisk as wildcard
210 return false;
211
212 if (!_attr_name.empty())
213 if (node.get(_attr_name) != _attr_value)
214 return false;
215
216 if (_child_idx == -1)
217 return true;
218 else if (n++ == _child_idx)
219 return true;
220 else
221 return false;
222}
223
224
225void XPath::init(const char* path)
226{
227 // Is this an absolute path?
228 if (*path == '/') {
229 _absolute = true;
230 ++path;
231 } else
232 _absolute = false;
233
234 // parse path
235 while(*path) {
237
238 path = elem.parse(path);
239
240 if (!path)
241 break;
242
243 if (*path == '/')
244 ++path;
245
246 push_back(elem);
247 }
248}
249
250
251const XMLNode* XMLNode::find_relative(const XPath& xpath) const
252{
253 const XMLNode* node = this;
254
255 for(XPath::const_iterator it=xpath.begin(); it!=xpath.end(); ++it) {
256 node = it->const_find(node);
257
258 if (!node)
259 return NULL;
260 }
261
262 return node;
263}
264
266{
267 XMLNode* node = this;
268
269 for(XPath::const_iterator it=xpath.begin(); it!=xpath.end(); ++it) {
270 node = it->find(node);
271
272 if (!node)
273 return NULL;
274 }
275
276 return node;
277}
278
280{
281 XMLNode* node = this;
282
283 for(XPath::const_iterator it=xpath.begin(); it!=xpath.end(); ++it) {
284 XMLNode* child = it->find(node);
285
286 if (!child) {
287 child = new XMLNode(it->_child_name);
288 node->add_child(child);
289
290 if (!it->_attr_name.empty())
291 (*this)[it->_attr_name] = it->_attr_value;
292 }
293
294 node = child;
295 }
296
297 return node;
298}
299
301int XMLNode::count(XPath::const_iterator from, const XPath::const_iterator& to) const
302{
303 const XPathElement& elem = *from++;
304 int cnt = 0;
305 int n = 0;
306
307 for(XMLNode::Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
308 if (elem.matches(**it, n)) {
309 if (from != to)
310 // iterate deeper
311 cnt += (*it)->count(from, to);
312 else
313 // increment match counter
314 ++cnt;
315 }
316
317 return cnt;
318}
319
321bool XMLNode::filter(const XPath& xpath, XMLNode& target) const
322{
323 XMLNode* ret = filter(xpath.begin(), xpath.end());
324
325 if (ret) {
326 // move returned nodes to target node
327 target._children.move(ret->_children);
328 target._attributes = ret->_attributes;
329
330 delete ret;
331
332 return true;
333 } else
334 return false;
335}
336
338XMLNode* XMLNode::filter(XPath::const_iterator from, const XPath::const_iterator& to) const
339{
340 XMLNode* copy = NULL;
341
342 const XPathElement& elem = *from++;
343 int cnt = 0;
344 int n = 0;
345
346 for(XMLNode::Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
347 if (elem.matches(**it, n)) {
348 if (!copy)
350
351 if (from != to) {
352 XMLNode* ret = (*it)->filter(from, to);
353
354 if (ret) {
355 copy->add_child(ret);
356 ++cnt;
357 }
358 } else {
359 copy->add_child(new XMLNode(**it, XMLNode::COPY_NOCHILDREN));
360 ++cnt;
361 }
362 }
363
364 if (cnt > 0) {
365 return copy;
366 } else {
367 delete copy;
368 return NULL;
369 }
370}
371
372
374std::string EncodeXMLString(const XS_String& str, bool cdata)
375{
376 LPCXSSTR s = str.c_str();
377 size_t l = XS_len(s);
378
379 if (cdata) {
380 // encode the whole string in a CDATA section
381 std::string ret = CDATA_START;
382
383#ifdef XS_STRING_UTF8
384 ret += str;
385#else
386 ret += get_utf8(str);
387#endif
388
389 ret += CDATA_END;
390
391 return ret;
392 } else if (l <= BUFFER_LEN) {
393 LPXSSTR buffer = (LPXSSTR)alloca(6*sizeof(XS_CHAR)*XS_len(s)); // worst case "&quot;" / "&apos;"
394 LPXSSTR o = buffer;
395
396 for(LPCXSSTR p=s; *p; ++p)
397 switch(*p) {
398 case '&':
399 *o++ = '&'; *o++ = 'a'; *o++ = 'm'; *o++ = 'p'; *o++ = ';'; // "&amp;"
400 break;
401
402 case '<':
403 *o++ = '&'; *o++ = 'l'; *o++ = 't'; *o++ = ';'; // "&lt;"
404 break;
405
406 case '>':
407 *o++ = '&'; *o++ = 'g'; *o++ = 't'; *o++ = ';'; // "&gt;"
408 break;
409
410 case '"':
411 *o++ = '&'; *o++ = 'q'; *o++ = 'u'; *o++ = 'o'; *o++ = 't'; *o++ = ';'; // "&quot;"
412 break;
413
414 case '\'':
415 *o++ = '&'; *o++ = 'a'; *o++ = 'p'; *o++ = 'o'; *o++ = 's'; *o++ = ';'; // "&apos;"
416 break;
417
418 default:
419 if ((unsigned)*p<0x20 && *p!='\t' && *p!='\r' && *p!='\n') {
420 char b[16];
421 sprintf(b, "&#%d;", (unsigned)*p);
422 for(const char*q=b; *q; )
423 *o++ = *q++;
424 } else
425 *o++ = *p;
426 }
427
428#ifdef XS_STRING_UTF8
429 return XS_String(buffer, o-buffer);
430#else
431 return get_utf8(buffer, o-buffer);
432#endif
433 } else { // l > BUFFER_LEN
434 // alternative code for larger strings using ostringstream
435 // and avoiding to use alloca() for preallocated memory
437
438 LPCXSSTR s = str.c_str();
439
440 for(LPCXSSTR p=s; *p; ++p)
441 switch(*p) {
442 case '&':
443 out << "&amp;";
444 break;
445
446 case '<':
447 out << "&lt;";
448 break;
449
450 case '>':
451 out << "&gt;";
452 break;
453
454 case '"':
455 out << "&quot;";
456 break;
457
458 case '\'':
459 out << "&apos;";
460 break;
461
462 default:
463 if ((unsigned)*p<0x20 && *p!='\t' && *p!='\r' && *p!='\n')
464 out << "&#" << (unsigned)*p << ";";
465 else
466 out << *p;
467 }
468
469#ifdef XS_STRING_UTF8
470 return XS_String(out.str());
471#else
472 return get_utf8(out.str());
473#endif
474 }
475}
476
478XS_String DecodeXMLString(const std::string& str)
479{
480#ifdef XS_STRING_UTF8
481 const XS_String& str_utf8 = str;
482#else
483 XS_String str_utf8;
484 assign_utf8(str_utf8, str.c_str(), str.length());
485#endif
486
487 LPCXSSTR s = str_utf8.c_str();
489 LPXSSTR o = buffer;
490
491 for(LPCXSSTR p=s; *p; ++p)
492 if (*p == '&') {
493 if (!XS_nicmp(p+1, XS_TEXT("lt;"), 3)) {
494 *o++ = '<';
495 p += 3;
496 } else if (!XS_nicmp(p+1, XS_TEXT("gt;"), 3)) {
497 *o++ = '>';
498 p += 3;
499 } else if (!XS_nicmp(p+1, XS_TEXT("amp;"), 4)) {
500 *o++ = '&';
501 p += 4;
502 } else if (!XS_nicmp(p+1, XS_TEXT("quot;"), 5)) {
503 *o++ = '"';
504 p += 5;
505 } else if (!XS_nicmp(p+1, XS_TEXT("apos;"), 5)) {
506 *o++ = '\'';
507 p += 5;
508 } else //@@ maybe decode "&#xx;" special characters
509 *o++ = *p;
510 } else if (*p=='<' && !XS_nicmp(p+1,XS_TEXT("![CDATA["),8)) {
512 if (e) {
513 p += 9;
514 size_t l = e - p;
515 memcpy(o, p, l);
516 o += l;
517 p = e + 2;
518 } else
519 *o++ = *p;
520 } else
521 *o++ = *p;
522
523 return XS_String(buffer, o-buffer);
524}
525
526
528void XMLNode::original_write_worker(std::ostream& out) const
529{
530 out << _leading << '<' << EncodeXMLString(*this);
531
532 for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
533 out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";
534
535 if (!_children.empty() || !_content.empty()) {
536 out << '>';
537
538 if (_cdata_content)
540 else
541 out << _content;
542
543 for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
544 (*it)->original_write_worker(out);
545
546 out << _end_leading << "</" << EncodeXMLString(*this) << '>';
547 } else
548 out << "/>";
549
550 out << _trailing;
551}
552
553
555void XMLNode::plain_write_worker(std::ostream& out) const
556{
557 out << '<' << EncodeXMLString(*this);
558
559 for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
560 out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";
561
562 // strip leading white space from content
563 const char* content = _content.c_str();
564 while(isspace((unsigned char)*content)) ++content;
565
566 if (!_children.empty() || *content) {
567 out << ">" << content;
568
569 for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
570 (*it)->plain_write_worker(out);
571
572 out << "</" << EncodeXMLString(*this) << ">";
573 } else
574 out << "/>";
575}
576
577
579void XMLNode::pretty_write_worker(std::ostream& out, const XMLFormat& format, int indent) const
580{
581 for(int i=indent; i--; )
583
584 out << '<' << EncodeXMLString(*this);
585
586 for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
587 out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";
588
589 // strip leading white space from content
590 const char* content = _content.c_str();
591 while(isspace((unsigned char)*content)) ++content;
592
593 if (!_children.empty() || *content) {
594 out << '>' << content;
595
596 if (!_children.empty())
597 out << format._endl;
598
599 for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
600 (*it)->pretty_write_worker(out, format, indent+1);
601
602 for(int i=indent; i--; )
604
605 out << "</" << EncodeXMLString(*this) << '>' << format._endl;
606 } else
607 out << "/>" << format._endl;
608}
609
610
612void XMLNode::smart_write_worker(std::ostream& out, const XMLFormat& format, int indent) const
613{
614 // strip the first line feed from _leading
615 const char* leading = _leading.c_str();
616 if (*leading == '\n') ++leading;
617
618 if (!*leading)
619 for(int i=indent; i--; )
621 else
622 out << leading;
623
624 out << '<' << EncodeXMLString(*this);
625
626 for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
627 out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";
628
629 // strip leading white space from content
630 const char* content = _content.c_str();
631 while(isspace((unsigned char)*content)) ++content;
632
633 if (_children.empty() && !*content)
634 out << "/>";
635 else {
636 out << '>';
637
638 if (_cdata_content)
640 else if (!*content)
641 out << format._endl;
642 else
643 out << content;
644
645 Children::const_iterator it = _children.begin();
646
647 if (it != _children.end()) {
648 for(; it!=_children.end(); ++it)
649 (*it)->smart_write_worker(out, format, indent+1);
650
651 // strip the first line feed from _end_leading
652 const char* end_leading = _end_leading.c_str();
653 if (*end_leading == '\n') ++end_leading;
654
655 if (!*end_leading)
656 for(int i=indent; i--; )
658 else
659 out << end_leading;
660 } else
661 out << _end_leading;
662
663 out << "</" << EncodeXMLString(*this) << '>';
664 }
665
666 if (_trailing.empty())
667 out << format._endl;
668 else
669 out << _trailing;
670}
671
672
673std::ostream& operator<<(std::ostream& out, const XMLError& err)
674{
675 out << err._systemId << "(" << err._line << ") [column " << err._column << "] : "
676 << err._message;
677
678 return out;
679}
680
681
682const char* get_xmlsym_end_utf8(const char* p)
683{
684 for(; *p; ++p) {
685 char c = *p;
686
687 // NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar | Extender
688 if (c == '\xC3') // UTF-8 escape character
689 ++p; //TODO only continue on umlaut characters
690 else if (!isalnum(c) && c!='.' && c!='-' && c!='_' && c!=':')
691 break;
692 }
693
694 return p;
695}
696
697
698void DocType::parse(const char* p)
699{
700 while(isspace((unsigned char)*p)) ++p;
701
702 const char* start = p;
704 _name.assign(start, p-start);
705
706 while(isspace((unsigned char)*p)) ++p;
707
708 start = p;
710 std::string keyword(p, p-start); // "PUBLIC" or "SYSTEM"
711
712 while(isspace((unsigned char)*p)) ++p;
713
714 if (*p=='"' || *p=='\'') {
715 char delim = *p;
716
717 start = ++p;
718 while(*p && *p!=delim) ++p;
719
720 if (*p == delim)
721 _public.assign(start, p++-start);
722 } else
723 _public.erase();
724
725 while(isspace((unsigned char)*p)) ++p;
726
727 if (*p=='"' || *p=='\'') {
728 char delim = *p;
729
730 start = ++p;
731 while(*p && *p!=delim) ++p;
732
733 if (*p == delim)
734 _system.assign(start, p++-start);
735 } else
736 _system.erase();
737}
738
739
740void XMLFormat::print_header(std::ostream& out, bool lf) const
741{
742 out << "<?xml version=\"" << _version << "\" encoding=\"" << _encoding << "\"";
743
744 if (_standalone != -1)
745 out << " standalone=\"yes\"";
746
747 out << "?>";
748
749 if (lf)
750 out << _endl;
751
752 if (!_doctype.empty()) {
753 out << "<!DOCTYPE " << _doctype._name;
754
755 if (!_doctype._public.empty()) {
756 out << " PUBLIC \"" << _doctype._public << '"';
757
758 if (lf)
759 out << _endl;
760
761 out << " \"" << _doctype._system << '"';
762 } else if (!_doctype._system.empty())
763 out << " SYSTEM \"" << _doctype._system << '"';
764
765 out << "?>";
766
767 if (lf)
768 out << _endl;
769 }
770
771 for(StyleSheetList::const_iterator it=_stylesheets.begin(); it!=_stylesheets.end(); ++it) {
772 it->print(out);
773
774 if (lf)
775 out << _endl;
776 }
777
778/* if (!_additional.empty()) {
779 out << _additional;
780
781 if (lf)
782 out << _endl;
783 } */
784}
785
786void StyleSheet::print(std::ostream& out) const
787{
788 out << "<?xml-stylesheet"
789 " href=\"" << _href << "\""
790 " type=\"" << _type << "\"";
791
792 if (!_title.empty())
793 out << " title=\"" << _title << "\"";
794
795 if (!_media.empty())
796 out << " media=\"" << _media << "\"";
797
798 if (!_charset.empty())
799 out << " charset=\"" << _charset << "\"";
800
801 if (_alternate)
802 out << " alternate=\"yes\"";
803
804 out << "?>";
805}
806
807
809std::string XMLError::str() const
810{
811 std::ostringstream out;
812
813 out << *this;
814
815 return out.str();
816}
817
818
821{
822 std::ostringstream out;
823
824 for(const_iterator it=begin(); it!=end(); ++it)
825 out << *it << std::endl;
826
827 return out.str();
828}
829
830
832{
833 if (_pos->_children.empty())
834 _pos->_trailing.append(_content);
835 else
836 _pos->_children.back()->_trailing.append(_content);
837
838 _content.erase();
839}
840
841
843void XMLReaderBase::XmlDeclHandler(const char* version, const char* encoding, int standalone)
844{
845 if (version)
847
848 if (encoding)
850
851 _format._standalone = standalone;
852}
853
854
857{
858 const char* s = _content.c_str();
859 const char* e = s + _content.length();
860 const char* p = s;
861
862 // search for content end leaving only white space for leading
863 for(p=e; p>s; --p)
864 if (!isspace((unsigned char)p[-1]))
865 break;
866
867 if (p != s) {
868 if (_pos->_children.empty()) { // no children in last node?
869 if (_last_tag == TAG_START)
870 _pos->_content.append(s, p-s);
871 else if (_last_tag == TAG_END)
872 _pos->_trailing.append(s, p-s);
873 else // TAG_NONE at root node
874 p = s;
875 } else
876 _pos->_children.back()->_trailing.append(s, p-s);
877 }
878
879 std::string leading;
880
881 if (p != e)
882 leading.assign(p, e-p);
883
884 XMLNode* node = new XMLNode(name, leading);
885
887
888#ifdef XMLNODE_LOCATION
889 node->_location = get_location();
890#endif
891
892 node->_attributes = attributes;
893
895 _content.erase();
896}
897
900{
901 const char* s = _content.c_str();
902 const char* e = s + _content.length();
903 const char* p;
904
905 if (!strncmp(s,CDATA_START,9) && !strncmp(e-3,CDATA_END,3)) {
906 s += 9;
907 p = (e-=3);
908
909 _pos->_cdata_content = true;
910 } else {
911 // search for content end leaving only white space for _end_leading
912 for(p=e; p>s; --p)
913 if (!isspace((unsigned char)p[-1]))
914 break;
915
916 _pos->_cdata_content = false;
917 }
918
919 if (p != s) {
920 if (_pos->_children.empty()) // no children in current node?
921 _pos->_content.append(s, p-s);
922 else if (_last_tag == TAG_START)
923 _pos->_content.append(s, p-s);
924 else
925 _pos->_children.back()->_trailing.append(s, p-s);
926 }
927
928 if (p != e)
929 _pos->_end_leading.assign(p, e-p);
930
931 _pos.back();
932
934 _content.erase();
935}
936
937#if defined(XS_USE_XERCES) || defined(XS_USE_EXPAT)
940{
941#if defined(XML_UNICODE) || defined(XS_USE_XERCES)
942 _content.append(String_from_XML_Char(s, len));
943#else
944 _content.append(s, len);
945#endif
946}
947#endif
948
949
951
953{
954 if (!_stack.empty()) {
955 StackEntry& last = _stack.top();
956
957 if (last._state < PRE_CLOSED) {
960 }
961
962 ++last._children;
963 }
964
966 entry._node_name = name;
967 _stack.push(entry);
968
970}
971
973{
974 if (!_stack.empty()) {
975 write_post(_stack.top());
976
977 _stack.pop();
978 return true;
979 } else
980 return false;
981}
982
984{
985 _out << '>';
986
987 entry._state = PRE_CLOSED;
988}
989
991{
993 _out << _format._endl;
994
996 for(size_t i=_stack.size(); --i>0; )
998 }
999
1000 _out << '<' << EncodeXMLString(entry._node_name);
1001 //entry._state = PRE;
1002}
1003
1005{
1006 for(AttrMap::const_iterator it=entry._attributes.begin(); it!=entry._attributes.end(); ++it)
1007 _out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";
1008
1009 entry._state = ATTRIBUTES;
1010}
1011
1013{
1014 if (entry._state < ATTRIBUTES)
1016
1017 if (entry._children || !entry._content.empty()) {
1018 if (entry._state < PRE_CLOSED)
1020
1021 _out << entry._content;
1022 //entry._state = CONTENT;
1023
1024 if (_format._pretty>=PRETTY_LINEFEED && entry._content.empty())
1025 _out << _format._endl;
1026
1027 if (_format._pretty==PRETTY_INDENT && entry._content.empty()) {
1028 for(size_t i=_stack.size(); --i>0; )
1030 }
1031
1032 _out << "</" << EncodeXMLString(entry._node_name) << ">";
1033 } else {
1034 _out << "/>";
1035 }
1036
1037 entry._state = POST;
1038}
1039
1040
1041} // namespace XMLStorage
#define isspace(c)
Definition: acclib.h:69
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
char * strchr(const char *String, int ch)
Definition: utclib.c:501
static int bracket
Definition: adnsresfilter.c:59
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
r l[0]
Definition: byte_order.h:168
#define NULL
Definition: types.h:112
content
Definition: atl_ax.c:994
static const WCHAR indent[]
Definition: object.c:1156
static const WCHAR version[]
Definition: asmname.c:66
char XML_Char
GLuint start
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLuint GLuint end
Definition: gl.h:1545
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLdouble n
Definition: glext.h:7729
GLuint buffer
Definition: glext.h:5915
const GLubyte * c
Definition: glext.h:8905
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glext.h:7005
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLenum target
Definition: glext.h:7315
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static HRESULT get_location(HTMLInnerWindow *This, HTMLLocation **ret)
Definition: htmlwindow.c:43
_Check_return_ _CRTIMP int __cdecl isalnum(_In_ int _C)
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
uint32_t entry
Definition: isohybrid.c:63
#define e
Definition: ke_i.h:82
#define alloca
Definition: malloc.h:357
#define matches(FN)
Definition: match.h:70
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define BUFFER_LEN
Definition: utility.h:97
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static UINT UINT last
Definition: font.c:45
static size_t elem
Definition: string.c:68
static unsigned(__cdecl *hash_bstr)(bstr_t s)
static HWND child
Definition: cursoricon.c:298
std::ostringstream fast_ostringstream
Definition: xmlstorage.h:2696
const XS_String XS_VALUE
Definition: xmlstorage.cpp:62
@ PRETTY_LINEFEED
Definition: xmlstorage.h:719
static std::string unescape(const char *s, char b, char e)
remove escape characters from zero terminated string
Definition: xmlstorage.cpp:67
std::string EncodeXMLString(const XS_String &str, bool cdata)
encode XML string literals
Definition: xmlstorage.cpp:374
const XS_String XS_PROPERTY
Definition: xmlstorage.cpp:63
const char * get_xmlsym_end_utf8(const char *p)
Definition: xmlstorage.cpp:682
const XS_String XS_KEY
Definition: xmlstorage.cpp:61
XS_String DecodeXMLString(const std::string &str)
decode XML string literals
Definition: xmlstorage.cpp:478
#define err(...)
#define equal(x, y)
Definition: reader.cc:56
static FILE * out
Definition: regtests2xml.c:44
const WCHAR * str
CardRegion * from
Definition: spigame.cpp:19
std::string _public
Definition: xmlstorage.h:764
void parse(const char *str)
Definition: xmlstorage.cpp:698
bool empty() const
Definition: xmlstorage.h:770
std::string _system
Definition: xmlstorage.h:765
std::string _name
Definition: xmlstorage.h:761
std::string _charset
Definition: xmlstorage.h:731
void print(std::ostream &out) const
Definition: xmlstorage.cpp:786
XS_String str() const
return merged error strings
Definition: xmlstorage.cpp:820
XML Error with message and location.
Definition: xmlstorage.h:664
std::string str() const
return formated error message
Definition: xmlstorage.cpp:809
friend std::ostream & operator<<(std::ostream &, const XMLError &err)
Definition: xmlstorage.cpp:673
Management of XML file headers and formating.
Definition: xmlstorage.h:775
const char * _endl
Definition: xmlstorage.h:789
void print_header(std::ostream &out, bool lf=true) const
Definition: xmlstorage.cpp:740
std::string _encoding
Definition: xmlstorage.h:792
PRETTY_FLAGS _pretty
Definition: xmlstorage.h:788
std::string _version
Definition: xmlstorage.h:791
StyleSheetList _stylesheets
Definition: xmlstorage.h:796
map of XML node attributes
Definition: xmlstorage.h:895
void assign(Children &other)
Definition: xmlstorage.h:923
in memory representation of an XML node
Definition: xmlstorage.h:855
AttributeMap _attributes
Definition: xmlstorage.h:1271
const XMLNode * find_relative(const XPath &xpath) const
XPath find function (const)
Definition: xmlstorage.cpp:251
std::string _content
Definition: xmlstorage.h:1274
XMLNode * create_relative(const XPath &xpath)
relative XPath create function
Definition: xmlstorage.cpp:279
std::string _end_leading
Definition: xmlstorage.h:1275
bool filter(const XPath &xpath, XMLNode &target) const
copy matching tree nodes using the given XPath filter expression
Definition: xmlstorage.cpp:321
void smart_write_worker(std::ostream &out, const XMLFormat &format, int indent) const
write node with children tree to output stream using smart formating
Definition: xmlstorage.cpp:612
void pretty_write_worker(std::ostream &out, const XMLFormat &format, int indent) const
pretty print node with children tree to output stream
Definition: xmlstorage.cpp:579
std::string _trailing
Definition: xmlstorage.h:1276
void plain_write_worker(std::ostream &out) const
print node without any white space
Definition: xmlstorage.cpp:555
std::string _leading
Definition: xmlstorage.h:1273
void original_write_worker(std::ostream &out) const
write node with children tree to output stream using original white space
Definition: xmlstorage.cpp:528
int count(const XPath &xpath) const
count the nodes matching the given relative XPath expression
Definition: xmlstorage.h:1244
bool back()
go back to previous position
Definition: xmlstorage.h:1581
void add_down(XMLNode *child)
insert children when building tree
Definition: xmlstorage.h:1574
bool go(const XPath &xpath)
move to the position defined by xpath in XML tree
Definition: xmlstorage.cpp:114
void go_to(XMLNode *child)
go to specified node
Definition: xmlstorage.h:1786
virtual void StartElementHandler(const XS_String &name, const XMLNode::AttributeMap &attributes)
notifications about XML start tag
Definition: xmlstorage.cpp:856
virtual void XmlDeclHandler(const char *version, const char *encoding, int standalone)
store XML version and encoding into XML reader
Definition: xmlstorage.cpp:843
virtual void EndElementHandler()
notifications about XML end tag
Definition: xmlstorage.cpp:899
enum XMLStorage::XMLReaderBase::@1535 _last_tag
virtual void DefaultHandler(const std::string &s)
store content, white space and comments
Definition: xs-native.cpp:434
container for XMLWriter state information
Definition: xmlstorage.h:2974
static XS_String s_empty_attr
Definition: xmlstorage.h:2986
void write_pre(StackEntry &entry)
Definition: xmlstorage.cpp:990
void close_pre(StackEntry &entry)
Definition: xmlstorage.cpp:983
std::ostream & _out
Definition: xmlstorage.h:2968
void write_post(StackEntry &entry)
bool back()
go back to previous position
Definition: xmlstorage.cpp:972
void create(const XS_String &name)
create node and move to it
Definition: xmlstorage.cpp:952
void write_attributes(StackEntry &entry)
std::stack< StackEntry > _stack
Definition: xmlstorage.h:2984
const char * parse(const char *path)
Definition: xmlstorage.cpp:142
XMLNode * find(XMLNode *node) const
Definition: xmlstorage.cpp:184
const XMLNode * const_find(const XMLNode *node) const
Definition: xmlstorage.cpp:195
bool matches(const XMLNode &node, int &n) const
Definition: xmlstorage.cpp:206
void init(const char *path)
Definition: xmlstorage.cpp:225
string class for TCHAR strings
Definition: xmlstorage.h:293
void assign(const XS_String &s)
Definition: xmlstorage.h:338
const XMLNode * _root
Definition: xmlstorage.h:1906
void go_to(const XMLNode *child)
go to specified node
Definition: xmlstorage.h:1911
const XMLNode * _cur
Definition: xmlstorage.h:1907
bool go(const XPath &xpath)
move to the position defined by xpath in XML tree
Definition: xmlstorage.cpp:128
Definition: query.h:87
Definition: name.c:39
Definition: dlist.c:348
int ret
static clock_t begin
Definition: xmllint.c:458
static char * encoding
Definition: xmllint.c:155
#define CDATA_START
Definition: xmlstorage.h:435
#define XS_EMPTY_STR
Definition: xmlstorage.h:406
#define XS_FLOATFMT_STR
Definition: xmlstorage.h:410
#define XML_INDENT_SPACE
Definition: xmlstorage.h:617
#define XS_PROPERTY_STR
Definition: xmlstorage.h:414
#define XS_nicmp
Definition: xmlstorage.h:243
#define XS_CHAR
Definition: xmlstorage.h:236
#define XS_TRUE_STR
Definition: xmlstorage.h:407
#define XS_VALUE_STR
Definition: xmlstorage.h:413
#define XS_TRUE
Definition: xmlstorage.h:425
#define XS_KEY_STR
Definition: xmlstorage.h:412
#define XS_FALSE_STR
Definition: xmlstorage.h:408
#define LPCXSSTR
Definition: xmlstorage.h:239
#define XS_EMPTY
Definition: xmlstorage.h:424
#define XS_TEXT(x)
Definition: xmlstorage.h:237
#define XS_INTFMT
Definition: xmlstorage.h:427
#define XS_len
Definition: xmlstorage.h:246
#define XS_FLOATFMT
Definition: xmlstorage.h:428
#define LPXSSTR
Definition: xmlstorage.h:238
#define XS_INTFMT_STR
Definition: xmlstorage.h:409
#define XS_strstr
Definition: xmlstorage.h:249
#define XS_FALSE
Definition: xmlstorage.h:426
#define CDATA_END
Definition: xmlstorage.h:436