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