DD4hep  1.30.0
Detector Description Toolkit for High Energy Physics
tinyxmlparser_inl.h
Go to the documentation of this file.
1 #ifndef DDCORE_SRC_XML_TINYXMLPARSER_INL_H
2 #define DDCORE_SRC_XML_TINYXMLPARSER_INL_H
3 
4 /*
5  www.sourceforge.net/projects/tinyxml
6  Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
7 
8  This software is provided 'as-is', without any express or implied
9  warranty. In no event will the authors be held liable for any
10  damages arising from the use of this software.
11 
12  Permission is granted to anyone to use this software for any
13  purpose, including commercial applications, and to alter it and
14  redistribute it freely, subject to the following restrictions:
15 
16  1. The origin of this software must not be misrepresented; you must
17  not claim that you wrote the original software. If you use this
18  software in a product, an acknowledgment in the product documentation
19  would be appreciated but is not required.
20 
21  2. Altered source versions must be plainly marked as such, and
22  must not be misrepresented as being the original software.
23 
24  3. This notice may not be removed or altered from any source
25  distribution.
26 
27  F.Gaede, DESY : changed extension to .cc for use with marlin
28  and include from "marlin/tinyxml.h"
29 
30 */
31 
32 #include <ctype.h>
33 #include <stddef.h>
34 
35 #include <XML/tinyxml.h>
36 
37 //#define DEBUG_PARSER
38 #if defined( DEBUG_PARSER )
39 # if defined( DEBUG ) && defined( _MSC_VER )
40 # include <windows.h>
41 # define TIXML_LOG OutputDebugString
42 # else
43 # define TIXML_LOG printf
44 # endif
45 #endif
46 
47 // fallthrough only exists from c++17
48 #if defined __has_cpp_attribute
49  #if __has_cpp_attribute(fallthrough)
50  #define ATTR_FALLTHROUGH [[fallthrough]]
51  #else
52  #define ATTR_FALLTHROUGH
53  #endif
54 #else
55  #define ATTR_FALLTHROUGH
56 #endif
57 
58 
59 // Note tha "PutString" hardcodes the same list. This
60 // is less flexible than it appears. Changing the entries
61 // or order will break putstring.
63  {
64  //FIXME: workaround for processor conditions of type &&
65  //needs to be tested if there are no adverse effects due to this change!!
66  { "&", 1, '&' },
67  //{ "&amp;", 5, '&' },
68 
69  { "&lt;", 4, '<' },
70  { "&gt;", 4, '>' },
71  { "&quot;", 6, '\"' },
72  { "&apos;", 6, '\'' }
73  };
74 
75 // Bunch of unicode info at:
76 // http://www.unicode.org/faq/utf_bom.html
77 // Including the basic of this table, which determines the #bytes in the
78 // sequence from the lead byte. 1 placed for invalid sequences --
79 // although the result will be junk, pass it through as much as possible.
80 // Beware of the non-characters in UTF-8:
81 // ef bb bf (Microsoft "lead bytes")
82 // ef bf be
83 // ef bf bf
84 
85 const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
86 const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
87 const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
88 
89 const int TiXmlBase::utf8ByteTable[256] =
90  {
91  // 0 1 2 3 4 5 6 7 8 9 a b c d e f
92  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00
93  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10
94  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20
95  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30
96  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40
97  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50
98  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60
99  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range
100  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid
101  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90
102  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0
103  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0
104  1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte
105  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0
106  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte
107  4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid
108  };
109 
110 
111 void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length )
112 {
113  const unsigned long BYTE_MASK = 0xBF;
114  const unsigned long BYTE_MARK = 0x80;
115  const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
116 
117  if (input < 0x80)
118  *length = 1;
119  else if ( input < 0x800 )
120  *length = 2;
121  else if ( input < 0x10000 )
122  *length = 3;
123  else if ( input < 0x200000 )
124  *length = 4;
125  else
126  { *length = 0; return; } // This code won't covert this correctly anyway.
127 
128  output += *length;
129 
130  // Scary scary fall throughs.
131  switch (*length)
132  {
133  case 4:
134  --output;
135  *output = (char)((input | BYTE_MARK) & BYTE_MASK);
136  input >>= 6;
138  case 3:
139  --output;
140  *output = (char)((input | BYTE_MARK) & BYTE_MASK);
141  input >>= 6;
143  case 2:
144  --output;
145  *output = (char)((input | BYTE_MARK) & BYTE_MASK);
146  input >>= 6;
148  case 1:
149  --output;
150  *output = (char)(input | FIRST_BYTE_MARK[*length]);
152  default:
153  break;
154  }
155 }
156 
157 
158 /*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding /*encoding*/ )
159 {
160  // This will only work for low-ascii, everything else is assumed to be a valid
161  // letter. I'm not sure this is the best approach, but it is quite tricky trying
162  // to figure out alhabetical vs. not across encoding. So take a very
163  // conservative approach.
164 
165  // if ( encoding == TIXML_ENCODING_UTF8 )
166  // {
167  if ( anyByte < 127 )
168  return isalpha( anyByte );
169  else
170  return 1; // What else to do? The unicode set is huge...get the english ones right.
171  // }
172  // else
173  // {
174  // return isalpha( anyByte );
175  // }
176 }
177 
178 
179 /*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding /*encoding*/ )
180 {
181  // This will only work for low-ascii, everything else is assumed to be a valid
182  // letter. I'm not sure this is the best approach, but it is quite tricky trying
183  // to figure out alhabetical vs. not across encoding. So take a very
184  // conservative approach.
185 
186  // if ( encoding == TIXML_ENCODING_UTF8 )
187  // {
188  if ( anyByte < 127 )
189  return isalnum( anyByte );
190  else
191  return 1; // What else to do? The unicode set is huge...get the english ones right.
192  // }
193  // else
194  // {
195  // return isalnum( anyByte );
196  // }
197 }
198 
199 
201 {
202  friend class TiXmlDocument;
203 public:
204  void Stamp( const char* now, TiXmlEncoding encoding );
205 
206  const TiXmlCursor& Cursor() { return cursor; }
207 
208 private:
209  // Only used by the document!
210  TiXmlParsingData( const char* start, int _tabsize, int row, int col )
211  {
212  assert( start );
213  stamp = start;
214  tabsize = _tabsize;
215  cursor.row = row;
216  cursor.col = col;
217  }
218 
220  const char* stamp;
221  int tabsize;
222 };
223 
224 
225 void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding )
226 {
227  assert( now );
228 
229  // Do nothing if the tabsize is 0.
230  if ( tabsize < 1 )
231  {
232  return;
233  }
234 
235  // Get the current row, column.
236  int row = cursor.row;
237  int col = cursor.col;
238  const char* p = stamp;
239  assert( p );
240 
241  while ( p < now )
242  {
243  // Treat p as unsigned, so we have a happy compiler.
244  const unsigned char* pU = (const unsigned char*)p;
245 
246  // Code contributed by Fletcher Dunn: (modified by lee)
247  switch (*pU) {
248  case 0:
249  // We *should* never get here, but in case we do, don't
250  // advance past the terminating null character, ever
251  return;
252 
253  case '\r':
254  // bump down to the next line
255  ++row;
256  col = 0;
257  // Eat the character
258  ++p;
259 
260  // Check for \r\n sequence, and treat this as a single character
261  if (*p == '\n') {
262  ++p;
263  }
264  break;
265 
266  case '\n':
267  // bump down to the next line
268  ++row;
269  col = 0;
270 
271  // Eat the character
272  ++p;
273 
274  // Check for \n\r sequence, and treat this as a single
275  // character. (Yes, this bizarre thing does occur still
276  // on some arcane platforms...)
277  if (*p == '\r') {
278  ++p;
279  }
280  break;
281 
282  case '\t':
283  // Eat the character
284  ++p;
285 
286  // Skip to next tab stop
287  col = (col / tabsize + 1) * tabsize;
288  break;
289 
290  case TIXML_UTF_LEAD_0:
291  if ( encoding == TIXML_ENCODING_UTF8 )
292  {
293  if ( *(p+1) && *(p+2) )
294  {
295  // In these cases, don't advance the column. These are
296  // 0-width spaces.
297  if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 )
298  p += 3;
299  else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU )
300  p += 3;
301  else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU )
302  p += 3;
303  else
304  { p +=3; ++col; } // A normal character.
305  }
306  }
307  else
308  {
309  ++p;
310  ++col;
311  }
312  break;
313 
314  default:
315  if ( encoding == TIXML_ENCODING_UTF8 )
316  {
317  // Eat the 1 to 4 byte utf8 character.
318  int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)];
319  if ( step == 0 )
320  step = 1; // Error case from bad encoding, but handle gracefully.
321  p += step;
322 
323  // Just advance one column, of course.
324  ++col;
325  }
326  else
327  {
328  ++p;
329  ++col;
330  }
331  break;
332  }
333  }
334  cursor.row = row;
335  cursor.col = col;
336  assert( cursor.row >= -1 );
337  assert( cursor.col >= -1 );
338  stamp = p;
339  assert( stamp );
340 }
341 
342 
343 const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding )
344 {
345  if ( !p || !*p )
346  {
347  return 0;
348  }
349  if ( encoding == TIXML_ENCODING_UTF8 )
350  {
351  while ( *p )
352  {
353  const unsigned char* pU = (const unsigned char*)p;
354 
355  // Skip the stupid Microsoft UTF-8 Byte order marks
356  if ( *(pU+0)==TIXML_UTF_LEAD_0
357  && *(pU+1)==TIXML_UTF_LEAD_1
358  && *(pU+2)==TIXML_UTF_LEAD_2 )
359  {
360  p += 3;
361  continue;
362  }
363  else if(*(pU+0)==TIXML_UTF_LEAD_0
364  && *(pU+1)==0xbfU
365  && *(pU+2)==0xbeU )
366  {
367  p += 3;
368  continue;
369  }
370  else if(*(pU+0)==TIXML_UTF_LEAD_0
371  && *(pU+1)==0xbfU
372  && *(pU+2)==0xbfU )
373  {
374  p += 3;
375  continue;
376  }
377 
378  if ( IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) // Still using old rules for white space.
379  ++p;
380  else
381  break;
382  }
383  }
384  else
385  {
386  while ( ( *p && IsWhiteSpace( *p ) ) || *p == '\n' || *p =='\r' )
387  ++p;
388  }
389 
390  return p;
391 }
392 
393 #ifdef TIXML_USE_STL
394 /*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream * in, TIXML_STRING * tag )
395 {
396  for( ;; )
397  {
398  if ( !in->good() ) return false;
399 
400  int c = in->peek();
401  // At this scope, we can't get to a document. So fail silently.
402  if ( !IsWhiteSpace( c ) || c <= 0 )
403  return true;
404 
405  *tag += (char) in->get();
406  }
407 }
408 
409 /*static*/ bool TiXmlBase::StreamTo( std::istream * in, int character, TIXML_STRING * tag )
410 {
411  //assert( character > 0 && character < 128 ); // else it won't work in utf-8
412  while ( in->good() )
413  {
414  int c = in->peek();
415  if ( c == character )
416  return true;
417  if ( c <= 0 ) // Silent failure: can't get document at this scope
418  return false;
419 
420  in->get();
421  *tag += (char) c;
422  }
423  return false;
424 }
425 #endif
426 
427 // One of TinyXML's more performance demanding functions. Try to keep the memory overhead down. The
428 // "assign" optimization removes over 10% of the execution time.
429 //
430 const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding )
431 {
432  // Oddly, not supported on some comilers,
433  //name->clear();
434  // So use this:
435  *name = "";
436  assert( p );
437 
438  // Names start with letters or underscores.
439  // Of course, in unicode, tinyxml has no idea what a letter *is*. The
440  // algorithm is generous.
441  //
442  // After that, they can be letters, underscores, numbers,
443  // hyphens, or colons. (Colons are valid ony for namespaces,
444  // but tinyxml can't tell namespaces from names.)
445  if ( p && *p
446  && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) )
447  {
448  const char* start = p;
449  while( p && *p
450  && ( IsAlphaNum( (unsigned char ) *p, encoding )
451  || *p == '_'
452  || *p == '-'
453  || *p == '.'
454  || *p == ':' ) )
455  {
456  //(*name) += *p; // expensive
457  ++p;
458  }
459  if ( p-start > 0 ) {
460  name->assign( start, p-start );
461  }
462  return p;
463  }
464  return 0;
465 }
466 
467 const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding )
468 {
469  // Presume an entity, and pull it out.
470  TIXML_STRING ent;
471  int i;
472  *length = 0;
473 
474  if ( *(p+1) && *(p+1) == '#' && *(p+2) )
475  {
476  unsigned long ucs = 0;
477  ptrdiff_t delta = 0;
478  unsigned mult = 1;
479 
480  if ( *(p+2) == 'x' )
481  {
482  // Hexadecimal.
483  if ( !*(p+3) ) return 0;
484 
485  const char* q = p+3;
486  q = strchr( q, ';' );
487 
488  if ( !q || !*q ) return 0;
489 
490  delta = q-p;
491  --q;
492 
493  while ( *q != 'x' )
494  {
495  if ( *q >= '0' && *q <= '9' )
496  ucs += mult * (*q - '0');
497  else if ( *q >= 'a' && *q <= 'f' )
498  ucs += mult * (*q - 'a' + 10);
499  else if ( *q >= 'A' && *q <= 'F' )
500  ucs += mult * (*q - 'A' + 10 );
501  else
502  return 0;
503  mult *= 16;
504  --q;
505  }
506  }
507  else
508  {
509  // Decimal.
510  if ( !*(p+2) ) return 0;
511 
512  const char* q = p+2;
513  q = strchr( q, ';' );
514 
515  if ( !q || !*q ) return 0;
516 
517  delta = q-p;
518  --q;
519 
520  while ( *q != '#' )
521  {
522  if ( *q >= '0' && *q <= '9' )
523  ucs += mult * (*q - '0');
524  else
525  return 0;
526  mult *= 10;
527  --q;
528  }
529  }
530  if ( encoding == TIXML_ENCODING_UTF8 )
531  {
532  // convert the UCS to UTF-8
533  ConvertUTF32ToUTF8( ucs, value, length );
534  }
535  else
536  {
537  *value = (char)ucs;
538  *length = 1;
539  }
540  return p + delta + 1;
541  }
542 
543  // Now try to match it.
544  for( i=0; i<NUM_ENTITY; ++i )
545  {
546  if ( strncmp( entity[i].str, p, entity[i].strLength ) == 0 )
547  {
548  assert( strlen( entity[i].str ) == entity[i].strLength );
549  *value = entity[i].chr;
550  *length = 1;
551  return ( p + entity[i].strLength );
552  }
553  }
554 
555  // So it wasn't an entity, its unrecognized, or something like that.
556  *value = *p; // Don't put back the last one, since we return it!
557  //*length = 1; // Leave unrecognized entities - this doesn't really work.
558  // Just writes strange XML.
559  return p+1;
560 }
561 
562 
563 bool TiXmlBase::StringEqual( const char* p,
564  const char* tag,
565  bool ignoreCase,
566  TiXmlEncoding encoding )
567 {
568  assert( p );
569  assert( tag );
570  if ( !p || !*p )
571  {
572  assert( 0 );
573  return false;
574  }
575 
576  const char* q = p;
577 
578  if ( ignoreCase )
579  {
580  while ( *q && *tag && ToLower( *q, encoding ) == ToLower( *tag, encoding ) )
581  {
582  ++q;
583  ++tag;
584  }
585 
586  if ( *tag == 0 )
587  return true;
588  }
589  else
590  {
591  while ( *q && *tag && *q == *tag )
592  {
593  ++q;
594  ++tag;
595  }
596 
597  if ( *tag == 0 ) // Have we found the end of the tag, and everything equal?
598  return true;
599  }
600  return false;
601 }
602 
603 const char* TiXmlBase::ReadText( const char* p,
604  TIXML_STRING * text,
605  bool trimWhiteSpace,
606  const char* endTag,
607  bool caseInsensitive,
608  TiXmlEncoding encoding )
609 {
610  *text = "";
611  if ( !trimWhiteSpace // certain tags always keep whitespace
612  || !condenseWhiteSpace ) // if true, whitespace is always kept
613  {
614  // Keep all the white space.
615  while ( p && *p
616  && !StringEqual( p, endTag, caseInsensitive, encoding )
617  )
618  {
619  int len;
620  char cArr[4] = { 0, 0, 0, 0 };
621  p = GetChar( p, cArr, &len, encoding );
622  text->append( cArr, len );
623  }
624  }
625  else
626  {
627  bool whitespace = false;
628 
629  // Remove leading white space:
630  p = SkipWhiteSpace( p, encoding );
631  while ( p && *p
632  && !StringEqual( p, endTag, caseInsensitive, encoding ) )
633  {
634  if ( *p == '\r' || *p == '\n' )
635  {
636  whitespace = true;
637  ++p;
638  }
639  else if ( IsWhiteSpace( *p ) )
640  {
641  whitespace = true;
642  ++p;
643  }
644  else
645  {
646  // If we've found whitespace, add it before the
647  // new character. Any whitespace just becomes a space.
648  if ( whitespace )
649  {
650  (*text) += ' ';
651  whitespace = false;
652  }
653  int len;
654  char cArr[4] = { 0, 0, 0, 0 };
655  p = GetChar( p, cArr, &len, encoding );
656  if ( len == 1 )
657  (*text) += cArr[0]; // more efficient
658  else
659  text->append( cArr, len );
660  }
661  }
662  }
663  if ( p )
664  p += strlen( endTag );
665  return p;
666 }
667 
668 #ifdef TIXML_USE_STL
669 
670 void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag )
671 {
672  // The basic issue with a document is that we don't know what we're
673  // streaming. Read something presumed to be a tag (and hope), then
674  // identify it, and call the appropriate stream method on the tag.
675  //
676  // This "pre-streaming" will never read the closing ">" so the
677  // sub-tag can orient itself.
678 
679  if ( !StreamTo( in, '<', tag ) )
680  {
682  return;
683  }
684 
685  while ( in->good() )
686  {
687  int tagIndex = (int) tag->length();
688  while ( in->good() && in->peek() != '>' )
689  {
690  int c = in->get();
691  if ( c <= 0 )
692  {
694  break;
695  }
696  (*tag) += (char) c;
697  }
698 
699  if ( in->good() )
700  {
701  // We now have something we presume to be a node of
702  // some sort. Identify it, and call the node to
703  // continue streaming.
704  TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING );
705 
706  if ( node )
707  {
708  node->StreamIn( in, tag );
709  bool isElement = node->ToElement() != 0;
710  delete node;
711  node = 0;
712 
713  // If this is the root element, we're done. Parsing will be
714  // done by the >> operator.
715  if ( isElement )
716  {
717  return;
718  }
719  }
720  else
721  {
723  return;
724  }
725  }
726  }
727  // We should have returned sooner.
729 }
730 
731 #endif
732 
733 const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding )
734 {
735  ClearError();
736 
737  // Parse away, at the document level. Since a document
738  // contains nothing but other tags, most of what happens
739  // here is skipping white space.
740  if ( !p || !*p )
741  {
743  return 0;
744  }
745 
746  // Note that, for a document, this needs to come
747  // before the while space skip, so that parsing
748  // starts from the pointer we are given.
749  location.Clear();
750  if ( prevData )
751  {
752  location.row = prevData->cursor.row;
753  location.col = prevData->cursor.col;
754  }
755  else
756  {
757  location.row = 0;
758  location.col = 0;
759  }
761  location = data.Cursor();
762 
763  if ( encoding == TIXML_ENCODING_UNKNOWN )
764  {
765  // Check for the Microsoft UTF-8 lead bytes.
766  const unsigned char* pU = (const unsigned char*)p;
767  if ( *(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0
768  && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1
769  && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 )
770  {
771  encoding = TIXML_ENCODING_UTF8;
772  useMicrosoftBOM = true;
773  }
774  }
775 
776  p = SkipWhiteSpace( p, encoding );
777  if ( !p )
778  {
780  return 0;
781  }
782 
783  while ( p && *p )
784  {
785  TiXmlNode* node = Identify( p, encoding );
786  if ( node )
787  {
788  p = node->Parse( p, &data, encoding );
789  LinkEndChild( node );
790  }
791  else
792  {
793  break;
794  }
795 
796  // Did we get encoding info?
797  if ( encoding == TIXML_ENCODING_UNKNOWN
798  && node->ToDeclaration() )
799  {
800  TiXmlDeclaration* dec = node->ToDeclaration();
801  const char* enc = dec->Encoding();
802  assert( enc );
803 
804  if ( *enc == 0 )
805  encoding = TIXML_ENCODING_UTF8;
806  else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) )
807  encoding = TIXML_ENCODING_UTF8;
808  else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) )
809  encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice
810  else
811  encoding = TIXML_ENCODING_LEGACY;
812  }
813 
814  p = SkipWhiteSpace( p, encoding );
815  }
816 
817  // Was this empty?
818  if ( !firstChild ) {
819  SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding );
820  return 0;
821  }
822 
823  // All is well.
824  return p;
825 }
826 
827 void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding )
828 {
829  // The first error in a chain is more accurate - don't set again!
830  if ( error )
831  return;
832 
833  assert( err > 0 && err < TIXML_ERROR_STRING_COUNT );
834  error = true;
835  errorId = err;
837 
839  if ( pError && data )
840  {
841  data->Stamp( pError, encoding );
842  errorLocation = data->Cursor();
843  }
844 }
845 
846 
847 TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding )
848 {
849  TiXmlNode* returnNode = 0;
850 
851  p = SkipWhiteSpace( p, encoding );
852  if( !p || !*p || *p != '<' )
853  {
854  return 0;
855  }
856 
857  TiXmlDocument* doc = GetDocument();
858  p = SkipWhiteSpace( p, encoding );
859 
860  if ( !p || !*p )
861  {
862  return 0;
863  }
864 
865  // What is this thing?
866  // - Elements start with a letter or underscore, but xml is reserved.
867  // - Comments: <!--
868  // - Decleration: <?xml
869  // - Everthing else is unknown to tinyxml.
870  //
871 
872  const char* xmlHeader = { "<?xml" };
873  const char* commentHeader = { "<!--" };
874  const char* dtdHeader = { "<!" };
875  const char* cdataHeader = { "<![CDATA[" };
876 
877  if ( StringEqual( p, xmlHeader, true, encoding ) )
878  {
879 #ifdef DEBUG_PARSER
880  TIXML_LOG( "XML parsing Declaration\n" );
881 #endif
882  returnNode = new TiXmlDeclaration();
883  }
884  else if ( StringEqual( p, commentHeader, false, encoding ) )
885  {
886 #ifdef DEBUG_PARSER
887  TIXML_LOG( "XML parsing Comment\n" );
888 #endif
889  returnNode = new TiXmlComment();
890  }
891  else if ( StringEqual( p, cdataHeader, false, encoding ) )
892  {
893 #ifdef DEBUG_PARSER
894  TIXML_LOG( "XML parsing CDATA\n" );
895 #endif
896  TiXmlText* text = new TiXmlText( "" );
897  text->SetCDATA( true );
898  returnNode = text;
899  }
900  else if ( StringEqual( p, dtdHeader, false, encoding ) )
901  {
902 #ifdef DEBUG_PARSER
903  TIXML_LOG( "XML parsing Unknown(1)\n" );
904 #endif
905  returnNode = new TiXmlUnknown();
906  }
907  else if ( IsAlpha( *(p+1), encoding )
908  || *(p+1) == '_' )
909  {
910 #ifdef DEBUG_PARSER
911  TIXML_LOG( "XML parsing Element\n" );
912 #endif
913  returnNode = new TiXmlElement( "" );
914  }
915  else
916  {
917 #ifdef DEBUG_PARSER
918  TIXML_LOG( "XML parsing Unknown(2)\n" );
919 #endif
920  returnNode = new TiXmlUnknown();
921  }
922 
923  if ( returnNode )
924  {
925  // Set the parent, so it can report errors
926  returnNode->parent = this;
927  }
928  else
929  {
930  if ( doc )
932  }
933  return returnNode;
934 }
935 
936 #ifdef TIXML_USE_STL
937 
938 void TiXmlElement::StreamIn (std::istream * in, TIXML_STRING * tag)
939 {
940  // We're called with some amount of pre-parsing. That is, some of "this"
941  // element is in "tag". Go ahead and stream to the closing ">"
942  while( in->good() )
943  {
944  int c = in->get();
945  if ( c <= 0 )
946  {
947  TiXmlDocument* document = GetDocument();
948  if ( document )
950  return;
951  }
952  (*tag) += (char) c ;
953 
954  if ( c == '>' )
955  break;
956  }
957 
958  if ( tag->length() < 3 ) return;
959 
960  // Okay...if we are a "/>" tag, then we're done. We've read a complete tag.
961  // If not, identify and stream.
962 
963  if ( tag->at( tag->length() - 1 ) == '>'
964  && tag->at( tag->length() - 2 ) == '/' )
965  {
966  // All good!
967  return;
968  }
969  else if ( tag->at( tag->length() - 1 ) == '>' )
970  {
971  // There is more. Could be:
972  // text
973  // cdata text (which looks like another node)
974  // closing tag
975  // another node.
976  for ( ;; )
977  {
978  StreamWhiteSpace( in, tag );
979 
980  // Do we have text?
981  if ( in->good() && in->peek() != '<' )
982  {
983  // Yep, text.
984  TiXmlText text( "" );
985  text.StreamIn( in, tag );
986 
987  // What follows text is a closing tag or another node.
988  // Go around again and figure it out.
989  continue;
990  }
991 
992  // We now have either a closing tag...or another node.
993  // We should be at a "<", regardless.
994  if ( !in->good() ) return;
995  assert( in->peek() == '<' );
996  int tagIndex = (int) tag->length();
997 
998  bool closingTag = false;
999  bool firstCharFound = false;
1000 
1001  for( ;; )
1002  {
1003  if ( !in->good() )
1004  return;
1005 
1006  int c = in->peek();
1007  if ( c <= 0 )
1008  {
1009  TiXmlDocument* document = GetDocument();
1010  if ( document )
1012  return;
1013  }
1014 
1015  if ( c == '>' )
1016  break;
1017 
1018  *tag += (char) c;
1019  in->get();
1020 
1021  // Early out if we find the CDATA id.
1022  if ( c == '[' && tag->size() >= 9 )
1023  {
1024  size_t len = tag->size();
1025  const char* start = tag->c_str() + len - 9;
1026  if ( strcmp( start, "<![CDATA[" ) == 0 ) {
1027  assert( !closingTag );
1028  break;
1029  }
1030  }
1031 
1032  if ( !firstCharFound && c != '<' && !IsWhiteSpace( c ) )
1033  {
1034  firstCharFound = true;
1035  if ( c == '/' )
1036  closingTag = true;
1037  }
1038  }
1039  // If it was a closing tag, then read in the closing '>' to clean up the input stream.
1040  // If it was not, the streaming will be done by the tag.
1041  if ( closingTag )
1042  {
1043  if ( !in->good() )
1044  return;
1045 
1046  int c = in->get();
1047  if ( c <= 0 )
1048  {
1049  TiXmlDocument* document = GetDocument();
1050  if ( document )
1052  return;
1053  }
1054  assert( c == '>' );
1055  *tag += (char) c;
1056 
1057  // We are done, once we've found our closing tag.
1058  return;
1059  }
1060  else
1061  {
1062  // If not a closing tag, id it, and stream.
1063  const char* tagloc = tag->c_str() + tagIndex;
1064  TiXmlNode* node = Identify( tagloc, TIXML_DEFAULT_ENCODING );
1065  if ( !node )
1066  return;
1067  node->StreamIn( in, tag );
1068  delete node;
1069  node = 0;
1070 
1071  // No return: go around from the beginning: text, closing tag, or node.
1072  }
1073  }
1074  }
1075 }
1076 #endif
1077 
1078 const char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
1079 {
1080  p = SkipWhiteSpace( p, encoding );
1081  TiXmlDocument* document = GetDocument();
1082 
1083  if ( !p || !*p )
1084  {
1085  if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, 0, 0, encoding );
1086  return 0;
1087  }
1088 
1089  if ( data )
1090  {
1091  data->Stamp( p, encoding );
1092  location = data->Cursor();
1093  }
1094 
1095  if ( *p != '<' )
1096  {
1097  if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, p, data, encoding );
1098  return 0;
1099  }
1100 
1101  p = SkipWhiteSpace( p+1, encoding );
1102 
1103  // Read the name.
1104  const char* pErr = p;
1105 
1106  p = ReadName( p, &value, encoding );
1107  if ( !p || !*p )
1108  {
1109  if ( document ) document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, pErr, data, encoding );
1110  return 0;
1111  }
1112 
1113  TIXML_STRING endTag ("</");
1114  endTag += value;
1115  endTag += ">";
1116 
1117  // Check for and read attributes. Also look for an empty
1118  // tag or an end tag.
1119  while ( p && *p )
1120  {
1121  pErr = p;
1122  p = SkipWhiteSpace( p, encoding );
1123  if ( !p || !*p )
1124  {
1125  if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
1126  return 0;
1127  }
1128  if ( *p == '/' )
1129  {
1130  ++p;
1131  // Empty tag.
1132  if ( *p != '>' )
1133  {
1134  if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding );
1135  return 0;
1136  }
1137  return (p+1);
1138  }
1139  else if ( *p == '>' )
1140  {
1141  // Done with attributes (if there were any.)
1142  // Read the value -- which can include other
1143  // elements -- read the end tag, and return.
1144  ++p;
1145  p = ReadValue( p, data, encoding ); // Note this is an Element method, and will set the error if one happens.
1146  if ( !p || !*p )
1147  return 0;
1148 
1149  // We should find the end tag now
1150  if ( StringEqual( p, endTag.c_str(), false, encoding ) )
1151  {
1152  p += endTag.length();
1153  return p;
1154  }
1155  else
1156  {
1157  if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
1158  return 0;
1159  }
1160  }
1161  else
1162  {
1163  // Try to read an attribute:
1164  TiXmlAttribute* attrib = new TiXmlAttribute();
1165  if ( !attrib )
1166  {
1167  if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, pErr, data, encoding );
1168  return 0;
1169  }
1170 
1171  attrib->SetDocument( document );
1172  pErr = p;
1173  p = attrib->Parse( p, data, encoding );
1174 
1175  if ( !p || !*p )
1176  {
1177  if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding );
1178  delete attrib;
1179  return 0;
1180  }
1181 
1182  // Handle_t the strange case of double attributes:
1183 #ifdef TIXML_USE_STL
1184  TiXmlAttribute* node = attributeSet.Find( attrib->NameTStr() );
1185 #else
1186  TiXmlAttribute* node = attributeSet.Find( attrib->Name() );
1187 #endif
1188  if ( node )
1189  {
1190  node->SetValue( attrib->Value() );
1191  delete attrib;
1192  return 0;
1193  }
1194 
1195  attributeSet.Add( attrib );
1196  }
1197  }
1198  return p;
1199 }
1200 
1201 
1202 const char* TiXmlElement::ReadValue( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
1203 {
1204  TiXmlDocument* document = GetDocument();
1205 
1206  // Read in text and elements in any order.
1207  const char* pWithWhiteSpace = p;
1208  p = SkipWhiteSpace( p, encoding );
1209 
1210  while ( p && *p )
1211  {
1212  if ( *p != '<' )
1213  {
1214  // Take what we have, make a text element.
1215  TiXmlText* textNode = new TiXmlText( "" );
1216 
1217  if ( !textNode )
1218  {
1219  if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, encoding );
1220  return 0;
1221  }
1222 
1224  {
1225  p = textNode->Parse( p, data, encoding );
1226  }
1227  else
1228  {
1229  // Special case: we want to keep the white space
1230  // so that leading spaces aren't removed.
1231  p = textNode->Parse( pWithWhiteSpace, data, encoding );
1232  }
1233 
1234  if ( !textNode->Blank() )
1235  LinkEndChild( textNode );
1236  else
1237  delete textNode;
1238  }
1239  else
1240  {
1241  // We hit a '<'
1242  // Have we hit a new element or an end tag? This could also be
1243  // a TiXmlText in the "CDATA" style.
1244  if ( StringEqual( p, "</", false, encoding ) )
1245  {
1246  return p;
1247  }
1248  else
1249  {
1250  TiXmlNode* node = Identify( p, encoding );
1251  if ( node )
1252  {
1253  p = node->Parse( p, data, encoding );
1254  LinkEndChild( node );
1255  }
1256  else
1257  {
1258  return 0;
1259  }
1260  }
1261  }
1262  pWithWhiteSpace = p;
1263  p = SkipWhiteSpace( p, encoding );
1264  }
1265 
1266  if ( !p )
1267  {
1268  if ( document ) document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, 0, 0, encoding );
1269  }
1270  return p;
1271 }
1272 
1273 
1274 #ifdef TIXML_USE_STL
1275 void TiXmlUnknown::StreamIn( std::istream * in, TIXML_STRING * tag )
1276 {
1277  while ( in->good() )
1278  {
1279  int c = in->get();
1280  if ( c <= 0 )
1281  {
1282  TiXmlDocument* document = GetDocument();
1283  if ( document )
1285  return;
1286  }
1287  (*tag) += (char) c;
1288 
1289  if ( c == '>' )
1290  {
1291  // All is well.
1292  return;
1293  }
1294  }
1295 }
1296 #endif
1297 
1298 
1299 const char* TiXmlUnknown::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
1300 {
1301  TiXmlDocument* document = GetDocument();
1302  p = SkipWhiteSpace( p, encoding );
1303 
1304  if ( data )
1305  {
1306  data->Stamp( p, encoding );
1307  location = data->Cursor();
1308  }
1309  if ( !p || !*p || *p != '<' )
1310  {
1311  if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN, p, data, encoding );
1312  return 0;
1313  }
1314  ++p;
1315  value = "";
1316 
1317  while ( p && *p && *p != '>' )
1318  {
1319  value += *p;
1320  ++p;
1321  }
1322 
1323  if ( !p )
1324  {
1325  if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN, 0, 0, encoding );
1326  }
1327  if ( *p == '>' )
1328  return p+1;
1329  return p;
1330 }
1331 
1332 #ifdef TIXML_USE_STL
1333 void TiXmlComment::StreamIn( std::istream * in, TIXML_STRING * tag )
1334 {
1335  while ( in->good() )
1336  {
1337  int c = in->get();
1338  if ( c <= 0 )
1339  {
1340  TiXmlDocument* document = GetDocument();
1341  if ( document )
1343  return;
1344  }
1345 
1346  (*tag) += (char) c;
1347 
1348  if ( c == '>'
1349  && tag->at( tag->length() - 2 ) == '-'
1350  && tag->at( tag->length() - 3 ) == '-' )
1351  {
1352  // All is well.
1353  return;
1354  }
1355  }
1356 }
1357 #endif
1358 
1359 
1360 const char* TiXmlComment::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
1361 {
1362  TiXmlDocument* document = GetDocument();
1363  value = "";
1364 
1365  p = SkipWhiteSpace( p, encoding );
1366 
1367  if ( data )
1368  {
1369  data->Stamp( p, encoding );
1370  location = data->Cursor();
1371  }
1372  const char* startTag = "<!--";
1373  const char* endTag = "-->";
1374 
1375  if ( !StringEqual( p, startTag, false, encoding ) )
1376  {
1377  document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding );
1378  return 0;
1379  }
1380  p += strlen( startTag );
1381  p = ReadText( p, &value, false, endTag, false, encoding );
1382  return p;
1383 }
1384 
1385 
1386 const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
1387 {
1388  p = SkipWhiteSpace( p, encoding );
1389  if ( !p || !*p ) return 0;
1390 
1391  // int tabsize = 4;
1392  // if ( document )
1393  // tabsize = document->TabSize();
1394 
1395  if ( data )
1396  {
1397  data->Stamp( p, encoding );
1398  location = data->Cursor();
1399  }
1400  // Read the name, the '=' and the value.
1401  const char* pErr = p;
1402  p = ReadName( p, &name, encoding );
1403  if ( !p || !*p )
1404  {
1405  if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
1406  return 0;
1407  }
1408  p = SkipWhiteSpace( p, encoding );
1409  if ( !p || !*p || *p != '=' )
1410  {
1411  if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
1412  return 0;
1413  }
1414 
1415  ++p; // skip '='
1416  p = SkipWhiteSpace( p, encoding );
1417  if ( !p || !*p )
1418  {
1419  if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
1420  return 0;
1421  }
1422 
1423  const char* end;
1424  const char SINGLE_QUOTE = '\'';
1425  const char DOUBLE_QUOTE = '\"';
1426 
1427  if ( *p == SINGLE_QUOTE )
1428  {
1429  ++p;
1430  end = "\'"; // single quote in string
1431  p = ReadText( p, &value, false, end, false, encoding );
1432  }
1433  else if ( *p == DOUBLE_QUOTE )
1434  {
1435  ++p;
1436  end = "\""; // double quote in string
1437  p = ReadText( p, &value, false, end, false, encoding );
1438  }
1439  else
1440  {
1441  // All attribute values should be in single or double quotes.
1442  // But this is such a common error that the parser will try
1443  // its best, even without them.
1444  value = "";
1445  while ( p && *p // existence
1446  && !IsWhiteSpace( *p ) && *p != '\n' && *p != '\r' // whitespace
1447  && *p != '/' && *p != '>' ) // tag end
1448  {
1449  if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) {
1450  // [ 1451649 ] Attribute values with trailing quotes not handled correctly
1451  // We did not have an opening quote but seem to have a
1452  // closing one. Give up and throw an error.
1453  if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
1454  return 0;
1455  }
1456  value += *p;
1457  ++p;
1458  }
1459  }
1460  return p;
1461 }
1462 
1463 #ifdef TIXML_USE_STL
1464 void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag )
1465 {
1466  while ( in->good() )
1467  {
1468  int c = in->peek();
1469  if ( !cdata && (c == '<' ) )
1470  {
1471  return;
1472  }
1473  if ( c <= 0 )
1474  {
1475  TiXmlDocument* document = GetDocument();
1476  if ( document )
1478  return;
1479  }
1480 
1481  (*tag) += (char) c;
1482  in->get(); // "commits" the peek made above
1483 
1484  if ( cdata && c == '>' && tag->size() >= 3 ) {
1485  size_t len = tag->size();
1486  if ( (*tag)[len-2] == ']' && (*tag)[len-3] == ']' ) {
1487  // terminator of cdata.
1488  return;
1489  }
1490  }
1491  }
1492 }
1493 #endif
1494 
1495 const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
1496 {
1497  value = "";
1498  TiXmlDocument* document = GetDocument();
1499 
1500  if ( data )
1501  {
1502  data->Stamp( p, encoding );
1503  location = data->Cursor();
1504  }
1505 
1506  const char* const startTag = "<![CDATA[";
1507  const char* const endTag = "]]>";
1508 
1509  if ( cdata || StringEqual( p, startTag, false, encoding ) )
1510  {
1511  cdata = true;
1512 
1513  if ( !StringEqual( p, startTag, false, encoding ) )
1514  {
1515  document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding );
1516  return 0;
1517  }
1518  p += strlen( startTag );
1519 
1520  // Keep all the white space, ignore the encoding, etc.
1521  while ( p && *p
1522  && !StringEqual( p, endTag, false, encoding )
1523  )
1524  {
1525  value += *p;
1526  ++p;
1527  }
1528 
1529  TIXML_STRING dummy;
1530  p = ReadText( p, &dummy, false, endTag, false, encoding );
1531  return p;
1532  }
1533  else
1534  {
1535  bool ignoreWhite = true;
1536 
1537  const char* end = "<";
1538  p = ReadText( p, &value, ignoreWhite, end, false, encoding );
1539  if ( p )
1540  return p-1; // don't truncate the '<'
1541  return 0;
1542  }
1543 }
1544 
1545 #ifdef TIXML_USE_STL
1546 void TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag )
1547 {
1548  while ( in->good() )
1549  {
1550  int c = in->get();
1551  if ( c <= 0 )
1552  {
1553  TiXmlDocument* document = GetDocument();
1554  if ( document )
1556  return;
1557  }
1558  (*tag) += (char) c;
1559 
1560  if ( c == '>' )
1561  {
1562  // All is well.
1563  return;
1564  }
1565  }
1566 }
1567 #endif
1568 
1569 const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding )
1570 {
1571  p = SkipWhiteSpace( p, _encoding );
1572  // Find the beginning, find the end, and look for
1573  // the stuff in-between.
1574  TiXmlDocument* document = GetDocument();
1575  if ( !p || !*p || !StringEqual( p, "<?xml", true, _encoding ) )
1576  {
1577  if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding );
1578  return 0;
1579  }
1580  if ( data )
1581  {
1582  data->Stamp( p, _encoding );
1583  location = data->Cursor();
1584  }
1585  p += 5;
1586 
1587  version = "";
1588  encoding = "";
1589  standalone = "";
1590 
1591  while ( p && *p )
1592  {
1593  if ( *p == '>' )
1594  {
1595  ++p;
1596  return p;
1597  }
1598 
1599  p = SkipWhiteSpace( p, _encoding );
1600  if ( StringEqual( p, "version", true, _encoding ) )
1601  {
1602  TiXmlAttribute attrib;
1603  p = attrib.Parse( p, data, _encoding );
1604  version = attrib.Value();
1605  }
1606  else if ( StringEqual( p, "encoding", true, _encoding ) )
1607  {
1608  TiXmlAttribute attrib;
1609  p = attrib.Parse( p, data, _encoding );
1610  encoding = attrib.Value();
1611  }
1612  else if ( StringEqual( p, "standalone", true, _encoding ) )
1613  {
1614  TiXmlAttribute attrib;
1615  p = attrib.Parse( p, data, _encoding );
1616  standalone = attrib.Value();
1617  }
1618  else
1619  {
1620  // Read over whatever it is.
1621  while( p && *p && *p != '>' && !IsWhiteSpace( *p ) )
1622  ++p;
1623  }
1624  }
1625  return 0;
1626 }
1627 
1628 bool TiXmlText::Blank() const
1629 {
1630  for ( unsigned i=0; i<value.length(); i++ )
1631  if ( !IsWhiteSpace( value[i] ) )
1632  return false;
1633  return true;
1634 }
1635 
1636 
1637 #endif
TiXmlDocument::StreamIn
virtual void StreamIn(std::istream *in, TIXML_STRING *tag) override
TiXmlElement::attributeSet
TiXmlAttributeSet attributeSet
Definition: tinyxml.h:1278
TiXmlBase::ConvertUTF32ToUTF8
static void ConvertUTF32ToUTF8(unsigned long input, char *output, int *length)
Definition: tinyxmlparser_inl.h:111
TiXmlBase::Parse
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding)=0
TiXmlDocument
TinyXML class. See http://www.grinninglizard.com/tinyxml.
Definition: tinyxml.h:1547
TiXmlDocument::TabSize
int TabSize() const
Definition: tinyxml.h:1680
TiXmlBase::IsWhiteSpace
static bool IsWhiteSpace(char c)
Definition: tinyxml.h:314
TiXmlDocument::errorDesc
TIXML_STRING errorDesc
Definition: tinyxml.h:1732
TIXML_ENCODING_UTF8
@ TIXML_ENCODING_UTF8
Definition: tinyxml.h:183
TiXmlBase::TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME
@ TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME
Definition: tinyxml.h:295
TiXmlNode::value
TIXML_STRING value
Definition: tinyxml.h:863
TiXmlComment::StreamIn
virtual void StreamIn(std::istream *in, TIXML_STRING *tag) override
TiXmlText::SetCDATA
void SetCDATA(bool _cdata)
Turns on or off a CDATA representation of text.
Definition: tinyxml.h:1379
TiXmlDeclaration::version
TIXML_STRING version
Definition: tinyxml.h:1488
TiXmlCursor::Clear
void Clear()
Definition: tinyxml.h:109
TiXmlDeclaration::Parse
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding) override
Definition: tinyxmlparser_inl.h:1569
TiXmlBase::GetEntity
static const char * GetEntity(const char *in, char *value, int *length, TiXmlEncoding encoding)
Definition: tinyxmlparser_inl.h:467
TiXmlUnknown::StreamIn
virtual void StreamIn(std::istream *in, TIXML_STRING *tag) override
delta
const Delta * delta
Definition: AlignmentsCalculator.cpp:67
TiXmlDeclaration::encoding
TIXML_STRING encoding
Definition: tinyxml.h:1488
TIXML_ENCODING_UNKNOWN
@ TIXML_ENCODING_UNKNOWN
Definition: tinyxml.h:183
TiXmlBase::Entity
TinyXML class. See http://www.grinninglizard.com/tinyxml.
Definition: tinyxml.h:415
TiXmlDocument::errorId
int errorId
Definition: tinyxml.h:1732
TiXmlNode::ToElement
virtual const TiXmlElement * ToElement() const
Cast to a more defined type. Will return null if not of the requested type.
Definition: tinyxml.h:778
tinyxml.h
TiXmlAttribute::name
TIXML_STRING name
Definition: tinyxml.h:1006
TiXmlDocument::SetError
void SetError(int err, const char *errorLocation, TiXmlParsingData *prevData, TiXmlEncoding encoding)
Definition: tinyxmlparser_inl.h:827
TiXmlBase::StreamTo
static bool StreamTo(std::istream *in, int character, TIXML_STRING *tag)
TiXmlNode::LinkEndChild
TiXmlNode * LinkEndChild(TiXmlNode *addThis)
Definition: tinyxml_inl.h:174
TiXmlText::Blank
bool Blank() const
Definition: tinyxmlparser_inl.h:1628
TiXmlParsingData::TiXmlParsingData
TiXmlParsingData(const char *start, int _tabsize, int row, int col)
Definition: tinyxmlparser_inl.h:210
TiXmlDeclaration::Encoding
const char * Encoding() const
Encoding. Will return an empty string if none was found.
Definition: tinyxml.h:1450
TiXmlNode::TiXmlElement
friend class TiXmlElement
Definition: tinyxml.h:436
TiXmlElement::ReadValue
const char * ReadValue(const char *in, TiXmlParsingData *prevData, TiXmlEncoding encoding)
Definition: tinyxmlparser_inl.h:1202
TiXmlBase::TIXML_ERROR_PARSING_COMMENT
@ TIXML_ERROR_PARSING_COMMENT
Definition: tinyxml.h:301
TiXmlNode::GetDocument
const TiXmlDocument * GetDocument() const
Definition: tinyxml_inl.h:510
TiXmlDocument::Parse
virtual const char * Parse(const char *p, TiXmlParsingData *data=0, TiXmlEncoding encoding=TIXML_DEFAULT_ENCODING) override
Definition: tinyxmlparser_inl.h:733
TiXmlBase::NUM_ENTITY
@ NUM_ENTITY
Definition: tinyxml.h:421
TiXmlAttribute::Value
const char * Value() const
Return the value of this attribute.
Definition: tinyxml.h:912
TiXmlDocument::ClearError
void ClearError()
Definition: tinyxml.h:1687
TiXmlComment
TinyXML class. See http://www.grinninglizard.com/tinyxml.
Definition: tinyxml.h:1283
TiXmlParsingData::Stamp
void Stamp(const char *now, TiXmlEncoding encoding)
Definition: tinyxmlparser_inl.h:225
TiXmlBase::TIXML_ERROR_READING_ATTRIBUTES
@ TIXML_ERROR_READING_ATTRIBUTES
Definition: tinyxml.h:297
TiXmlAttribute::SetValue
void SetValue(const char *_value)
Set the value.
Definition: tinyxml.h:944
TiXmlBase::StringEqual
static bool StringEqual(const char *p, const char *endTag, bool ignoreCase, TiXmlEncoding encoding)
Definition: tinyxmlparser_inl.h:563
TiXmlAttribute::NameTStr
const TIXML_STRING & NameTStr() const
Definition: tinyxml.h:924
TiXmlBase::TIXML_ERROR_PARSING_EMPTY
@ TIXML_ERROR_PARSING_EMPTY
Definition: tinyxml.h:298
TIXML_ENCODING_LEGACY
@ TIXML_ENCODING_LEGACY
Definition: tinyxml.h:183
TiXmlNode::firstChild
TiXmlNode * firstChild
Definition: tinyxml.h:860
TiXmlAttribute
TinyXML class. See http://www.grinninglizard.com/tinyxml.
Definition: tinyxml.h:880
TiXmlAttribute::document
TiXmlDocument * document
Definition: tinyxml.h:1005
TiXmlAttribute::SetDocument
void SetDocument(TiXmlDocument *doc)
Definition: tinyxml.h:997
TiXmlUnknown
TinyXML class. See http://www.grinninglizard.com/tinyxml.
Definition: tinyxml.h:1498
TiXmlBase::IsWhiteSpaceCondensed
static bool IsWhiteSpaceCondensed()
Return the current white space setting.
Definition: tinyxml.h:244
TiXmlComment::Parse
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding) override
Definition: tinyxmlparser_inl.h:1360
TIXML_UTF_LEAD_1
const unsigned char TIXML_UTF_LEAD_1
Definition: tinyxmlparser_inl.h:86
TiXmlBase::TIXML_ERROR_READING_END_TAG
@ TIXML_ERROR_READING_END_TAG
Definition: tinyxml.h:299
TiXmlUnknown::Parse
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding) override
Definition: tinyxmlparser_inl.h:1299
TiXmlDeclaration
TinyXML class. See http://www.grinninglizard.com/tinyxml.
Definition: tinyxml.h:1424
TiXmlParsingData::cursor
TiXmlCursor cursor
Definition: tinyxmlparser_inl.h:219
TiXmlElement::Parse
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding) override
Definition: tinyxmlparser_inl.h:1078
TiXmlBase::StreamWhiteSpace
static bool StreamWhiteSpace(std::istream *in, TIXML_STRING *tag)
TIXML_UTF_LEAD_0
const unsigned char TIXML_UTF_LEAD_0
Definition: tinyxmlparser_inl.h:85
TiXmlBase::TIXML_ERROR_STRING_COUNT
@ TIXML_ERROR_STRING_COUNT
Definition: tinyxml.h:308
TiXmlParsingData
TinyXML class. See http://www.grinninglizard.com/tinyxml.
Definition: tinyxmlparser_inl.h:201
TiXmlNode
TinyXML class. See http://www.grinninglizard.com/tinyxml.
Definition: tinyxml.h:434
TIXML_DEFAULT_ENCODING
const TiXmlEncoding TIXML_DEFAULT_ENCODING
Definition: tinyxml.h:186
TiXmlBase::location
TiXmlCursor location
Definition: tinyxml.h:390
TiXmlBase::entity
static Entity entity[NUM_ENTITY]
Definition: tinyxml.h:424
TiXmlAttributeSet::Find
const TiXmlAttribute * Find(const char *_name) const
Definition: tinyxml_inl.h:1600
TiXmlNode::StreamIn
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)=0
TiXmlBase::TIXML_ERROR_EMBEDDED_NULL
@ TIXML_ERROR_EMBEDDED_NULL
Definition: tinyxml.h:304
TiXmlBase::TIXML_ERROR_PARSING_CDATA
@ TIXML_ERROR_PARSING_CDATA
Definition: tinyxml.h:305
TiXmlText::StreamIn
virtual void StreamIn(std::istream *in, TIXML_STRING *tag) override
TiXmlDocument::error
bool error
Definition: tinyxml.h:1731
TiXmlBase::SkipWhiteSpace
static const char * SkipWhiteSpace(const char *, TiXmlEncoding encoding)
Definition: tinyxmlparser_inl.h:343
TiXmlBase::condenseWhiteSpace
static bool condenseWhiteSpace
Definition: tinyxml.h:425
TiXmlAttribute::Parse
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding) override
Definition: tinyxmlparser_inl.h:1386
TiXmlCursor::col
int col
Definition: tinyxml.h:114
TiXmlBase::TIXML_ERROR_PARSING_DECLARATION
@ TIXML_ERROR_PARSING_DECLARATION
Definition: tinyxml.h:302
TiXmlParsingData::stamp
const char * stamp
Definition: tinyxmlparser_inl.h:220
TiXmlEncoding
TiXmlEncoding
Definition: tinyxml.h:182
TiXmlParsingData::tabsize
int tabsize
Definition: tinyxmlparser_inl.h:221
TiXmlBase::ReadName
static const char * ReadName(const char *p, TIXML_STRING *name, TiXmlEncoding encoding)
Definition: tinyxmlparser_inl.h:430
TIXML_UTF_LEAD_2
const unsigned char TIXML_UTF_LEAD_2
Definition: tinyxmlparser_inl.h:87
TiXmlText::Parse
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding) override
Definition: tinyxmlparser_inl.h:1495
TiXmlBase::Entity::chr
char chr
Definition: tinyxml.h:418
TiXmlCursor
TinyXML class. See http://www.grinninglizard.com/tinyxml.
Definition: tinyxml.h:105
TiXmlDeclaration::standalone
TIXML_STRING standalone
Definition: tinyxml.h:1488
TiXmlBase::TIXML_ERROR_OUT_OF_MEMORY
@ TIXML_ERROR_OUT_OF_MEMORY
Definition: tinyxml.h:293
TiXmlBase::TIXML_ERROR
@ TIXML_ERROR
Definition: tinyxml.h:291
TiXmlBase::TIXML_ERROR_DOCUMENT_EMPTY
@ TIXML_ERROR_DOCUMENT_EMPTY
Definition: tinyxml.h:303
TiXmlText::cdata
bool cdata
Definition: tinyxml.h:1408
TiXmlAttributeSet::Add
void Add(TiXmlAttribute *attribute)
Definition: tinyxml_inl.h:1541
TiXmlBase::TIXML_ERROR_PARSING_UNKNOWN
@ TIXML_ERROR_PARSING_UNKNOWN
Definition: tinyxml.h:300
TiXmlBase::TIXML_ERROR_PARSING_ELEMENT
@ TIXML_ERROR_PARSING_ELEMENT
Definition: tinyxml.h:294
TiXmlBase::ReadText
static const char * ReadText(const char *in, TIXML_STRING *text, bool ignoreWhiteSpace, const char *endTag, bool ignoreCase, TiXmlEncoding encoding)
Definition: tinyxmlparser_inl.h:603
TiXmlBase::IsAlphaNum
static int IsAlphaNum(unsigned char anyByte, TiXmlEncoding encoding)
Definition: tinyxmlparser_inl.h:179
TiXmlCursor::row
int row
Definition: tinyxml.h:113
TiXmlParsingData::Cursor
const TiXmlCursor & Cursor()
Definition: tinyxmlparser_inl.h:206
TiXmlBase::utf8ByteTable
static const int utf8ByteTable[256]
Definition: tinyxml.h:285
TiXmlAttribute::Name
const char * Name() const
Return the name of this attribute.
Definition: tinyxml.h:909
TiXmlBase::errorString
static const char * errorString[TIXML_ERROR_STRING_COUNT]
Definition: tinyxml.h:388
TiXmlBase::IsAlpha
static int IsAlpha(unsigned char anyByte, TiXmlEncoding encoding)
Definition: tinyxmlparser_inl.h:158
ATTR_FALLTHROUGH
#define ATTR_FALLTHROUGH
Definition: tinyxmlparser_inl.h:55
TiXmlDocument::errorLocation
TiXmlCursor errorLocation
Definition: tinyxml.h:1734
TiXmlElement::StreamIn
virtual void StreamIn(std::istream *in, TIXML_STRING *tag) override
TiXmlDeclaration::StreamIn
virtual void StreamIn(std::istream *in, TIXML_STRING *tag) override
TiXmlNode::Identify
TiXmlNode * Identify(const char *start, TiXmlEncoding encoding)
Definition: tinyxmlparser_inl.h:847
TiXmlDocument::useMicrosoftBOM
bool useMicrosoftBOM
Definition: tinyxml.h:1735
TiXmlText
TinyXML class. See http://www.grinninglizard.com/tinyxml.
Definition: tinyxml.h:1339
TiXmlBase::TIXML_ERROR_READING_ELEMENT_VALUE
@ TIXML_ERROR_READING_ELEMENT_VALUE
Definition: tinyxml.h:296
TiXmlBase::ToLower
static int ToLower(int v, TiXmlEncoding encoding)
Definition: tinyxml.h:399
TiXmlAttribute::value
TIXML_STRING value
Definition: tinyxml.h:1006
TIXML_STRING
#define TIXML_STRING
Definition: tinyxml.h:59
TiXmlBase::GetChar
static const char * GetChar(const char *p, char *_value, int *length, TiXmlEncoding encoding)
Definition: tinyxml.h:349
TiXmlNode::parent
TiXmlNode * parent
Definition: tinyxml.h:857
TiXmlNode::ToDeclaration
virtual const TiXmlDeclaration * ToDeclaration() const
Cast to a more defined type. Will return null if not of the requested type.
Definition: tinyxml.h:790