TDME2  1.9.200
tinyxml.cpp
Go to the documentation of this file.
1 /*
2 www.sourceforge.net/projects/tinyxml
3 Original code by Lee Thomason (www.grinninglizard.com)
4 
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any
7 damages arising from the use of this software.
8 
9 Permission is granted to anyone to use this software for any
10 purpose, including commercial applications, and to alter it and
11 redistribute it freely, subject to the following restrictions:
12 
13 1. The origin of this software must not be misrepresented; you must
14 not claim that you wrote the original software. If you use this
15 software in a product, an acknowledgment in the product documentation
16 would be appreciated but is not required.
17 
18 2. Altered source versions must be plainly marked as such, and
19 must not be misrepresented as being the original software.
20 
21 3. This notice may not be removed or altered from any source
22 distribution.
23 */
24 
25 #include "tinyxml.h"
26 
27 #include <ctype.h>
28 #include <iostream>
29 #include <sstream>
30 
31 
32 using namespace tinyxml;
33 
34 FILE* TiXmlFOpen( const char* filename, const char* mode );
35 
37 
38 // Microsoft compiler security
39 FILE* TiXmlFOpen( const char* filename, const char* mode )
40 {
41  return fopen( filename, mode );
42 }
43 
44 void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString )
45 {
46  int i=0;
47 
48  while( i<(int)str.length() )
49  {
50  unsigned char c = (unsigned char) str[i];
51 
52  if ( c == '&'
53  && i < ( (int)str.length() - 2 )
54  && str[i+1] == '#'
55  && str[i+2] == 'x' )
56  {
57  // Hexadecimal character reference.
58  // Pass through unchanged.
59  // &#xA9; -- copyright symbol, for example.
60  //
61  // The -1 is a bug fix from Rob Laveaux. It keeps
62  // an overflow from happening if there is no ';'.
63  // There are actually 2 ways to exit this loop -
64  // while fails (error case) and break (semicolon found).
65  // However, there is no mechanism (currently) for
66  // this function to return an error.
67  while ( i<(int)str.length()-1 )
68  {
69  outString->append( str.c_str() + i, 1 );
70  ++i;
71  if ( str[i] == ';' )
72  break;
73  }
74  }
75  else if ( c == '&' )
76  {
77  outString->append( entity[0].str, entity[0].strLength );
78  ++i;
79  }
80  else if ( c == '<' )
81  {
82  outString->append( entity[1].str, entity[1].strLength );
83  ++i;
84  }
85  else if ( c == '>' )
86  {
87  outString->append( entity[2].str, entity[2].strLength );
88  ++i;
89  }
90  else if ( c == '\"' )
91  {
92  outString->append( entity[3].str, entity[3].strLength );
93  ++i;
94  }
95  else if ( c == '\'' )
96  {
97  outString->append( entity[4].str, entity[4].strLength );
98  ++i;
99  }
100  else if ( c < 32 )
101  {
102  // Easy pass at non-alpha/numeric/symbol
103  // Below 32 is symbolic.
104  char buf[ 32 ];
105 
106  #if defined(TIXML_SNPRINTF)
107  TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) );
108  #else
109  sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
110  #endif
111 
112  //*ME: warning C4267: convert 'size_t' to 'int'
113  //*ME: Int-Cast to make compiler happy ...
114  outString->append( buf, (int)strlen( buf ) );
115  ++i;
116  }
117  else
118  {
119  //char realc = (char) c;
120  //outString->append( &realc, 1 );
121  *outString += (char) c; // somewhat more efficient function call.
122  ++i;
123  }
124  }
125 }
126 
127 
129 {
130  parent = 0;
131  type = _type;
132  firstChild = 0;
133  lastChild = 0;
134  prev = 0;
135  next = 0;
136 }
137 
138 
140 {
141  TiXmlNode* node = firstChild;
142  TiXmlNode* temp = 0;
143 
144  while ( node )
145  {
146  temp = node;
147  node = node->next;
148  delete temp;
149  }
150 }
151 
152 
153 void TiXmlNode::CopyTo( TiXmlNode* target ) const
154 {
155  target->SetValue (value.c_str() );
156  target->userData = userData;
157  target->location = location;
158 }
159 
160 
162 {
163  TiXmlNode* node = firstChild;
164  TiXmlNode* temp = 0;
165 
166  while ( node )
167  {
168  temp = node;
169  node = node->next;
170  delete temp;
171  }
172 
173  firstChild = 0;
174  lastChild = 0;
175 }
176 
177 
179 {
180  assert( node->parent == 0 || node->parent == this );
181  assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() );
182 
183  if ( node->Type() == TiXmlNode::TINYXML_DOCUMENT )
184  {
185  delete node;
186  if ( GetDocument() )
188  return 0;
189  }
190 
191  node->parent = this;
192 
193  node->prev = lastChild;
194  node->next = 0;
195 
196  if ( lastChild )
197  lastChild->next = node;
198  else
199  firstChild = node; // it was an empty list.
200 
201  lastChild = node;
202  return node;
203 }
204 
205 
207 {
208  if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
209  {
210  if ( GetDocument() )
212  return 0;
213  }
214  TiXmlNode* node = addThis.Clone();
215  if ( !node )
216  return 0;
217 
218  return LinkEndChild( node );
219 }
220 
221 
223 {
224  if ( !beforeThis || beforeThis->parent != this ) {
225  return 0;
226  }
227  if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
228  {
229  if ( GetDocument() )
231  return 0;
232  }
233 
234  TiXmlNode* node = addThis.Clone();
235  if ( !node )
236  return 0;
237  node->parent = this;
238 
239  node->next = beforeThis;
240  node->prev = beforeThis->prev;
241  if ( beforeThis->prev )
242  {
243  beforeThis->prev->next = node;
244  }
245  else
246  {
247  assert( firstChild == beforeThis );
248  firstChild = node;
249  }
250  beforeThis->prev = node;
251  return node;
252 }
253 
254 
256 {
257  if ( !afterThis || afterThis->parent != this ) {
258  return 0;
259  }
260  if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
261  {
262  if ( GetDocument() )
264  return 0;
265  }
266 
267  TiXmlNode* node = addThis.Clone();
268  if ( !node )
269  return 0;
270  node->parent = this;
271 
272  node->prev = afterThis;
273  node->next = afterThis->next;
274  if ( afterThis->next )
275  {
276  afterThis->next->prev = node;
277  }
278  else
279  {
280  assert( lastChild == afterThis );
281  lastChild = node;
282  }
283  afterThis->next = node;
284  return node;
285 }
286 
287 
288 TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )
289 {
290  if ( !replaceThis )
291  return 0;
292 
293  if ( replaceThis->parent != this )
294  return 0;
295 
296  if ( withThis.ToDocument() ) {
297  // A document can never be a child. Thanks to Noam.
298  TiXmlDocument* document = GetDocument();
299  if ( document )
301  return 0;
302  }
303 
304  TiXmlNode* node = withThis.Clone();
305  if ( !node )
306  return 0;
307 
308  node->next = replaceThis->next;
309  node->prev = replaceThis->prev;
310 
311  if ( replaceThis->next )
312  replaceThis->next->prev = node;
313  else
314  lastChild = node;
315 
316  if ( replaceThis->prev )
317  replaceThis->prev->next = node;
318  else
319  firstChild = node;
320 
321  delete replaceThis;
322  node->parent = this;
323  return node;
324 }
325 
326 
328 {
329  if ( !removeThis ) {
330  return false;
331  }
332 
333  if ( removeThis->parent != this )
334  {
335  assert( 0 );
336  return false;
337  }
338 
339  if ( removeThis->next )
340  removeThis->next->prev = removeThis->prev;
341  else
342  lastChild = removeThis->prev;
343 
344  if ( removeThis->prev )
345  removeThis->prev->next = removeThis->next;
346  else
347  firstChild = removeThis->next;
348 
349  delete removeThis;
350  return true;
351 }
352 
353 const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const
354 {
355  const TiXmlNode* node;
356  for ( node = firstChild; node; node = node->next )
357  {
358  if ( strcmp( node->Value(), _value ) == 0 )
359  return node;
360  }
361  return 0;
362 }
363 
364 
365 const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const
366 {
367  const TiXmlNode* node;
368  for ( node = lastChild; node; node = node->prev )
369  {
370  if ( strcmp( node->Value(), _value ) == 0 )
371  return node;
372  }
373  return 0;
374 }
375 
376 
377 const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const
378 {
379  if ( !previous )
380  {
381  return FirstChild();
382  }
383  else
384  {
385  assert( previous->parent == this );
386  return previous->NextSibling();
387  }
388 }
389 
390 
391 const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const
392 {
393  if ( !previous )
394  {
395  return FirstChild( val );
396  }
397  else
398  {
399  assert( previous->parent == this );
400  return previous->NextSibling( val );
401  }
402 }
403 
404 
405 const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const
406 {
407  const TiXmlNode* node;
408  for ( node = next; node; node = node->next )
409  {
410  if ( strcmp( node->Value(), _value ) == 0 )
411  return node;
412  }
413  return 0;
414 }
415 
416 
417 const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
418 {
419  const TiXmlNode* node;
420  for ( node = prev; node; node = node->prev )
421  {
422  if ( strcmp( node->Value(), _value ) == 0 )
423  return node;
424  }
425  return 0;
426 }
427 
428 
429 void TiXmlElement::RemoveAttribute( const char * name )
430 {
431  TIXML_STRING str( name );
432  TiXmlAttribute* node = attributeSet.Find( str );
433 
434  if ( node )
435  {
436  attributeSet.Remove( node );
437  delete node;
438  }
439 }
440 
442 {
443  const TiXmlNode* node;
444 
445  for ( node = FirstChild();
446  node;
447  node = node->NextSibling() )
448  {
449  if ( node->ToElement() )
450  return node->ToElement();
451  }
452  return 0;
453 }
454 
455 
456 const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const
457 {
458  const TiXmlNode* node;
459 
460  for ( node = FirstChild( _value );
461  node;
462  node = node->NextSibling( _value ) )
463  {
464  if ( node->ToElement() )
465  return node->ToElement();
466  }
467  return 0;
468 }
469 
470 
472 {
473  const TiXmlNode* node;
474 
475  for ( node = NextSibling();
476  node;
477  node = node->NextSibling() )
478  {
479  if ( node->ToElement() )
480  return node->ToElement();
481  }
482  return 0;
483 }
484 
485 
486 const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const
487 {
488  const TiXmlNode* node;
489 
490  for ( node = NextSibling( _value );
491  node;
492  node = node->NextSibling( _value ) )
493  {
494  if ( node->ToElement() )
495  return node->ToElement();
496  }
497  return 0;
498 }
499 
500 
502 {
503  const TiXmlNode* node;
504 
505  for( node = this; node; node = node->parent )
506  {
507  if ( node->ToDocument() )
508  return node->ToDocument();
509  }
510  return 0;
511 }
512 
513 
514 TiXmlElement::TiXmlElement (const char * _value)
515  : TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
516 {
517  firstChild = lastChild = 0;
518  value = _value;
519 }
520 
521 
522 TiXmlElement::TiXmlElement( const std::string& _value )
523  : TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
524 {
525  firstChild = lastChild = 0;
526  value = _value;
527 }
528 
529 
531  : TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
532 {
533  firstChild = lastChild = 0;
534  copy.CopyTo( this );
535 }
536 
537 
539 {
540  ClearThis();
541  base.CopyTo( this );
542  return *this;
543 }
544 
545 
547 {
548  ClearThis();
549 }
550 
551 
553 {
554  Clear();
555  while( attributeSet.First() )
556  {
558  attributeSet.Remove( node );
559  delete node;
560  }
561 }
562 
563 
564 const char* TiXmlElement::Attribute( const char* name ) const
565 {
566  const TiXmlAttribute* node = attributeSet.Find( name );
567  if ( node )
568  return node->Value();
569  return 0;
570 }
571 
572 
573 const std::string* TiXmlElement::Attribute( const std::string& name ) const
574 {
575  const TiXmlAttribute* attrib = attributeSet.Find( name );
576  if ( attrib )
577  return &attrib->ValueStr();
578  return 0;
579 }
580 
581 
582 const char* TiXmlElement::Attribute( const char* name, int* i ) const
583 {
584  const TiXmlAttribute* attrib = attributeSet.Find( name );
585  const char* result = 0;
586 
587  if ( attrib ) {
588  result = attrib->Value();
589  if ( i ) {
590  attrib->QueryIntValue( i );
591  }
592  }
593  return result;
594 }
595 
596 
597 const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const
598 {
599  const TiXmlAttribute* attrib = attributeSet.Find( name );
600  const std::string* result = 0;
601 
602  if ( attrib ) {
603  result = &attrib->ValueStr();
604  if ( i ) {
605  attrib->QueryIntValue( i );
606  }
607  }
608  return result;
609 }
610 
611 
612 const char* TiXmlElement::Attribute( const char* name, double* d ) const
613 {
614  const TiXmlAttribute* attrib = attributeSet.Find( name );
615  const char* result = 0;
616 
617  if ( attrib ) {
618  result = attrib->Value();
619  if ( d ) {
620  attrib->QueryDoubleValue( d );
621  }
622  }
623  return result;
624 }
625 
626 
627 const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const
628 {
629  const TiXmlAttribute* attrib = attributeSet.Find( name );
630  const std::string* result = 0;
631 
632  if ( attrib ) {
633  result = &attrib->ValueStr();
634  if ( d ) {
635  attrib->QueryDoubleValue( d );
636  }
637  }
638  return result;
639 }
640 
641 
642 int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
643 {
644  const TiXmlAttribute* attrib = attributeSet.Find( name );
645  if ( !attrib )
646  return TIXML_NO_ATTRIBUTE;
647  return attrib->QueryIntValue( ival );
648 }
649 
650 
651 int TiXmlElement::QueryUnsignedAttribute( const char* name, unsigned* value ) const
652 {
653  const TiXmlAttribute* node = attributeSet.Find( name );
654  if ( !node )
655  return TIXML_NO_ATTRIBUTE;
656 
657  int ival = 0;
658  int result = node->QueryIntValue( &ival );
659  *value = (unsigned)ival;
660  return result;
661 }
662 
663 
664 int TiXmlElement::QueryBoolAttribute( const char* name, bool* bval ) const
665 {
666  const TiXmlAttribute* node = attributeSet.Find( name );
667  if ( !node )
668  return TIXML_NO_ATTRIBUTE;
669 
670  int result = TIXML_WRONG_TYPE;
671  if ( StringEqual( node->Value(), "true", true, TIXML_ENCODING_UNKNOWN )
672  || StringEqual( node->Value(), "yes", true, TIXML_ENCODING_UNKNOWN )
673  || StringEqual( node->Value(), "1", true, TIXML_ENCODING_UNKNOWN ) )
674  {
675  *bval = true;
676  result = TIXML_SUCCESS;
677  }
678  else if ( StringEqual( node->Value(), "false", true, TIXML_ENCODING_UNKNOWN )
679  || StringEqual( node->Value(), "no", true, TIXML_ENCODING_UNKNOWN )
680  || StringEqual( node->Value(), "0", true, TIXML_ENCODING_UNKNOWN ) )
681  {
682  *bval = false;
683  result = TIXML_SUCCESS;
684  }
685  return result;
686 }
687 
688 
689 int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const
690 {
691  const TiXmlAttribute* attrib = attributeSet.Find( name );
692  if ( !attrib )
693  return TIXML_NO_ATTRIBUTE;
694  return attrib->QueryIntValue( ival );
695 }
696 
697 
698 int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
699 {
700  const TiXmlAttribute* attrib = attributeSet.Find( name );
701  if ( !attrib )
702  return TIXML_NO_ATTRIBUTE;
703  return attrib->QueryDoubleValue( dval );
704 }
705 
706 
707 int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const
708 {
709  const TiXmlAttribute* attrib = attributeSet.Find( name );
710  if ( !attrib )
711  return TIXML_NO_ATTRIBUTE;
712  return attrib->QueryDoubleValue( dval );
713 }
714 
715 
716 void TiXmlElement::SetAttribute( const char * name, int val )
717 {
718  TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
719  if ( attrib ) {
720  attrib->SetIntValue( val );
721  }
722 }
723 
724 
725 void TiXmlElement::SetAttribute( const std::string& name, int val )
726 {
727  TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
728  if ( attrib ) {
729  attrib->SetIntValue( val );
730  }
731 }
732 
733 
734 void TiXmlElement::SetDoubleAttribute( const char * name, double val )
735 {
736  TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
737  if ( attrib ) {
738  attrib->SetDoubleValue( val );
739  }
740 }
741 
742 
743 void TiXmlElement::SetDoubleAttribute( const std::string& name, double val )
744 {
745  TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
746  if ( attrib ) {
747  attrib->SetDoubleValue( val );
748  }
749 }
750 
751 
752 void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
753 {
754  TiXmlAttribute* attrib = attributeSet.FindOrCreate( cname );
755  if ( attrib ) {
756  attrib->SetValue( cvalue );
757  }
758 }
759 
760 
761 void TiXmlElement::SetAttribute( const std::string& _name, const std::string& _value )
762 {
763  TiXmlAttribute* attrib = attributeSet.FindOrCreate( _name );
764  if ( attrib ) {
765  attrib->SetValue( _value );
766  }
767 }
768 
769 
770 void TiXmlElement::Print( FILE* cfile, int depth ) const
771 {
772  int i;
773  assert( cfile );
774  for ( i=0; i<depth; i++ ) {
775  fprintf( cfile, " " );
776  }
777 
778  fprintf( cfile, "<%s", value.c_str() );
779 
780  const TiXmlAttribute* attrib;
781  for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
782  {
783  fprintf( cfile, " " );
784  attrib->Print( cfile, depth );
785  }
786 
787  // There are 3 different formatting approaches:
788  // 1) An element without children is printed as a <foo /> node
789  // 2) An element with only a text child is printed as <foo> text </foo>
790  // 3) An element with children is printed on multiple lines.
791  TiXmlNode* node;
792  if ( !firstChild )
793  {
794  fprintf( cfile, " />" );
795  }
796  else if ( firstChild == lastChild && firstChild->ToText() )
797  {
798  fprintf( cfile, ">" );
799  firstChild->Print( cfile, depth + 1 );
800  fprintf( cfile, "</%s>", value.c_str() );
801  }
802  else
803  {
804  fprintf( cfile, ">" );
805 
806  for ( node = firstChild; node; node=node->NextSibling() )
807  {
808  if ( !node->ToText() )
809  {
810  fprintf( cfile, "\n" );
811  }
812  node->Print( cfile, depth+1 );
813  }
814  fprintf( cfile, "\n" );
815  for( i=0; i<depth; ++i ) {
816  fprintf( cfile, " " );
817  }
818  fprintf( cfile, "</%s>", value.c_str() );
819  }
820 }
821 
822 
823 void TiXmlElement::CopyTo( TiXmlElement* target ) const
824 {
825  // superclass:
826  TiXmlNode::CopyTo( target );
827 
828  // Element class:
829  // Clone the attributes, then clone the children.
830  const TiXmlAttribute* attribute = 0;
831  for( attribute = attributeSet.First();
832  attribute;
833  attribute = attribute->Next() )
834  {
835  target->SetAttribute( attribute->Name(), attribute->Value() );
836  }
837 
838  TiXmlNode* node = 0;
839  for ( node = firstChild; node; node = node->NextSibling() )
840  {
841  target->LinkEndChild( node->Clone() );
842  }
843 }
844 
845 bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const
846 {
847  if ( visitor->VisitEnter( *this, attributeSet.First() ) )
848  {
849  for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
850  {
851  if ( !node->Accept( visitor ) )
852  break;
853  }
854  }
855  return visitor->VisitExit( *this );
856 }
857 
858 
860 {
861  TiXmlElement* clone = new TiXmlElement( Value() );
862  if ( !clone )
863  return 0;
864 
865  CopyTo( clone );
866  return clone;
867 }
868 
869 
870 const char* TiXmlElement::GetText() const
871 {
872  const TiXmlNode* child = this->FirstChild();
873  if ( child ) {
874  const TiXmlText* childText = child->ToText();
875  if ( childText ) {
876  return childText->Value();
877  }
878  }
879  return 0;
880 }
881 
882 
884 {
885  tabsize = 4;
886  useMicrosoftBOM = false;
887  ClearError();
888 }
889 
890 TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
891 {
892  tabsize = 4;
893  useMicrosoftBOM = false;
894  value = documentName;
895  ClearError();
896 }
897 
898 
899 TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
900 {
901  tabsize = 4;
902  useMicrosoftBOM = false;
903  value = documentName;
904  ClearError();
905 }
906 
907 
908 TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
909 {
910  copy.CopyTo( this );
911 }
912 
913 
915 {
916  Clear();
917  copy.CopyTo( this );
918  return *this;
919 }
920 
921 
923 {
924  return LoadFile( Value(), encoding );
925 }
926 
927 
929 {
930  return SaveFile( Value() );
931 }
932 
933 bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding )
934 {
935  TIXML_STRING filename( _filename );
936  value = filename;
937 
938  // reading in binary mode so that tinyxml can normalize the EOL
939  FILE* file = TiXmlFOpen( value.c_str (), "rb" );
940 
941  if ( file )
942  {
943  bool result = LoadFile( file, encoding );
944  fclose( file );
945  return result;
946  }
947  else
948  {
950  return false;
951  }
952 }
953 
954 bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
955 {
956  if ( !file )
957  {
959  return false;
960  }
961 
962  // Delete the existing data:
963  Clear();
964  location.Clear();
965 
966  // Get the file size, so we can pre-allocate the string. HUGE speed impact.
967  long length = 0;
968  fseek( file, 0, SEEK_END );
969  length = ftell( file );
970  fseek( file, 0, SEEK_SET );
971 
972  // Strange case, but good to handle up front.
973  if ( length <= 0 )
974  {
976  return false;
977  }
978 
979  // Subtle bug here. TinyXml did use fgets. But from the XML spec:
980  // 2.11 End-of-Line Handling
981  // <snip>
982  // <quote>
983  // ...the XML processor MUST behave as if it normalized all line breaks in external
984  // parsed entities (including the document entity) on input, before parsing, by translating
985  // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to
986  // a single #xA character.
987  // </quote>
988  //
989  // It is not clear fgets does that, and certainly isn't clear it works cross platform.
990  // Generally, you expect fgets to translate from the convention of the OS to the c/unix
991  // convention, and not work generally.
992 
993  /*
994  while( fgets( buf, sizeof(buf), file ) )
995  {
996  data += buf;
997  }
998  */
999 
1000  char* buf = new char[ length+1 ];
1001  buf[0] = 0;
1002 
1003  if ( fread( buf, length, 1, file ) != 1 ) {
1004  delete [] buf;
1006  return false;
1007  }
1008 
1009  // Process the buffer in place to normalize new lines. (See comment above.)
1010  // Copies from the 'p' to 'q' pointer, where p can advance faster if
1011  // a newline-carriage return is hit.
1012  //
1013  // Wikipedia:
1014  // Systems based on ASCII or a compatible character set use either LF (Line feed, '\n', 0x0A, 10 in decimal) or
1015  // CR (Carriage return, '\r', 0x0D, 13 in decimal) individually, or CR followed by LF (CR+LF, 0x0D 0x0A)...
1016  // * LF: Multics, Unix and Unix-like systems (GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD, etc.), BeOS, Amiga, RISC OS, and others
1017  // * CR+LF: DEC RT-11 and most other early non-Unix, non-IBM OSes, CP/M, MP/M, DOS, OS/2, Microsoft Windows, Symbian OS
1018  // * CR: Commodore 8-bit machines, Apple II family, Mac OS up to version 9 and OS-9
1019 
1020  const char* p = buf; // the read head
1021  char* q = buf; // the write head
1022  const char CR = 0x0d;
1023  const char LF = 0x0a;
1024 
1025  buf[length] = 0;
1026  while( *p ) {
1027  assert( p < (buf+length) );
1028  assert( q <= (buf+length) );
1029  assert( q <= p );
1030 
1031  if ( *p == CR ) {
1032  *q++ = LF;
1033  p++;
1034  if ( *p == LF ) { // check for CR+LF (and skip LF)
1035  p++;
1036  }
1037  }
1038  else {
1039  *q++ = *p++;
1040  }
1041  }
1042  assert( q <= (buf+length) );
1043  *q = 0;
1044 
1045  Parse( buf, 0, encoding );
1046 
1047  delete [] buf;
1048  return !Error();
1049 }
1050 
1051 
1052 bool TiXmlDocument::SaveFile( const char * filename ) const
1053 {
1054  // The old c stuff lives on...
1055  FILE* fp = TiXmlFOpen( filename, "w" );
1056  if ( fp )
1057  {
1058  bool result = SaveFile( fp );
1059  fclose( fp );
1060  return result;
1061  }
1062  return false;
1063 }
1064 
1065 
1066 bool TiXmlDocument::SaveFile( FILE* fp ) const
1067 {
1068  if ( useMicrosoftBOM )
1069  {
1070  const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
1071  const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
1072  const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
1073 
1074  fputc( TIXML_UTF_LEAD_0, fp );
1075  fputc( TIXML_UTF_LEAD_1, fp );
1076  fputc( TIXML_UTF_LEAD_2, fp );
1077  }
1078  Print( fp, 0 );
1079  return (ferror(fp) == 0);
1080 }
1081 
1082 
1084 {
1085  TiXmlNode::CopyTo( target );
1086 
1087  target->error = error;
1088  target->errorId = errorId;
1089  target->errorDesc = errorDesc;
1090  target->tabsize = tabsize;
1091  target->errorLocation = errorLocation;
1092  target->useMicrosoftBOM = useMicrosoftBOM;
1093 
1094  TiXmlNode* node = 0;
1095  for ( node = firstChild; node; node = node->NextSibling() )
1096  {
1097  target->LinkEndChild( node->Clone() );
1098  }
1099 }
1100 
1101 
1103 {
1104  TiXmlDocument* clone = new TiXmlDocument();
1105  if ( !clone )
1106  return 0;
1107 
1108  CopyTo( clone );
1109  return clone;
1110 }
1111 
1112 
1113 void TiXmlDocument::Print( FILE* cfile, int depth ) const
1114 {
1115  assert( cfile );
1116  for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
1117  {
1118  node->Print( cfile, depth );
1119  fprintf( cfile, "\n" );
1120  }
1121 }
1122 
1123 
1124 bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const
1125 {
1126  if ( visitor->VisitEnter( *this ) )
1127  {
1128  for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
1129  {
1130  if ( !node->Accept( visitor ) )
1131  break;
1132  }
1133  }
1134  return visitor->VisitExit( *this );
1135 }
1136 
1137 
1139 {
1140  // We are using knowledge of the sentinel. The sentinel
1141  // have a value or name.
1142  if ( next->value.empty() && next->name.empty() )
1143  return 0;
1144  return next;
1145 }
1146 
1147 /*
1148 TiXmlAttribute* TiXmlAttribute::Next()
1149 {
1150  // We are using knowledge of the sentinel. The sentinel
1151  // have a value or name.
1152  if ( next->value.empty() && next->name.empty() )
1153  return 0;
1154  return next;
1155 }
1156 */
1157 
1159 {
1160  // We are using knowledge of the sentinel. The sentinel
1161  // have a value or name.
1162  if ( prev->value.empty() && prev->name.empty() )
1163  return 0;
1164  return prev;
1165 }
1166 
1167 /*
1168 TiXmlAttribute* TiXmlAttribute::Previous()
1169 {
1170  // We are using knowledge of the sentinel. The sentinel
1171  // have a value or name.
1172  if ( prev->value.empty() && prev->name.empty() )
1173  return 0;
1174  return prev;
1175 }
1176 */
1177 
1178 void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
1179 {
1180  TIXML_STRING n, v;
1181 
1182  EncodeString( name, &n );
1183  EncodeString( value, &v );
1184 
1185  if (value.find ('\"') == TIXML_STRING::npos) {
1186  if ( cfile ) {
1187  fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
1188  }
1189  if ( str ) {
1190  (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\"";
1191  }
1192  }
1193  else {
1194  if ( cfile ) {
1195  fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
1196  }
1197  if ( str ) {
1198  (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'";
1199  }
1200  }
1201 }
1202 
1203 
1204 int TiXmlAttribute::QueryIntValue( int* ival ) const
1205 {
1206  if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 )
1207  return TIXML_SUCCESS;
1208  return TIXML_WRONG_TYPE;
1209 }
1210 
1211 int TiXmlAttribute::QueryDoubleValue( double* dval ) const
1212 {
1213  if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 )
1214  return TIXML_SUCCESS;
1215  return TIXML_WRONG_TYPE;
1216 }
1217 
1219 {
1220  char buf [64];
1221  #if defined(TIXML_SNPRINTF)
1222  TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value);
1223  #else
1224  sprintf (buf, "%d", _value);
1225  #endif
1226  SetValue (buf);
1227 }
1228 
1229 void TiXmlAttribute::SetDoubleValue( double _value )
1230 {
1231  char buf [256];
1232  #if defined(TIXML_SNPRINTF)
1233  TIXML_SNPRINTF( buf, sizeof(buf), "%g", _value);
1234  #else
1235  sprintf (buf, "%g", _value);
1236  #endif
1237  SetValue (buf);
1238 }
1239 
1241 {
1242  return atoi (value.c_str ());
1243 }
1244 
1246 {
1247  return atof (value.c_str ());
1248 }
1249 
1250 
1251 TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT )
1252 {
1253  copy.CopyTo( this );
1254 }
1255 
1256 
1258 {
1259  Clear();
1260  base.CopyTo( this );
1261  return *this;
1262 }
1263 
1264 
1265 void TiXmlComment::Print( FILE* cfile, int depth ) const
1266 {
1267  assert( cfile );
1268  for ( int i=0; i<depth; i++ )
1269  {
1270  fprintf( cfile, " " );
1271  }
1272  fprintf( cfile, "<!--%s-->", value.c_str() );
1273 }
1274 
1275 
1276 void TiXmlComment::CopyTo( TiXmlComment* target ) const
1277 {
1278  TiXmlNode::CopyTo( target );
1279 }
1280 
1281 
1282 bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const
1283 {
1284  return visitor->Visit( *this );
1285 }
1286 
1287 
1289 {
1290  TiXmlComment* clone = new TiXmlComment();
1291 
1292  if ( !clone )
1293  return 0;
1294 
1295  CopyTo( clone );
1296  return clone;
1297 }
1298 
1299 
1300 void TiXmlText::Print( FILE* cfile, int depth ) const
1301 {
1302  assert( cfile );
1303  if ( cdata )
1304  {
1305  int i;
1306  fprintf( cfile, "\n" );
1307  for ( i=0; i<depth; i++ ) {
1308  fprintf( cfile, " " );
1309  }
1310  fprintf( cfile, "<![CDATA[%s]]>\n", value.c_str() ); // unformatted output
1311  }
1312  else
1313  {
1314  TIXML_STRING buffer;
1315  EncodeString( value, &buffer );
1316  fprintf( cfile, "%s", buffer.c_str() );
1317  }
1318 }
1319 
1320 
1321 void TiXmlText::CopyTo( TiXmlText* target ) const
1322 {
1323  TiXmlNode::CopyTo( target );
1324  target->cdata = cdata;
1325 }
1326 
1327 
1328 bool TiXmlText::Accept( TiXmlVisitor* visitor ) const
1329 {
1330  return visitor->Visit( *this );
1331 }
1332 
1333 
1335 {
1336  TiXmlText* clone = 0;
1337  clone = new TiXmlText( "" );
1338 
1339  if ( !clone )
1340  return 0;
1341 
1342  CopyTo( clone );
1343  return clone;
1344 }
1345 
1346 
1347 TiXmlDeclaration::TiXmlDeclaration( const char * _version,
1348  const char * _encoding,
1349  const char * _standalone )
1350  : TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
1351 {
1352  version = _version;
1353  encoding = _encoding;
1354  standalone = _standalone;
1355 }
1356 
1357 
1358 TiXmlDeclaration::TiXmlDeclaration( const std::string& _version,
1359  const std::string& _encoding,
1360  const std::string& _standalone )
1361  : TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
1362 {
1363  version = _version;
1364  encoding = _encoding;
1365  standalone = _standalone;
1366 }
1367 
1368 
1370  : TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
1371 {
1372  copy.CopyTo( this );
1373 }
1374 
1375 
1377 {
1378  Clear();
1379  copy.CopyTo( this );
1380  return *this;
1381 }
1382 
1383 
1384 void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
1385 {
1386  if ( cfile ) fprintf( cfile, "<?xml " );
1387  if ( str ) (*str) += "<?xml ";
1388 
1389  if ( !version.empty() ) {
1390  if ( cfile ) fprintf (cfile, "version=\"%s\" ", version.c_str ());
1391  if ( str ) { (*str) += "version=\""; (*str) += version; (*str) += "\" "; }
1392  }
1393  if ( !encoding.empty() ) {
1394  if ( cfile ) fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
1395  if ( str ) { (*str) += "encoding=\""; (*str) += encoding; (*str) += "\" "; }
1396  }
1397  if ( !standalone.empty() ) {
1398  if ( cfile ) fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
1399  if ( str ) { (*str) += "standalone=\""; (*str) += standalone; (*str) += "\" "; }
1400  }
1401  if ( cfile ) fprintf( cfile, "?>" );
1402  if ( str ) (*str) += "?>";
1403 }
1404 
1405 
1407 {
1408  TiXmlNode::CopyTo( target );
1409 
1410  target->version = version;
1411  target->encoding = encoding;
1412  target->standalone = standalone;
1413 }
1414 
1415 
1417 {
1418  return visitor->Visit( *this );
1419 }
1420 
1421 
1423 {
1424  TiXmlDeclaration* clone = new TiXmlDeclaration();
1425 
1426  if ( !clone )
1427  return 0;
1428 
1429  CopyTo( clone );
1430  return clone;
1431 }
1432 
1433 
1434 void TiXmlUnknown::Print( FILE* cfile, int depth ) const
1435 {
1436  for ( int i=0; i<depth; i++ )
1437  fprintf( cfile, " " );
1438  fprintf( cfile, "<%s>", value.c_str() );
1439 }
1440 
1441 
1442 void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
1443 {
1444  TiXmlNode::CopyTo( target );
1445 }
1446 
1447 
1448 bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const
1449 {
1450  return visitor->Visit( *this );
1451 }
1452 
1453 
1455 {
1456  TiXmlUnknown* clone = new TiXmlUnknown();
1457 
1458  if ( !clone )
1459  return 0;
1460 
1461  CopyTo( clone );
1462  return clone;
1463 }
1464 
1465 
1467 {
1468  sentinel.next = &sentinel;
1469  sentinel.prev = &sentinel;
1470 }
1471 
1472 
1474 {
1475  assert( sentinel.next == &sentinel );
1476  assert( sentinel.prev == &sentinel );
1477 }
1478 
1479 
1481 {
1482  assert( !Find( TIXML_STRING( addMe->Name() ) ) ); // Shouldn't be multiply adding to the set.
1483 
1484  addMe->next = &sentinel;
1485  addMe->prev = sentinel.prev;
1486 
1487  sentinel.prev->next = addMe;
1488  sentinel.prev = addMe;
1489 }
1490 
1492 {
1493  TiXmlAttribute* node;
1494 
1495  for( node = sentinel.next; node != &sentinel; node = node->next )
1496  {
1497  if ( node == removeMe )
1498  {
1499  node->prev->next = node->next;
1500  node->next->prev = node->prev;
1501  node->next = 0;
1502  node->prev = 0;
1503  return;
1504  }
1505  }
1506  assert( 0 ); // we tried to remove a non-linked attribute.
1507 }
1508 
1509 
1510 TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const
1511 {
1512  for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
1513  {
1514  if ( node->name == name )
1515  return node;
1516  }
1517  return 0;
1518 }
1519 
1521 {
1522  TiXmlAttribute* attrib = Find( _name );
1523  if ( !attrib ) {
1524  attrib = new TiXmlAttribute();
1525  Add( attrib );
1526  attrib->SetName( _name );
1527  }
1528  return attrib;
1529 }
1530 
1531 
1532 TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const
1533 {
1534  for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
1535  {
1536  if ( strcmp( node->name.c_str(), name ) == 0 )
1537  return node;
1538  }
1539  return 0;
1540 }
1541 
1542 
1544 {
1545  TiXmlAttribute* attrib = Find( _name );
1546  if ( !attrib ) {
1547  attrib = new TiXmlAttribute();
1548  Add( attrib );
1549  attrib->SetName( _name );
1550  }
1551  return attrib;
1552 }
1553 
1554 namespace tinyxml {
1555 std::istream& operator>> (std::istream& in, TiXmlNode& base)
1556 {
1557  TIXML_STRING tag;
1558  tag.reserve( 8 * 1000 );
1559  base.StreamIn( &in, &tag );
1560 
1561  base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
1562  return in;
1563 }
1564 
1565 
1566 std::ostream& operator<< (std::ostream & out, const TiXmlNode & base)
1567 {
1568  TiXmlPrinter printer;
1569  printer.SetStreamPrinting();
1570  base.Accept( &printer );
1571  out << printer.Str();
1572 
1573  return out;
1574 }
1575 
1576 
1577 std::string& operator<< (std::string& out, const TiXmlNode& base )
1578 {
1579  TiXmlPrinter printer;
1580  printer.SetStreamPrinting();
1581  base.Accept( &printer );
1582  out.append( printer.Str() );
1583 
1584  return out;
1585 }
1586 };
1587 
1588 
1590 {
1591  if ( node )
1592  {
1593  TiXmlNode* child = node->FirstChild();
1594  if ( child )
1595  return TiXmlHandle( child );
1596  }
1597  return TiXmlHandle( 0 );
1598 }
1599 
1600 
1601 TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const
1602 {
1603  if ( node )
1604  {
1605  TiXmlNode* child = node->FirstChild( value );
1606  if ( child )
1607  return TiXmlHandle( child );
1608  }
1609  return TiXmlHandle( 0 );
1610 }
1611 
1612 
1614 {
1615  if ( node )
1616  {
1617  TiXmlElement* child = node->FirstChildElement();
1618  if ( child )
1619  return TiXmlHandle( child );
1620  }
1621  return TiXmlHandle( 0 );
1622 }
1623 
1624 
1625 TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const
1626 {
1627  if ( node )
1628  {
1629  TiXmlElement* child = node->FirstChildElement( value );
1630  if ( child )
1631  return TiXmlHandle( child );
1632  }
1633  return TiXmlHandle( 0 );
1634 }
1635 
1636 
1638 {
1639  if ( node )
1640  {
1641  int i;
1642  TiXmlNode* child = node->FirstChild();
1643  for ( i=0;
1644  child && i<count;
1645  child = child->NextSibling(), ++i )
1646  {
1647  // nothing
1648  }
1649  if ( child )
1650  return TiXmlHandle( child );
1651  }
1652  return TiXmlHandle( 0 );
1653 }
1654 
1655 
1656 TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const
1657 {
1658  if ( node )
1659  {
1660  int i;
1661  TiXmlNode* child = node->FirstChild( value );
1662  for ( i=0;
1663  child && i<count;
1664  child = child->NextSibling( value ), ++i )
1665  {
1666  // nothing
1667  }
1668  if ( child )
1669  return TiXmlHandle( child );
1670  }
1671  return TiXmlHandle( 0 );
1672 }
1673 
1674 
1676 {
1677  if ( node )
1678  {
1679  int i;
1680  TiXmlElement* child = node->FirstChildElement();
1681  for ( i=0;
1682  child && i<count;
1683  child = child->NextSiblingElement(), ++i )
1684  {
1685  // nothing
1686  }
1687  if ( child )
1688  return TiXmlHandle( child );
1689  }
1690  return TiXmlHandle( 0 );
1691 }
1692 
1693 
1694 TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const
1695 {
1696  if ( node )
1697  {
1698  int i;
1699  TiXmlElement* child = node->FirstChildElement( value );
1700  for ( i=0;
1701  child && i<count;
1702  child = child->NextSiblingElement( value ), ++i )
1703  {
1704  // nothing
1705  }
1706  if ( child )
1707  return TiXmlHandle( child );
1708  }
1709  return TiXmlHandle( 0 );
1710 }
1711 
1712 
1714 {
1715  return true;
1716 }
1717 
1719 {
1720  return true;
1721 }
1722 
1723 bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute )
1724 {
1725  DoIndent();
1726  buffer += "<";
1727  buffer += element.Value();
1728 
1729  for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() )
1730  {
1731  buffer += " ";
1732  attrib->Print( 0, 0, &buffer );
1733  }
1734 
1735  if ( !element.FirstChild() )
1736  {
1737  buffer += " />";
1738  DoLineBreak();
1739  }
1740  else
1741  {
1742  buffer += ">";
1743  if ( element.FirstChild()->ToText()
1744  && element.LastChild() == element.FirstChild()
1745  && element.FirstChild()->ToText()->CDATA() == false )
1746  {
1747  simpleTextPrint = true;
1748  // no DoLineBreak()!
1749  }
1750  else
1751  {
1752  DoLineBreak();
1753  }
1754  }
1755  ++depth;
1756  return true;
1757 }
1758 
1759 
1761 {
1762  --depth;
1763  if ( !element.FirstChild() )
1764  {
1765  // nothing.
1766  }
1767  else
1768  {
1769  if ( simpleTextPrint )
1770  {
1771  simpleTextPrint = false;
1772  }
1773  else
1774  {
1775  DoIndent();
1776  }
1777  buffer += "</";
1778  buffer += element.Value();
1779  buffer += ">";
1780  DoLineBreak();
1781  }
1782  return true;
1783 }
1784 
1785 
1786 bool TiXmlPrinter::Visit( const TiXmlText& text )
1787 {
1788  if ( text.CDATA() )
1789  {
1790  DoIndent();
1791  buffer += "<![CDATA[";
1792  buffer += text.Value();
1793  buffer += "]]>";
1794  DoLineBreak();
1795  }
1796  else if ( simpleTextPrint )
1797  {
1798  TIXML_STRING str;
1799  TiXmlBase::EncodeString( text.ValueTStr(), &str );
1800  buffer += str;
1801  }
1802  else
1803  {
1804  DoIndent();
1805  TIXML_STRING str;
1806  TiXmlBase::EncodeString( text.ValueTStr(), &str );
1807  buffer += str;
1808  DoLineBreak();
1809  }
1810  return true;
1811 }
1812 
1813 
1814 bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration )
1815 {
1816  DoIndent();
1817  declaration.Print( 0, 0, &buffer );
1818  DoLineBreak();
1819  return true;
1820 }
1821 
1822 
1823 bool TiXmlPrinter::Visit( const TiXmlComment& comment )
1824 {
1825  DoIndent();
1826  buffer += "<!--";
1827  buffer += comment.Value();
1828  buffer += "-->";
1829  DoLineBreak();
1830  return true;
1831 }
1832 
1833 
1834 bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown )
1835 {
1836  DoIndent();
1837  buffer += "<";
1838  buffer += unknown.Value();
1839  buffer += ">";
1840  DoLineBreak();
1841  return true;
1842 }
1843 
void Remove(TiXmlAttribute *attribute)
Definition: tinyxml.cpp:1491
TiXmlAttribute * Find(const char *_name) const
Definition: tinyxml.cpp:1532
void Add(TiXmlAttribute *attribute)
Definition: tinyxml.cpp:1480
const TiXmlAttribute * First() const
Definition: tinyxml.h:860
TiXmlAttribute * FindOrCreate(const char *_name)
Definition: tinyxml.cpp:1543
TiXmlAttribute sentinel
Definition: tinyxml.h:877
An attribute is a name-value pair.
Definition: tinyxml.h:734
void SetIntValue(int _value)
Set the value from an integer.
Definition: tinyxml.cpp:1218
const TiXmlAttribute * Previous() const
Get the previous sibling attribute in the DOM. Returns null at beginning.
Definition: tinyxml.cpp:1158
virtual void Print(FILE *cfile, int depth) const
All TinyXml classes can print themselves to a filestream or the string class (TiXmlString in non-STL ...
Definition: tinyxml.h:818
double DoubleValue() const
Return the value of this attribute, converted to a double.
Definition: tinyxml.cpp:1245
int IntValue() const
Return the value of this attribute, converted to an integer.
Definition: tinyxml.cpp:1240
const char * Value() const
Return the value of this attribute.
Definition: tinyxml.h:764
TIXML_STRING value
Definition: tinyxml.h:833
void SetDoubleValue(double _value)
Set the value from a double.
Definition: tinyxml.cpp:1229
const TiXmlAttribute * Next() const
Get the next sibling attribute in the DOM. Returns null at end.
Definition: tinyxml.cpp:1138
int QueryDoubleValue(double *_value) const
QueryDoubleValue examines the value string. See QueryIntValue().
Definition: tinyxml.cpp:1211
TiXmlAttribute * next
Definition: tinyxml.h:835
void SetName(const char *_name)
Set the name of this attribute.
Definition: tinyxml.h:785
const char * Name() const
Return the name of this attribute.
Definition: tinyxml.h:763
const std::string & ValueStr() const
Return the value of this attribute.
Definition: tinyxml.h:765
TiXmlAttribute * prev
Definition: tinyxml.h:834
void SetValue(const char *_value)
Set the value.
Definition: tinyxml.h:786
int QueryIntValue(int *_value) const
QueryIntValue examines the value string.
Definition: tinyxml.cpp:1204
TIXML_STRING name
Definition: tinyxml.h:832
TiXmlBase is a base class for every class in TinyXml.
Definition: tinyxml.h:170
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding)=0
static bool condenseWhiteSpace
Definition: tinyxml.h:386
friend class TiXmlNode
Definition: tinyxml.h:171
void * userData
Field containing a generic user pointer.
Definition: tinyxml.h:349
static bool StringEqual(const char *p, const char *endTag, bool ignoreCase, TiXmlEncoding encoding)
TiXmlCursor location
Definition: tinyxml.h:346
static Entity entity[NUM_ENTITY]
Definition: tinyxml.h:385
static void EncodeString(const TIXML_STRING &str, TIXML_STRING *out)
Expands entities in a string.
Definition: tinyxml.cpp:44
virtual void Print(FILE *cfile, int depth) const =0
All TinyXml classes can print themselves to a filestream or the string class (TiXmlString in non-STL ...
@ TIXML_ERROR_DOCUMENT_EMPTY
Definition: tinyxml.h:253
@ TIXML_ERROR_DOCUMENT_TOP_ONLY
Definition: tinyxml.h:256
@ TIXML_ERROR_OPENING_FILE
Definition: tinyxml.h:243
An XML comment.
Definition: tinyxml.h:1099
void CopyTo(TiXmlComment *target) const
Definition: tinyxml.cpp:1276
virtual TiXmlNode * Clone() const
Returns a copy of this Comment.
Definition: tinyxml.cpp:1288
virtual void Print(FILE *cfile, int depth) const
All TinyXml classes can print themselves to a filestream or the string class (TiXmlString in non-STL ...
Definition: tinyxml.cpp:1265
virtual bool Accept(TiXmlVisitor *visitor) const
Walk the XML tree visiting this node and all of its children.
Definition: tinyxml.cpp:1282
TiXmlComment & operator=(const TiXmlComment &base)
Definition: tinyxml.cpp:1257
TiXmlComment()
Constructs an empty comment.
Definition: tinyxml.h:1102
In correct XML the declaration is the first entry in the file.
Definition: tinyxml.h:1216
TIXML_STRING standalone
Definition: tinyxml.h:1269
TiXmlDeclaration & operator=(const TiXmlDeclaration &copy)
Definition: tinyxml.cpp:1376
virtual void Print(FILE *cfile, int depth, TIXML_STRING *str) const
Definition: tinyxml.cpp:1384
void CopyTo(TiXmlDeclaration *target) const
Definition: tinyxml.cpp:1406
TIXML_STRING encoding
Definition: tinyxml.h:1268
virtual TiXmlNode * Clone() const
Creates a copy of this Declaration and returns it.
Definition: tinyxml.cpp:1422
virtual bool Accept(TiXmlVisitor *visitor) const
Walk the XML tree visiting this node and all of its children.
Definition: tinyxml.cpp:1416
TiXmlDeclaration()
Construct an empty declaration.
Definition: tinyxml.h:1219
TIXML_STRING version
Definition: tinyxml.h:1267
Always the top level node.
Definition: tinyxml.h:1317
bool SaveFile() const
Save a file using the current document value. Returns true if successful.
Definition: tinyxml.cpp:928
virtual const char * Parse(const char *p, TiXmlParsingData *data=0, TiXmlEncoding encoding=TIXML_DEFAULT_ENCODING)
Parse the given null terminated block of xml data.
void SetError(int err, const char *errorLocation, TiXmlParsingData *prevData, TiXmlEncoding encoding)
virtual bool Accept(TiXmlVisitor *content) const
Walk the XML tree visiting this node and all of its children.
Definition: tinyxml.cpp:1124
bool LoadFile(TiXmlEncoding encoding=TIXML_DEFAULT_ENCODING)
Load a file using the current document value.
Definition: tinyxml.cpp:922
virtual TiXmlNode * Clone() const
Create an exact duplicate of this node and return it.
Definition: tinyxml.cpp:1102
TiXmlDocument()
Create an empty document, that has no name.
Definition: tinyxml.cpp:883
void ClearError()
If you have handled the error, it can be reset with this call.
Definition: tinyxml.h:1430
TiXmlDocument & operator=(const TiXmlDocument &copy)
Definition: tinyxml.cpp:914
TiXmlCursor errorLocation
Definition: tinyxml.h:1470
bool Error() const
If an error occurs, Error will be set to true.
Definition: tinyxml.h:1379
void Print() const
Write the document to standard out using formatted printing ("pretty print").
Definition: tinyxml.h:1438
void CopyTo(TiXmlDocument *target) const
Definition: tinyxml.cpp:1083
TIXML_STRING errorDesc
Definition: tinyxml.h:1468
The element is a container class.
Definition: tinyxml.h:886
const char * Attribute(const char *name) const
Given an attribute name, Attribute() returns the value for the attribute of that name,...
Definition: tinyxml.cpp:564
int QueryIntAttribute(const char *name, int *_value) const
QueryIntAttribute examines the attribute - it is an alternative to the Attribute() method with richer...
Definition: tinyxml.cpp:642
TiXmlElement & operator=(const TiXmlElement &base)
Definition: tinyxml.cpp:538
virtual TiXmlNode * Clone() const
Creates a new Element and returns it - the returned element is a copy.
Definition: tinyxml.cpp:859
void RemoveAttribute(const char *name)
Deletes an attribute with the given name.
Definition: tinyxml.cpp:429
virtual ~TiXmlElement()
Definition: tinyxml.cpp:546
void SetDoubleAttribute(const std::string &name, double value)
Definition: tinyxml.cpp:743
const char * GetText() const
Convenience function for easy access to the text inside an element.
Definition: tinyxml.cpp:870
virtual void Print(FILE *cfile, int depth) const
All TinyXml classes can print themselves to a filestream or the string class (TiXmlString in non-STL ...
Definition: tinyxml.cpp:770
TiXmlAttributeSet attributeSet
Definition: tinyxml.h:1092
void CopyTo(TiXmlElement *target) const
Definition: tinyxml.cpp:823
int QueryBoolAttribute(const char *name, bool *_value) const
QueryBoolAttribute examines the attribute - see QueryIntAttribute().
Definition: tinyxml.cpp:664
virtual bool Accept(TiXmlVisitor *visitor) const
Walk the XML tree visiting this node and all of its children.
Definition: tinyxml.cpp:845
void SetAttribute(const char *name, const char *_value)
Sets an attribute of name to a given value.
Definition: tinyxml.cpp:752
int QueryUnsignedAttribute(const char *name, unsigned *_value) const
QueryUnsignedAttribute examines the attribute - see QueryIntAttribute().
Definition: tinyxml.cpp:651
int QueryDoubleAttribute(const char *name, double *_value) const
QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
Definition: tinyxml.cpp:698
A TiXmlHandle is a class that wraps a node pointer with null checks; this is an incredibly useful thi...
Definition: tinyxml.h:1556
TiXmlHandle FirstChild() const
Return a handle to the first child node.
Definition: tinyxml.cpp:1589
TiXmlHandle ChildElement(const char *value, int index) const
Return a handle to the "index" child element with the given name.
Definition: tinyxml.cpp:1694
TiXmlHandle Child(const char *value, int index) const
Return a handle to the "index" child with the given name.
Definition: tinyxml.cpp:1656
TiXmlNode * node
Definition: tinyxml.h:1629
TiXmlHandle(TiXmlNode *_node)
Create a handle from any node (at any depth of the tree.) This can be a null pointer.
Definition: tinyxml.h:1559
TiXmlHandle FirstChildElement() const
Return a handle to the first child element.
Definition: tinyxml.cpp:1613
The parent class for everything in the Document Object Model.
Definition: tinyxml.h:397
TiXmlNode * LinkEndChild(TiXmlNode *addThis)
Add a new node related to this.
Definition: tinyxml.cpp:178
const TiXmlNode * FirstChild() const
The first child of this node. Will be null if there are no children.
Definition: tinyxml.h:488
TiXmlNode * InsertBeforeChild(TiXmlNode *beforeThis, const TiXmlNode &addThis)
Add a new node related to this.
Definition: tinyxml.cpp:222
TiXmlNode * InsertAfterChild(TiXmlNode *afterThis, const TiXmlNode &addThis)
Add a new node related to this.
Definition: tinyxml.cpp:255
const TiXmlNode * PreviousSibling() const
Navigate to a sibling node.
Definition: tinyxml.h:576
const char * Value() const
The meaning of 'value' changes for the specific type of TiXmlNode.
Definition: tinyxml.h:457
const TiXmlNode * IterateChildren(const TiXmlNode *previous) const
An alternate way to walk the children of a node.
Definition: tinyxml.cpp:377
virtual ~TiXmlNode()
Definition: tinyxml.cpp:139
TIXML_STRING value
Definition: tinyxml.h:715
virtual bool Accept(TiXmlVisitor *visitor) const =0
Accept a hierchical visit the nodes in the TinyXML DOM.
const TiXmlNode * LastChild() const
Definition: tinyxml.h:497
NodeType type
Definition: tinyxml.h:710
virtual TiXmlNode * Clone() const =0
Create an exact duplicate of this node and return it.
const TiXmlNode * NextSibling() const
Navigate to a sibling node.
Definition: tinyxml.h:591
int Type() const
Query the type (as an enumerated value, above) of this node.
Definition: tinyxml.h:640
void CopyTo(TiXmlNode *target) const
Definition: tinyxml.cpp:153
TiXmlNode * prev
Definition: tinyxml.h:717
const TiXmlNode * NextSibling(const std::string &_value) const
STL std::string form.
Definition: tinyxml.h:587
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)=0
TiXmlNode * parent
Definition: tinyxml.h:709
virtual const TiXmlText * ToText() const
Cast to a more defined type. Will return null if not of the requested type.
Definition: tinyxml.h:657
TiXmlNode * next
Definition: tinyxml.h:718
TiXmlNode * firstChild
Definition: tinyxml.h:712
virtual const TiXmlElement * ToElement() const
Cast to a more defined type. Will return null if not of the requested type.
Definition: tinyxml.h:654
TiXmlNode * lastChild
Definition: tinyxml.h:713
const TiXmlElement * NextSiblingElement() const
Convenience function to get through elements.
Definition: tinyxml.cpp:471
void Clear()
Delete all the children of this node. Does not affect 'this'.
Definition: tinyxml.cpp:161
TiXmlNode * ReplaceChild(TiXmlNode *replaceThis, const TiXmlNode &withThis)
Replace a child of this node.
Definition: tinyxml.cpp:288
const TiXmlDocument * GetDocument() const
Return a pointer to the Document this node lives in.
Definition: tinyxml.cpp:501
bool RemoveChild(TiXmlNode *removeThis)
Delete a child of this node.
Definition: tinyxml.cpp:327
friend class TiXmlElement
Definition: tinyxml.h:399
TiXmlNode * InsertEndChild(const TiXmlNode &addThis)
Add a new node related to this.
Definition: tinyxml.cpp:206
NodeType
The types of XML nodes supported by TinyXml.
Definition: tinyxml.h:433
void SetValue(const char *_value)
Changes the value of the node.
Definition: tinyxml.h:476
const TIXML_STRING & ValueTStr() const
Definition: tinyxml.h:465
const TiXmlElement * FirstChildElement() const
Convenience function to get through elements.
Definition: tinyxml.cpp:441
virtual const TiXmlDocument * ToDocument() const
Cast to a more defined type. Will return null if not of the requested type.
Definition: tinyxml.h:653
Print to memory functionality.
Definition: tinyxml.h:1653
virtual bool Visit(const TiXmlDeclaration &declaration)
Visit a declaration.
Definition: tinyxml.cpp:1814
TIXML_STRING buffer
Definition: tinyxml.h:1708
virtual bool VisitExit(const TiXmlDocument &doc)
Visit a document.
Definition: tinyxml.cpp:1718
void SetStreamPrinting()
Switch over to "stream printing" which is the most dense formatting without linebreaks.
Definition: tinyxml.h:1686
const std::string & Str()
Return the result.
Definition: tinyxml.h:1695
virtual bool VisitEnter(const TiXmlDocument &doc)
Visit a document.
Definition: tinyxml.cpp:1713
TiXmlText(const char *initValue)
Constructor for text element.
Definition: tinyxml.h:1154
virtual bool Accept(TiXmlVisitor *content) const
Walk the XML tree visiting this node and all of its children.
Definition: tinyxml.cpp:1328
virtual TiXmlNode * Clone() const
[internal use] Creates a new Element and returns it.
Definition: tinyxml.cpp:1334
virtual void Print(FILE *cfile, int depth) const
All TinyXml classes can print themselves to a filestream or the string class (TiXmlString in non-STL ...
Definition: tinyxml.cpp:1300
void CopyTo(TiXmlText *target) const
Definition: tinyxml.cpp:1321
bool CDATA() const
Queries whether this represents text using a CDATA section.
Definition: tinyxml.h:1175
Any tag that tinyXml doesn't recognize is saved as an unknown.
Definition: tinyxml.h:1281
virtual bool Accept(TiXmlVisitor *content) const
Walk the XML tree visiting this node and all of its children.
Definition: tinyxml.cpp:1448
virtual TiXmlNode * Clone() const
Creates a copy of this Unknown and returns it.
Definition: tinyxml.cpp:1454
void CopyTo(TiXmlUnknown *target) const
Definition: tinyxml.cpp:1442
virtual void Print(FILE *cfile, int depth) const
All TinyXml classes can print themselves to a filestream or the string class (TiXmlString in non-STL ...
Definition: tinyxml.cpp:1434
Implements the interface to the "Visitor pattern" (see the Accept() method.) If you call the Accept()...
Definition: tinyxml.h:104
virtual bool Visit(const TiXmlDeclaration &)
Visit a declaration.
Definition: tinyxml.h:119
virtual bool VisitExit(const TiXmlDocument &)
Visit a document.
Definition: tinyxml.h:111
virtual bool VisitEnter(const TiXmlDocument &)
Visit a document.
Definition: tinyxml.h:109
std::istream & operator>>(std::istream &in, TiXmlNode &base)
Definition: tinyxml.cpp:1555
std::ostream & operator<<(std::ostream &out, const TiXmlNode &base)
Definition: tinyxml.cpp:1566
TiXmlEncoding
Definition: tinyxml.h:139
@ TIXML_ENCODING_UNKNOWN
Definition: tinyxml.h:140
@ TIXML_WRONG_TYPE
Definition: tinyxml.h:133
@ TIXML_SUCCESS
Definition: tinyxml.h:131
@ TIXML_NO_ATTRIBUTE
Definition: tinyxml.h:132
const TiXmlEncoding TIXML_DEFAULT_ENCODING
Definition: tinyxml.h:145
FILE * TiXmlFOpen(const char *filename, const char *mode)
Definition: tinyxml.cpp:39
#define TIXML_STRING
Definition: tinyxml.h:36
#define TIXML_SSCANF
Definition: tinyxml.h:52
#define TIXML_SNPRINTF
Definition: tinyxml.h:51
const unsigned char TIXML_UTF_LEAD_0
const unsigned char TIXML_UTF_LEAD_1
const unsigned char TIXML_UTF_LEAD_2