37 FILE* TiXmlFOpen(
const char* filename,
const char* mode );
39 bool TiXmlBase::condenseWhiteSpace =
true;
42 FILE* TiXmlFOpen(
const char* filename,
const char* mode )
44 #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
51 int size = MultiByteToWideChar(CP_UTF8, 0, filename, -1,
54 wchar_t *buffer =
new wchar_t[size];
55 int rc = MultiByteToWideChar(CP_UTF8, 0, filename, -1,
59 err = _wfopen_s( &fp, buffer, mode[0] ==
'w' ? L
"w" : L
"rb" );
70 return fopen( filename, mode );
78 while( i<(
int)str.length() )
80 unsigned char c = (
unsigned char) str[i];
83 && i < ( (
int)str.length() - 2 )
97 while ( i<(
int)str.length()-1 )
99 outString->append( str.c_str() + i, 1 );
107 outString->append( entity[0].str, entity[0].strLength );
112 outString->append( entity[1].str, entity[1].strLength );
117 outString->append( entity[2].str, entity[2].strLength );
120 else if ( c ==
'\"' )
122 outString->append( entity[3].str, entity[3].strLength );
125 else if ( c ==
'\'' )
127 outString->append( entity[4].str, entity[4].strLength );
136 #if defined(TIXML_SNPRINTF)
137 TIXML_SNPRINTF( buf,
sizeof(buf),
"&#x%02X;", (
unsigned) ( c & 0xff ) );
139 sprintf( buf,
"&#x%02X;", (
unsigned) ( c & 0xff ) );
144 outString->append( buf, (
int)strlen( buf ) );
151 *outString += (char) c;
162 firstChild =
nullptr;
169 TiXmlNode::~TiXmlNode()
183 void TiXmlNode::CopyTo(
TiXmlNode* target )
const
186 target->userData = userData;
187 target->location = location;
203 firstChild =
nullptr;
210 assert( node->parent ==
nullptr || node->parent ==
this );
213 if ( node->
Type() == TiXmlNode::TINYXML_DOCUMENT )
216 if (
GetDocument() )
GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY,
nullptr,
nullptr, TIXML_ENCODING_UNKNOWN );
222 node->prev = lastChild;
223 node->next =
nullptr;
226 lastChild->next = node;
237 if ( addThis.
Type() == TiXmlNode::TINYXML_DOCUMENT )
239 if (
GetDocument() )
GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY,
nullptr,
nullptr, TIXML_ENCODING_UNKNOWN );
252 if ( !beforeThis || beforeThis->parent !=
this ) {
255 if ( addThis.
Type() == TiXmlNode::TINYXML_DOCUMENT )
257 if (
GetDocument() )
GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY,
nullptr,
nullptr, TIXML_ENCODING_UNKNOWN );
266 node->next = beforeThis;
267 node->prev = beforeThis->prev;
268 if ( beforeThis->prev )
270 beforeThis->prev->next = node;
274 assert( firstChild == beforeThis );
277 beforeThis->prev = node;
284 if ( !afterThis || afterThis->parent !=
this ) {
287 if ( addThis.
Type() == TiXmlNode::TINYXML_DOCUMENT )
289 if (
GetDocument() )
GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY,
nullptr,
nullptr, TIXML_ENCODING_UNKNOWN );
298 node->prev = afterThis;
299 node->next = afterThis->next;
300 if ( afterThis->next )
302 afterThis->next->prev = node;
306 assert( lastChild == afterThis );
309 afterThis->next = node;
319 if ( replaceThis->parent !=
this )
326 document->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY,
nullptr,
nullptr, TIXML_ENCODING_UNKNOWN );
334 node->next = replaceThis->next;
335 node->prev = replaceThis->prev;
337 if ( replaceThis->next )
338 replaceThis->next->prev = node;
342 if ( replaceThis->prev )
343 replaceThis->prev->next = node;
359 if ( removeThis->parent !=
this )
365 if ( removeThis->next )
366 removeThis->next->prev = removeThis->prev;
368 lastChild = removeThis->prev;
370 if ( removeThis->prev )
371 removeThis->prev->next = removeThis->next;
373 firstChild = removeThis->next;
382 for ( node = firstChild; node; node = node->next )
384 if ( strcmp( node->
Value(), _value ) == 0 )
391 const TiXmlNode* TiXmlNode::LastChild(
const char * _value )
const
394 for ( node = lastChild; node; node = node->prev )
396 if ( strcmp( node->
Value(), _value ) == 0 )
411 assert( previous->parent ==
this );
425 assert( previous->parent ==
this );
434 for ( node = next; node; node = node->next )
436 if ( strcmp( node->
Value(), _value ) == 0 )
446 for ( node = prev; node; node = node->prev )
448 if ( strcmp( node->
Value(), _value ) == 0 )
458 TIXML_STRING str( name );
465 attributeSet.Remove( node );
534 for( node =
this; node; node = node->parent )
546 firstChild = lastChild =
nullptr;
552 TiXmlElement::TiXmlElement(
const std::string& _value )
555 firstChild = lastChild =
nullptr;
564 firstChild = lastChild =
nullptr;
569 void TiXmlElement::operator=(
const TiXmlElement& base )
576 TiXmlElement::~TiXmlElement()
582 void TiXmlElement::ClearThis()
585 while( attributeSet.First() )
588 attributeSet.Remove( node );
598 return node->
Value();
608 return &attrib->ValueStr();
617 const char* result =
nullptr;
620 result = attrib->
Value();
633 const std::string* result =
nullptr;
636 result = &attrib->ValueStr();
649 const char* result =
nullptr;
652 result = attrib->
Value();
665 const std::string* result =
nullptr;
668 result = &attrib->ValueStr();
682 return TIXML_NO_ATTRIBUTE;
692 return TIXML_NO_ATTRIBUTE;
702 return TIXML_NO_ATTRIBUTE;
712 return TIXML_NO_ATTRIBUTE;
782 for ( i=0; i<depth; i++ ) {
783 fprintf( cfile,
" " );
786 fprintf( cfile,
"<%s", value.c_str() );
789 for ( attrib = attributeSet.First(); attrib; attrib = attrib->
Next() )
791 fprintf( cfile,
" " );
792 attrib->
Print( cfile, depth );
802 fprintf( cfile,
" />" );
804 else if ( firstChild == lastChild && firstChild->ToText() )
806 fprintf( cfile,
">" );
807 firstChild->Print( cfile, depth + 1 );
808 fprintf( cfile,
"</%s>", value.c_str() );
812 fprintf( cfile,
">" );
814 for ( node = firstChild; node; node=node->
NextSibling() )
818 fprintf( cfile,
"\n" );
820 node->
Print( cfile, depth+1 );
822 fprintf( cfile,
"\n" );
823 for( i=0; i<depth; ++i ) {
824 fprintf( cfile,
" " );
826 fprintf( cfile,
"</%s>", value.c_str() );
834 TiXmlNode::CopyTo( target );
839 for( attribute = attributeSet.First();
841 attribute = attribute->
Next() )
847 for ( node = firstChild; node; node = node->
NextSibling() )
855 if ( visitor->
VisitEnter( *
this, attributeSet.First() ) )
859 if ( !node->
Accept( visitor ) )
884 return childText->
Value();
894 useMicrosoftBOM =
false;
901 useMicrosoftBOM =
false;
902 value = documentName;
911 useMicrosoftBOM =
false;
912 value = documentName;
944 TIXML_STRING filename( _filename );
948 FILE* file = TiXmlFOpen( value.c_str (),
"rb" );
952 bool result =
LoadFile( file, encoding );
958 SetError( TIXML_ERROR_OPENING_FILE,
nullptr,
nullptr, TIXML_ENCODING_UNKNOWN );
967 SetError( TIXML_ERROR_OPENING_FILE,
nullptr,
nullptr, TIXML_ENCODING_UNKNOWN );
977 fseek( file, 0, SEEK_END );
978 length = ftell( file );
979 fseek( file, 0, SEEK_SET );
984 SetError( TIXML_ERROR_DOCUMENT_EMPTY,
nullptr,
nullptr, TIXML_ENCODING_UNKNOWN );
1009 char* buf =
new char[ length+1 ];
1012 if ( fread( buf, length, 1, file ) != 1 ) {
1014 SetError( TIXML_ERROR_OPENING_FILE,
nullptr,
nullptr, TIXML_ENCODING_UNKNOWN );
1029 const char* p = buf;
1031 const char CR = 0x0d;
1032 const char LF = 0x0a;
1036 assert( p < (buf+length) );
1037 assert( q <= (buf+length) );
1051 assert( q <= (buf+length) );
1054 Parse( buf,
nullptr, encoding );
1064 FILE* fp = TiXmlFOpen( filename,
"w" );
1077 if ( useMicrosoftBOM )
1079 const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
1080 const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
1081 const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
1083 fputc( TIXML_UTF_LEAD_0, fp );
1084 fputc( TIXML_UTF_LEAD_1, fp );
1085 fputc( TIXML_UTF_LEAD_2, fp );
1088 return (ferror(fp) == 0);
1094 TiXmlNode::CopyTo( target );
1096 target->error = error;
1097 target->errorId = errorId;
1098 target->errorDesc = errorDesc;
1099 target->tabsize = tabsize;
1100 target->errorLocation = errorLocation;
1101 target->useMicrosoftBOM = useMicrosoftBOM;
1104 for ( node = firstChild; node; node = node->
NextSibling() )
1127 node->
Print( cfile, depth );
1128 fprintf( cfile,
"\n" );
1139 if ( !node->
Accept( visitor ) )
1151 if ( next->value.empty() && next->name.empty() )
1171 if ( prev->value.empty() && prev->name.empty() )
1194 if (value.find (
'\"') == TIXML_STRING::npos) {
1196 fprintf (cfile,
"%s=\"%s\"", n.c_str(), v.c_str() );
1199 (*str) += n; (*str) +=
"=\""; (*str) += v; (*str) +=
"\"";
1204 fprintf (cfile,
"%s='%s'", n.c_str(), v.c_str() );
1207 (*str) += n; (*str) +=
"='"; (*str) += v; (*str) +=
"'";
1215 if ( TIXML_SSCANF( value.c_str(),
"%d", ival ) == 1 )
1216 return TIXML_SUCCESS;
1217 return TIXML_WRONG_TYPE;
1222 if ( TIXML_SSCANF( value.c_str(),
"%lf", dval ) == 1 )
1223 return TIXML_SUCCESS;
1224 return TIXML_WRONG_TYPE;
1230 #if defined(TIXML_SNPRINTF)
1231 TIXML_SNPRINTF(buf,
sizeof(buf),
"%d", _value);
1233 sprintf (buf,
"%d", _value);
1241 #if defined(TIXML_SNPRINTF)
1242 TIXML_SNPRINTF( buf,
sizeof(buf),
"%g", _value);
1244 sprintf (buf,
"%g", _value);
1251 return atoi (value.c_str ());
1256 return atof (value.c_str ());
1262 copy.CopyTo(
this );
1266 void TiXmlComment::operator=(
const TiXmlComment& base )
1269 base.CopyTo(
this );
1276 for (
int i=0; i<depth; i++ )
1278 fprintf( cfile,
" " );
1280 fprintf( cfile,
"<!--%s-->", value.c_str() );
1284 void TiXmlComment::CopyTo(
TiXmlComment* target )
const
1286 TiXmlNode::CopyTo( target );
1292 return visitor->
Visit( *
this );
1314 fprintf( cfile,
"\n" );
1315 for ( i=0; i<depth; i++ ) {
1316 fprintf( cfile,
" " );
1318 fprintf( cfile,
"<![CDATA[%s]]>\n", value.c_str() );
1322 TIXML_STRING buffer;
1324 fprintf( cfile,
"%s", buffer.c_str() );
1329 void TiXmlText::CopyTo(
TiXmlText* target )
const
1331 TiXmlNode::CopyTo( target );
1332 target->cdata = cdata;
1338 return visitor->
Visit( *
this );
1356 const char * _encoding,
1357 const char * _standalone )
1361 encoding = _encoding;
1362 standalone = _standalone;
1366 #ifdef TIXML_USE_STL
1368 const std::string& _encoding,
1369 const std::string& _standalone )
1373 encoding = _encoding;
1374 standalone = _standalone;
1382 copy.CopyTo(
this );
1389 copy.CopyTo(
this );
1393 void TiXmlDeclaration::Print( FILE* cfile,
int , TIXML_STRING* str )
const
1395 if ( cfile ) fprintf( cfile,
"<?xml " );
1396 if ( str ) (*str) +=
"<?xml ";
1398 if ( !version.empty() ) {
1399 if ( cfile ) fprintf (cfile,
"version=\"%s\" ", version.c_str ());
1400 if ( str ) { (*str) +=
"version=\""; (*str) += version; (*str) +=
"\" "; }
1402 if ( !encoding.empty() ) {
1403 if ( cfile ) fprintf (cfile,
"encoding=\"%s\" ", encoding.c_str ());
1404 if ( str ) { (*str) +=
"encoding=\""; (*str) += encoding; (*str) +=
"\" "; }
1406 if ( !standalone.empty() ) {
1407 if ( cfile ) fprintf (cfile,
"standalone=\"%s\" ", standalone.c_str ());
1408 if ( str ) { (*str) +=
"standalone=\""; (*str) += standalone; (*str) +=
"\" "; }
1410 if ( cfile ) fprintf( cfile,
"?>" );
1411 if ( str ) (*str) +=
"?>";
1417 TiXmlNode::CopyTo( target );
1419 target->version = version;
1420 target->encoding = encoding;
1421 target->standalone = standalone;
1427 return visitor->
Visit( *
this );
1445 for (
int i=0; i<depth; i++ )
1446 fprintf( cfile,
" " );
1447 fprintf( cfile,
"<%s>", value.c_str() );
1451 void TiXmlUnknown::CopyTo(
TiXmlUnknown* target )
const
1453 TiXmlNode::CopyTo( target );
1459 return visitor->
Visit( *
this );
1475 TiXmlAttributeSet::TiXmlAttributeSet()
1477 sentinel.next = &sentinel;
1478 sentinel.prev = &sentinel;
1482 TiXmlAttributeSet::~TiXmlAttributeSet()
1484 assert( sentinel.next == &sentinel );
1485 assert( sentinel.prev == &sentinel );
1491 #ifdef TIXML_USE_STL
1492 assert( !Find( TIXML_STRING( addMe->
Name() ) ) );
1494 assert( !Find( addMe->
Name() ) );
1497 addMe->next = &sentinel;
1498 addMe->prev = sentinel.prev;
1500 sentinel.prev->next = addMe;
1501 sentinel.prev = addMe;
1508 for( node = sentinel.next; node != &sentinel; node = node->next )
1510 if ( node == removeMe )
1512 node->prev->next = node->next;
1513 node->next->prev = node->prev;
1514 node->next =
nullptr;
1515 node->prev =
nullptr;
1523 #ifdef TIXML_USE_STL
1524 TiXmlAttribute* TiXmlAttributeSet::Find(
const std::string& name )
const
1526 for(
TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
1528 if ( node->name == name )
1534 TiXmlAttribute* TiXmlAttributeSet::FindOrCreate(
const std::string& _name )
1547 TiXmlAttribute* TiXmlAttributeSet::Find(
const char* name )
const
1549 for(
TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
1551 if ( strcmp( node->name.c_str(), name ) == 0 )
1558 TiXmlAttribute* TiXmlAttributeSet::FindOrCreate(
const char* _name )
1570 #ifdef TIXML_USE_STL
1571 std::istream& operator>> (std::istream & in,
TiXmlNode & base)
1574 tag.reserve( 8 * 1000 );
1575 base.StreamIn( &in, &tag );
1577 base.Parse( tag.c_str(),
nullptr, TIXML_DEFAULT_ENCODING );
1583 #ifdef TIXML_USE_STL
1584 std::ostream& operator<< (std::ostream & out,
const TiXmlNode & base)
1589 out << printer.Str();
1595 std::string& operator<< (std::string& out,
const TiXmlNode& base )
1600 out.append( printer.Str() );
1623 TiXmlNode* child = node->FirstChild( value );
1647 TiXmlElement* child = node->FirstChildElement( value );
1679 TiXmlNode* child = node->FirstChild( value );
1717 TiXmlElement* child = node->FirstChildElement( value );
1745 buffer += element.
Value();
1747 for(
const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->
Next() )
1750 attrib->
Print(
nullptr, 0, &buffer );
1762 && element.LastChild() == element.
FirstChild()
1765 simpleTextPrint =
true;
1787 if ( simpleTextPrint )
1789 simpleTextPrint =
false;
1796 buffer += element.
Value();
1809 buffer +=
"<![CDATA[";
1810 buffer += text.
Value();
1814 else if ( simpleTextPrint )
1835 declaration.Print(
nullptr, 0, &buffer );
1845 buffer += comment.
Value();
1856 buffer += unknown.
Value();