35 #include "gearxml/tinyxml.h"
47 bool TiXmlBase::condenseWhiteSpace =
true;
49 void TiXmlBase::PutString(
const TIXML_STRING& str, TIXML_OSTREAM* stream )
52 PutString( str, &buffer );
56 void TiXmlBase::PutString(
const TIXML_STRING& str, TIXML_STRING* outString )
60 while( i<(
int)str.length() )
62 unsigned char c = (
unsigned char) str[i];
65 && i < ( (
int)str.length() - 2 )
79 while ( i<(
int)str.length()-1 )
81 outString->append( str.c_str() + i, 1 );
89 outString->append( entity[0].str, entity[0].strLength );
94 outString->append( entity[1].str, entity[1].strLength );
99 outString->append( entity[2].str, entity[2].strLength );
102 else if ( c ==
'\"' )
104 outString->append( entity[3].str, entity[3].strLength );
107 else if ( c ==
'\'' )
109 outString->append( entity[4].str, entity[4].strLength );
117 sprintf( buf,
"&#x%02X;", (
unsigned) ( c & 0xff ) );
120 outString->append( buf, (
int)strlen( buf ) );
127 *outString += (char) c;
135 TiXmlBase::StringToBuffer::StringToBuffer(
const TIXML_STRING& str )
137 buffer =
new char[ str.length()+1 ];
140 strcpy( buffer, str.c_str() );
145 TiXmlBase::StringToBuffer::~StringToBuffer()
152 TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase()
163 TiXmlNode::~TiXmlNode()
165 TiXmlNode* node = firstChild;
177 void TiXmlNode::CopyTo( TiXmlNode* target )
const
179 target->SetValue (value.c_str() );
205 node->prev = lastChild;
209 lastChild->next = node;
230 if ( !beforeThis || beforeThis->parent !=
this )
238 node->next = beforeThis;
239 node->prev = beforeThis->prev;
240 if ( beforeThis->prev )
242 beforeThis->prev->next = node;
246 assert( firstChild == beforeThis );
249 beforeThis->prev = node;
256 if ( !afterThis || afterThis->parent !=
this )
264 node->prev = afterThis;
265 node->next = afterThis->next;
266 if ( afterThis->next )
268 afterThis->next->prev = node;
272 assert( lastChild == afterThis );
275 afterThis->next = node;
282 if ( replaceThis->parent !=
this )
289 node->next = replaceThis->next;
290 node->prev = replaceThis->prev;
292 if ( replaceThis->next )
293 replaceThis->next->prev = node;
297 if ( replaceThis->prev )
298 replaceThis->prev->next = node;
310 if ( removeThis->parent !=
this )
316 if ( removeThis->next )
317 removeThis->next->prev = removeThis->prev;
319 lastChild = removeThis->prev;
321 if ( removeThis->prev )
322 removeThis->prev->next = removeThis->next;
324 firstChild = removeThis->next;
333 for ( node = firstChild; node; node = node->next )
335 if ( node->SValue() == _value )
345 for ( node = firstChild; node; node = node->next )
347 if ( node->SValue() == _value )
354 const TiXmlNode* TiXmlNode::LastChild(
const char * _value )
const
357 for ( node = lastChild; node; node = node->prev )
359 if ( node->SValue() == _value )
368 for ( node = lastChild; node; node = node->prev )
370 if ( node->SValue() == _value )
384 assert( previous->parent ==
this );
397 assert( previous->parent ==
this );
410 assert( previous->parent ==
this );
423 assert( previous->parent ==
this );
431 for ( node = next; node; node = node->next )
433 if ( node->SValue() == _value )
442 for ( node = next; node; node = node->next )
444 if ( node->SValue() == _value )
453 for ( node = prev; node; node = node->prev )
455 if ( node->SValue() == _value )
464 for ( node = prev; node; node = node->prev )
466 if ( node->SValue() == _value )
477 attributeSet.Remove( node );
599 for( node =
this; node; node = node->parent )
611 for( node =
this; node; node = node->parent )
622 firstChild = lastChild = 0;
631 firstChild = lastChild = 0;
638 : TiXmlNode( TiXmlNode::ELEMENT )
640 firstChild = lastChild = 0;
645 TiXmlElement& TiXmlElement::operator=(
const TiXmlElement& base )
653 TiXmlElement::~TiXmlElement()
659 void TiXmlElement::ClearThis()
662 while( attributeSet.First() )
664 TiXmlAttribute* node = attributeSet.First();
665 attributeSet.Remove( node );
676 return node->
Value();
714 return TIXML_NO_ATTRIBUTE;
724 return TIXML_NO_ATTRIBUTE;
733 sprintf( buf,
"%d", val );
741 sprintf( buf,
"%.9e", val );
758 attributeSet.Add( attrib );
763 if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
770 for ( i=0; i<depth; i++ )
772 fprintf( cfile,
" " );
775 fprintf( cfile,
"<%s", value.c_str() );
778 for ( attrib = attributeSet.First(); attrib; attrib = attrib->
Next() )
780 fprintf( cfile,
" " );
781 attrib->Print( cfile, depth );
791 fprintf( cfile,
" />" );
793 else if ( firstChild == lastChild && firstChild->
ToText() )
795 fprintf( cfile,
">" );
796 firstChild->
Print( cfile, depth + 1 );
797 fprintf( cfile,
"</%s>", value.c_str() );
801 fprintf( cfile,
">" );
803 for ( node = firstChild; node; node=node->
NextSibling() )
807 fprintf( cfile,
"\n" );
809 node->
Print( cfile, depth+1 );
811 fprintf( cfile,
"\n" );
812 for( i=0; i<depth; ++i )
813 fprintf( cfile,
" " );
814 fprintf( cfile,
"</%s>", value.c_str() );
818 void TiXmlElement::StreamOut( TIXML_OSTREAM * stream )
const
820 (*stream) <<
"<" << value;
823 for ( attrib = attributeSet.First(); attrib; attrib = attrib->
Next() )
826 attrib->StreamOut( stream );
836 for ( node = firstChild; node; node=node->NextSibling() )
838 node->StreamOut( stream );
840 (*stream) <<
"</" << value <<
">";
849 void TiXmlElement::CopyTo( TiXmlElement* target )
const
852 TiXmlNode::CopyTo( target );
856 const TiXmlAttribute* attribute = 0;
857 for( attribute = attributeSet.First();
859 attribute = attribute->
Next() )
861 target->SetAttribute( attribute->Name(), attribute->Value() );
865 for ( node = firstChild; node; node = node->NextSibling() )
867 target->LinkEndChild( node->Clone() );
892 value = documentName;
901 value = documentName;
913 TiXmlDocument& TiXmlDocument::operator=(
const TiXmlDocument& copy )
926 if ( buf.buffer &&
LoadFile( buf.buffer, encoding ) )
938 if ( buf.buffer &&
SaveFile( buf.buffer ) )
960 FILE* file = fopen( value.c_str (),
"r" );
966 fseek( file, 0, SEEK_END );
967 length = ftell( file );
968 fseek( file, 0, SEEK_SET );
980 data.reserve( length );
982 const int BUF_SIZE = 2048;
985 while( fgets( buf, BUF_SIZE, file ) )
991 Parse( data.c_str(), 0, encoding );
998 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
1005 FILE* fp = fopen( filename,
"w" );
1018 TiXmlNode::CopyTo( target );
1020 target->error = error;
1021 target->errorDesc = errorDesc.c_str ();
1024 for ( node = firstChild; node; node = node->
NextSibling() )
1047 node->
Print( cfile, depth );
1048 fprintf( cfile,
"\n" );
1052 void TiXmlDocument::StreamOut( TIXML_OSTREAM * out )
const
1057 node->StreamOut( out );
1072 if ( next->value.empty() && next->name.empty() )
1081 if ( next->value.empty() && next->name.empty() )
1090 if ( prev->value.empty() && prev->name.empty() )
1099 if ( prev->value.empty() && prev->name.empty() )
1108 PutString( name, &n );
1109 PutString( value, &v );
1111 if (value.find (
'\"') == TIXML_STRING::npos)
1112 fprintf (cfile,
"%s=\"%s\"", n.c_str(), v.c_str() );
1114 fprintf (cfile,
"%s='%s'", n.c_str(), v.c_str() );
1118 void TiXmlAttribute::StreamOut( TIXML_OSTREAM * stream )
const
1120 if (value.find(
'\"' ) != TIXML_STRING::npos)
1122 PutString( name, stream );
1123 (*stream) <<
"=" <<
"'";
1124 PutString( value, stream );
1129 PutString( name, stream );
1130 (*stream) <<
"=" <<
"\"";
1131 PutString( value, stream );
1138 if ( sscanf( value.c_str(),
"%d", ival ) == 1 )
1139 return TIXML_SUCCESS;
1140 return TIXML_WRONG_TYPE;
1145 if ( sscanf( value.c_str(),
"%le", dval ) == 1 )
1146 return TIXML_SUCCESS;
1147 return TIXML_WRONG_TYPE;
1153 sprintf (buf,
"%d", _value);
1162 sprintf (buf,
"%.9e", _value);
1168 return atoi (value.c_str ());
1173 return atof (value.c_str ());
1179 copy.CopyTo(
this );
1183 TiXmlComment& TiXmlComment::operator=(
const TiXmlComment& base )
1186 base.CopyTo(
this );
1193 for (
int i=0; i<depth; i++ )
1195 fputs(
" ", cfile );
1197 fprintf( cfile,
"<!--%s-->", value.c_str() );
1200 void TiXmlComment::StreamOut( TIXML_OSTREAM * stream )
const
1202 (*stream) <<
"<!--";
1209 void TiXmlComment::CopyTo( TiXmlComment* target )
const
1211 TiXmlNode::CopyTo( target );
1229 TIXML_STRING buffer;
1230 PutString( value, &buffer );
1231 fprintf( cfile,
"%s", buffer.c_str() );
1235 void TiXmlText::StreamOut( TIXML_OSTREAM * stream )
const
1237 PutString( value, stream );
1241 void TiXmlText::CopyTo( TiXmlText* target )
const
1243 TiXmlNode::CopyTo( target );
1261 const char * _encoding,
1262 const char * _standalone )
1266 encoding = _encoding;
1267 standalone = _standalone;
1271 #ifdef TIXML_USE_STL
1273 const std::string& _encoding,
1274 const std::string& _standalone )
1278 encoding = _encoding;
1279 standalone = _standalone;
1285 : TiXmlNode( TiXmlNode::DECLARATION )
1287 copy.CopyTo(
this );
1291 TiXmlDeclaration& TiXmlDeclaration::operator=(
const TiXmlDeclaration& copy )
1294 copy.CopyTo(
this );
1301 fprintf (cfile,
"<?xml ");
1303 if ( !version.empty() )
1304 fprintf (cfile,
"version=\"%s\" ", version.c_str ());
1305 if ( !encoding.empty() )
1306 fprintf (cfile,
"encoding=\"%s\" ", encoding.c_str ());
1307 if ( !standalone.empty() )
1308 fprintf (cfile,
"standalone=\"%s\" ", standalone.c_str ());
1309 fprintf (cfile,
"?>");
1312 void TiXmlDeclaration::StreamOut( TIXML_OSTREAM * stream )
const
1314 (*stream) <<
"<?xml ";
1316 if ( !version.empty() )
1318 (*stream) <<
"version=\"";
1319 PutString( version, stream );
1322 if ( !encoding.empty() )
1324 (*stream) <<
"encoding=\"";
1325 PutString( encoding, stream );
1326 (*stream ) <<
"\" ";
1328 if ( !standalone.empty() )
1330 (*stream) <<
"standalone=\"";
1331 PutString( standalone, stream );
1338 void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target )
const
1340 TiXmlNode::CopyTo( target );
1342 target->version = version;
1343 target->encoding = encoding;
1344 target->standalone = standalone;
1362 for (
int i=0; i<depth; i++ )
1363 fprintf( cfile,
" " );
1364 fprintf( cfile,
"<%s>", value.c_str() );
1368 void TiXmlUnknown::StreamOut( TIXML_OSTREAM * stream )
const
1370 (*stream) <<
"<" << value <<
">";
1374 void TiXmlUnknown::CopyTo( TiXmlUnknown* target )
const
1376 TiXmlNode::CopyTo( target );
1392 TiXmlAttributeSet::TiXmlAttributeSet()
1394 sentinel.next = &sentinel;
1395 sentinel.prev = &sentinel;
1399 TiXmlAttributeSet::~TiXmlAttributeSet()
1401 assert( sentinel.next == &sentinel );
1402 assert( sentinel.prev == &sentinel );
1406 void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
1408 assert( !Find( addMe->Name() ) );
1410 addMe->next = &sentinel;
1411 addMe->prev = sentinel.prev;
1413 sentinel.prev->next = addMe;
1414 sentinel.prev = addMe;
1417 void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
1419 TiXmlAttribute* node;
1421 for( node = sentinel.next; node != &sentinel; node = node->next )
1423 if ( node == removeMe )
1425 node->prev->next = node->next;
1426 node->next->prev = node->prev;
1435 const TiXmlAttribute* TiXmlAttributeSet::Find(
const char * name )
const
1437 const TiXmlAttribute* node;
1439 for( node = sentinel.next; node != &sentinel; node = node->next )
1441 if ( node->name == name )
1447 TiXmlAttribute* TiXmlAttributeSet::Find(
const char * name )
1449 TiXmlAttribute* node;
1451 for( node = sentinel.next; node != &sentinel; node = node->next )
1453 if ( node->name == name )
1459 #ifdef TIXML_USE_STL
1460 TIXML_ISTREAM & operator >> (TIXML_ISTREAM & in, TiXmlNode & base)
1463 tag.reserve( 8 * 1000 );
1464 base.StreamIn( &in, &tag );
1466 base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
1472 TIXML_OSTREAM & operator<< (TIXML_OSTREAM & out,
const TiXmlNode & base)
1474 base.StreamOut (& out);
1479 #ifdef TIXML_USE_STL
1480 std::string & operator<< (std::string& out,
const TiXmlNode& base )
1482 std::ostringstream os_stream( std::ostringstream::out );
1483 base.StreamOut( &os_stream );
1485 out.append( os_stream.str() );
virtual const char * Parse(const char *p, TiXmlParsingData *data=0, TiXmlEncoding encoding=TIXML_DEFAULT_ENCODING)
Parse the given null terminated block of xml data.
bool SaveFile() const
Save a file using the current document value. Returns true if successful.
TiXmlDeclaration()
Construct an empty declaration.
void SetDoubleValue(double value)
Set the value from a double.
void SetValue(const char *_value)
Set the value.
int IntValue() const
Return the value of this attribute, converted to an integer.
const TiXmlNode * NextSibling(const std::string &_value) const
STL std::string form.
virtual TiXmlNode * Clone() const
Creates a new Element and returns it - the returned element is a copy.
TiXmlElement(const char *in_value)
Construct an element.
virtual void Print(FILE *cfile, int depth) const =0
All TinyXml classes can print themselves to a filestream.
TiXmlNode * LinkEndChild(TiXmlNode *addThis)
Add a new node related to this.
virtual TiXmlNode * Clone() const =0
Create an exact duplicate of this node and return it.
virtual void Print(FILE *cfile, int depth) const
Print this declaration to a FILE stream.
bool LoadFile(TiXmlEncoding encoding=TIXML_DEFAULT_ENCODING)
Load a file using the current document value.
void Clear()
Delete all the children of this node. Does not affect 'this'.
In correct XML the declaration is the first entry in the file.
An attribute is a name-value pair.
virtual TiXmlNode * Clone() const
Creates a copy of this Unknown and returns it.
const TiXmlNode * NextSibling() const
Navigate to a sibling node.
virtual void Print(FILE *cfile, int depth) const
Write this text object to a FILE stream.
void SetIntValue(int value)
Set the value from an integer.
const char * Value() const
The meaning of 'value' changes for the specific type of TiXmlNode.
A TiXmlHandle is a class that wraps a node pointer with null checks; this is an incredibly useful thi...
const TiXmlDocument * ToDocument() const
Cast to a more defined type. Will return null not of the requested type.
virtual void Print(FILE *cfile, int depth) const
Print this Unknown to a FILE stream.
Always the top level node.
double DoubleValue() const
Return the value of this attribute, converted to a double.
TiXmlNode * InsertBeforeChild(TiXmlNode *beforeThis, const TiXmlNode &addThis)
Add a new node related to this.
int QueryDoubleAttribute(const char *name, double *value) const
QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
Any tag that tinyXml doesn't recognize is saved as an unknown.
The parent class for everything in the Document Object Model.
const char * Attribute(const char *name) const
Given an attribute name, Attribute() returns the value for the attribute of that name, or null if none exists.
TiXmlHandle ChildElement(const char *value, int index) const
Return a handle to the "index" child element with the given name.
TiXmlNode * ReplaceChild(TiXmlNode *replaceThis, const TiXmlNode &withThis)
Replace a child of this node.
int QueryDoubleValue(double *value) const
QueryDoubleValue examines the value string. See QueryIntValue().
virtual TiXmlNode * Clone() const
Create an exact duplicate of this node and return it.
const TiXmlElement * ToElement() const
Cast to a more defined type. Will return null not of the requested type.
void * userData
Field containing a generic user pointer.
int QueryIntAttribute(const char *name, int *value) const
QueryIntAttribute examines the attribute - it is an alternative to the Attribute() method with richer...
virtual TiXmlNode * Clone() const
Creates a copy of this Declaration and returns it.
The element is a container class.
const TiXmlNode * PreviousSibling() const
Navigate to a sibling node.
TiXmlNode * InsertEndChild(const TiXmlNode &addThis)
Add a new node related to this.
bool Error() const
If an error occurs, Error will be set to true.
bool RemoveChild(TiXmlNode *removeThis)
Delete a child of this node.
void SetDoubleAttribute(const char *name, double value)
Sets an attribute of name to a given value.
void RemoveAttribute(const char *name)
Deletes an attribute with the given name.
TiXmlHandle(TiXmlNode *aNode)
Create a handle from any node (at any depth of the tree.) This can be a null pointer.
virtual void Print(FILE *cfile, int depth) const
All TinyXml classes can print themselves to a filestream.
void ClearError()
If you have handled the error, it can be reset with this call.
const TiXmlNode * FirstChild() const
The first child of this node. Will be null if there are no children.
TiXmlHandle Child(const char *value, int index) const
Return a handle to the "index" child with the given name.
const char * Value() const
Return the value of this attribute.
TiXmlDocument()
Create an empty document, that has no name.
virtual TiXmlNode * Clone() const
[internal use] Creates a new Element and returns it.
const TiXmlElement * NextSiblingElement() const
Convenience function to get through elements.
TiXmlNode * InsertAfterChild(TiXmlNode *afterThis, const TiXmlNode &addThis)
Add a new node related to this.
TiXmlHandle FirstChildElement() const
Return a handle to the first child element.
int QueryIntValue(int *value) const
QueryIntValue examines the value string.
const TiXmlNode * IterateChildren(const TiXmlNode *previous) const
An alternate way to walk the children of a node.
const TiXmlText * ToText() const
Cast to a more defined type. Will return null not of the requested type.
void SetAttribute(const char *name, const char *value)
Sets an attribute of name to a given value.
virtual void Print(FILE *cfile, int depth) const
All TinyXml classes can print themselves to a filestream.
const TiXmlDocument * GetDocument() const
Return a pointer to the Document this node lives in.
void Print() const
Dump the document to standard out.
const TiXmlAttribute * Next() const
Get the next sibling attribute in the DOM. Returns null at end.
TiXmlText(const char *initValue)
Constructor.
TiXmlHandle FirstChild() const
Return a handle to the first child node.
const TiXmlElement * FirstChildElement() const
Convenience function to get through elements.
const TiXmlAttribute * Previous() const
Get the previous sibling attribute in the DOM. Returns null at beginning.