tinyxml2.cpp
Go to the documentation of this file.
1 /*
2 Original code by Lee Thomason (www.grinninglizard.com)
3 
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any
6 damages arising from the use of this software.
7 
8 Permission is granted to anyone to use this software for any
9 purpose, including commercial applications, and to alter it and
10 redistribute it freely, subject to the following restrictions:
11 
12 1. The origin of this software must not be misrepresented; you must
13 not claim that you wrote the original software. If you use this
14 software in a product, an acknowledgment in the product documentation
15 would be appreciated but is not required.
16 
17 2. Altered source versions must be plainly marked as such, and
18 must not be misrepresented as being the original software.
19 
20 3. This notice may not be removed or altered from any source
21 distribution.
22 */
23 
24 #include "tinyxml2.h"
25 
26 #include <new> // yes, this one new style header, is in the Android SDK.
27 #if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__)
28 # include <stddef.h>
29 # include <stdarg.h>
30 #else
31 # include <cstddef>
32 # include <cstdarg>
33 #endif
34 
35 #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE)
36  // Microsoft Visual Studio, version 2005 and higher. Not WinCE.
37  /*int _snprintf_s(
38  char *buffer,
39  size_t sizeOfBuffer,
40  size_t count,
41  const char *format [,
42  argument] ...
43  );*/
44  static inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... )
45  {
46  va_list va;
47  va_start( va, format );
48  const int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va );
49  va_end( va );
50  return result;
51  }
52 
53  static inline int TIXML_VSNPRINTF( char* buffer, size_t size, const char* format, va_list va )
54  {
55  const int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va );
56  return result;
57  }
58 
59  #define TIXML_VSCPRINTF _vscprintf
60  #define TIXML_SSCANF sscanf_s
61 #elif defined _MSC_VER
62  // Microsoft Visual Studio 2003 and earlier or WinCE
63  #define TIXML_SNPRINTF _snprintf
64  #define TIXML_VSNPRINTF _vsnprintf
65  #define TIXML_SSCANF sscanf
66  #if (_MSC_VER < 1400 ) && (!defined WINCE)
67  // Microsoft Visual Studio 2003 and not WinCE.
68  #define TIXML_VSCPRINTF _vscprintf // VS2003's C runtime has this, but VC6 C runtime or WinCE SDK doesn't have.
69  #else
70  // Microsoft Visual Studio 2003 and earlier or WinCE.
71  static inline int TIXML_VSCPRINTF( const char* format, va_list va )
72  {
73  int len = 512;
74  for (;;) {
75  len = len*2;
76  char* str = new char[len]();
77  const int required = _vsnprintf(str, len, format, va);
78  delete[] str;
79  if ( required != -1 ) {
80  TIXMLASSERT( required >= 0 );
81  len = required;
82  break;
83  }
84  }
85  TIXMLASSERT( len >= 0 );
86  return len;
87  }
88  #endif
89 #else
90  // GCC version 3 and higher
91  //#warning( "Using sn* functions." )
92  #define TIXML_SNPRINTF snprintf
93  #define TIXML_VSNPRINTF vsnprintf
94  static inline int TIXML_VSCPRINTF( const char* format, va_list va )
95  {
96  int len = vsnprintf( 0, 0, format, va );
97  TIXMLASSERT( len >= 0 );
98  return len;
99  }
100  #define TIXML_SSCANF sscanf
101 #endif
102 
103 #if defined(_WIN64)
104  #define TIXML_FSEEK _fseeki64
105  #define TIXML_FTELL _ftelli64
106 #elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__CYGWIN__)
107  #define TIXML_FSEEK fseeko
108  #define TIXML_FTELL ftello
109 #elif defined(__ANDROID__)
110  #if __ANDROID_API__ > 24
111  #define TIXML_FSEEK fseeko64
112  #define TIXML_FTELL ftello64
113  #else
114  #define TIXML_FSEEK fseeko
115  #define TIXML_FTELL ftello
116  #endif
117 #else
118  #define TIXML_FSEEK fseek
119  #define TIXML_FTELL ftell
120 #endif
121 
122 
123 static const char LINE_FEED = static_cast<char>(0x0a); // all line endings are normalized to LF
124 static const char LF = LINE_FEED;
125 static const char CARRIAGE_RETURN = static_cast<char>(0x0d); // CR gets filtered out
126 static const char CR = CARRIAGE_RETURN;
127 static const char SINGLE_QUOTE = '\'';
128 static const char DOUBLE_QUOTE = '\"';
129 
130 // Bunch of unicode info at:
131 // http://www.unicode.org/faq/utf_bom.html
132 // ef bb bf (Microsoft "lead bytes") - designates UTF-8
133 
134 static const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
135 static const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
136 static const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
137 
138 namespace tinyxml2
139 {
140 
141 struct Entity {
142  const char* pattern;
143  int length;
144  char value;
145 };
146 
147 static const int NUM_ENTITIES = 5;
148 static const Entity entities[NUM_ENTITIES] = {
149  { "quot", 4, DOUBLE_QUOTE },
150  { "amp", 3, '&' },
151  { "apos", 4, SINGLE_QUOTE },
152  { "lt", 2, '<' },
153  { "gt", 2, '>' }
154 };
155 
156 
158 {
159  Reset();
160 }
161 
162 
164 {
165  if ( this == other ) {
166  return;
167  }
168  // This in effect implements the assignment operator by "moving"
169  // ownership (as in auto_ptr).
170 
171  TIXMLASSERT( other != 0 );
172  TIXMLASSERT( other->_flags == 0 );
173  TIXMLASSERT( other->_start == 0 );
174  TIXMLASSERT( other->_end == 0 );
175 
176  other->Reset();
177 
178  other->_flags = _flags;
179  other->_start = _start;
180  other->_end = _end;
181 
182  _flags = 0;
183  _start = 0;
184  _end = 0;
185 }
186 
187 
189 {
190  if ( _flags & NEEDS_DELETE ) {
191  delete [] _start;
192  }
193  _flags = 0;
194  _start = 0;
195  _end = 0;
196 }
197 
198 
199 void StrPair::SetStr( const char* str, int flags )
200 {
201  TIXMLASSERT( str );
202  Reset();
203  size_t len = strlen( str );
204  TIXMLASSERT( _start == 0 );
205  _start = new char[ len+1 ];
206  memcpy( _start, str, len+1 );
207  _end = _start + len;
208  _flags = flags | NEEDS_DELETE;
209 }
210 
211 
212 char* StrPair::ParseText( char* p, const char* endTag, int strFlags, int* curLineNumPtr )
213 {
214  TIXMLASSERT( p );
215  TIXMLASSERT( endTag && *endTag );
216  TIXMLASSERT(curLineNumPtr);
217 
218  char* start = p;
219  const char endChar = *endTag;
220  size_t length = strlen( endTag );
221 
222  // Inner loop of text parsing.
223  while ( *p ) {
224  if ( *p == endChar && strncmp( p, endTag, length ) == 0 ) {
225  Set( start, p, strFlags );
226  return p + length;
227  } else if (*p == '\n') {
228  ++(*curLineNumPtr);
229  }
230  ++p;
231  TIXMLASSERT( p );
232  }
233  return 0;
234 }
235 
236 
237 char* StrPair::ParseName( char* p )
238 {
239  if ( !p || !(*p) ) {
240  return 0;
241  }
242  if ( !XMLUtil::IsNameStartChar( (unsigned char) *p ) ) {
243  return 0;
244  }
245 
246  char* const start = p;
247  ++p;
248  while ( *p && XMLUtil::IsNameChar( (unsigned char) *p ) ) {
249  ++p;
250  }
251 
252  Set( start, p, 0 );
253  return p;
254 }
255 
256 
258 {
259  // Adjusting _start would cause undefined behavior on delete[]
260  TIXMLASSERT( ( _flags & NEEDS_DELETE ) == 0 );
261  // Trim leading space.
263 
264  if ( *_start ) {
265  const char* p = _start; // the read pointer
266  char* q = _start; // the write pointer
267 
268  while( *p ) {
269  if ( XMLUtil::IsWhiteSpace( *p )) {
270  p = XMLUtil::SkipWhiteSpace( p, 0 );
271  if ( *p == 0 ) {
272  break; // don't write to q; this trims the trailing space.
273  }
274  *q = ' ';
275  ++q;
276  }
277  *q = *p;
278  ++q;
279  ++p;
280  }
281  *q = 0;
282  }
283 }
284 
285 
286 const char* StrPair::GetStr()
287 {
288  TIXMLASSERT( _start );
289  TIXMLASSERT( _end );
290  if ( _flags & NEEDS_FLUSH ) {
291  *_end = 0;
292  _flags ^= NEEDS_FLUSH;
293 
294  if ( _flags ) {
295  const char* p = _start; // the read pointer
296  char* q = _start; // the write pointer
297 
298  while( p < _end ) {
299  if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == CR ) {
300  // CR-LF pair becomes LF
301  // CR alone becomes LF
302  // LF-CR becomes LF
303  if ( *(p+1) == LF ) {
304  p += 2;
305  }
306  else {
307  ++p;
308  }
309  *q = LF;
310  ++q;
311  }
312  else if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == LF ) {
313  if ( *(p+1) == CR ) {
314  p += 2;
315  }
316  else {
317  ++p;
318  }
319  *q = LF;
320  ++q;
321  }
322  else if ( (_flags & NEEDS_ENTITY_PROCESSING) && *p == '&' ) {
323  // Entities handled by tinyXML2:
324  // - special entities in the entity table [in/out]
325  // - numeric character reference [in]
326  // &#20013; or &#x4e2d;
327 
328  if ( *(p+1) == '#' ) {
329  const int buflen = 10;
330  char buf[buflen] = { 0 };
331  int len = 0;
332  const char* adjusted = const_cast<char*>( XMLUtil::GetCharacterRef( p, buf, &len ) );
333  if ( adjusted == 0 ) {
334  *q = *p;
335  ++p;
336  ++q;
337  }
338  else {
339  TIXMLASSERT( 0 <= len && len <= buflen );
340  TIXMLASSERT( q + len <= adjusted );
341  p = adjusted;
342  memcpy( q, buf, len );
343  q += len;
344  }
345  }
346  else {
347  bool entityFound = false;
348  for( int i = 0; i < NUM_ENTITIES; ++i ) {
349  const Entity& entity = entities[i];
350  if ( strncmp( p + 1, entity.pattern, entity.length ) == 0
351  && *( p + entity.length + 1 ) == ';' ) {
352  // Found an entity - convert.
353  *q = entity.value;
354  ++q;
355  p += entity.length + 2;
356  entityFound = true;
357  break;
358  }
359  }
360  if ( !entityFound ) {
361  // fixme: treat as error?
362  ++p;
363  ++q;
364  }
365  }
366  }
367  else {
368  *q = *p;
369  ++p;
370  ++q;
371  }
372  }
373  *q = 0;
374  }
375  // The loop below has plenty going on, and this
376  // is a less useful mode. Break it out.
379  }
380  _flags = (_flags & NEEDS_DELETE);
381  }
382  TIXMLASSERT( _start );
383  return _start;
384 }
385 
386 
387 
388 
389 // --------- XMLUtil ----------- //
390 
391 const char* XMLUtil::writeBoolTrue = "true";
392 const char* XMLUtil::writeBoolFalse = "false";
393 
394 void XMLUtil::SetBoolSerialization(const char* writeTrue, const char* writeFalse)
395 {
396  static const char* defTrue = "true";
397  static const char* defFalse = "false";
398 
399  writeBoolTrue = (writeTrue) ? writeTrue : defTrue;
400  writeBoolFalse = (writeFalse) ? writeFalse : defFalse;
401 }
402 
403 
404 const char* XMLUtil::ReadBOM( const char* p, bool* bom )
405 {
406  TIXMLASSERT( p );
407  TIXMLASSERT( bom );
408  *bom = false;
409  const unsigned char* pu = reinterpret_cast<const unsigned char*>(p);
410  // Check for BOM:
411  if ( *(pu+0) == TIXML_UTF_LEAD_0
412  && *(pu+1) == TIXML_UTF_LEAD_1
413  && *(pu+2) == TIXML_UTF_LEAD_2 ) {
414  *bom = true;
415  p += 3;
416  }
417  TIXMLASSERT( p );
418  return p;
419 }
420 
421 
422 void XMLUtil::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length )
423 {
424  const unsigned long BYTE_MASK = 0xBF;
425  const unsigned long BYTE_MARK = 0x80;
426  const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
427 
428  if (input < 0x80) {
429  *length = 1;
430  }
431  else if ( input < 0x800 ) {
432  *length = 2;
433  }
434  else if ( input < 0x10000 ) {
435  *length = 3;
436  }
437  else if ( input < 0x200000 ) {
438  *length = 4;
439  }
440  else {
441  *length = 0; // This code won't convert this correctly anyway.
442  return;
443  }
444 
445  output += *length;
446 
447  // Scary scary fall throughs are annotated with carefully designed comments
448  // to suppress compiler warnings such as -Wimplicit-fallthrough in gcc
449  switch (*length) {
450  case 4:
451  --output;
452  *output = static_cast<char>((input | BYTE_MARK) & BYTE_MASK);
453  input >>= 6;
454  //fall through
455  case 3:
456  --output;
457  *output = static_cast<char>((input | BYTE_MARK) & BYTE_MASK);
458  input >>= 6;
459  //fall through
460  case 2:
461  --output;
462  *output = static_cast<char>((input | BYTE_MARK) & BYTE_MASK);
463  input >>= 6;
464  //fall through
465  case 1:
466  --output;
467  *output = static_cast<char>(input | FIRST_BYTE_MARK[*length]);
468  break;
469  default:
470  TIXMLASSERT( false );
471  }
472 }
473 
474 
475 const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length )
476 {
477  // Presume an entity, and pull it out.
478  *length = 0;
479 
480  if ( *(p+1) == '#' && *(p+2) ) {
481  unsigned long ucs = 0;
482  TIXMLASSERT( sizeof( ucs ) >= 4 );
483  ptrdiff_t delta = 0;
484  unsigned mult = 1;
485  static const char SEMICOLON = ';';
486 
487  if ( *(p+2) == 'x' ) {
488  // Hexadecimal.
489  const char* q = p+3;
490  if ( !(*q) ) {
491  return 0;
492  }
493 
494  q = strchr( q, SEMICOLON );
495 
496  if ( !q ) {
497  return 0;
498  }
499  TIXMLASSERT( *q == SEMICOLON );
500 
501  delta = q-p;
502  --q;
503 
504  while ( *q != 'x' ) {
505  unsigned int digit = 0;
506 
507  if ( *q >= '0' && *q <= '9' ) {
508  digit = *q - '0';
509  }
510  else if ( *q >= 'a' && *q <= 'f' ) {
511  digit = *q - 'a' + 10;
512  }
513  else if ( *q >= 'A' && *q <= 'F' ) {
514  digit = *q - 'A' + 10;
515  }
516  else {
517  return 0;
518  }
519  TIXMLASSERT( digit < 16 );
520  TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit );
521  const unsigned int digitScaled = mult * digit;
522  TIXMLASSERT( ucs <= ULONG_MAX - digitScaled );
523  ucs += digitScaled;
524  TIXMLASSERT( mult <= UINT_MAX / 16 );
525  mult *= 16;
526  --q;
527  }
528  }
529  else {
530  // Decimal.
531  const char* q = p+2;
532  if ( !(*q) ) {
533  return 0;
534  }
535 
536  q = strchr( q, SEMICOLON );
537 
538  if ( !q ) {
539  return 0;
540  }
541  TIXMLASSERT( *q == SEMICOLON );
542 
543  delta = q-p;
544  --q;
545 
546  while ( *q != '#' ) {
547  if ( *q >= '0' && *q <= '9' ) {
548  const unsigned int digit = *q - '0';
549  TIXMLASSERT( digit < 10 );
550  TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit );
551  const unsigned int digitScaled = mult * digit;
552  TIXMLASSERT( ucs <= ULONG_MAX - digitScaled );
553  ucs += digitScaled;
554  }
555  else {
556  return 0;
557  }
558  TIXMLASSERT( mult <= UINT_MAX / 10 );
559  mult *= 10;
560  --q;
561  }
562  }
563  // convert the UCS to UTF-8
564  ConvertUTF32ToUTF8( ucs, value, length );
565  return p + delta + 1;
566  }
567  return p+1;
568 }
569 
570 
571 void XMLUtil::ToStr( int v, char* buffer, int bufferSize )
572 {
573  TIXML_SNPRINTF( buffer, bufferSize, "%d", v );
574 }
575 
576 
577 void XMLUtil::ToStr( unsigned v, char* buffer, int bufferSize )
578 {
579  TIXML_SNPRINTF( buffer, bufferSize, "%u", v );
580 }
581 
582 
583 void XMLUtil::ToStr( bool v, char* buffer, int bufferSize )
584 {
585  TIXML_SNPRINTF( buffer, bufferSize, "%s", v ? writeBoolTrue : writeBoolFalse);
586 }
587 
588 /*
589  ToStr() of a number is a very tricky topic.
590  https://github.com/leethomason/tinyxml2/issues/106
591 */
592 void XMLUtil::ToStr( float v, char* buffer, int bufferSize )
593 {
594  TIXML_SNPRINTF( buffer, bufferSize, "%.8g", v );
595 }
596 
597 
598 void XMLUtil::ToStr( double v, char* buffer, int bufferSize )
599 {
600  TIXML_SNPRINTF( buffer, bufferSize, "%.17g", v );
601 }
602 
603 
604 void XMLUtil::ToStr( int64_t v, char* buffer, int bufferSize )
605 {
606  // horrible syntax trick to make the compiler happy about %lld
607  TIXML_SNPRINTF(buffer, bufferSize, "%lld", static_cast<long long>(v));
608 }
609 
610 void XMLUtil::ToStr( uint64_t v, char* buffer, int bufferSize )
611 {
612  // horrible syntax trick to make the compiler happy about %llu
613  TIXML_SNPRINTF(buffer, bufferSize, "%llu", (long long)v);
614 }
615 
616 bool XMLUtil::ToInt(const char* str, int* value)
617 {
618  if (IsPrefixHex(str)) {
619  unsigned v;
620  if (TIXML_SSCANF(str, "%x", &v) == 1) {
621  *value = static_cast<int>(v);
622  return true;
623  }
624  }
625  else {
626  if (TIXML_SSCANF(str, "%d", value) == 1) {
627  return true;
628  }
629  }
630  return false;
631 }
632 
633 bool XMLUtil::ToUnsigned(const char* str, unsigned* value)
634 {
635  if (TIXML_SSCANF(str, IsPrefixHex(str) ? "%x" : "%u", value) == 1) {
636  return true;
637  }
638  return false;
639 }
640 
641 bool XMLUtil::ToBool( const char* str, bool* value )
642 {
643  int ival = 0;
644  if ( ToInt( str, &ival )) {
645  *value = (ival==0) ? false : true;
646  return true;
647  }
648  static const char* TRUE_VALS[] = { "true", "True", "TRUE", 0 };
649  static const char* FALSE_VALS[] = { "false", "False", "FALSE", 0 };
650 
651  for (int i = 0; TRUE_VALS[i]; ++i) {
652  if (StringEqual(str, TRUE_VALS[i])) {
653  *value = true;
654  return true;
655  }
656  }
657  for (int i = 0; FALSE_VALS[i]; ++i) {
658  if (StringEqual(str, FALSE_VALS[i])) {
659  *value = false;
660  return true;
661  }
662  }
663  return false;
664 }
665 
666 
667 bool XMLUtil::ToFloat( const char* str, float* value )
668 {
669  if ( TIXML_SSCANF( str, "%f", value ) == 1 ) {
670  return true;
671  }
672  return false;
673 }
674 
675 
676 bool XMLUtil::ToDouble( const char* str, double* value )
677 {
678  if ( TIXML_SSCANF( str, "%lf", value ) == 1 ) {
679  return true;
680  }
681  return false;
682 }
683 
684 
685 bool XMLUtil::ToInt64(const char* str, int64_t* value)
686 {
687  if (IsPrefixHex(str)) {
688  unsigned long long v = 0; // horrible syntax trick to make the compiler happy about %llx
689  if (TIXML_SSCANF(str, "%llx", &v) == 1) {
690  *value = static_cast<int64_t>(v);
691  return true;
692  }
693  }
694  else {
695  long long v = 0; // horrible syntax trick to make the compiler happy about %lld
696  if (TIXML_SSCANF(str, "%lld", &v) == 1) {
697  *value = static_cast<int64_t>(v);
698  return true;
699  }
700  }
701  return false;
702 }
703 
704 
705 bool XMLUtil::ToUnsigned64(const char* str, uint64_t* value) {
706  unsigned long long v = 0; // horrible syntax trick to make the compiler happy about %llu
707  if(TIXML_SSCANF(str, IsPrefixHex(str) ? "%llx" : "%llu", &v) == 1) {
708  *value = (uint64_t)v;
709  return true;
710  }
711  return false;
712 }
713 
714 
715 char* XMLDocument::Identify( char* p, XMLNode** node, bool first )
716 {
717  TIXMLASSERT( node );
718  TIXMLASSERT( p );
719  char* const start = p;
720  int const startLine = _parseCurLineNum;
722  if( !*p ) {
723  *node = 0;
724  TIXMLASSERT( p );
725  return p;
726  }
727 
728  // These strings define the matching patterns:
729  static const char* xmlHeader = { "<?" };
730  static const char* commentHeader = { "<!--" };
731  static const char* cdataHeader = { "<![CDATA[" };
732  static const char* dtdHeader = { "<!" };
733  static const char* elementHeader = { "<" }; // and a header for everything else; check last.
734 
735  static const int xmlHeaderLen = 2;
736  static const int commentHeaderLen = 4;
737  static const int cdataHeaderLen = 9;
738  static const int dtdHeaderLen = 2;
739  static const int elementHeaderLen = 1;
740 
741  TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLUnknown ) ); // use same memory pool
742  TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLDeclaration ) ); // use same memory pool
743  XMLNode* returnNode = 0;
744  if ( XMLUtil::StringEqual( p, xmlHeader, xmlHeaderLen ) ) {
745  returnNode = CreateUnlinkedNode<XMLDeclaration>( _commentPool );
746  returnNode->_parseLineNum = _parseCurLineNum;
747  p += xmlHeaderLen;
748  }
749  else if ( XMLUtil::StringEqual( p, commentHeader, commentHeaderLen ) ) {
750  returnNode = CreateUnlinkedNode<XMLComment>( _commentPool );
751  returnNode->_parseLineNum = _parseCurLineNum;
752  p += commentHeaderLen;
753  }
754  else if ( XMLUtil::StringEqual( p, cdataHeader, cdataHeaderLen ) ) {
755  XMLText* text = CreateUnlinkedNode<XMLText>( _textPool );
756  returnNode = text;
757  returnNode->_parseLineNum = _parseCurLineNum;
758  p += cdataHeaderLen;
759  text->SetCData( true );
760  }
761  else if ( XMLUtil::StringEqual( p, dtdHeader, dtdHeaderLen ) ) {
762  returnNode = CreateUnlinkedNode<XMLUnknown>( _commentPool );
763  returnNode->_parseLineNum = _parseCurLineNum;
764  p += dtdHeaderLen;
765  }
766  else if ( XMLUtil::StringEqual( p, elementHeader, elementHeaderLen ) ) {
767 
768  // Preserve whitespace pedantically before closing tag, when it's immediately after opening tag
769  if (WhitespaceMode() == PEDANTIC_WHITESPACE && first && p != start && *(p + elementHeaderLen) == '/') {
770  returnNode = CreateUnlinkedNode<XMLText>(_textPool);
771  returnNode->_parseLineNum = startLine;
772  p = start; // Back it up, all the text counts.
773  _parseCurLineNum = startLine;
774  }
775  else {
776  returnNode = CreateUnlinkedNode<XMLElement>(_elementPool);
777  returnNode->_parseLineNum = _parseCurLineNum;
778  p += elementHeaderLen;
779  }
780  }
781  else {
782  returnNode = CreateUnlinkedNode<XMLText>( _textPool );
783  returnNode->_parseLineNum = _parseCurLineNum; // Report line of first non-whitespace character
784  p = start; // Back it up, all the text counts.
785  _parseCurLineNum = startLine;
786  }
787 
788  TIXMLASSERT( returnNode );
789  TIXMLASSERT( p );
790  *node = returnNode;
791  return p;
792 }
793 
794 
795 bool XMLDocument::Accept( XMLVisitor* visitor ) const
796 {
797  TIXMLASSERT( visitor );
798  if ( visitor->VisitEnter( *this ) ) {
799  for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) {
800  if ( !node->Accept( visitor ) ) {
801  break;
802  }
803  }
804  }
805  return visitor->VisitExit( *this );
806 }
807 
808 
809 // --------- XMLNode ----------- //
810 
812  _document( doc ),
813  _parent( 0 ),
814  _value(),
815  _parseLineNum( 0 ),
816  _firstChild( 0 ), _lastChild( 0 ),
817  _prev( 0 ), _next( 0 ),
818  _userData( 0 ),
819  _memPool( 0 )
820 {
821 }
822 
823 
825 {
826  DeleteChildren();
827  if ( _parent ) {
828  _parent->Unlink( this );
829  }
830 }
831 
832 // ChildElementCount was originally suggested by msteiger on the sourceforge page for TinyXML and modified by KB1SPH for TinyXML-2.
833 
834 int XMLNode::ChildElementCount(const char *value) const {
835  int count = 0;
836 
837  const XMLElement *e = FirstChildElement(value);
838 
839  while (e) {
840  e = e->NextSiblingElement(value);
841  count++;
842  }
843 
844  return count;
845 }
846 
848  int count = 0;
849 
850  const XMLElement *e = FirstChildElement();
851 
852  while (e) {
853  e = e->NextSiblingElement();
854  count++;
855  }
856 
857  return count;
858 }
859 
860 const char* XMLNode::Value() const
861 {
862  // Edge case: XMLDocuments don't have a Value. Return null.
863  if ( this->ToDocument() )
864  return 0;
865  return _value.GetStr();
866 }
867 
868 void XMLNode::SetValue( const char* str, bool staticMem )
869 {
870  if ( staticMem ) {
871  _value.SetInternedStr( str );
872  }
873  else {
874  _value.SetStr( str );
875  }
876 }
877 
879 {
880  XMLNode* clone = this->ShallowClone(target);
881  if (!clone) return 0;
882 
883  for (const XMLNode* child = this->FirstChild(); child; child = child->NextSibling()) {
884  XMLNode* childClone = child->DeepClone(target);
885  TIXMLASSERT(childClone);
886  clone->InsertEndChild(childClone);
887  }
888  return clone;
889 }
890 
892 {
893  while( _firstChild ) {
896  }
897  _firstChild = _lastChild = 0;
898 }
899 
900 
902 {
903  TIXMLASSERT( child );
904  TIXMLASSERT( child->_document == _document );
905  TIXMLASSERT( child->_parent == this );
906  if ( child == _firstChild ) {
908  }
909  if ( child == _lastChild ) {
911  }
912 
913  if ( child->_prev ) {
914  child->_prev->_next = child->_next;
915  }
916  if ( child->_next ) {
917  child->_next->_prev = child->_prev;
918  }
919  child->_next = 0;
920  child->_prev = 0;
921  child->_parent = 0;
922 }
923 
924 
926 {
927  TIXMLASSERT( node );
928  TIXMLASSERT( node->_document == _document );
929  TIXMLASSERT( node->_parent == this );
930  Unlink( node );
931  TIXMLASSERT(node->_prev == 0);
932  TIXMLASSERT(node->_next == 0);
933  TIXMLASSERT(node->_parent == 0);
934  DeleteNode( node );
935 }
936 
937 
939 {
940  TIXMLASSERT( addThis );
941  if ( addThis->_document != _document ) {
942  TIXMLASSERT( false );
943  return 0;
944  }
945  InsertChildPreamble( addThis );
946 
947  if ( _lastChild ) {
949  TIXMLASSERT( _lastChild->_next == 0 );
950  _lastChild->_next = addThis;
951  addThis->_prev = _lastChild;
952  _lastChild = addThis;
953 
954  addThis->_next = 0;
955  }
956  else {
957  TIXMLASSERT( _firstChild == 0 );
958  _firstChild = _lastChild = addThis;
959 
960  addThis->_prev = 0;
961  addThis->_next = 0;
962  }
963  addThis->_parent = this;
964  return addThis;
965 }
966 
967 
969 {
970  TIXMLASSERT( addThis );
971  if ( addThis->_document != _document ) {
972  TIXMLASSERT( false );
973  return 0;
974  }
975  InsertChildPreamble( addThis );
976 
977  if ( _firstChild ) {
979  TIXMLASSERT( _firstChild->_prev == 0 );
980 
981  _firstChild->_prev = addThis;
982  addThis->_next = _firstChild;
983  _firstChild = addThis;
984 
985  addThis->_prev = 0;
986  }
987  else {
988  TIXMLASSERT( _lastChild == 0 );
989  _firstChild = _lastChild = addThis;
990 
991  addThis->_prev = 0;
992  addThis->_next = 0;
993  }
994  addThis->_parent = this;
995  return addThis;
996 }
997 
998 
1000 {
1001  TIXMLASSERT( addThis );
1002  if ( addThis->_document != _document ) {
1003  TIXMLASSERT( false );
1004  return 0;
1005  }
1006 
1007  TIXMLASSERT( afterThis );
1008 
1009  if ( afterThis->_parent != this ) {
1010  TIXMLASSERT( false );
1011  return 0;
1012  }
1013  if ( afterThis == addThis ) {
1014  // Current state: BeforeThis -> AddThis -> OneAfterAddThis
1015  // Now AddThis must disappear from it's location and then
1016  // reappear between BeforeThis and OneAfterAddThis.
1017  // So just leave it where it is.
1018  return addThis;
1019  }
1020 
1021  if ( afterThis->_next == 0 ) {
1022  // The last node or the only node.
1023  return InsertEndChild( addThis );
1024  }
1025  InsertChildPreamble( addThis );
1026  addThis->_prev = afterThis;
1027  addThis->_next = afterThis->_next;
1028  afterThis->_next->_prev = addThis;
1029  afterThis->_next = addThis;
1030  addThis->_parent = this;
1031  return addThis;
1032 }
1033 
1034 
1035 
1036 
1037 const XMLElement* XMLNode::FirstChildElement( const char* name ) const
1038 {
1039  for( const XMLNode* node = _firstChild; node; node = node->_next ) {
1040  const XMLElement* element = node->ToElementWithName( name );
1041  if ( element ) {
1042  return element;
1043  }
1044  }
1045  return 0;
1046 }
1047 
1048 
1049 const XMLElement* XMLNode::LastChildElement( const char* name ) const
1050 {
1051  for( const XMLNode* node = _lastChild; node; node = node->_prev ) {
1052  const XMLElement* element = node->ToElementWithName( name );
1053  if ( element ) {
1054  return element;
1055  }
1056  }
1057  return 0;
1058 }
1059 
1060 
1061 const XMLElement* XMLNode::NextSiblingElement( const char* name ) const
1062 {
1063  for( const XMLNode* node = _next; node; node = node->_next ) {
1064  const XMLElement* element = node->ToElementWithName( name );
1065  if ( element ) {
1066  return element;
1067  }
1068  }
1069  return 0;
1070 }
1071 
1072 
1073 const XMLElement* XMLNode::PreviousSiblingElement( const char* name ) const
1074 {
1075  for( const XMLNode* node = _prev; node; node = node->_prev ) {
1076  const XMLElement* element = node->ToElementWithName( name );
1077  if ( element ) {
1078  return element;
1079  }
1080  }
1081  return 0;
1082 }
1083 
1084 
1085 char* XMLNode::ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr )
1086 {
1087  // This is a recursive method, but thinking about it "at the current level"
1088  // it is a pretty simple flat list:
1089  // <foo/>
1090  // <!-- comment -->
1091  //
1092  // With a special case:
1093  // <foo>
1094  // </foo>
1095  // <!-- comment -->
1096  //
1097  // Where the closing element (/foo) *must* be the next thing after the opening
1098  // element, and the names must match. BUT the tricky bit is that the closing
1099  // element will be read by the child.
1100  //
1101  // 'endTag' is the end tag for this node, it is returned by a call to a child.
1102  // 'parentEnd' is the end tag for the parent, which is filled in and returned.
1103 
1105  if (_document->Error())
1106  return 0;
1107 
1108  bool first = true;
1109  while( p && *p ) {
1110  XMLNode* node = 0;
1111 
1112  p = _document->Identify( p, &node, first );
1113  TIXMLASSERT( p );
1114  if ( node == 0 ) {
1115  break;
1116  }
1117  first = false;
1118 
1119  const int initialLineNum = node->_parseLineNum;
1120 
1121  StrPair endTag;
1122  p = node->ParseDeep( p, &endTag, curLineNumPtr );
1123  if ( !p ) {
1124  _document->DeleteNode( node );
1125  if ( !_document->Error() ) {
1126  _document->SetError( XML_ERROR_PARSING, initialLineNum, 0);
1127  }
1128  break;
1129  }
1130 
1131  const XMLDeclaration* const decl = node->ToDeclaration();
1132  if ( decl ) {
1133  // Declarations are only allowed at document level
1134  //
1135  // Multiple declarations are allowed but all declarations
1136  // must occur before anything else.
1137  //
1138  // Optimized due to a security test case. If the first node is
1139  // a declaration, and the last node is a declaration, then only
1140  // declarations have so far been added.
1141  bool wellLocated = false;
1142 
1143  if (ToDocument()) {
1144  if (FirstChild()) {
1145  wellLocated =
1146  FirstChild() &&
1147  FirstChild()->ToDeclaration() &&
1148  LastChild() &&
1149  LastChild()->ToDeclaration();
1150  }
1151  else {
1152  wellLocated = true;
1153  }
1154  }
1155  if ( !wellLocated ) {
1156  _document->SetError( XML_ERROR_PARSING_DECLARATION, initialLineNum, "XMLDeclaration value=%s", decl->Value());
1157  _document->DeleteNode( node );
1158  break;
1159  }
1160  }
1161 
1162  XMLElement* ele = node->ToElement();
1163  if ( ele ) {
1164  // We read the end tag. Return it to the parent.
1165  if ( ele->ClosingType() == XMLElement::CLOSING ) {
1166  if ( parentEndTag ) {
1167  ele->_value.TransferTo( parentEndTag );
1168  }
1169  node->_memPool->SetTracked(); // created and then immediately deleted.
1170  DeleteNode( node );
1171  return p;
1172  }
1173 
1174  // Handle an end tag returned to this level.
1175  // And handle a bunch of annoying errors.
1176  bool mismatch = false;
1177  if ( endTag.Empty() ) {
1178  if ( ele->ClosingType() == XMLElement::OPEN ) {
1179  mismatch = true;
1180  }
1181  }
1182  else {
1183  if ( ele->ClosingType() != XMLElement::OPEN ) {
1184  mismatch = true;
1185  }
1186  else if ( !XMLUtil::StringEqual( endTag.GetStr(), ele->Name() ) ) {
1187  mismatch = true;
1188  }
1189  }
1190  if ( mismatch ) {
1191  _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, initialLineNum, "XMLElement name=%s", ele->Name());
1192  _document->DeleteNode( node );
1193  break;
1194  }
1195  }
1196  InsertEndChild( node );
1197  }
1198  return 0;
1199 }
1200 
1201 /*static*/ void XMLNode::DeleteNode( XMLNode* node )
1202 {
1203  if ( node == 0 ) {
1204  return;
1205  }
1206  TIXMLASSERT(node->_document);
1207  if (!node->ToDocument()) {
1208  node->_document->MarkInUse(node);
1209  }
1210 
1211  MemPool* pool = node->_memPool;
1212  node->~XMLNode();
1213  pool->Free( node );
1214 }
1215 
1216 void XMLNode::InsertChildPreamble( XMLNode* insertThis ) const
1217 {
1218  TIXMLASSERT( insertThis );
1219  TIXMLASSERT( insertThis->_document == _document );
1220 
1221  if (insertThis->_parent) {
1222  insertThis->_parent->Unlink( insertThis );
1223  }
1224  else {
1225  insertThis->_document->MarkInUse(insertThis);
1226  insertThis->_memPool->SetTracked();
1227  }
1228 }
1229 
1230 const XMLElement* XMLNode::ToElementWithName( const char* name ) const
1231 {
1232  const XMLElement* element = this->ToElement();
1233  if ( element == 0 ) {
1234  return 0;
1235  }
1236  if ( name == 0 ) {
1237  return element;
1238  }
1239  if ( XMLUtil::StringEqual( element->Name(), name ) ) {
1240  return element;
1241  }
1242  return 0;
1243 }
1244 
1245 // --------- XMLText ---------- //
1246 char* XMLText::ParseDeep( char* p, StrPair*, int* curLineNumPtr )
1247 {
1248  if ( this->CData() ) {
1249  p = _value.ParseText( p, "]]>", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr );
1250  if ( !p ) {
1252  }
1253  return p;
1254  }
1255  else {
1259  }
1260 
1261  p = _value.ParseText( p, "<", flags, curLineNumPtr );
1262  if ( p && *p ) {
1263  return p-1;
1264  }
1265  if ( !p ) {
1267  }
1268  }
1269  return 0;
1270 }
1271 
1272 
1274 {
1275  if ( !doc ) {
1276  doc = _document;
1277  }
1278  XMLText* text = doc->NewText( Value() ); // fixme: this will always allocate memory. Intern?
1279  text->SetCData( this->CData() );
1280  return text;
1281 }
1282 
1283 
1284 bool XMLText::ShallowEqual( const XMLNode* compare ) const
1285 {
1286  TIXMLASSERT( compare );
1287  const XMLText* text = compare->ToText();
1288  return ( text && XMLUtil::StringEqual( text->Value(), Value() ) );
1289 }
1290 
1291 
1292 bool XMLText::Accept( XMLVisitor* visitor ) const
1293 {
1294  TIXMLASSERT( visitor );
1295  return visitor->Visit( *this );
1296 }
1297 
1298 
1299 // --------- XMLComment ---------- //
1300 
1302 {
1303 }
1304 
1305 
1307 {
1308 }
1309 
1310 
1311 char* XMLComment::ParseDeep( char* p, StrPair*, int* curLineNumPtr )
1312 {
1313  // Comment parses as text.
1314  p = _value.ParseText( p, "-->", StrPair::COMMENT, curLineNumPtr );
1315  if ( p == 0 ) {
1317  }
1318  return p;
1319 }
1320 
1321 
1323 {
1324  if ( !doc ) {
1325  doc = _document;
1326  }
1327  XMLComment* comment = doc->NewComment( Value() ); // fixme: this will always allocate memory. Intern?
1328  return comment;
1329 }
1330 
1331 
1332 bool XMLComment::ShallowEqual( const XMLNode* compare ) const
1333 {
1334  TIXMLASSERT( compare );
1335  const XMLComment* comment = compare->ToComment();
1336  return ( comment && XMLUtil::StringEqual( comment->Value(), Value() ));
1337 }
1338 
1339 
1340 bool XMLComment::Accept( XMLVisitor* visitor ) const
1341 {
1342  TIXMLASSERT( visitor );
1343  return visitor->Visit( *this );
1344 }
1345 
1346 
1347 // --------- XMLDeclaration ---------- //
1348 
1350 {
1351 }
1352 
1353 
1355 {
1356  //printf( "~XMLDeclaration\n" );
1357 }
1358 
1359 
1360 char* XMLDeclaration::ParseDeep( char* p, StrPair*, int* curLineNumPtr )
1361 {
1362  // Declaration parses as text.
1363  p = _value.ParseText( p, "?>", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr );
1364  if ( p == 0 ) {
1366  }
1367  return p;
1368 }
1369 
1370 
1372 {
1373  if ( !doc ) {
1374  doc = _document;
1375  }
1376  XMLDeclaration* dec = doc->NewDeclaration( Value() ); // fixme: this will always allocate memory. Intern?
1377  return dec;
1378 }
1379 
1380 
1381 bool XMLDeclaration::ShallowEqual( const XMLNode* compare ) const
1382 {
1383  TIXMLASSERT( compare );
1384  const XMLDeclaration* declaration = compare->ToDeclaration();
1385  return ( declaration && XMLUtil::StringEqual( declaration->Value(), Value() ));
1386 }
1387 
1388 
1389 
1390 bool XMLDeclaration::Accept( XMLVisitor* visitor ) const
1391 {
1392  TIXMLASSERT( visitor );
1393  return visitor->Visit( *this );
1394 }
1395 
1396 // --------- XMLUnknown ---------- //
1397 
1399 {
1400 }
1401 
1402 
1404 {
1405 }
1406 
1407 
1408 char* XMLUnknown::ParseDeep( char* p, StrPair*, int* curLineNumPtr )
1409 {
1410  // Unknown parses as text.
1411  p = _value.ParseText( p, ">", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr );
1412  if ( !p ) {
1414  }
1415  return p;
1416 }
1417 
1418 
1420 {
1421  if ( !doc ) {
1422  doc = _document;
1423  }
1424  XMLUnknown* text = doc->NewUnknown( Value() ); // fixme: this will always allocate memory. Intern?
1425  return text;
1426 }
1427 
1428 
1429 bool XMLUnknown::ShallowEqual( const XMLNode* compare ) const
1430 {
1431  TIXMLASSERT( compare );
1432  const XMLUnknown* unknown = compare->ToUnknown();
1433  return ( unknown && XMLUtil::StringEqual( unknown->Value(), Value() ));
1434 }
1435 
1436 
1437 bool XMLUnknown::Accept( XMLVisitor* visitor ) const
1438 {
1439  TIXMLASSERT( visitor );
1440  return visitor->Visit( *this );
1441 }
1442 
1443 // --------- XMLAttribute ---------- //
1444 
1445 const char* XMLAttribute::Name() const
1446 {
1447  return _name.GetStr();
1448 }
1449 
1450 const char* XMLAttribute::Value() const
1451 {
1452  return _value.GetStr();
1453 }
1454 
1455 char* XMLAttribute::ParseDeep( char* p, bool processEntities, int* curLineNumPtr )
1456 {
1457  // Parse using the name rules: bug fix, was using ParseText before
1458  p = _name.ParseName( p );
1459  if ( !p || !*p ) {
1460  return 0;
1461  }
1462 
1463  // Skip white space before =
1464  p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr );
1465  if ( *p != '=' ) {
1466  return 0;
1467  }
1468 
1469  ++p; // move up to opening quote
1470  p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr );
1471  if ( *p != '\"' && *p != '\'' ) {
1472  return 0;
1473  }
1474 
1475  const char endTag[2] = { *p, 0 };
1476  ++p; // move past opening quote
1477 
1478  p = _value.ParseText( p, endTag, processEntities ? StrPair::ATTRIBUTE_VALUE : StrPair::ATTRIBUTE_VALUE_LEAVE_ENTITIES, curLineNumPtr );
1479  return p;
1480 }
1481 
1482 
1483 void XMLAttribute::SetName( const char* n )
1484 {
1485  _name.SetStr( n );
1486 }
1487 
1488 
1490 {
1491  if ( XMLUtil::ToInt( Value(), value )) {
1492  return XML_SUCCESS;
1493  }
1494  return XML_WRONG_ATTRIBUTE_TYPE;
1495 }
1496 
1497 
1498 XMLError XMLAttribute::QueryUnsignedValue( unsigned int* value ) const
1499 {
1500  if ( XMLUtil::ToUnsigned( Value(), value )) {
1501  return XML_SUCCESS;
1502  }
1503  return XML_WRONG_ATTRIBUTE_TYPE;
1504 }
1505 
1506 
1508 {
1509  if (XMLUtil::ToInt64(Value(), value)) {
1510  return XML_SUCCESS;
1511  }
1512  return XML_WRONG_ATTRIBUTE_TYPE;
1513 }
1514 
1515 
1517 {
1518  if(XMLUtil::ToUnsigned64(Value(), value)) {
1519  return XML_SUCCESS;
1520  }
1521  return XML_WRONG_ATTRIBUTE_TYPE;
1522 }
1523 
1524 
1526 {
1527  if ( XMLUtil::ToBool( Value(), value )) {
1528  return XML_SUCCESS;
1529  }
1530  return XML_WRONG_ATTRIBUTE_TYPE;
1531 }
1532 
1533 
1535 {
1536  if ( XMLUtil::ToFloat( Value(), value )) {
1537  return XML_SUCCESS;
1538  }
1539  return XML_WRONG_ATTRIBUTE_TYPE;
1540 }
1541 
1542 
1544 {
1545  if ( XMLUtil::ToDouble( Value(), value )) {
1546  return XML_SUCCESS;
1547  }
1548  return XML_WRONG_ATTRIBUTE_TYPE;
1549 }
1550 
1551 
1552 void XMLAttribute::SetAttribute( const char* v )
1553 {
1554  _value.SetStr( v );
1555 }
1556 
1557 
1559 {
1560  char buf[BUF_SIZE];
1561  XMLUtil::ToStr( v, buf, BUF_SIZE );
1562  _value.SetStr( buf );
1563 }
1564 
1565 
1566 void XMLAttribute::SetAttribute( unsigned v )
1567 {
1568  char buf[BUF_SIZE];
1569  XMLUtil::ToStr( v, buf, BUF_SIZE );
1570  _value.SetStr( buf );
1571 }
1572 
1573 
1575 {
1576  char buf[BUF_SIZE];
1577  XMLUtil::ToStr(v, buf, BUF_SIZE);
1578  _value.SetStr(buf);
1579 }
1580 
1582 {
1583  char buf[BUF_SIZE];
1584  XMLUtil::ToStr(v, buf, BUF_SIZE);
1585  _value.SetStr(buf);
1586 }
1587 
1588 
1590 {
1591  char buf[BUF_SIZE];
1592  XMLUtil::ToStr( v, buf, BUF_SIZE );
1593  _value.SetStr( buf );
1594 }
1595 
1597 {
1598  char buf[BUF_SIZE];
1599  XMLUtil::ToStr( v, buf, BUF_SIZE );
1600  _value.SetStr( buf );
1601 }
1602 
1604 {
1605  char buf[BUF_SIZE];
1606  XMLUtil::ToStr( v, buf, BUF_SIZE );
1607  _value.SetStr( buf );
1608 }
1609 
1610 
1611 // --------- XMLElement ---------- //
1613  _closingType( OPEN ),
1614  _rootAttribute( 0 )
1615 {
1616 }
1617 
1618 
1620 {
1621  while( _rootAttribute ) {
1624  _rootAttribute = next;
1625  }
1626 }
1627 
1628 
1629 const XMLAttribute* XMLElement::FindAttribute( const char* name ) const
1630 {
1631  for( XMLAttribute* a = _rootAttribute; a; a = a->_next ) {
1632  if ( XMLUtil::StringEqual( a->Name(), name ) ) {
1633  return a;
1634  }
1635  }
1636  return 0;
1637 }
1638 
1639 
1640 const char* XMLElement::Attribute( const char* name, const char* value ) const
1641 {
1642  const XMLAttribute* a = FindAttribute( name );
1643  if ( !a ) {
1644  return 0;
1645  }
1646  if ( !value || XMLUtil::StringEqual( a->Value(), value )) {
1647  return a->Value();
1648  }
1649  return 0;
1650 }
1651 
1652 int XMLElement::IntAttribute(const char* name, int defaultValue) const
1653 {
1654  int i = defaultValue;
1655  QueryIntAttribute(name, &i);
1656  return i;
1657 }
1658 
1659 unsigned XMLElement::UnsignedAttribute(const char* name, unsigned defaultValue) const
1660 {
1661  unsigned i = defaultValue;
1662  QueryUnsignedAttribute(name, &i);
1663  return i;
1664 }
1665 
1666 int64_t XMLElement::Int64Attribute(const char* name, int64_t defaultValue) const
1667 {
1668  int64_t i = defaultValue;
1669  QueryInt64Attribute(name, &i);
1670  return i;
1671 }
1672 
1673 uint64_t XMLElement::Unsigned64Attribute(const char* name, uint64_t defaultValue) const
1674 {
1675  uint64_t i = defaultValue;
1676  QueryUnsigned64Attribute(name, &i);
1677  return i;
1678 }
1679 
1680 bool XMLElement::BoolAttribute(const char* name, bool defaultValue) const
1681 {
1682  bool b = defaultValue;
1683  QueryBoolAttribute(name, &b);
1684  return b;
1685 }
1686 
1687 double XMLElement::DoubleAttribute(const char* name, double defaultValue) const
1688 {
1689  double d = defaultValue;
1690  QueryDoubleAttribute(name, &d);
1691  return d;
1692 }
1693 
1694 float XMLElement::FloatAttribute(const char* name, float defaultValue) const
1695 {
1696  float f = defaultValue;
1697  QueryFloatAttribute(name, &f);
1698  return f;
1699 }
1700 
1701 const char* XMLElement::GetText() const
1702 {
1703  /* skip comment node */
1704  const XMLNode* node = FirstChild();
1705  while (node) {
1706  if (node->ToComment()) {
1707  node = node->NextSibling();
1708  continue;
1709  }
1710  break;
1711  }
1712 
1713  if ( node && node->ToText() ) {
1714  return node->Value();
1715  }
1716  return 0;
1717 }
1718 
1719 
1720 void XMLElement::SetText( const char* inText )
1721 {
1722  if ( FirstChild() && FirstChild()->ToText() )
1723  FirstChild()->SetValue( inText );
1724  else {
1725  XMLText* theText = GetDocument()->NewText( inText );
1726  InsertFirstChild( theText );
1727  }
1728 }
1729 
1730 
1731 void XMLElement::SetText( int v )
1732 {
1733  char buf[BUF_SIZE];
1734  XMLUtil::ToStr( v, buf, BUF_SIZE );
1735  SetText( buf );
1736 }
1737 
1738 
1739 void XMLElement::SetText( unsigned v )
1740 {
1741  char buf[BUF_SIZE];
1742  XMLUtil::ToStr( v, buf, BUF_SIZE );
1743  SetText( buf );
1744 }
1745 
1746 
1747 void XMLElement::SetText(int64_t v)
1748 {
1749  char buf[BUF_SIZE];
1750  XMLUtil::ToStr(v, buf, BUF_SIZE);
1751  SetText(buf);
1752 }
1753 
1754 void XMLElement::SetText(uint64_t v) {
1755  char buf[BUF_SIZE];
1756  XMLUtil::ToStr(v, buf, BUF_SIZE);
1757  SetText(buf);
1758 }
1759 
1760 
1761 void XMLElement::SetText( bool v )
1762 {
1763  char buf[BUF_SIZE];
1764  XMLUtil::ToStr( v, buf, BUF_SIZE );
1765  SetText( buf );
1766 }
1767 
1768 
1769 void XMLElement::SetText( float v )
1770 {
1771  char buf[BUF_SIZE];
1772  XMLUtil::ToStr( v, buf, BUF_SIZE );
1773  SetText( buf );
1774 }
1775 
1776 
1777 void XMLElement::SetText( double v )
1778 {
1779  char buf[BUF_SIZE];
1780  XMLUtil::ToStr( v, buf, BUF_SIZE );
1781  SetText( buf );
1782 }
1783 
1784 
1786 {
1787  if ( FirstChild() && FirstChild()->ToText() ) {
1788  const char* t = FirstChild()->Value();
1789  if ( XMLUtil::ToInt( t, ival ) ) {
1790  return XML_SUCCESS;
1791  }
1792  return XML_CAN_NOT_CONVERT_TEXT;
1793  }
1794  return XML_NO_TEXT_NODE;
1795 }
1796 
1797 
1799 {
1800  if ( FirstChild() && FirstChild()->ToText() ) {
1801  const char* t = FirstChild()->Value();
1802  if ( XMLUtil::ToUnsigned( t, uval ) ) {
1803  return XML_SUCCESS;
1804  }
1805  return XML_CAN_NOT_CONVERT_TEXT;
1806  }
1807  return XML_NO_TEXT_NODE;
1808 }
1809 
1810 
1812 {
1813  if (FirstChild() && FirstChild()->ToText()) {
1814  const char* t = FirstChild()->Value();
1815  if (XMLUtil::ToInt64(t, ival)) {
1816  return XML_SUCCESS;
1817  }
1818  return XML_CAN_NOT_CONVERT_TEXT;
1819  }
1820  return XML_NO_TEXT_NODE;
1821 }
1822 
1823 
1825 {
1826  if(FirstChild() && FirstChild()->ToText()) {
1827  const char* t = FirstChild()->Value();
1828  if(XMLUtil::ToUnsigned64(t, uval)) {
1829  return XML_SUCCESS;
1830  }
1831  return XML_CAN_NOT_CONVERT_TEXT;
1832  }
1833  return XML_NO_TEXT_NODE;
1834 }
1835 
1836 
1838 {
1839  if ( FirstChild() && FirstChild()->ToText() ) {
1840  const char* t = FirstChild()->Value();
1841  if ( XMLUtil::ToBool( t, bval ) ) {
1842  return XML_SUCCESS;
1843  }
1844  return XML_CAN_NOT_CONVERT_TEXT;
1845  }
1846  return XML_NO_TEXT_NODE;
1847 }
1848 
1849 
1851 {
1852  if ( FirstChild() && FirstChild()->ToText() ) {
1853  const char* t = FirstChild()->Value();
1854  if ( XMLUtil::ToDouble( t, dval ) ) {
1855  return XML_SUCCESS;
1856  }
1857  return XML_CAN_NOT_CONVERT_TEXT;
1858  }
1859  return XML_NO_TEXT_NODE;
1860 }
1861 
1862 
1864 {
1865  if ( FirstChild() && FirstChild()->ToText() ) {
1866  const char* t = FirstChild()->Value();
1867  if ( XMLUtil::ToFloat( t, fval ) ) {
1868  return XML_SUCCESS;
1869  }
1870  return XML_CAN_NOT_CONVERT_TEXT;
1871  }
1872  return XML_NO_TEXT_NODE;
1873 }
1874 
1875 int XMLElement::IntText(int defaultValue) const
1876 {
1877  int i = defaultValue;
1878  QueryIntText(&i);
1879  return i;
1880 }
1881 
1882 unsigned XMLElement::UnsignedText(unsigned defaultValue) const
1883 {
1884  unsigned i = defaultValue;
1885  QueryUnsignedText(&i);
1886  return i;
1887 }
1888 
1889 int64_t XMLElement::Int64Text(int64_t defaultValue) const
1890 {
1891  int64_t i = defaultValue;
1892  QueryInt64Text(&i);
1893  return i;
1894 }
1895 
1896 uint64_t XMLElement::Unsigned64Text(uint64_t defaultValue) const
1897 {
1898  uint64_t i = defaultValue;
1899  QueryUnsigned64Text(&i);
1900  return i;
1901 }
1902 
1903 bool XMLElement::BoolText(bool defaultValue) const
1904 {
1905  bool b = defaultValue;
1906  QueryBoolText(&b);
1907  return b;
1908 }
1909 
1910 double XMLElement::DoubleText(double defaultValue) const
1911 {
1912  double d = defaultValue;
1913  QueryDoubleText(&d);
1914  return d;
1915 }
1916 
1917 float XMLElement::FloatText(float defaultValue) const
1918 {
1919  float f = defaultValue;
1920  QueryFloatText(&f);
1921  return f;
1922 }
1923 
1924 
1926 {
1927  XMLAttribute* last = 0;
1928  XMLAttribute* attrib = 0;
1929  for( attrib = _rootAttribute;
1930  attrib;
1931  last = attrib, attrib = attrib->_next ) {
1932  if ( XMLUtil::StringEqual( attrib->Name(), name ) ) {
1933  break;
1934  }
1935  }
1936  if ( !attrib ) {
1937  attrib = CreateAttribute();
1938  TIXMLASSERT( attrib );
1939  if ( last ) {
1940  TIXMLASSERT( last->_next == 0 );
1941  last->_next = attrib;
1942  }
1943  else {
1944  TIXMLASSERT( _rootAttribute == 0 );
1945  _rootAttribute = attrib;
1946  }
1947  attrib->SetName( name );
1948  }
1949  return attrib;
1950 }
1951 
1952 
1953 void XMLElement::DeleteAttribute( const char* name )
1954 {
1955  XMLAttribute* prev = 0;
1956  for( XMLAttribute* a=_rootAttribute; a; a=a->_next ) {
1957  if ( XMLUtil::StringEqual( name, a->Name() ) ) {
1958  if ( prev ) {
1959  prev->_next = a->_next;
1960  }
1961  else {
1962  _rootAttribute = a->_next;
1963  }
1964  DeleteAttribute( a );
1965  break;
1966  }
1967  prev = a;
1968  }
1969 }
1970 
1971 
1972 char* XMLElement::ParseAttributes( char* p, int* curLineNumPtr )
1973 {
1974  XMLAttribute* prevAttribute = 0;
1975 
1976  // Read the attributes.
1977  while( p ) {
1978  p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr );
1979  if ( !(*p) ) {
1980  _document->SetError( XML_ERROR_PARSING_ELEMENT, _parseLineNum, "XMLElement name=%s", Name() );
1981  return 0;
1982  }
1983 
1984  // attribute.
1985  if (XMLUtil::IsNameStartChar( (unsigned char) *p ) ) {
1986  XMLAttribute* attrib = CreateAttribute();
1987  TIXMLASSERT( attrib );
1989 
1990  const int attrLineNum = attrib->_parseLineNum;
1991 
1992  p = attrib->ParseDeep( p, _document->ProcessEntities(), curLineNumPtr );
1993  if ( !p || Attribute( attrib->Name() ) ) {
1994  DeleteAttribute( attrib );
1995  _document->SetError( XML_ERROR_PARSING_ATTRIBUTE, attrLineNum, "XMLElement name=%s", Name() );
1996  return 0;
1997  }
1998  // There is a minor bug here: if the attribute in the source xml
1999  // document is duplicated, it will not be detected and the
2000  // attribute will be doubly added. However, tracking the 'prevAttribute'
2001  // avoids re-scanning the attribute list. Preferring performance for
2002  // now, may reconsider in the future.
2003  if ( prevAttribute ) {
2004  TIXMLASSERT( prevAttribute->_next == 0 );
2005  prevAttribute->_next = attrib;
2006  }
2007  else {
2008  TIXMLASSERT( _rootAttribute == 0 );
2009  _rootAttribute = attrib;
2010  }
2011  prevAttribute = attrib;
2012  }
2013  // end of the tag
2014  else if ( *p == '>' ) {
2015  ++p;
2016  break;
2017  }
2018  // end of the tag
2019  else if ( *p == '/' && *(p+1) == '>' ) {
2020  _closingType = CLOSED;
2021  return p+2; // done; sealed element.
2022  }
2023  else {
2025  return 0;
2026  }
2027  }
2028  return p;
2029 }
2030 
2032 {
2033  if ( attribute == 0 ) {
2034  return;
2035  }
2036  MemPool* pool = attribute->_memPool;
2037  attribute->~XMLAttribute();
2038  pool->Free( attribute );
2039 }
2040 
2042 {
2043  TIXMLASSERT( sizeof( XMLAttribute ) == _document->_attributePool.ItemSize() );
2044  XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute();
2045  TIXMLASSERT( attrib );
2046  attrib->_memPool = &_document->_attributePool;
2047  attrib->_memPool->SetTracked();
2048  return attrib;
2049 }
2050 
2051 
2053 {
2054  XMLElement* node = _document->NewElement(name);
2055  return InsertEndChild(node) ? node : 0;
2056 }
2057 
2059 {
2060  XMLComment* node = _document->NewComment(comment);
2061  return InsertEndChild(node) ? node : 0;
2062 }
2063 
2065 {
2066  XMLText* node = _document->NewText(text);
2067  return InsertEndChild(node) ? node : 0;
2068 }
2069 
2071 {
2072  XMLDeclaration* node = _document->NewDeclaration(text);
2073  return InsertEndChild(node) ? node : 0;
2074 }
2075 
2077 {
2078  XMLUnknown* node = _document->NewUnknown(text);
2079  return InsertEndChild(node) ? node : 0;
2080 }
2081 
2082 
2083 
2084 //
2085 // <ele></ele>
2086 // <ele>foo<b>bar</b></ele>
2087 //
2088 char* XMLElement::ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr )
2089 {
2090  // Read the element name.
2091  p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr );
2092 
2093  // The closing element is the </element> form. It is
2094  // parsed just like a regular element then deleted from
2095  // the DOM.
2096  if ( *p == '/' ) {
2098  ++p;
2099  }
2100 
2101  p = _value.ParseName( p );
2102  if ( _value.Empty() ) {
2103  return 0;
2104  }
2105 
2106  p = ParseAttributes( p, curLineNumPtr );
2107  if ( !p || !*p || _closingType != OPEN ) {
2108  return p;
2109  }
2110 
2111  p = XMLNode::ParseDeep( p, parentEndTag, curLineNumPtr );
2112  return p;
2113 }
2114 
2115 
2116 
2118 {
2119  if ( !doc ) {
2120  doc = _document;
2121  }
2122  XMLElement* element = doc->NewElement( Value() ); // fixme: this will always allocate memory. Intern?
2123  for( const XMLAttribute* a=FirstAttribute(); a; a=a->Next() ) {
2124  element->SetAttribute( a->Name(), a->Value() ); // fixme: this will always allocate memory. Intern?
2125  }
2126  return element;
2127 }
2128 
2129 
2130 bool XMLElement::ShallowEqual( const XMLNode* compare ) const
2131 {
2132  TIXMLASSERT( compare );
2133  const XMLElement* other = compare->ToElement();
2134  if ( other && XMLUtil::StringEqual( other->Name(), Name() )) {
2135 
2136  const XMLAttribute* a=FirstAttribute();
2137  const XMLAttribute* b=other->FirstAttribute();
2138 
2139  while ( a && b ) {
2140  if ( !XMLUtil::StringEqual( a->Value(), b->Value() ) ) {
2141  return false;
2142  }
2143  a = a->Next();
2144  b = b->Next();
2145  }
2146  if ( a || b ) {
2147  // different count
2148  return false;
2149  }
2150  return true;
2151  }
2152  return false;
2153 }
2154 
2155 
2156 bool XMLElement::Accept( XMLVisitor* visitor ) const
2157 {
2158  TIXMLASSERT( visitor );
2159  if ( visitor->VisitEnter( *this, _rootAttribute ) ) {
2160  for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) {
2161  if ( !node->Accept( visitor ) ) {
2162  break;
2163  }
2164  }
2165  }
2166  return visitor->VisitExit( *this );
2167 }
2168 
2169 
2170 // --------- XMLDocument ----------- //
2171 
2172 // Warning: List must match 'enum XMLError'
2174  "XML_SUCCESS",
2175  "XML_NO_ATTRIBUTE",
2176  "XML_WRONG_ATTRIBUTE_TYPE",
2177  "XML_ERROR_FILE_NOT_FOUND",
2178  "XML_ERROR_FILE_COULD_NOT_BE_OPENED",
2179  "XML_ERROR_FILE_READ_ERROR",
2180  "XML_ERROR_PARSING_ELEMENT",
2181  "XML_ERROR_PARSING_ATTRIBUTE",
2182  "XML_ERROR_PARSING_TEXT",
2183  "XML_ERROR_PARSING_CDATA",
2184  "XML_ERROR_PARSING_COMMENT",
2185  "XML_ERROR_PARSING_DECLARATION",
2186  "XML_ERROR_PARSING_UNKNOWN",
2187  "XML_ERROR_EMPTY_DOCUMENT",
2188  "XML_ERROR_MISMATCHED_ELEMENT",
2189  "XML_ERROR_PARSING",
2190  "XML_CAN_NOT_CONVERT_TEXT",
2191  "XML_NO_TEXT_NODE",
2192  "XML_ELEMENT_DEPTH_EXCEEDED"
2193 };
2194 
2195 
2196 XMLDocument::XMLDocument( bool processEntities, Whitespace whitespaceMode ) :
2197  XMLNode( 0 ),
2198  _writeBOM( false ),
2199  _processEntities( processEntities ),
2200  _errorID(XML_SUCCESS),
2201  _whitespaceMode( whitespaceMode ),
2202  _errorStr(),
2203  _errorLineNum( 0 ),
2204  _charBuffer( 0 ),
2205  _parseCurLineNum( 0 ),
2206  _parsingDepth(0),
2207  _unlinked(),
2208  _elementPool(),
2209  _attributePool(),
2210  _textPool(),
2211  _commentPool()
2212 {
2213  // avoid VC++ C4355 warning about 'this' in initializer list (C4355 is off by default in VS2012+)
2214  _document = this;
2215 }
2216 
2217 
2219 {
2220  Clear();
2221 }
2222 
2223 
2224 void XMLDocument::MarkInUse(const XMLNode* const node)
2225 {
2226  TIXMLASSERT(node);
2227  TIXMLASSERT(node->_parent == 0);
2228 
2229  for (int i = 0; i < _unlinked.Size(); ++i) {
2230  if (node == _unlinked[i]) {
2231  _unlinked.SwapRemove(i);
2232  break;
2233  }
2234  }
2235 }
2236 
2238 {
2239  DeleteChildren();
2240  while( _unlinked.Size()) {
2241  DeleteNode(_unlinked[0]); // Will remove from _unlinked as part of delete.
2242  }
2243 
2244 #ifdef TINYXML2_DEBUG
2245  const bool hadError = Error();
2246 #endif
2247  ClearError();
2248 
2249  delete [] _charBuffer;
2250  _charBuffer = 0;
2251  _parsingDepth = 0;
2252 
2253 #if 0
2254  _textPool.Trace( "text" );
2255  _elementPool.Trace( "element" );
2256  _commentPool.Trace( "comment" );
2257  _attributePool.Trace( "attribute" );
2258 #endif
2259 
2260 #ifdef TINYXML2_DEBUG
2261  if ( !hadError ) {
2262  TIXMLASSERT( _elementPool.CurrentAllocs() == _elementPool.Untracked() );
2263  TIXMLASSERT( _attributePool.CurrentAllocs() == _attributePool.Untracked() );
2264  TIXMLASSERT( _textPool.CurrentAllocs() == _textPool.Untracked() );
2265  TIXMLASSERT( _commentPool.CurrentAllocs() == _commentPool.Untracked() );
2266  }
2267 #endif
2268 }
2269 
2270 
2272 {
2273  TIXMLASSERT(target);
2274  if (target == this) {
2275  return; // technically success - a no-op.
2276  }
2277 
2278  target->Clear();
2279  for (const XMLNode* node = this->FirstChild(); node; node = node->NextSibling()) {
2280  target->InsertEndChild(node->DeepClone(target));
2281  }
2282 }
2283 
2285 {
2286  XMLElement* ele = CreateUnlinkedNode<XMLElement>( _elementPool );
2287  ele->SetName( name );
2288  return ele;
2289 }
2290 
2291 
2293 {
2294  XMLComment* comment = CreateUnlinkedNode<XMLComment>( _commentPool );
2295  comment->SetValue( str );
2296  return comment;
2297 }
2298 
2299 
2300 XMLText* XMLDocument::NewText( const char* str )
2301 {
2302  XMLText* text = CreateUnlinkedNode<XMLText>( _textPool );
2303  text->SetValue( str );
2304  return text;
2305 }
2306 
2307 
2309 {
2310  XMLDeclaration* dec = CreateUnlinkedNode<XMLDeclaration>( _commentPool );
2311  dec->SetValue( str ? str : "xml version=\"1.0\" encoding=\"UTF-8\"" );
2312  return dec;
2313 }
2314 
2315 
2317 {
2318  XMLUnknown* unk = CreateUnlinkedNode<XMLUnknown>( _commentPool );
2319  unk->SetValue( str );
2320  return unk;
2321 }
2322 
2323 static FILE* callfopen( const char* filepath, const char* mode )
2324 {
2325  TIXMLASSERT( filepath );
2326  TIXMLASSERT( mode );
2327 #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE)
2328  FILE* fp = 0;
2329  const errno_t err = fopen_s( &fp, filepath, mode );
2330  if ( err ) {
2331  return 0;
2332  }
2333 #else
2334  FILE* fp = fopen( filepath, mode );
2335 #endif
2336  return fp;
2337 }
2338 
2340  TIXMLASSERT( node );
2341  TIXMLASSERT(node->_document == this );
2342  if (node->_parent) {
2343  node->_parent->DeleteChild( node );
2344  }
2345  else {
2346  // Isn't in the tree.
2347  // Use the parent delete.
2348  // Also, we need to mark it tracked: we 'know'
2349  // it was never used.
2350  node->_memPool->SetTracked();
2351  // Call the static XMLNode version:
2352  XMLNode::DeleteNode(node);
2353  }
2354 }
2355 
2356 
2357 XMLError XMLDocument::LoadFile( const char* filename )
2358 {
2359  if ( !filename ) {
2360  TIXMLASSERT( false );
2361  SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename=<null>" );
2362  return _errorID;
2363  }
2364 
2365  Clear();
2366  FILE* fp = callfopen( filename, "rb" );
2367  if ( !fp ) {
2368  SetError( XML_ERROR_FILE_NOT_FOUND, 0, "filename=%s", filename );
2369  return _errorID;
2370  }
2371  LoadFile( fp );
2372  fclose( fp );
2373  return _errorID;
2374 }
2375 
2377 {
2378  Clear();
2379 
2380  TIXML_FSEEK( fp, 0, SEEK_SET );
2381  if ( fgetc( fp ) == EOF && ferror( fp ) != 0 ) {
2383  return _errorID;
2384  }
2385 
2386  TIXML_FSEEK( fp, 0, SEEK_END );
2387 
2388  unsigned long long filelength;
2389  {
2390  const long long fileLengthSigned = TIXML_FTELL( fp );
2391  TIXML_FSEEK( fp, 0, SEEK_SET );
2392  if ( fileLengthSigned == -1L ) {
2394  return _errorID;
2395  }
2396  TIXMLASSERT( fileLengthSigned >= 0 );
2397  filelength = static_cast<unsigned long long>(fileLengthSigned);
2398  }
2399 
2400  const size_t maxSizeT = static_cast<size_t>(-1);
2401  // We'll do the comparison as an unsigned long long, because that's guaranteed to be at
2402  // least 8 bytes, even on a 32-bit platform.
2403  if ( filelength >= static_cast<unsigned long long>(maxSizeT) ) {
2404  // Cannot handle files which won't fit in buffer together with null terminator
2406  return _errorID;
2407  }
2408 
2409  if ( filelength == 0 ) {
2411  return _errorID;
2412  }
2413 
2414  const size_t size = static_cast<size_t>(filelength);
2415  TIXMLASSERT( _charBuffer == 0 );
2416  _charBuffer = new char[size+1];
2417  const size_t read = fread( _charBuffer, 1, size, fp );
2418  if ( read != size ) {
2420  return _errorID;
2421  }
2422 
2423  _charBuffer[size] = 0;
2424 
2425  Parse();
2426  return _errorID;
2427 }
2428 
2429 
2430 XMLError XMLDocument::SaveFile( const char* filename, bool compact )
2431 {
2432  if ( !filename ) {
2433  TIXMLASSERT( false );
2434  SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename=<null>" );
2435  return _errorID;
2436  }
2437 
2438  FILE* fp = callfopen( filename, "w" );
2439  if ( !fp ) {
2440  SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename=%s", filename );
2441  return _errorID;
2442  }
2443  SaveFile(fp, compact);
2444  fclose( fp );
2445  return _errorID;
2446 }
2447 
2448 
2449 XMLError XMLDocument::SaveFile( FILE* fp, bool compact )
2450 {
2451  // Clear any error from the last save, otherwise it will get reported
2452  // for *this* call.
2453  ClearError();
2454  XMLPrinter stream( fp, compact );
2455  Print( &stream );
2456  return _errorID;
2457 }
2458 
2459 
2460 XMLError XMLDocument::Parse( const char* xml, size_t nBytes )
2461 {
2462  Clear();
2463 
2464  if ( nBytes == 0 || !xml || !*xml ) {
2466  return _errorID;
2467  }
2468  if ( nBytes == static_cast<size_t>(-1) ) {
2469  nBytes = strlen( xml );
2470  }
2471  TIXMLASSERT( _charBuffer == 0 );
2472  _charBuffer = new char[ nBytes+1 ];
2473  memcpy( _charBuffer, xml, nBytes );
2474  _charBuffer[nBytes] = 0;
2475 
2476  Parse();
2477  if ( Error() ) {
2478  // clean up now essentially dangling memory.
2479  // and the parse fail can put objects in the
2480  // pools that are dead and inaccessible.
2481  DeleteChildren();
2482  _elementPool.Clear();
2483  _attributePool.Clear();
2484  _textPool.Clear();
2485  _commentPool.Clear();
2486  }
2487  return _errorID;
2488 }
2489 
2490 
2491 void XMLDocument::Print( XMLPrinter* streamer ) const
2492 {
2493  if ( streamer ) {
2494  Accept( streamer );
2495  }
2496  else {
2497  XMLPrinter stdoutStreamer( stdout );
2498  Accept( &stdoutStreamer );
2499  }
2500 }
2501 
2502 
2505  _errorLineNum = 0;
2506  _errorStr.Reset();
2507 }
2508 
2509 
2510 void XMLDocument::SetError( XMLError error, int lineNum, const char* format, ... )
2511 {
2512  TIXMLASSERT( error >= 0 && error < XML_ERROR_COUNT );
2513  _errorID = error;
2514  _errorLineNum = lineNum;
2515  _errorStr.Reset();
2516 
2517  const size_t BUFFER_SIZE = 1000;
2518  char* buffer = new char[BUFFER_SIZE];
2519 
2520  TIXMLASSERT(sizeof(error) <= sizeof(int));
2521  TIXML_SNPRINTF(buffer, BUFFER_SIZE, "Error=%s ErrorID=%d (0x%x) Line number=%d", ErrorIDToName(error), int(error), int(error), lineNum);
2522 
2523  if (format) {
2524  size_t len = strlen(buffer);
2525  TIXML_SNPRINTF(buffer + len, BUFFER_SIZE - len, ": ");
2526  len = strlen(buffer);
2527 
2528  va_list va;
2529  va_start(va, format);
2530  TIXML_VSNPRINTF(buffer + len, BUFFER_SIZE - len, format, va);
2531  va_end(va);
2532  }
2534  delete[] buffer;
2535 }
2536 
2537 
2538 /*static*/ const char* XMLDocument::ErrorIDToName(XMLError errorID)
2539 {
2540  TIXMLASSERT( errorID >= 0 && errorID < XML_ERROR_COUNT );
2541  const char* errorName = _errorNames[errorID];
2542  TIXMLASSERT( errorName && errorName[0] );
2543  return errorName;
2544 }
2545 
2546 const char* XMLDocument::ErrorStr() const
2547 {
2548  return _errorStr.Empty() ? "" : _errorStr.GetStr();
2549 }
2550 
2551 
2553 {
2554  printf("%s\n", ErrorStr());
2555 }
2556 
2557 const char* XMLDocument::ErrorName() const
2558 {
2559  return ErrorIDToName(_errorID);
2560 }
2561 
2563 {
2564  TIXMLASSERT( NoChildren() ); // Clear() must have been called previously
2566  _parseCurLineNum = 1;
2567  _parseLineNum = 1;
2568  char* p = _charBuffer;
2570  p = const_cast<char*>( XMLUtil::ReadBOM( p, &_writeBOM ) );
2571  if ( !*p ) {
2573  return;
2574  }
2575  ParseDeep(p, 0, &_parseCurLineNum );
2576 }
2577 
2579 {
2580  _parsingDepth++;
2582  SetError(XML_ELEMENT_DEPTH_EXCEEDED, _parseCurLineNum, "Element nesting is too deep." );
2583  }
2584 }
2585 
2587 {
2589  --_parsingDepth;
2590 }
2591 
2592 XMLPrinter::XMLPrinter( FILE* file, bool compact, int depth ) :
2593  _elementJustOpened( false ),
2594  _stack(),
2595  _firstElement( true ),
2596  _fp( file ),
2597  _depth( depth ),
2598  _textDepth( -1 ),
2599  _processEntities( true ),
2600  _compactMode( compact ),
2601  _buffer()
2602 {
2603  for( int i=0; i<ENTITY_RANGE; ++i ) {
2604  _entityFlag[i] = false;
2605  _restrictedEntityFlag[i] = false;
2606  }
2607  for( int i=0; i<NUM_ENTITIES; ++i ) {
2608  const char entityValue = entities[i].value;
2609  const unsigned char flagIndex = static_cast<unsigned char>(entityValue);
2610  TIXMLASSERT( flagIndex < ENTITY_RANGE );
2611  _entityFlag[flagIndex] = true;
2612  }
2613  _restrictedEntityFlag[static_cast<unsigned char>('&')] = true;
2614  _restrictedEntityFlag[static_cast<unsigned char>('<')] = true;
2615  _restrictedEntityFlag[static_cast<unsigned char>('>')] = true; // not required, but consistency is nice
2616  _buffer.Push( 0 );
2617 }
2618 
2619 
2620 void XMLPrinter::Print( const char* format, ... )
2621 {
2622  va_list va;
2623  va_start( va, format );
2624 
2625  if ( _fp ) {
2626  vfprintf( _fp, format, va );
2627  }
2628  else {
2629  const int len = TIXML_VSCPRINTF( format, va );
2630  // Close out and re-start the va-args
2631  va_end( va );
2632  TIXMLASSERT( len >= 0 );
2633  va_start( va, format );
2634  TIXMLASSERT( _buffer.Size() > 0 && _buffer[_buffer.Size() - 1] == 0 );
2635  char* p = _buffer.PushArr( len ) - 1; // back up over the null terminator.
2636  TIXML_VSNPRINTF( p, len+1, format, va );
2637  }
2638  va_end( va );
2639 }
2640 
2641 
2642 void XMLPrinter::Write( const char* data, size_t size )
2643 {
2644  if ( _fp ) {
2645  fwrite ( data , sizeof(char), size, _fp);
2646  }
2647  else {
2648  char* p = _buffer.PushArr( static_cast<int>(size) ) - 1; // back up over the null terminator.
2649  memcpy( p, data, size );
2650  p[size] = 0;
2651  }
2652 }
2653 
2654 
2655 void XMLPrinter::Putc( char ch )
2656 {
2657  if ( _fp ) {
2658  fputc ( ch, _fp);
2659  }
2660  else {
2661  char* p = _buffer.PushArr( sizeof(char) ) - 1; // back up over the null terminator.
2662  p[0] = ch;
2663  p[1] = 0;
2664  }
2665 }
2666 
2667 
2668 void XMLPrinter::PrintSpace( int depth )
2669 {
2670  for( int i=0; i<depth; ++i ) {
2671  Write( " " );
2672  }
2673 }
2674 
2675 
2676 void XMLPrinter::PrintString( const char* p, bool restricted )
2677 {
2678  // Look for runs of bytes between entities to print.
2679  const char* q = p;
2680 
2681  if ( _processEntities ) {
2682  const bool* flag = restricted ? _restrictedEntityFlag : _entityFlag;
2683  while ( *q ) {
2684  TIXMLASSERT( p <= q );
2685  // Remember, char is sometimes signed. (How many times has that bitten me?)
2686  if ( *q > 0 && *q < ENTITY_RANGE ) {
2687  // Check for entities. If one is found, flush
2688  // the stream up until the entity, write the
2689  // entity, and keep looking.
2690  if ( flag[static_cast<unsigned char>(*q)] ) {
2691  while ( p < q ) {
2692  const size_t delta = q - p;
2693  const int toPrint = ( INT_MAX < delta ) ? INT_MAX : static_cast<int>(delta);
2694  Write( p, toPrint );
2695  p += toPrint;
2696  }
2697  bool entityPatternPrinted = false;
2698  for( int i=0; i<NUM_ENTITIES; ++i ) {
2699  if ( entities[i].value == *q ) {
2700  Putc( '&' );
2701  Write( entities[i].pattern, entities[i].length );
2702  Putc( ';' );
2703  entityPatternPrinted = true;
2704  break;
2705  }
2706  }
2707  if ( !entityPatternPrinted ) {
2708  // TIXMLASSERT( entityPatternPrinted ) causes gcc -Wunused-but-set-variable in release
2709  TIXMLASSERT( false );
2710  }
2711  ++p;
2712  }
2713  }
2714  ++q;
2715  TIXMLASSERT( p <= q );
2716  }
2717  // Flush the remaining string. This will be the entire
2718  // string if an entity wasn't found.
2719  if ( p < q ) {
2720  const size_t delta = q - p;
2721  const int toPrint = ( INT_MAX < delta ) ? INT_MAX : static_cast<int>(delta);
2722  Write( p, toPrint );
2723  }
2724  }
2725  else {
2726  Write( p );
2727  }
2728 }
2729 
2730 
2731 void XMLPrinter::PushHeader( bool writeBOM, bool writeDec )
2732 {
2733  if ( writeBOM ) {
2734  static const unsigned char bom[] = { TIXML_UTF_LEAD_0, TIXML_UTF_LEAD_1, TIXML_UTF_LEAD_2, 0 };
2735  Write( reinterpret_cast< const char* >( bom ) );
2736  }
2737  if ( writeDec ) {
2738  PushDeclaration( "xml version=\"1.0\"" );
2739  }
2740 }
2741 
2742 void XMLPrinter::PrepareForNewNode( bool compactMode )
2743 {
2745 
2746  if ( compactMode ) {
2747  return;
2748  }
2749 
2750  if ( _firstElement ) {
2751  PrintSpace (_depth);
2752  } else if ( _textDepth < 0) {
2753  Putc( '\n' );
2754  PrintSpace( _depth );
2755  }
2756 
2757  _firstElement = false;
2758 }
2759 
2760 void XMLPrinter::OpenElement( const char* name, bool compactMode )
2761 {
2762  PrepareForNewNode( compactMode );
2763  _stack.Push( name );
2764 
2765  Write ( "<" );
2766  Write ( name );
2767 
2768  _elementJustOpened = true;
2769  ++_depth;
2770 }
2771 
2772 
2773 void XMLPrinter::PushAttribute( const char* name, const char* value )
2774 {
2776  Putc ( ' ' );
2777  Write( name );
2778  Write( "=\"" );
2779  PrintString( value, false );
2780  Putc ( '\"' );
2781 }
2782 
2783 
2784 void XMLPrinter::PushAttribute( const char* name, int v )
2785 {
2786  char buf[BUF_SIZE];
2787  XMLUtil::ToStr( v, buf, BUF_SIZE );
2788  PushAttribute( name, buf );
2789 }
2790 
2791 
2792 void XMLPrinter::PushAttribute( const char* name, unsigned v )
2793 {
2794  char buf[BUF_SIZE];
2795  XMLUtil::ToStr( v, buf, BUF_SIZE );
2796  PushAttribute( name, buf );
2797 }
2798 
2799 
2800 void XMLPrinter::PushAttribute(const char* name, int64_t v)
2801 {
2802  char buf[BUF_SIZE];
2803  XMLUtil::ToStr(v, buf, BUF_SIZE);
2804  PushAttribute(name, buf);
2805 }
2806 
2807 
2808 void XMLPrinter::PushAttribute(const char* name, uint64_t v)
2809 {
2810  char buf[BUF_SIZE];
2811  XMLUtil::ToStr(v, buf, BUF_SIZE);
2812  PushAttribute(name, buf);
2813 }
2814 
2815 
2816 void XMLPrinter::PushAttribute( const char* name, bool v )
2817 {
2818  char buf[BUF_SIZE];
2819  XMLUtil::ToStr( v, buf, BUF_SIZE );
2820  PushAttribute( name, buf );
2821 }
2822 
2823 
2824 void XMLPrinter::PushAttribute( const char* name, double v )
2825 {
2826  char buf[BUF_SIZE];
2827  XMLUtil::ToStr( v, buf, BUF_SIZE );
2828  PushAttribute( name, buf );
2829 }
2830 
2831 
2832 void XMLPrinter::CloseElement( bool compactMode )
2833 {
2834  --_depth;
2835  const char* name = _stack.Pop();
2836 
2837  if ( _elementJustOpened ) {
2838  Write( "/>" );
2839  }
2840  else {
2841  if ( _textDepth < 0 && !compactMode) {
2842  Putc( '\n' );
2843  PrintSpace( _depth );
2844  }
2845  Write ( "</" );
2846  Write ( name );
2847  Write ( ">" );
2848  }
2849 
2850  if ( _textDepth == _depth ) {
2851  _textDepth = -1;
2852  }
2853  if ( _depth == 0 && !compactMode) {
2854  Putc( '\n' );
2855  }
2856  _elementJustOpened = false;
2857 }
2858 
2859 
2861 {
2862  if ( !_elementJustOpened ) {
2863  return;
2864  }
2865  _elementJustOpened = false;
2866  Putc( '>' );
2867 }
2868 
2869 
2870 void XMLPrinter::PushText( const char* text, bool cdata )
2871 {
2872  _textDepth = _depth-1;
2873 
2875  if ( cdata ) {
2876  Write( "<![CDATA[" );
2877  Write( text );
2878  Write( "]]>" );
2879  }
2880  else {
2881  PrintString( text, true );
2882  }
2883 }
2884 
2885 
2886 void XMLPrinter::PushText( int64_t value )
2887 {
2888  char buf[BUF_SIZE];
2889  XMLUtil::ToStr( value, buf, BUF_SIZE );
2890  PushText( buf, false );
2891 }
2892 
2893 
2894 void XMLPrinter::PushText( uint64_t value )
2895 {
2896  char buf[BUF_SIZE];
2897  XMLUtil::ToStr(value, buf, BUF_SIZE);
2898  PushText(buf, false);
2899 }
2900 
2901 
2902 void XMLPrinter::PushText( int value )
2903 {
2904  char buf[BUF_SIZE];
2905  XMLUtil::ToStr( value, buf, BUF_SIZE );
2906  PushText( buf, false );
2907 }
2908 
2909 
2910 void XMLPrinter::PushText( unsigned value )
2911 {
2912  char buf[BUF_SIZE];
2913  XMLUtil::ToStr( value, buf, BUF_SIZE );
2914  PushText( buf, false );
2915 }
2916 
2917 
2918 void XMLPrinter::PushText( bool value )
2919 {
2920  char buf[BUF_SIZE];
2921  XMLUtil::ToStr( value, buf, BUF_SIZE );
2922  PushText( buf, false );
2923 }
2924 
2925 
2926 void XMLPrinter::PushText( float value )
2927 {
2928  char buf[BUF_SIZE];
2929  XMLUtil::ToStr( value, buf, BUF_SIZE );
2930  PushText( buf, false );
2931 }
2932 
2933 
2934 void XMLPrinter::PushText( double value )
2935 {
2936  char buf[BUF_SIZE];
2937  XMLUtil::ToStr( value, buf, BUF_SIZE );
2938  PushText( buf, false );
2939 }
2940 
2941 
2942 void XMLPrinter::PushComment( const char* comment )
2943 {
2945 
2946  Write( "<!--" );
2947  Write( comment );
2948  Write( "-->" );
2949 }
2950 
2951 
2952 void XMLPrinter::PushDeclaration( const char* value )
2953 {
2955 
2956  Write( "<?" );
2957  Write( value );
2958  Write( "?>" );
2959 }
2960 
2961 
2962 void XMLPrinter::PushUnknown( const char* value )
2963 {
2965 
2966  Write( "<!" );
2967  Write( value );
2968  Putc( '>' );
2969 }
2970 
2971 
2973 {
2975  if ( doc.HasBOM() ) {
2976  PushHeader( true, false );
2977  }
2978  return true;
2979 }
2980 
2981 
2982 bool XMLPrinter::VisitEnter( const XMLElement& element, const XMLAttribute* attribute )
2983 {
2984  const XMLElement* parentElem = 0;
2985  if ( element.Parent() ) {
2986  parentElem = element.Parent()->ToElement();
2987  }
2988  const bool compactMode = parentElem ? CompactMode( *parentElem ) : _compactMode;
2989  OpenElement( element.Name(), compactMode );
2990  while ( attribute ) {
2991  PushAttribute( attribute->Name(), attribute->Value() );
2992  attribute = attribute->Next();
2993  }
2994  return true;
2995 }
2996 
2997 
2998 bool XMLPrinter::VisitExit( const XMLElement& element )
2999 {
3000  CloseElement( CompactMode(element) );
3001  return true;
3002 }
3003 
3004 
3005 bool XMLPrinter::Visit( const XMLText& text )
3006 {
3007  PushText( text.Value(), text.CData() );
3008  return true;
3009 }
3010 
3011 
3012 bool XMLPrinter::Visit( const XMLComment& comment )
3013 {
3014  PushComment( comment.Value() );
3015  return true;
3016 }
3017 
3018 bool XMLPrinter::Visit( const XMLDeclaration& declaration )
3019 {
3020  PushDeclaration( declaration.Value() );
3021  return true;
3022 }
3023 
3024 
3025 bool XMLPrinter::Visit( const XMLUnknown& unknown )
3026 {
3027  PushUnknown( unknown.Value() );
3028  return true;
3029 }
3030 
3031 } // namespace tinyxml2
tinyxml2::XMLDocument::DeepCopy
void DeepCopy(XMLDocument *target) const
Definition: tinyxml2.cpp:2271
cx::size
constexpr auto size(const C &c) -> decltype(c.size())
Definition: wildcards.hpp:636
tinyxml2::XMLText::ShallowEqual
virtual bool ShallowEqual(const XMLNode *compare) const override
Definition: tinyxml2.cpp:1284
tinyxml2::MemPool::SetTracked
virtual void SetTracked()=0
tinyxml2::XMLElement::QueryDoubleText
XMLError QueryDoubleText(double *dval) const
See QueryIntText()
Definition: tinyxml2.cpp:1850
tinyxml2::XMLPrinter::Putc
virtual void Putc(char ch)
Definition: tinyxml2.cpp:2655
tinyxml2::XMLDocument::HasBOM
bool HasBOM() const
Definition: tinyxml2.h:1802
tinyxml2::XMLElement::InsertNewUnknown
XMLUnknown * InsertNewUnknown(const char *text)
See InsertNewChildElement()
Definition: tinyxml2.cpp:2076
tinyxml2::XMLPrinter::PushAttribute
void PushAttribute(const char *name, const char *value)
If streaming, add an attribute to an open element.
Definition: tinyxml2.cpp:2773
TIXML_UTF_LEAD_0
static const unsigned char TIXML_UTF_LEAD_0
Definition: tinyxml2.cpp:134
tinyxml2::XMLDocument::ClearError
void ClearError()
Clears the error flags.
Definition: tinyxml2.cpp:2503
tinyxml2::XMLUnknown::XMLUnknown
XMLUnknown(XMLDocument *doc)
Definition: tinyxml2.cpp:1398
tinyxml2::XMLElement::QueryUnsigned64Attribute
XMLError QueryUnsigned64Attribute(const char *name, uint64_t *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1373
TIXML_VSCPRINTF
static int TIXML_VSCPRINTF(const char *format, va_list va)
Definition: tinyxml2.cpp:94
tinyxml2::XMLElement::UnsignedText
unsigned UnsignedText(unsigned defaultValue=0) const
See QueryIntText()
Definition: tinyxml2.cpp:1882
tinyxml2::XMLText::ParseDeep
char * ParseDeep(char *p, StrPair *parentEndTag, int *curLineNumPtr) override
Definition: tinyxml2.cpp:1246
tinyxml2::XMLDocument::Error
bool Error() const
Return true if there was an error parsing the document.
Definition: tinyxml2.h:1885
tinyxml2::XMLComment::Accept
virtual bool Accept(XMLVisitor *visitor) const override
Definition: tinyxml2.cpp:1340
tinyxml2::StrPair::_start
char * _start
Definition: tinyxml2.h:189
tinyxml2::XML_NO_TEXT_NODE
@ XML_NO_TEXT_NODE
Definition: tinyxml2.h:538
tinyxml2::XMLElement::DoubleAttribute
double DoubleAttribute(const char *name, double defaultValue=0) const
See IntAttribute()
Definition: tinyxml2.cpp:1687
tinyxml2::XMLPrinter::Write
virtual void Write(const char *data, size_t size)
Definition: tinyxml2.cpp:2642
tinyxml2::XMLAttribute::Value
const char * Value() const
The value of the attribute.
Definition: tinyxml2.cpp:1450
tinyxml2::StrPair::Empty
bool Empty() const
Definition: tinyxml2.h:163
tinyxml2::XMLNode::InsertFirstChild
XMLNode * InsertFirstChild(XMLNode *addThis)
Definition: tinyxml2.cpp:968
tinyxml2::XMLElement::Int64Attribute
int64_t Int64Attribute(const char *name, int64_t defaultValue=0) const
See IntAttribute()
Definition: tinyxml2.cpp:1666
tinyxml2::Entity::length
int length
Definition: tinyxml2.cpp:143
lexyd::ascii::digit
constexpr auto digit
Definition: ascii.hpp:258
tinyxml2::XMLElement::Attribute
const char * Attribute(const char *name, const char *value=0) const
Definition: tinyxml2.cpp:1640
tinyxml2::XMLText::CData
bool CData() const
Returns true if this is a CDATA text element.
Definition: tinyxml2.h:1012
tinyxml2::XMLUnknown::Accept
virtual bool Accept(XMLVisitor *visitor) const override
Definition: tinyxml2.cpp:1437
tinyxml2::XMLNode::ShallowClone
virtual XMLNode * ShallowClone(XMLDocument *document) const =0
tinyxml2::XMLNode::_lastChild
XMLNode * _lastChild
Definition: tinyxml2.h:963
tinyxml2::XMLNode::ToDeclaration
virtual XMLDeclaration * ToDeclaration()
Safely cast to a Declaration, or null.
Definition: tinyxml2.h:705
tinyxml2::StrPair::ParseText
char * ParseText(char *in, const char *endTag, int strFlags, int *curLineNumPtr)
Definition: tinyxml2.cpp:212
tinyxml2::XMLUtil::ToUnsigned
static bool ToUnsigned(const char *str, unsigned *value)
Definition: tinyxml2.cpp:633
tinyxml2::COLLAPSE_WHITESPACE
@ COLLAPSE_WHITESPACE
Definition: tinyxml2.h:1710
tinyxml2::XMLElement::_rootAttribute
XMLAttribute * _rootAttribute
Definition: tinyxml2.h:1704
tinyxml2::XMLPrinter::_stack
DynArray< const char *, 10 > _stack
Definition: tinyxml2.h:2346
tinyxml2::XMLDocument::ErrorIDToName
static const char * ErrorIDToName(XMLError errorID)
Definition: tinyxml2.cpp:2538
tinyxml2::XMLNode::Value
const char * Value() const
Definition: tinyxml2.cpp:860
tinyxml2::XMLDeclaration::~XMLDeclaration
virtual ~XMLDeclaration()
Definition: tinyxml2.cpp:1354
tinyxml2::XMLDocument::_charBuffer
char * _charBuffer
Definition: tinyxml2.h:1944
tinyxml2::XMLAttribute::SetAttribute
void SetAttribute(const char *value)
Set the attribute to a string value.
Definition: tinyxml2.cpp:1552
tinyxml2::XMLElement::DeleteAttribute
void DeleteAttribute(const char *name)
Definition: tinyxml2.cpp:1953
tinyxml2::XMLComment
Definition: tinyxml2.h:1034
tinyxml2::XMLVisitor::VisitExit
virtual bool VisitExit(const XMLDocument &)
Visit a document.
Definition: tinyxml2.h:488
tinyxml2::XMLAttribute::_next
XMLAttribute * _next
Definition: tinyxml2.h:1258
tinyxml2::XMLElement::ParseAttributes
char * ParseAttributes(char *p, int *curLineNumPtr)
Definition: tinyxml2.cpp:1972
tinyxml2::XMLPrinter::PrintString
void PrintString(const char *, bool restrictedEntitySet)
Definition: tinyxml2.cpp:2676
tinyxml2::MemPool
Definition: tinyxml2.h:327
TIXML_FSEEK
#define TIXML_FSEEK
Definition: tinyxml2.cpp:118
tinyxml2::XMLNode::_memPool
MemPool * _memPool
Definition: tinyxml2.h:971
tinyxml2::XMLPrinter::OpenElement
void OpenElement(const char *name, bool compactMode=false)
Definition: tinyxml2.cpp:2760
tinyxml2::XMLElement::IntAttribute
int IntAttribute(const char *name, int defaultValue=0) const
Definition: tinyxml2.cpp:1652
tinyxml2::StrPair::GetStr
const char * GetStr()
Definition: tinyxml2.cpp:286
tinyxml2::XML_ERROR_PARSING_UNKNOWN
@ XML_ERROR_PARSING_UNKNOWN
Definition: tinyxml2.h:533
tinyxml2::StrPair::Reset
void Reset()
Definition: tinyxml2.cpp:188
tinyxml2::XMLNode::XMLDocument
friend class XMLDocument
Definition: tinyxml2.h:673
tinyxml2::XMLError
XMLError
Definition: tinyxml2.h:520
tinyxml2::XMLElement::QueryBoolAttribute
XMLError QueryBoolAttribute(const char *name, bool *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1382
tinyxml2::XMLDocument::~XMLDocument
~XMLDocument()
Definition: tinyxml2.cpp:2218
tinyxml2::XMLNode::_parent
XMLNode * _parent
Definition: tinyxml2.h:958
TIXMLASSERT
#define TIXMLASSERT(x)
Definition: tinyxml2.h:92
tinyxml2::XMLNode::DeepClone
XMLNode * DeepClone(XMLDocument *target) const
Definition: tinyxml2.cpp:878
tinyxml2::XMLNode::NoChildren
bool NoChildren() const
Returns true if this node has no children.
Definition: tinyxml2.h:767
tinyxml2::XMLDocument::NewUnknown
XMLUnknown * NewUnknown(const char *text)
Definition: tinyxml2.cpp:2316
tinyxml2::XMLElement::SetName
void SetName(const char *str, bool staticMem=false)
Set the name of the element.
Definition: tinyxml2.h:1276
tinyxml2::XML_ERROR_FILE_NOT_FOUND
@ XML_ERROR_FILE_NOT_FOUND
Definition: tinyxml2.h:524
tinyxml2::XMLDocument::_writeBOM
bool _writeBOM
Definition: tinyxml2.h:1938
tinyxml2::XMLDocument::_errorID
XMLError _errorID
Definition: tinyxml2.h:1940
tinyxml2::XMLUtil::ReadBOM
static const char * ReadBOM(const char *p, bool *hasBOM)
Definition: tinyxml2.cpp:404
tinyxml2::XMLPrinter
Definition: tinyxml2.h:2241
tinyxml2::XML_ERROR_FILE_COULD_NOT_BE_OPENED
@ XML_ERROR_FILE_COULD_NOT_BE_OPENED
Definition: tinyxml2.h:525
tinyxml2::XML_WRONG_ATTRIBUTE_TYPE
@ XML_WRONG_ATTRIBUTE_TYPE
Definition: tinyxml2.h:523
tinyxml2::XMLElement::SetAttribute
void SetAttribute(const char *name, const char *value)
Sets the named attribute to value.
Definition: tinyxml2.h:1468
tinyxml2::XMLUtil::ToUnsigned64
static bool ToUnsigned64(const char *str, uint64_t *value)
Definition: tinyxml2.cpp:705
tinyxml2::XMLUnknown::ShallowEqual
virtual bool ShallowEqual(const XMLNode *compare) const override
Definition: tinyxml2.cpp:1429
tinyxml2::XMLPrinter::VisitExit
virtual bool VisitExit(const XMLDocument &) override
Visit a document.
Definition: tinyxml2.h:2294
tinyxml2::StrPair::NEEDS_WHITESPACE_COLLAPSING
@ NEEDS_WHITESPACE_COLLAPSING
Definition: tinyxml2.h:139
CARRIAGE_RETURN
static const char CARRIAGE_RETURN
Definition: tinyxml2.cpp:125
tinyxml2::XMLDocument::LoadFile
XMLError LoadFile(const char *filename)
Definition: tinyxml2.cpp:2357
tinyxml2::XMLElement::CLOSING
@ CLOSING
Definition: tinyxml2.h:1677
tinyxml2::XMLElement::InsertNewText
XMLText * InsertNewText(const char *text)
See InsertNewChildElement()
Definition: tinyxml2.cpp:2064
tinyxml2::XML_ERROR_PARSING_DECLARATION
@ XML_ERROR_PARSING_DECLARATION
Definition: tinyxml2.h:532
tinyxml2::XMLNode::PreviousSiblingElement
const XMLElement * PreviousSiblingElement(const char *name=0) const
Get the previous (left) sibling element of this node, with an optionally supplied name.
Definition: tinyxml2.cpp:1073
tinyxml2::XML_ERROR_FILE_READ_ERROR
@ XML_ERROR_FILE_READ_ERROR
Definition: tinyxml2.h:526
tinyxml2::StrPair::TEXT_ELEMENT
@ TEXT_ELEMENT
Definition: tinyxml2.h:141
tinyxml2::XMLNode::_prev
XMLNode * _prev
Definition: tinyxml2.h:965
tinyxml2::XMLNode::NextSiblingElement
const XMLElement * NextSiblingElement(const char *name=0) const
Get the next (right) sibling element of this node, with an optionally supplied name.
Definition: tinyxml2.cpp:1061
tinyxml2::StrPair::ATTRIBUTE_VALUE_LEAVE_ENTITIES
@ ATTRIBUTE_VALUE_LEAVE_ENTITIES
Definition: tinyxml2.h:145
TIXML_UTF_LEAD_2
static const unsigned char TIXML_UTF_LEAD_2
Definition: tinyxml2.cpp:136
tinyxml2::XML_ERROR_PARSING_ELEMENT
@ XML_ERROR_PARSING_ELEMENT
Definition: tinyxml2.h:527
tinyxml2::StrPair::_flags
int _flags
Definition: tinyxml2.h:188
tinyxml2::StrPair::ParseName
char * ParseName(char *in)
Definition: tinyxml2.cpp:237
tinyxml2::XMLNode::DeleteChildren
void DeleteChildren()
Definition: tinyxml2.cpp:891
tinyxml2::XMLVisitor
Definition: tinyxml2.h:478
tinyxml2::XMLNode::~XMLNode
virtual ~XMLNode()
Definition: tinyxml2.cpp:824
tinyxml2::XMLElement::QueryInt64Attribute
XMLError QueryInt64Attribute(const char *name, int64_t *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1364
tinyxml2::XMLPrinter::_firstElement
bool _firstElement
Definition: tinyxml2.h:2356
tinyxml2::XML_ERROR_PARSING_TEXT
@ XML_ERROR_PARSING_TEXT
Definition: tinyxml2.h:529
tinyxml2::XMLUtil::ToInt
static bool ToInt(const char *str, int *value)
Definition: tinyxml2.cpp:616
tinyxml2::XMLDocument::WhitespaceMode
Whitespace WhitespaceMode() const
Definition: tinyxml2.h:1795
tinyxml2::XMLNode::DeleteNode
static void DeleteNode(XMLNode *node)
Definition: tinyxml2.cpp:1201
tinyxml2::StrPair::NEEDS_NEWLINE_NORMALIZATION
@ NEEDS_NEWLINE_NORMALIZATION
Definition: tinyxml2.h:138
tinyxml2::XMLNode::Unlink
void Unlink(XMLNode *child)
Definition: tinyxml2.cpp:901
tinyxml2::callfopen
static FILE * callfopen(const char *filepath, const char *mode)
Definition: tinyxml2.cpp:2323
tinyxml2::XMLDocument::PopDepth
void PopDepth()
Definition: tinyxml2.cpp:2586
tinyxml2::XMLPrinter::_textDepth
int _textDepth
Definition: tinyxml2.h:2359
tinyxml2::XMLElement::FindOrCreateAttribute
XMLAttribute * FindOrCreateAttribute(const char *name)
Definition: tinyxml2.cpp:1925
tinyxml2::XMLNode::InsertAfterChild
XMLNode * InsertAfterChild(XMLNode *afterThis, XMLNode *addThis)
Definition: tinyxml2.cpp:999
tinyxml2::XMLDocument::NewElement
XMLElement * NewElement(const char *name)
Definition: tinyxml2.cpp:2284
tinyxml2::XMLUtil::ConvertUTF32ToUTF8
static void ConvertUTF32ToUTF8(unsigned long input, char *output, int *length)
Definition: tinyxml2.cpp:422
tinyxml2::XMLElement::CreateAttribute
XMLAttribute * CreateAttribute()
Definition: tinyxml2.cpp:2041
tinyxml2::XMLDeclaration::ShallowClone
virtual XMLNode * ShallowClone(XMLDocument *document) const override
Definition: tinyxml2.cpp:1371
tinyxml2::XMLDocument::MarkInUse
void MarkInUse(const XMLNode *const)
Definition: tinyxml2.cpp:2224
tinyxml2::XMLPrinter::_buffer
DynArray< char, 20 > _buffer
Definition: tinyxml2.h:2370
tinyxml2::XMLElement::QueryIntText
XMLError QueryIntText(int *ival) const
Definition: tinyxml2.cpp:1785
tinyxml2::XMLElement::~XMLElement
virtual ~XMLElement()
Definition: tinyxml2.cpp:1619
tinyxml2::XMLElement::ShallowEqual
virtual bool ShallowEqual(const XMLNode *compare) const override
Definition: tinyxml2.cpp:2130
tinyxml2::XMLNode::NextSibling
const XMLNode * NextSibling() const
Get the next (right) sibling node of this node.
Definition: tinyxml2.h:824
TINYXML2_MAX_ELEMENT_DEPTH
static const int TINYXML2_MAX_ELEMENT_DEPTH
Definition: tinyxml2.h:112
tinyxml2::XMLNode::DeleteChild
void DeleteChild(XMLNode *node)
Definition: tinyxml2.cpp:925
tinyxml2::XMLDocument::_elementPool
MemPoolT< sizeof(XMLElement) > _elementPool
Definition: tinyxml2.h:1955
tinyxml2::XMLUnknown::ShallowClone
virtual XMLNode * ShallowClone(XMLDocument *document) const override
Definition: tinyxml2.cpp:1419
tinyxml2::XMLElement::GetText
const char * GetText() const
Definition: tinyxml2.cpp:1701
tinyxml2::XMLNode::GetDocument
const XMLDocument * GetDocument() const
Get the XMLDocument that owns this XMLNode.
Definition: tinyxml2.h:678
tinyxml2::XMLElement::QueryUnsigned64Text
XMLError QueryUnsigned64Text(uint64_t *uval) const
See QueryIntText()
Definition: tinyxml2.cpp:1824
tinyxml2::XML_ERROR_PARSING_COMMENT
@ XML_ERROR_PARSING_COMMENT
Definition: tinyxml2.h:531
TIXML_SSCANF
#define TIXML_SSCANF
Definition: tinyxml2.cpp:100
tinyxml2::XMLDocument::Accept
virtual bool Accept(XMLVisitor *visitor) const override
Definition: tinyxml2.cpp:795
tinyxml2::XMLDocument::SaveFile
XMLError SaveFile(const char *filename, bool compact=false)
Definition: tinyxml2.cpp:2430
tinyxml2::StrPair::Set
void Set(char *start, char *end, int flags)
Definition: tinyxml2.h:152
tinyxml2::XMLAttribute
Definition: tinyxml2.h:1143
TIXML_UTF_LEAD_1
static const unsigned char TIXML_UTF_LEAD_1
Definition: tinyxml2.cpp:135
tinyxml2::XMLPrinter::PrintSpace
virtual void PrintSpace(int depth)
Definition: tinyxml2.cpp:2668
tinyxml2::XMLElement::BUF_SIZE
@ BUF_SIZE
Definition: tinyxml2.h:1699
tinyxml2::XMLDocument::ProcessEntities
bool ProcessEntities() const
Definition: tinyxml2.h:1792
tinyxml2::XMLAttribute::ParseDeep
char * ParseDeep(char *p, bool processEntities, int *curLineNumPtr)
Definition: tinyxml2.cpp:1455
tinyxml2::XMLDocument::PrintError
void PrintError() const
A (trivial) utility function that prints the ErrorStr() to stdout.
Definition: tinyxml2.cpp:2552
tinyxml2::XMLText
Definition: tinyxml2.h:994
tinyxml2::Whitespace
Whitespace
Definition: tinyxml2.h:1708
tinyxml2::XMLPrinter::PrepareForNewNode
void PrepareForNewNode(bool compactMode)
Definition: tinyxml2.cpp:2742
tinyxml2::XMLNode::XMLElement
friend class XMLElement
Definition: tinyxml2.h:674
tinyxml2::XMLUtil::GetCharacterRef
static const char * GetCharacterRef(const char *p, char *value, int *length)
Definition: tinyxml2.cpp:475
tinyxml2::XMLDeclaration::XMLDeclaration
XMLDeclaration(XMLDocument *doc)
Definition: tinyxml2.cpp:1349
tinyxml2::XMLElement::_closingType
ElementClosingType _closingType
Definition: tinyxml2.h:1700
tinyxml2::XMLUtil::writeBoolTrue
static const char * writeBoolTrue
Definition: tinyxml2.h:641
tinyxml2::XMLNode::ToUnknown
virtual XMLUnknown * ToUnknown()
Safely cast to an Unknown, or null.
Definition: tinyxml2.h:709
tinyxml2::XMLDeclaration::ShallowEqual
virtual bool ShallowEqual(const XMLNode *compare) const override
Definition: tinyxml2.cpp:1381
tinyxml2::XMLPrinter::_entityFlag
bool _entityFlag[ENTITY_RANGE]
Definition: tinyxml2.h:2367
tinyxml2::XMLElement::FirstAttribute
const XMLAttribute * FirstAttribute() const
Return the first attribute in the list.
Definition: tinyxml2.h:1517
lexy::count
constexpr auto count
Sink that counts all arguments.
Definition: fold.hpp:88
tinyxml2::XMLAttribute::QueryUnsignedValue
XMLError QueryUnsignedValue(unsigned int *value) const
See QueryIntValue.
Definition: tinyxml2.cpp:1498
tinyxml2::StrPair::TEXT_ELEMENT_LEAVE_ENTITIES
@ TEXT_ELEMENT_LEAVE_ENTITIES
Definition: tinyxml2.h:142
tinyxml2::XMLAttribute::QueryInt64Value
XMLError QueryInt64Value(int64_t *value) const
See QueryIntValue.
Definition: tinyxml2.cpp:1507
tinyxml2::XMLUtil::IsNameStartChar
static bool IsNameStartChar(unsigned char ch)
Definition: tinyxml2.h:573
tinyxml2::XML_SUCCESS
@ XML_SUCCESS
Definition: tinyxml2.h:521
tinyxml2::XMLAttribute::QueryDoubleValue
XMLError QueryDoubleValue(double *value) const
See QueryIntValue.
Definition: tinyxml2.cpp:1543
tinyxml2::XMLElement::InsertNewChildElement
XMLElement * InsertNewChildElement(const char *name)
Definition: tinyxml2.cpp:2052
tinyxml2::XMLElement::UnsignedAttribute
unsigned UnsignedAttribute(const char *name, unsigned defaultValue=0) const
See IntAttribute()
Definition: tinyxml2.cpp:1659
tinyxml2::XMLElement::FloatText
float FloatText(float defaultValue=0) const
See QueryIntText()
Definition: tinyxml2.cpp:1917
tinyxml2::XMLPrinter::CloseElement
virtual void CloseElement(bool compactMode=false)
If streaming, close the Element.
Definition: tinyxml2.cpp:2832
tinyxml2::XMLAttribute::_value
StrPair _value
Definition: tinyxml2.h:1256
tinyxml2::XMLPrinter::_compactMode
bool _compactMode
Definition: tinyxml2.h:2361
tinyxml2::XMLAttribute::QueryBoolValue
XMLError QueryBoolValue(bool *value) const
See QueryIntValue.
Definition: tinyxml2.cpp:1525
tinyxml2::XMLAttribute::BUF_SIZE
@ BUF_SIZE
Definition: tinyxml2.h:1244
tinyxml2::XMLPrinter::_fp
FILE * _fp
Definition: tinyxml2.h:2357
tinyxml2::XMLDocument::_unlinked
DynArray< XMLNode *, 10 > _unlinked
Definition: tinyxml2.h:1953
tinyxml2::XMLElement::BoolText
bool BoolText(bool defaultValue=false) const
See QueryIntText()
Definition: tinyxml2.cpp:1903
tinyxml2::XMLDocument::Clear
void Clear()
Clear the document, resetting it to the initial state.
Definition: tinyxml2.cpp:2237
tinyxml2::XMLElement::IntText
int IntText(int defaultValue=0) const
Definition: tinyxml2.cpp:1875
tinyxml2::XMLNode::FirstChild
const XMLNode * FirstChild() const
Get the first child node, or null if none exists.
Definition: tinyxml2.h:772
tinyxml2::DynArray::Pop
T Pop()
Definition: tinyxml2.h:239
tinyxml2::XMLComment::XMLComment
XMLComment(XMLDocument *doc)
Definition: tinyxml2.cpp:1301
tinyxml2::XMLUtil::writeBoolFalse
static const char * writeBoolFalse
Definition: tinyxml2.h:642
tinyxml2::XMLDocument::SetError
void SetError(XMLError error, int lineNum, const char *format,...)
Definition: tinyxml2.cpp:2510
tinyxml2::DynArray::Size
int Size() const
Definition: tinyxml2.h:269
tinyxml2::XMLElement::FindAttribute
const XMLAttribute * FindAttribute(const char *name) const
Query a specific attribute in the list.
Definition: tinyxml2.cpp:1629
tinyxml2::XMLComment::~XMLComment
virtual ~XMLComment()
Definition: tinyxml2.cpp:1306
tinyxml2::XMLNode::_firstChild
XMLNode * _firstChild
Definition: tinyxml2.h:962
lexy::buffer
buffer(const CharT *, const CharT *) -> buffer< deduce_encoding< CharT >>
tinyxml2::XMLComment::ShallowEqual
virtual bool ShallowEqual(const XMLNode *compare) const override
Definition: tinyxml2.cpp:1332
tinyxml2::StrPair::SetInternedStr
void SetInternedStr(const char *str)
Definition: tinyxml2.h:167
tinyxml2::XMLDocument::ErrorStr
const char * ErrorStr() const
Definition: tinyxml2.cpp:2546
tinyxml2::XMLElement::QueryInt64Text
XMLError QueryInt64Text(int64_t *uval) const
See QueryIntText()
Definition: tinyxml2.cpp:1811
tinyxml2::XMLDeclaration
Definition: tinyxml2.h:1073
tinyxml2::XMLAttribute::_name
StrPair _name
Definition: tinyxml2.h:1255
tinyxml2::XMLDocument::_parseCurLineNum
int _parseCurLineNum
Definition: tinyxml2.h:1945
lexy_ext::child
auto child(const lexy::parse_tree< Reader, TokenKind, MemoryResource > &tree, typename lexy::parse_tree< Reader, TokenKind, MemoryResource >::node node, Predicate predicate) -> std::optional< typename lexy::parse_tree< Reader, TokenKind, MemoryResource >::node >
Returns the first child that matches predicate, if there is any.
Definition: parse_tree_algorithm.hpp:244
tinyxml2::XMLUnknown
Definition: tinyxml2.h:1108
tinyxml2::XMLComment::ParseDeep
char * ParseDeep(char *p, StrPair *parentEndTag, int *curLineNumPtr) override
Definition: tinyxml2.cpp:1311
SINGLE_QUOTE
static const char SINGLE_QUOTE
Definition: tinyxml2.cpp:127
tinyxml2::XMLDeclaration::ParseDeep
char * ParseDeep(char *p, StrPair *parentEndTag, int *curLineNumPtr) override
Definition: tinyxml2.cpp:1360
tinyxml2::XMLText::SetCData
void SetCData(bool isCData)
Declare whether this should be CDATA or standard text.
Definition: tinyxml2.h:1008
tinyxml2::XMLPrinter::BUF_SIZE
@ BUF_SIZE
Definition: tinyxml2.h:2365
tinyxml2::XMLElement
Definition: tinyxml2.h:1267
tinyxml2::StrPair::COMMENT
@ COMMENT
Definition: tinyxml2.h:146
tinyxml2::XMLElement::QueryBoolText
XMLError QueryBoolText(bool *bval) const
See QueryIntText()
Definition: tinyxml2.cpp:1837
tinyxml2::XMLUnknown::~XMLUnknown
virtual ~XMLUnknown()
Definition: tinyxml2.cpp:1403
tinyxml2::XMLElement::ClosingType
ElementClosingType ClosingType() const
Definition: tinyxml2.h:1679
tinyxml2::StrPair::TransferTo
void TransferTo(StrPair *other)
Definition: tinyxml2.cpp:163
tinyxml2::XMLNode::Parent
const XMLNode * Parent() const
Get the parent of this node on the DOM.
Definition: tinyxml2.h:758
tinyxml2::XMLAttribute::_parseLineNum
int _parseLineNum
Definition: tinyxml2.h:1257
tinyxml2::XMLText::Accept
virtual bool Accept(XMLVisitor *visitor) const override
Definition: tinyxml2.cpp:1292
CR
static const char CR
Definition: tinyxml2.cpp:126
tinyxml2::XMLNode::_value
StrPair _value
Definition: tinyxml2.h:959
tinyxml2::XMLPrinter::ENTITY_RANGE
@ ENTITY_RANGE
Definition: tinyxml2.h:2364
tinyxml2::XML_ERROR_PARSING_CDATA
@ XML_ERROR_PARSING_CDATA
Definition: tinyxml2.h:530
tinyxml2::XMLPrinter::CompactMode
virtual bool CompactMode(const XMLElement &)
Definition: tinyxml2.h:2332
tinyxml2::XMLAttribute::QueryFloatValue
XMLError QueryFloatValue(float *value) const
See QueryIntValue.
Definition: tinyxml2.cpp:1534
tinyxml2::XMLDocument::Identify
char * Identify(char *p, XMLNode **node, bool first)
Definition: tinyxml2.cpp:715
cx::prev
constexpr It prev(It it)
Definition: wildcards.hpp:631
tinyxml2::XMLElement::QueryDoubleAttribute
XMLError QueryDoubleAttribute(const char *name, double *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1390
tinyxml2::XMLPrinter::_processEntities
bool _processEntities
Definition: tinyxml2.h:2360
tinyxml2::XMLNode::ToElement
virtual XMLElement * ToElement()
Safely cast to an Element, or null.
Definition: tinyxml2.h:689
tinyxml2::DynArray::PushArr
T * PushArr(int count)
Definition: tinyxml2.h:230
tinyxml2::XMLNode::XMLNode
XMLNode(XMLDocument *)
Definition: tinyxml2.cpp:811
tinyxml2::XMLElement::CLOSED
@ CLOSED
Definition: tinyxml2.h:1676
tinyxml2::XMLElement::Unsigned64Attribute
uint64_t Unsigned64Attribute(const char *name, uint64_t defaultValue=0) const
See IntAttribute()
Definition: tinyxml2.cpp:1673
magic_enum::detail::n
constexpr auto n() noexcept
Definition: magic_enum.hpp:417
tinyxml2::StrPair::SetStr
void SetStr(const char *str, int flags=0)
Definition: tinyxml2.cpp:199
tinyxml2::XMLNode::ToElementWithName
const XMLElement * ToElementWithName(const char *name) const
Definition: tinyxml2.cpp:1230
tinyxml2::XMLDocument::_attributePool
MemPoolT< sizeof(XMLAttribute) > _attributePool
Definition: tinyxml2.h:1956
tinyxml2::XMLElement::Int64Text
int64_t Int64Text(int64_t defaultValue=0) const
See QueryIntText()
Definition: tinyxml2.cpp:1889
tinyxml2::XMLUtil::IsPrefixHex
static bool IsPrefixHex(const char *p)
Definition: tinyxml2.h:591
tinyxml2::XMLPrinter::PushDeclaration
void PushDeclaration(const char *value)
Definition: tinyxml2.cpp:2952
tinyxml2::XMLUnknown::ParseDeep
char * ParseDeep(char *p, StrPair *parentEndTag, int *curLineNumPtr) override
Definition: tinyxml2.cpp:1408
tinyxml2::XMLNode::_parseLineNum
int _parseLineNum
Definition: tinyxml2.h:960
tinyxml2::XMLElement::QueryUnsignedAttribute
XMLError QueryUnsignedAttribute(const char *name, unsigned int *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1355
tinyxml2::XMLElement::Accept
virtual bool Accept(XMLVisitor *visitor) const override
Definition: tinyxml2.cpp:2156
tinyxml2::XML_ERROR_PARSING_ATTRIBUTE
@ XML_ERROR_PARSING_ATTRIBUTE
Definition: tinyxml2.h:528
f
static FILE * f
Definition: minitrace.cpp:74
tinyxml2::XMLNode::InsertChildPreamble
void InsertChildPreamble(XMLNode *insertThis) const
Definition: tinyxml2.cpp:1216
tinyxml2::XMLDocument::Print
void Print(XMLPrinter *streamer=0) const
Definition: tinyxml2.cpp:2491
tinyxml2::XMLNode::LastChild
const XMLNode * LastChild() const
Get the last child node, or null if none exists.
Definition: tinyxml2.h:790
tinyxml2::XMLPrinter::PushComment
void PushComment(const char *comment)
Add a comment.
Definition: tinyxml2.cpp:2942
tinyxml2::XMLUtil::ToFloat
static bool ToFloat(const char *str, float *value)
Definition: tinyxml2.cpp:667
tinyxml2::XMLAttribute::QueryUnsigned64Value
XMLError QueryUnsigned64Value(uint64_t *value) const
See QueryIntValue.
Definition: tinyxml2.cpp:1516
DOUBLE_QUOTE
static const char DOUBLE_QUOTE
Definition: tinyxml2.cpp:128
LF
static const char LF
Definition: tinyxml2.cpp:124
tinyxml2::StrPair::ATTRIBUTE_VALUE
@ ATTRIBUTE_VALUE
Definition: tinyxml2.h:144
tinyxml2::XMLUtil::ToBool
static bool ToBool(const char *str, bool *value)
Definition: tinyxml2.cpp:641
tinyxml2::XMLDocument::ErrorName
const char * ErrorName() const
Definition: tinyxml2.cpp:2557
tinyxml2::XMLElement::InsertNewDeclaration
XMLDeclaration * InsertNewDeclaration(const char *text)
See InsertNewChildElement()
Definition: tinyxml2.cpp:2070
tinyxml2::XMLUtil::ToStr
static void ToStr(int v, char *buffer, int bufferSize)
Definition: tinyxml2.cpp:571
tinyxml2::XMLNode::SetValue
void SetValue(const char *val, bool staticMem=false)
Definition: tinyxml2.cpp:868
tinyxml2::XMLUtil::ToDouble
static bool ToDouble(const char *str, double *value)
Definition: tinyxml2.cpp:676
tinyxml2::XMLDocument::_errorLineNum
int _errorLineNum
Definition: tinyxml2.h:1943
tinyxml2::XMLNode::_next
XMLNode * _next
Definition: tinyxml2.h:966
tinyxml2::XMLNode::LastChildElement
const XMLElement * LastChildElement(const char *name=0) const
Definition: tinyxml2.cpp:1049
tinyxml2::NUM_ENTITIES
static const int NUM_ENTITIES
Definition: tinyxml2.cpp:147
TIXML_VSNPRINTF
#define TIXML_VSNPRINTF
Definition: tinyxml2.cpp:93
tinyxml2::XMLNode
Definition: tinyxml2.h:671
tinyxml2::MemPool::Free
virtual void Free(void *)=0
tinyxml2::XMLAttribute::_memPool
MemPool * _memPool
Definition: tinyxml2.h:1259
tinyxml2::Entity::value
char value
Definition: tinyxml2.cpp:144
tinyxml2::XMLAttribute::SetName
void SetName(const char *name)
Definition: tinyxml2.cpp:1483
tinyxml2::XMLPrinter::Print
virtual void Print(const char *format,...)
Definition: tinyxml2.cpp:2620
tinyxml2::XMLDocument::Parse
void Parse()
Definition: tinyxml2.cpp:2562
tinyxml2::DynArray::Push
void Push(T t)
Definition: tinyxml2.h:223
tinyxml2::XMLElement::BoolAttribute
bool BoolAttribute(const char *name, bool defaultValue=false) const
See IntAttribute()
Definition: tinyxml2.cpp:1680
tinyxml2::XMLComment::ShallowClone
virtual XMLNode * ShallowClone(XMLDocument *document) const override
Definition: tinyxml2.cpp:1322
tinyxml2::XMLUtil::IsWhiteSpace
static bool IsWhiteSpace(char p)
Definition: tinyxml2.h:569
tinyxml2::XMLPrinter::PushUnknown
void PushUnknown(const char *value)
Definition: tinyxml2.cpp:2962
TIXML_FTELL
#define TIXML_FTELL
Definition: tinyxml2.cpp:119
tinyxml2::StrPair::NEEDS_DELETE
@ NEEDS_DELETE
Definition: tinyxml2.h:185
tinyxml2::XMLNode::ToText
virtual XMLText * ToText()
Safely cast to Text, or null.
Definition: tinyxml2.h:693
tinyxml2::XMLElement::QueryIntAttribute
XMLError QueryIntAttribute(const char *name, int *value) const
Definition: tinyxml2.h:1346
tinyxml2::PEDANTIC_WHITESPACE
@ PEDANTIC_WHITESPACE
Definition: tinyxml2.h:1711
tinyxml2::XMLUtil::StringEqual
static bool StringEqual(const char *p, const char *q, int nChar=INT_MAX)
Definition: tinyxml2.h:596
tinyxml2::StrPair::NEEDS_FLUSH
@ NEEDS_FLUSH
Definition: tinyxml2.h:184
tinyxml2::XMLPrinter::XMLPrinter
XMLPrinter(FILE *file=0, bool compact=false, int depth=0)
Definition: tinyxml2.cpp:2592
tinyxml2::XMLElement::Unsigned64Text
uint64_t Unsigned64Text(uint64_t defaultValue=0) const
See QueryIntText()
Definition: tinyxml2.cpp:1896
tinyxml2::XMLUtil::ToInt64
static bool ToInt64(const char *str, int64_t *value)
Definition: tinyxml2.cpp:685
tinyxml2::XML_CAN_NOT_CONVERT_TEXT
@ XML_CAN_NOT_CONVERT_TEXT
Definition: tinyxml2.h:537
tinyxml2::XMLDocument
Definition: tinyxml2.h:1720
tinyxml2::XMLText::ShallowClone
virtual XMLNode * ShallowClone(XMLDocument *document) const override
Definition: tinyxml2.cpp:1273
tinyxml2::StrPair::~StrPair
~StrPair()
Definition: tinyxml2.cpp:157
tinyxml2::XML_ELEMENT_DEPTH_EXCEEDED
@ XML_ELEMENT_DEPTH_EXCEEDED
Definition: tinyxml2.h:539
tinyxml2
Definition: tinyxml2.cpp:138
tinyxml2::XMLAttribute::~XMLAttribute
virtual ~XMLAttribute()
Definition: tinyxml2.h:1247
tinyxml2::XMLNode::ToComment
virtual XMLComment * ToComment()
Safely cast to a Comment, or null.
Definition: tinyxml2.h:697
tinyxml2::XMLUtil::SetBoolSerialization
static void SetBoolSerialization(const char *writeTrue, const char *writeFalse)
Definition: tinyxml2.cpp:394
TIXML_SNPRINTF
#define TIXML_SNPRINTF
Definition: tinyxml2.cpp:92
tinyxml2::XMLVisitor::VisitEnter
virtual bool VisitEnter(const XMLDocument &)
Visit a document.
Definition: tinyxml2.h:484
tinyxml2::XMLAttribute::Name
const char * Name() const
The name of the attribute.
Definition: tinyxml2.cpp:1445
tinyxml2::XMLPrinter::Visit
virtual bool Visit(const XMLText &text) override
Visit a text node.
Definition: tinyxml2.cpp:3005
tinyxml2::XMLNode::_document
XMLDocument * _document
Definition: tinyxml2.h:957
tinyxml2::entities
static const Entity entities[NUM_ENTITIES]
Definition: tinyxml2.cpp:148
tinyxml2::XMLElement::QueryFloatText
XMLError QueryFloatText(float *fval) const
See QueryIntText()
Definition: tinyxml2.cpp:1863
tinyxml2::XMLNode::ChildElementCount
int ChildElementCount() const
Definition: tinyxml2.cpp:847
tinyxml2::XMLDocument::_commentPool
MemPoolT< sizeof(XMLComment) > _commentPool
Definition: tinyxml2.h:1958
tinyxml2::StrPair::NEEDS_ENTITY_PROCESSING
@ NEEDS_ENTITY_PROCESSING
Definition: tinyxml2.h:137
tinyxml2::XMLNode::ToDocument
virtual XMLDocument * ToDocument()
Safely cast to a Document, or null.
Definition: tinyxml2.h:701
LINE_FEED
static const char LINE_FEED
Definition: tinyxml2.cpp:123
tinyxml2::XMLUtil::SkipWhiteSpace
static const char * SkipWhiteSpace(const char *p, int *curLineNumPtr)
Definition: tinyxml2.h:551
tinyxml2.h
tinyxml2::XMLPrinter::SealElementIfJustOpened
void SealElementIfJustOpened()
Definition: tinyxml2.cpp:2860
tinyxml2::XML_ERROR_MISMATCHED_ELEMENT
@ XML_ERROR_MISMATCHED_ELEMENT
Definition: tinyxml2.h:535
tinyxml2::XMLNode::InsertEndChild
XMLNode * InsertEndChild(XMLNode *addThis)
Definition: tinyxml2.cpp:938
tinyxml2::XMLDocument::NewText
XMLText * NewText(const char *text)
Definition: tinyxml2.cpp:2300
tinyxml2::StrPair::CollapseWhitespace
void CollapseWhitespace()
Definition: tinyxml2.cpp:257
tinyxml2::XMLDocument::DeleteNode
void DeleteNode(XMLNode *node)
Definition: tinyxml2.cpp:2339
tinyxml2::XMLUtil::IsNameChar
static bool IsNameChar(unsigned char ch)
Definition: tinyxml2.h:584
tinyxml2::XMLDocument::_errorNames
static const char * _errorNames[XML_ERROR_COUNT]
Definition: tinyxml2.h:1960
tinyxml2::XMLDocument::_errorStr
StrPair _errorStr
Definition: tinyxml2.h:1942
tinyxml2::XMLElement::InsertNewComment
XMLComment * InsertNewComment(const char *comment)
See InsertNewChildElement()
Definition: tinyxml2.cpp:2058
tinyxml2::XML_ERROR_COUNT
@ XML_ERROR_COUNT
Definition: tinyxml2.h:541
tinyxml2::XMLDocument::PushDepth
void PushDepth()
Definition: tinyxml2.cpp:2578
tinyxml2::XMLVisitor::Visit
virtual bool Visit(const XMLDeclaration &)
Visit a declaration.
Definition: tinyxml2.h:502
tinyxml2::Entity
Definition: tinyxml2.cpp:141
lexyd::flag
constexpr auto flag(Rule)
Definition: flags.hpp:127
tinyxml2::XMLPrinter::PushHeader
void PushHeader(bool writeBOM, bool writeDeclaration)
Definition: tinyxml2.cpp:2731
tinyxml2::XMLDocument::_parsingDepth
int _parsingDepth
Definition: tinyxml2.h:1946
tinyxml2::XMLDocument::NewDeclaration
XMLDeclaration * NewDeclaration(const char *text=0)
Definition: tinyxml2.cpp:2308
tinyxml2::XMLElement::ParseDeep
char * ParseDeep(char *p, StrPair *parentEndTag, int *curLineNumPtr) override
Definition: tinyxml2.cpp:2088
tinyxml2::XMLElement::ShallowClone
virtual XMLNode * ShallowClone(XMLDocument *document) const override
Definition: tinyxml2.cpp:2117
tinyxml2::XMLElement::QueryFloatAttribute
XMLError QueryFloatAttribute(const char *name, float *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1398
tinyxml2::XML_ERROR_PARSING
@ XML_ERROR_PARSING
Definition: tinyxml2.h:536
lexyd::p
constexpr auto p
Parses the production.
Definition: production.hpp:127
tinyxml2::XMLElement::DoubleText
double DoubleText(double defaultValue=0) const
See QueryIntText()
Definition: tinyxml2.cpp:1910
tinyxml2::XMLNode::ParseDeep
virtual char * ParseDeep(char *p, StrPair *parentEndTag, int *curLineNumPtr)
Definition: tinyxml2.cpp:1085
tinyxml2::XMLPrinter::_restrictedEntityFlag
bool _restrictedEntityFlag[ENTITY_RANGE]
Definition: tinyxml2.h:2368
tinyxml2::XML_ERROR_EMPTY_DOCUMENT
@ XML_ERROR_EMPTY_DOCUMENT
Definition: tinyxml2.h:534
tinyxml2::XMLElement::QueryUnsignedText
XMLError QueryUnsignedText(unsigned *uval) const
See QueryIntText()
Definition: tinyxml2.cpp:1798
tinyxml2::XMLDocument::_textPool
MemPoolT< sizeof(XMLText) > _textPool
Definition: tinyxml2.h:1957
tinyxml2::XMLPrinter::_depth
int _depth
Definition: tinyxml2.h:2358
tinyxml2::XMLDocument::DepthTracker
Definition: tinyxml2.h:1969
tinyxml2::XMLDocument::NewComment
XMLComment * NewComment(const char *comment)
Definition: tinyxml2.cpp:2292
tinyxml2::StrPair::_end
char * _end
Definition: tinyxml2.h:190
tinyxml2::XMLPrinter::VisitEnter
virtual bool VisitEnter(const XMLDocument &) override
Visit a document.
Definition: tinyxml2.cpp:2972
tinyxml2::XMLPrinter::PushText
void PushText(const char *text, bool cdata=false)
Add a text node.
Definition: tinyxml2.cpp:2870
tinyxml2::XMLAttribute::QueryIntValue
XMLError QueryIntValue(int *value) const
Definition: tinyxml2.cpp:1489
tinyxml2::XMLDeclaration::Accept
virtual bool Accept(XMLVisitor *visitor) const override
Definition: tinyxml2.cpp:1390
tinyxml2::XMLNode::FirstChildElement
const XMLElement * FirstChildElement(const char *name=0) const
Definition: tinyxml2.cpp:1037
tinyxml2::XMLAttribute::Next
const XMLAttribute * Next() const
The next attribute in the list.
Definition: tinyxml2.h:1157
tinyxml2::XMLElement::OPEN
@ OPEN
Definition: tinyxml2.h:1675
tinyxml2::XMLPrinter::_elementJustOpened
bool _elementJustOpened
Definition: tinyxml2.h:2345
tinyxml2::Entity::pattern
const char * pattern
Definition: tinyxml2.cpp:142
tinyxml2::XMLElement::FloatAttribute
float FloatAttribute(const char *name, float defaultValue=0) const
See IntAttribute()
Definition: tinyxml2.cpp:1694
tinyxml2::StrPair
Definition: tinyxml2.h:133
tinyxml2::XMLElement::Name
const char * Name() const
Get the name of an element (which is the Value() of the node.)
Definition: tinyxml2.h:1272
tinyxml2::XMLElement::SetText
void SetText(const char *inText)
Definition: tinyxml2.cpp:1720


behaviortree_cpp_v4
Author(s): Davide Faconti
autogenerated on Fri Dec 13 2024 03:19:17