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