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


behaviortree_cpp_v4
Author(s): Davide Faconti
autogenerated on Fri Jun 28 2024 02:20:08