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


sick_safevisionary_base
Author(s):
autogenerated on Sat Oct 21 2023 02:24:26