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 void TiXmlElement::operator=(
const TiXmlElement& base )
652 TiXmlElement::~TiXmlElement()
658 void TiXmlElement::ClearThis()
661 while( attributeSet.First() )
663 TiXmlAttribute* node = attributeSet.First();
664 attributeSet.Remove( node );
675 return node->
Value();
713 return TIXML_NO_ATTRIBUTE;
723 return TIXML_NO_ATTRIBUTE;
732 sprintf( buf,
"%d", val );
740 sprintf( buf,
"%.9e", val );
757 attributeSet.Add( attrib );
762 if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
769 for ( i=0; i<depth; i++ )
771 fprintf( cfile,
" " );
774 fprintf( cfile,
"<%s", value.c_str() );
777 for ( attrib = attributeSet.First(); attrib; attrib = attrib->
Next() )
779 fprintf( cfile,
" " );
780 attrib->Print( cfile, depth );
790 fprintf( cfile,
" />" );
792 else if ( firstChild == lastChild && firstChild->
ToText() )
794 fprintf( cfile,
">" );
795 firstChild->
Print( cfile, depth + 1 );
796 fprintf( cfile,
"</%s>", value.c_str() );
800 fprintf( cfile,
">" );
802 for ( node = firstChild; node; node=node->
NextSibling() )
806 fprintf( cfile,
"\n" );
808 node->
Print( cfile, depth+1 );
810 fprintf( cfile,
"\n" );
811 for( i=0; i<depth; ++i )
812 fprintf( cfile,
" " );
813 fprintf( cfile,
"</%s>", value.c_str() );
817 void TiXmlElement::StreamOut( TIXML_OSTREAM * stream )
const
819 (*stream) <<
"<" << value;
822 for ( attrib = attributeSet.First(); attrib; attrib = attrib->
Next() )
825 attrib->StreamOut( stream );
835 for ( node = firstChild; node; node=node->NextSibling() )
837 node->StreamOut( stream );
839 (*stream) <<
"</" << value <<
">";
848 void TiXmlElement::CopyTo( TiXmlElement* target )
const
851 TiXmlNode::CopyTo( target );
855 const TiXmlAttribute* attribute = 0;
856 for( attribute = attributeSet.First();
858 attribute = attribute->
Next() )
860 target->SetAttribute( attribute->Name(), attribute->Value() );
864 for ( node = firstChild; node; node = node->NextSibling() )
866 target->LinkEndChild( node->Clone() );
891 value = documentName;
900 value = documentName;
912 void TiXmlDocument::operator=(
const TiXmlDocument& copy )
924 if ( buf.buffer &&
LoadFile( buf.buffer, encoding ) )
936 if ( buf.buffer &&
SaveFile( buf.buffer ) )
958 FILE* file = fopen( value.c_str (),
"r" );
964 fseek( file, 0, SEEK_END );
965 length = ftell( file );
966 fseek( file, 0, SEEK_SET );
978 data.reserve( length );
980 const int BUF_SIZE = 2048;
983 while( fgets( buf, BUF_SIZE, file ) )
989 Parse( data.c_str(), 0, encoding );
996 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
1003 FILE* fp = fopen( filename,
"w" );
1016 TiXmlNode::CopyTo( target );
1018 target->error = error;
1019 target->errorDesc = errorDesc.c_str ();
1022 for ( node = firstChild; node; node = node->
NextSibling() )
1045 node->
Print( cfile, depth );
1046 fprintf( cfile,
"\n" );
1050 void TiXmlDocument::StreamOut( TIXML_OSTREAM * out )
const
1055 node->StreamOut( out );
1070 if ( next->value.empty() && next->name.empty() )
1079 if ( next->value.empty() && next->name.empty() )
1088 if ( prev->value.empty() && prev->name.empty() )
1097 if ( prev->value.empty() && prev->name.empty() )
1106 PutString( name, &n );
1107 PutString( value, &v );
1109 if (value.find (
'\"') == TIXML_STRING::npos)
1110 fprintf (cfile,
"%s=\"%s\"", n.c_str(), v.c_str() );
1112 fprintf (cfile,
"%s='%s'", n.c_str(), v.c_str() );
1116 void TiXmlAttribute::StreamOut( TIXML_OSTREAM * stream )
const
1118 if (value.find(
'\"' ) != TIXML_STRING::npos)
1120 PutString( name, stream );
1121 (*stream) <<
"=" <<
"'";
1122 PutString( value, stream );
1127 PutString( name, stream );
1128 (*stream) <<
"=" <<
"\"";
1129 PutString( value, stream );
1136 if ( sscanf( value.c_str(),
"%d", ival ) == 1 )
1137 return TIXML_SUCCESS;
1138 return TIXML_WRONG_TYPE;
1143 if ( sscanf( value.c_str(),
"%le", dval ) == 1 )
1144 return TIXML_SUCCESS;
1145 return TIXML_WRONG_TYPE;
1151 sprintf (buf,
"%d", _value);
1160 sprintf (buf,
"%.9e", _value);
1166 return atoi (value.c_str ());
1171 return atof (value.c_str ());
1177 copy.CopyTo(
this );
1181 void TiXmlComment::operator=(
const TiXmlComment& base )
1184 base.CopyTo(
this );
1190 for (
int i=0; i<depth; i++ )
1192 fputs(
" ", cfile );
1194 fprintf( cfile,
"<!--%s-->", value.c_str() );
1197 void TiXmlComment::StreamOut( TIXML_OSTREAM * stream )
const
1199 (*stream) <<
"<!--";
1206 void TiXmlComment::CopyTo( TiXmlComment* target )
const
1208 TiXmlNode::CopyTo( target );
1226 TIXML_STRING buffer;
1227 PutString( value, &buffer );
1228 fprintf( cfile,
"%s", buffer.c_str() );
1232 void TiXmlText::StreamOut( TIXML_OSTREAM * stream )
const
1234 PutString( value, stream );
1238 void TiXmlText::CopyTo( TiXmlText* target )
const
1240 TiXmlNode::CopyTo( target );
1258 const char * _encoding,
1259 const char * _standalone )
1263 encoding = _encoding;
1264 standalone = _standalone;
1268 #ifdef TIXML_USE_STL
1270 const std::string& _encoding,
1271 const std::string& _standalone )
1275 encoding = _encoding;
1276 standalone = _standalone;
1282 : TiXmlNode( TiXmlNode::DECLARATION )
1284 copy.CopyTo(
this );
1288 void TiXmlDeclaration::operator=(
const TiXmlDeclaration& copy )
1291 copy.CopyTo(
this );
1297 fprintf (cfile,
"<?xml ");
1299 if ( !version.empty() )
1300 fprintf (cfile,
"version=\"%s\" ", version.c_str ());
1301 if ( !encoding.empty() )
1302 fprintf (cfile,
"encoding=\"%s\" ", encoding.c_str ());
1303 if ( !standalone.empty() )
1304 fprintf (cfile,
"standalone=\"%s\" ", standalone.c_str ());
1305 fprintf (cfile,
"?>");
1308 void TiXmlDeclaration::StreamOut( TIXML_OSTREAM * stream )
const
1310 (*stream) <<
"<?xml ";
1312 if ( !version.empty() )
1314 (*stream) <<
"version=\"";
1315 PutString( version, stream );
1318 if ( !encoding.empty() )
1320 (*stream) <<
"encoding=\"";
1321 PutString( encoding, stream );
1322 (*stream ) <<
"\" ";
1324 if ( !standalone.empty() )
1326 (*stream) <<
"standalone=\"";
1327 PutString( standalone, stream );
1334 void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target )
const
1336 TiXmlNode::CopyTo( target );
1338 target->version = version;
1339 target->encoding = encoding;
1340 target->standalone = standalone;
1358 for (
int i=0; i<depth; i++ )
1359 fprintf( cfile,
" " );
1360 fprintf( cfile,
"<%s>", value.c_str() );
1364 void TiXmlUnknown::StreamOut( TIXML_OSTREAM * stream )
const
1366 (*stream) <<
"<" << value <<
">";
1370 void TiXmlUnknown::CopyTo( TiXmlUnknown* target )
const
1372 TiXmlNode::CopyTo( target );
1388 TiXmlAttributeSet::TiXmlAttributeSet()
1390 sentinel.next = &sentinel;
1391 sentinel.prev = &sentinel;
1395 TiXmlAttributeSet::~TiXmlAttributeSet()
1397 assert( sentinel.next == &sentinel );
1398 assert( sentinel.prev == &sentinel );
1402 void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
1404 assert( !Find( addMe->Name() ) );
1406 addMe->next = &sentinel;
1407 addMe->prev = sentinel.prev;
1409 sentinel.prev->next = addMe;
1410 sentinel.prev = addMe;
1413 void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
1415 TiXmlAttribute* node;
1417 for( node = sentinel.next; node != &sentinel; node = node->next )
1419 if ( node == removeMe )
1421 node->prev->next = node->next;
1422 node->next->prev = node->prev;
1431 const TiXmlAttribute* TiXmlAttributeSet::Find(
const char * name )
const
1433 const TiXmlAttribute* node;
1435 for( node = sentinel.next; node != &sentinel; node = node->next )
1437 if ( node->name == name )
1443 TiXmlAttribute* TiXmlAttributeSet::Find(
const char * name )
1445 TiXmlAttribute* node;
1447 for( node = sentinel.next; node != &sentinel; node = node->next )
1449 if ( node->name == name )
1455 #ifdef TIXML_USE_STL
1456 TIXML_ISTREAM & operator >> (TIXML_ISTREAM & in, TiXmlNode & base)
1459 tag.reserve( 8 * 1000 );
1460 base.StreamIn( &in, &tag );
1462 base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
1468 TIXML_OSTREAM & operator<< (TIXML_OSTREAM & out,
const TiXmlNode & base)
1470 base.StreamOut (& out);
1475 #ifdef TIXML_USE_STL
1476 std::string & operator<< (std::string& out,
const TiXmlNode& base )
1478 std::ostringstream os_stream( std::ostringstream::out );
1479 base.StreamOut( &os_stream );
1481 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.
TiXmlHandle(TiXmlNode *node)
Create a handle from any node (at any depth of the tree.) This can be a null pointer.
void RemoveAttribute(const char *name)
Deletes an attribute with the given name.
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.