35 bool TiXmlBase::condenseWhiteSpace =
true;
38 FILE* TiXmlFOpen(
const char* filename,
const char* mode )
40 #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
42 errno_t err = fopen_s( &fp, filename, mode );
47 return fopen( filename, mode );
55 while( i<(
int)str.length() )
57 unsigned char c = (
unsigned char) str[i];
60 && i < ( (
int)str.length() - 2 )
74 while ( i<(
int)str.length()-1 )
76 outString->append( str.c_str() + i, 1 );
84 outString->append( entity[0].str, entity[0].strLength );
89 outString->append( entity[1].str, entity[1].strLength );
94 outString->append( entity[2].str, entity[2].strLength );
99 outString->append( entity[3].str, entity[3].strLength );
102 else if ( c ==
'\'' )
104 outString->append( entity[4].str, entity[4].strLength );
113 #if defined(TIXML_SNPRINTF)
114 TIXML_SNPRINTF( buf,
sizeof(buf),
"&#x%02X;", (
unsigned) ( c & 0xff ) );
116 sprintf( buf,
"&#x%02X;", (
unsigned) ( c & 0xff ) );
121 outString->append( buf, (
int)strlen( buf ) );
128 *outString += (char) c;
135 TiXmlNode::TiXmlNode( NodeType _type ) :
TiXmlBase()
146 TiXmlNode::~TiXmlNode()
160 void TiXmlNode::CopyTo(
TiXmlNode* target )
const
186 assert( node->parent == 0 || node->parent ==
this );
189 if ( node->
Type() == TiXmlNode::DOCUMENT )
192 if (
GetDocument() )
GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
198 node->prev = lastChild;
202 lastChild->next = node;
213 if ( addThis.
Type() == TiXmlNode::DOCUMENT )
215 if (
GetDocument() )
GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
228 if ( !beforeThis || beforeThis->parent !=
this ) {
231 if ( addThis.
Type() == TiXmlNode::DOCUMENT )
233 if (
GetDocument() )
GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
242 node->next = beforeThis;
243 node->prev = beforeThis->prev;
244 if ( beforeThis->prev )
246 beforeThis->prev->next = node;
250 assert( firstChild == beforeThis );
253 beforeThis->prev = node;
260 if ( !afterThis || afterThis->parent !=
this ) {
263 if ( addThis.
Type() == TiXmlNode::DOCUMENT )
265 if (
GetDocument() )
GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
274 node->prev = afterThis;
275 node->next = afterThis->next;
276 if ( afterThis->next )
278 afterThis->next->prev = node;
282 assert( lastChild == afterThis );
285 afterThis->next = node;
292 if ( replaceThis->parent !=
this )
299 node->next = replaceThis->next;
300 node->prev = replaceThis->prev;
302 if ( replaceThis->next )
303 replaceThis->next->prev = node;
307 if ( replaceThis->prev )
308 replaceThis->prev->next = node;
320 if ( removeThis->parent !=
this )
326 if ( removeThis->next )
327 removeThis->next->prev = removeThis->prev;
329 lastChild = removeThis->prev;
331 if ( removeThis->prev )
332 removeThis->prev->next = removeThis->next;
334 firstChild = removeThis->next;
343 for ( node = firstChild; node; node = node->next )
345 if ( strcmp( node->
Value(), _value ) == 0 )
352 const TiXmlNode* TiXmlNode::LastChild(
const char * _value )
const
355 for ( node = lastChild; node; node = node->prev )
357 if ( strcmp( node->
Value(), _value ) == 0 )
372 assert( previous->parent ==
this );
386 assert( previous->parent ==
this );
395 for ( node = next; node; node = node->next )
397 if ( strcmp( node->
Value(), _value ) == 0 )
407 for ( node = prev; node; node = node->prev )
409 if ( strcmp( node->
Value(), _value ) == 0 )
419 TIXML_STRING str( name );
426 attributeSet.Remove( node );
495 for( node =
this; node; node = node->parent )
507 firstChild = lastChild = 0;
516 firstChild = lastChild = 0;
525 firstChild = lastChild = 0;
530 void TiXmlElement::operator=(
const TiXmlElement& base )
537 TiXmlElement::~TiXmlElement()
543 void TiXmlElement::ClearThis()
546 while( attributeSet.First() )
549 attributeSet.Remove( node );
559 return node->
Value();
569 return &node->ValueStr();
594 const std::string* s =
Attribute( name );
598 *i = atoi( s->c_str() );
628 const std::string* s =
Attribute( name );
632 *d = atof( s->c_str() );
647 return TIXML_NO_ATTRIBUTE;
657 return TIXML_NO_ATTRIBUTE;
667 return TIXML_NO_ATTRIBUTE;
677 return TIXML_NO_ATTRIBUTE;
686 #if defined(TIXML_SNPRINTF)
687 TIXML_SNPRINTF( buf,
sizeof(buf),
"%d", val );
689 sprintf( buf,
"%d", val );
698 std::ostringstream oss;
708 #if defined(TIXML_SNPRINTF)
709 TIXML_SNPRINTF( buf,
sizeof(buf),
"%f", val );
711 sprintf( buf,
"%f", val );
720 TIXML_STRING _name( cname );
721 TIXML_STRING _value( cvalue );
723 const char* _name = cname;
724 const char* _value = cvalue;
737 attributeSet.Add( attrib );
742 if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
760 attributeSet.Add( attrib );
765 if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
775 for ( i=0; i<depth; i++ ) {
776 fprintf( cfile,
" " );
779 fprintf( cfile,
"<%s", value.c_str() );
782 for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
784 fprintf( cfile,
" " );
785 attrib->Print( cfile, depth );
795 fprintf( cfile,
" />" );
797 else if ( firstChild == lastChild && firstChild->
ToText() )
799 fprintf( cfile,
">" );
800 firstChild->
Print( cfile, depth + 1 );
801 fprintf( cfile,
"</%s>", value.c_str() );
805 fprintf( cfile,
">" );
807 for ( node = firstChild; node; node=node->
NextSibling() )
811 fprintf( cfile,
"\n" );
813 node->
Print( cfile, depth+1 );
815 fprintf( cfile,
"\n" );
816 for( i=0; i<depth; ++i ) {
817 fprintf( cfile,
" " );
819 fprintf( cfile,
"</%s>", value.c_str() );
827 TiXmlNode::CopyTo( target );
832 for( attribute = attributeSet.First();
834 attribute = attribute->
Next() )
840 for ( node = firstChild; node; node = node->
NextSibling() )
848 if ( visitor->
VisitEnter( *
this, attributeSet.First() ) )
852 if ( !node->
Accept( visitor ) )
877 return childText->
Value();
887 useMicrosoftBOM =
false;
894 useMicrosoftBOM =
false;
895 value = documentName;
904 useMicrosoftBOM =
false;
905 value = documentName;
954 TIXML_STRING filename( _filename );
958 FILE* file = TiXmlFOpen( value.c_str (),
"rb" );
962 bool result =
LoadFile( file, encoding );
968 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
977 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
987 fseek( file, 0, SEEK_END );
988 length = ftell( file );
989 fseek( file, 0, SEEK_SET );
994 SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
1001 data.reserve( length );
1024 char* buf =
new char[ length+1 ];
1027 if ( fread( buf, length, 1, file ) != 1 ) {
1029 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
1033 const char* lastPos = buf;
1034 const char* p = buf;
1038 assert( p < (buf+length) );
1042 data.append( lastPos, (p-lastPos+1) );
1045 assert( p <= (buf+length) );
1047 else if ( *p == 0xd ) {
1050 if ( (p-lastPos) > 0 ) {
1051 data.append( lastPos, p-lastPos );
1055 if ( *(p+1) == 0xa ) {
1059 assert( p <= (buf+length) );
1065 assert( p <= (buf+length) );
1074 data.append( lastPos, p-lastPos );
1079 Parse( data.c_str(), 0, encoding );
1091 FILE* fp = TiXmlFOpen( filename,
"w" );
1104 if ( useMicrosoftBOM )
1106 const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
1107 const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
1108 const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
1110 fputc( TIXML_UTF_LEAD_0, fp );
1111 fputc( TIXML_UTF_LEAD_1, fp );
1112 fputc( TIXML_UTF_LEAD_2, fp );
1115 return (ferror(fp) == 0);
1121 TiXmlNode::CopyTo( target );
1123 target->error = error;
1124 target->errorId = errorId;
1125 target->errorDesc = errorDesc;
1126 target->tabsize = tabsize;
1127 target->errorLocation = errorLocation;
1128 target->useMicrosoftBOM = useMicrosoftBOM;
1131 for ( node = firstChild; node; node = node->
NextSibling() )
1154 node->
Print( cfile, depth );
1155 fprintf( cfile,
"\n" );
1166 if ( !node->
Accept( visitor ) )
1178 if ( next->value.empty() && next->name.empty() )
1198 if ( prev->value.empty() && prev->name.empty() )
1221 if (value.find (
'\"') == TIXML_STRING::npos) {
1223 fprintf (cfile,
"%s=\"%s\"", n.c_str(), v.c_str() );
1226 (*str) += n; (*str) +=
"=\""; (*str) += v; (*str) +=
"\"";
1231 fprintf (cfile,
"%s='%s'", n.c_str(), v.c_str() );
1234 (*str) += n; (*str) +=
"='"; (*str) += v; (*str) +=
"'";
1242 if ( TIXML_SSCANF( value.c_str(),
"%d", ival ) == 1 )
1243 return TIXML_SUCCESS;
1244 return TIXML_WRONG_TYPE;
1249 if ( TIXML_SSCANF( value.c_str(),
"%lf", dval ) == 1 )
1250 return TIXML_SUCCESS;
1251 return TIXML_WRONG_TYPE;
1257 #if defined(TIXML_SNPRINTF)
1258 TIXML_SNPRINTF(buf,
sizeof(buf),
"%d", _value);
1260 sprintf (buf,
"%d", _value);
1268 #if defined(TIXML_SNPRINTF)
1269 TIXML_SNPRINTF( buf,
sizeof(buf),
"%lf", _value);
1271 sprintf (buf,
"%lf", _value);
1278 return atoi (value.c_str ());
1283 return atof (value.c_str ());
1289 copy.CopyTo(
this );
1293 void TiXmlComment::operator=(
const TiXmlComment& base )
1296 base.CopyTo(
this );
1303 for (
int i=0; i<depth; i++ )
1305 fprintf( cfile,
" " );
1307 fprintf( cfile,
"<!--%s-->", value.c_str() );
1311 void TiXmlComment::CopyTo(
TiXmlComment* target )
const
1313 TiXmlNode::CopyTo( target );
1319 return visitor->
Visit( *
this );
1341 fprintf( cfile,
"\n" );
1342 for ( i=0; i<depth; i++ ) {
1343 fprintf( cfile,
" " );
1345 fprintf( cfile,
"<![CDATA[%s]]>\n", value.c_str() );
1349 TIXML_STRING buffer;
1351 fprintf( cfile,
"%s", buffer.c_str() );
1356 void TiXmlText::CopyTo(
TiXmlText* target )
const
1358 TiXmlNode::CopyTo( target );
1359 target->cdata = cdata;
1365 return visitor->
Visit( *
this );
1383 const char * _encoding,
1384 const char * _standalone )
1388 encoding = _encoding;
1389 standalone = _standalone;
1393 #ifdef TIXML_USE_STL
1395 const std::string& _encoding,
1396 const std::string& _standalone )
1400 encoding = _encoding;
1401 standalone = _standalone;
1409 copy.CopyTo(
this );
1416 copy.CopyTo(
this );
1420 void TiXmlDeclaration::Print( FILE* cfile,
int , TIXML_STRING* str )
const
1422 if ( cfile ) fprintf( cfile,
"<?xml " );
1423 if ( str ) (*str) +=
"<?xml ";
1425 if ( !version.empty() ) {
1426 if ( cfile ) fprintf (cfile,
"version=\"%s\" ", version.c_str ());
1427 if ( str ) { (*str) +=
"version=\""; (*str) += version; (*str) +=
"\" "; }
1429 if ( !encoding.empty() ) {
1430 if ( cfile ) fprintf (cfile,
"encoding=\"%s\" ", encoding.c_str ());
1431 if ( str ) { (*str) +=
"encoding=\""; (*str) += encoding; (*str) +=
"\" "; }
1433 if ( !standalone.empty() ) {
1434 if ( cfile ) fprintf (cfile,
"standalone=\"%s\" ", standalone.c_str ());
1435 if ( str ) { (*str) +=
"standalone=\""; (*str) += standalone; (*str) +=
"\" "; }
1437 if ( cfile ) fprintf( cfile,
"?>" );
1438 if ( str ) (*str) +=
"?>";
1444 TiXmlNode::CopyTo( target );
1446 target->version = version;
1447 target->encoding = encoding;
1448 target->standalone = standalone;
1454 return visitor->
Visit( *
this );
1472 for (
int i=0; i<depth; i++ )
1473 fprintf( cfile,
" " );
1474 fprintf( cfile,
"<%s>", value.c_str() );
1478 void TiXmlUnknown::CopyTo(
TiXmlUnknown* target )
const
1480 TiXmlNode::CopyTo( target );
1486 return visitor->
Visit( *
this );
1502 TiXmlAttributeSet::TiXmlAttributeSet()
1504 sentinel.next = &sentinel;
1505 sentinel.prev = &sentinel;
1509 TiXmlAttributeSet::~TiXmlAttributeSet()
1511 assert( sentinel.next == &sentinel );
1512 assert( sentinel.prev == &sentinel );
1518 #ifdef TIXML_USE_STL
1519 assert( !Find( TIXML_STRING( addMe->
Name() ) ) );
1521 assert( !Find( addMe->
Name() ) );
1524 addMe->next = &sentinel;
1525 addMe->prev = sentinel.prev;
1527 sentinel.prev->next = addMe;
1528 sentinel.prev = addMe;
1535 for( node = sentinel.next; node != &sentinel; node = node->next )
1537 if ( node == removeMe )
1539 node->prev->next = node->next;
1540 node->next->prev = node->prev;
1550 #ifdef TIXML_USE_STL
1551 const TiXmlAttribute* TiXmlAttributeSet::Find(
const std::string& name )
const
1553 for(
const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
1555 if ( node->name == name )
1575 const TiXmlAttribute* TiXmlAttributeSet::Find(
const char* name )
const
1577 for(
const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
1579 if ( strcmp( node->name.c_str(), name ) == 0 )
1597 #ifdef TIXML_USE_STL
1598 std::istream& operator>> (std::istream & in,
TiXmlNode & base)
1601 tag.reserve( 8 * 1000 );
1602 base.StreamIn( &in, &tag );
1604 base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
1610 #ifdef TIXML_USE_STL
1611 std::ostream& operator<< (std::ostream & out,
const TiXmlNode & base)
1616 out << printer.Str();
1622 std::string& operator<< (std::string& out,
const TiXmlNode& base )
1627 out.append( printer.Str() );
1650 TiXmlNode* child = node->FirstChild( value );
1674 TiXmlElement* child = node->FirstChildElement( value );
1706 TiXmlNode* child = node->FirstChild( value );
1744 TiXmlElement* child = node->FirstChildElement( value );
1772 buffer += element.
Value();
1774 for(
const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->
Next() )
1777 attrib->
Print( 0, 0, &buffer );
1789 && element.LastChild() == element.
FirstChild()
1792 simpleTextPrint =
true;
1814 if ( simpleTextPrint )
1816 simpleTextPrint =
false;
1823 buffer += element.
Value();
1836 buffer +=
"<![CDATA[";
1837 buffer += text.
Value();
1841 else if ( simpleTextPrint )
1862 declaration.Print( 0, 0, &buffer );
1872 buffer += comment.
Value();
1883 buffer += unknown.
Value();