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