summaryrefslogtreecommitdiff
path: root/plugins/UserInfoEx/src/ex_import/tinyxml.cpp
diff options
context:
space:
mode:
authorKirill Volinsky <mataes2007@gmail.com>2013-07-25 15:32:06 +0000
committerKirill Volinsky <mataes2007@gmail.com>2013-07-25 15:32:06 +0000
commita757184e5db3112d3de0b69eec7d39b937e396bc (patch)
treee903787b3ca3af22a4d95ddf757e178b23da8619 /plugins/UserInfoEx/src/ex_import/tinyxml.cpp
parent33ebc5347bee5432ca63efb330acdd5a3b82f3fd (diff)
replace sprintf to mir_snprintf (part 5)
git-svn-id: http://svn.miranda-ng.org/main/trunk@5481 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/UserInfoEx/src/ex_import/tinyxml.cpp')
-rw-r--r--plugins/UserInfoEx/src/ex_import/tinyxml.cpp3887
1 files changed, 1933 insertions, 1954 deletions
diff --git a/plugins/UserInfoEx/src/ex_import/tinyxml.cpp b/plugins/UserInfoEx/src/ex_import/tinyxml.cpp
index b9d491b53e..0faa453a14 100644
--- a/plugins/UserInfoEx/src/ex_import/tinyxml.cpp
+++ b/plugins/UserInfoEx/src/ex_import/tinyxml.cpp
@@ -1,1955 +1,1934 @@
-/*
-www.sourceforge.net/projects/tinyxml
-Original code (2.0 and earlier)copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any
-damages arising from the use of this software.
-
-Permission is granted to anyone to use this software for any
-purpose, including commercial applications, and to alter it and
-redistribute it freely, subject to the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must
-not claim that you wrote the original software. If you use this
-software in a product, an acknowledgment in the product documentation
-would be appreciated but is not required.
-
-2. Altered source versions must be plainly marked as such, and
-must not be misrepresented as being the original software.
-
-3. This notice may not be removed or altered from any source
-distribution.
-
-===============================================================================
-
-UserinfoEx plugin for Miranda IM
-
-Copyright:
-© 2006-2010 DeathAxe, Yasnovidyashii, Merlin, K. Romanov, Kreol
-===============================================================================
- */
-
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier)copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+
+===============================================================================
+
+UserinfoEx plugin for Miranda IM
+
+Copyright:
+© 2006-2010 DeathAxe, Yasnovidyashii, Merlin, K. Romanov, Kreol
+===============================================================================
+ */
+
#include "..\commonheaders.h"
-
-bool TiXmlBase::condenseWhiteSpace = true;
-
-void TiXmlBase::StreamDepth(TIXML_OSTREAM* stream, int depth) const
-{
- for (int i = 0; i < depth; ++i)
- {
- (*stream) << " ";
- }
-}
-
-void TiXmlBase::PutString(const TIXML_STRING& str, TIXML_OSTREAM* stream)
-{
- TIXML_STRING buffer;
- PutString(str, &buffer);
- (*stream) << buffer;
-}
-
-void TiXmlBase::PutString(const TIXML_STRING& str, TIXML_STRING* outString)
-{
- int i=0;
-
- while (i<(int)str.length())
- {
- unsigned char c = (unsigned char) str[i];
-
- if ( c == '&'
- && i < ((int)str.length() - 2)
- && str[i+1] == '#'
- && str[i+2] == 'x')
- {
- // Hexadecimal character reference.
- // Pass through unchanged.
- // &#xA9; -- copyright symbol, for example.
- //
- // The -1 is a bug fix from Rob Laveaux. It keeps
- // an overflow from happening if there is no ';'.
- // There are actually 2 ways to exit this loop -
- // while fails (error case) and break (semicolon found).
- // However, there is no mechanism (currently) for
- // this function to return an error.
- while (i<(int)str.length()-1)
- {
- outString->append(str.c_str() + i, 1);
- ++i;
- if (str[i] == ';')
- break;
- }
- }
- else if (c == '&')
- {
- outString->append(entity[0].str, entity[0].strLength);
- ++i;
- }
- else if (c == '<')
- {
- outString->append(entity[1].str, entity[1].strLength);
- ++i;
- }
- else if (c == '>')
- {
- outString->append(entity[2].str, entity[2].strLength);
- ++i;
- }
- else if (c == '\"')
- {
- outString->append(entity[3].str, entity[3].strLength);
- ++i;
- }
- else if (c == '\'')
- {
- outString->append(entity[4].str, entity[4].strLength);
- ++i;
- }
- else if (c < 32)
- {
- // Easy pass at non-alpha/numeric/symbol
- // Below 32 is symbolic.
- char buf[ 32 ];
-
- #if defined(TIXML_SNPRINTF)
- TIXML_SNPRINTF(buf, sizeof(buf), "&#x%02X;", (unsigned) (c & 0xff));
- #else
- sprintf(buf, "&#x%02X;", (unsigned) (c & 0xff));
- #endif
-
- //*ME: warning C4267: convert 'size_t' to 'int'
- //*ME: Int-Cast to make compiler happy ...
- outString->append(buf, (int)strlen(buf));
- ++i;
- }
- else
- {
- //char realc = (char) c;
- //outString->append(&realc, 1);
- *outString += (char) c; // somewhat more efficient function call.
- ++i;
- }
- }
-}
-
-
-// <-- Strange class for a bug fix. Search for STL_STRING_BUG
-TiXmlBase::StringToBuffer::StringToBuffer(const TIXML_STRING& str)
-{
- buffer = new char[ str.length()+1 ];
- if (buffer)
- {
- strcpy(buffer, str.c_str());
- }
-}
-
-
-TiXmlBase::StringToBuffer::~StringToBuffer()
-{
- delete [] buffer;
-}
-// End strange bug fix. -->
-
-
-TiXmlNode::TiXmlNode(NodeType _type) : TiXmlBase()
-{
- parent = 0;
- type = _type;
- firstChild = 0;
- lastChild = 0;
- prev = 0;
- next = 0;
-}
-
-
-TiXmlNode::~TiXmlNode()
-{
- TiXmlNode* node = firstChild;
- TiXmlNode* temp = 0;
-
- while (node)
- {
- temp = node;
- node = node->next;
-
- delete temp;
- }
-}
-
-
-void TiXmlNode::CopyTo(TiXmlNode* target) const
-{
- target->SetValue (value.c_str());
- target->userData = userData;
-}
-
-
-void TiXmlNode::Clear()
-{
- TiXmlNode* node = firstChild;
- TiXmlNode* temp = 0;
-
- while (node)
- {
- temp = node;
- node = node->next;
- delete temp;
- }
-
- firstChild = 0;
- lastChild = 0;
-}
-
-
-TiXmlNode* TiXmlNode::LinkEndChild(TiXmlNode* node)
-{
- assert(node->parent == 0 || node->parent == this);
- assert(node->GetDocument() == 0 || node->GetDocument() == this->GetDocument());
-
- if (node->Type() == TiXmlNode::DOCUMENT)
- {
- delete node;
- if (GetDocument()) GetDocument()->SetError(TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN);
- return 0;
- }
-
- node->parent = this;
-
- node->prev = lastChild;
- node->next = 0;
-
- if (lastChild)
- lastChild->next = node;
- else
- firstChild = node; // it was an empty list.
-
- lastChild = node;
- return node;
-}
-
-
-TiXmlNode* TiXmlNode::InsertEndChild(const TiXmlNode& addThis)
-{
- if (addThis.Type() == TiXmlNode::DOCUMENT)
- {
- if (GetDocument()) GetDocument()->SetError(TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN);
- return 0;
- }
- TiXmlNode* node = addThis.Clone();
- if (!node)
- return 0;
-
- return LinkEndChild(node);
-}
-
-
-TiXmlNode* TiXmlNode::InsertBeforeChild(TiXmlNode* beforeThis, const TiXmlNode& addThis)
-{
- if (!beforeThis || beforeThis->parent != this) {
- return 0;
- }
- if (addThis.Type() == TiXmlNode::DOCUMENT)
- {
- if (GetDocument()) GetDocument()->SetError(TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN);
- return 0;
- }
-
- TiXmlNode* node = addThis.Clone();
- if (!node)
- return 0;
- node->parent = this;
-
- node->next = beforeThis;
- node->prev = beforeThis->prev;
- if (beforeThis->prev)
- {
- beforeThis->prev->next = node;
- }
- else
- {
- assert(firstChild == beforeThis);
- firstChild = node;
- }
- beforeThis->prev = node;
- return node;
-}
-
-
-TiXmlNode* TiXmlNode::InsertAfterChild(TiXmlNode* afterThis, const TiXmlNode& addThis)
-{
- if (!afterThis || afterThis->parent != this) {
- return 0;
- }
- if (addThis.Type() == TiXmlNode::DOCUMENT)
- {
- if (GetDocument()) GetDocument()->SetError(TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN);
- return 0;
- }
-
- TiXmlNode* node = addThis.Clone();
- if (!node)
- return 0;
- node->parent = this;
-
- node->prev = afterThis;
- node->next = afterThis->next;
- if (afterThis->next)
- {
- afterThis->next->prev = node;
- }
- else
- {
- assert(lastChild == afterThis);
- lastChild = node;
- }
- afterThis->next = node;
- return node;
-}
-
-
-TiXmlNode* TiXmlNode::ReplaceChild(TiXmlNode* replaceThis, const TiXmlNode& withThis)
-{
- if (replaceThis->parent != this)
- return 0;
-
- TiXmlNode* node = withThis.Clone();
- if (!node)
- return 0;
-
- node->next = replaceThis->next;
- node->prev = replaceThis->prev;
-
- if (replaceThis->next)
- replaceThis->next->prev = node;
- else
- lastChild = node;
-
- if (replaceThis->prev)
- replaceThis->prev->next = node;
- else
- firstChild = node;
-
- delete replaceThis;
- node->parent = this;
- return node;
-}
-
-
-bool TiXmlNode::RemoveChild(TiXmlNode* removeThis)
-{
- if (removeThis->parent != this)
- {
- assert(0);
- return false;
- }
-
- if (removeThis->next)
- removeThis->next->prev = removeThis->prev;
- else
- lastChild = removeThis->prev;
-
- if (removeThis->prev)
- removeThis->prev->next = removeThis->next;
- else
- firstChild = removeThis->next;
-
- delete removeThis;
- return true;
-}
-
-const TiXmlNode* TiXmlNode::FirstChild(const char * _value) const
-{
- const TiXmlNode* node;
- for (node = firstChild; node; node = node->next)
- {
- if (strcmp(node->Value(), _value) == 0)
- return node;
- }
- return 0;
-}
-
-
-TiXmlNode* TiXmlNode::FirstChild(const char * _value)
-{
- TiXmlNode* node;
- for (node = firstChild; node; node = node->next)
- {
- if (strcmp(node->Value(), _value) == 0)
- return node;
- }
- return 0;
-}
-
-
-const TiXmlNode* TiXmlNode::LastChild(const char * _value) const
-{
- const TiXmlNode* node;
- for (node = lastChild; node; node = node->prev)
- {
- if (strcmp(node->Value(), _value) == 0)
- return node;
- }
- return 0;
-}
-
-TiXmlNode* TiXmlNode::LastChild(const char * _value)
-{
- TiXmlNode* node;
- for (node = lastChild; node; node = node->prev)
- {
- if (strcmp(node->Value(), _value) == 0)
- return node;
- }
- return 0;
-}
-
-const TiXmlNode* TiXmlNode::IterateChildren(const TiXmlNode* previous) const
-{
- if (!previous)
- {
- return FirstChild();
- }
- else
- {
- assert(previous->parent == this);
- return previous->NextSibling();
- }
-}
-
-TiXmlNode* TiXmlNode::IterateChildren(TiXmlNode* previous)
-{
- if (!previous)
- {
- return FirstChild();
- }
- else
- {
- assert(previous->parent == this);
- return previous->NextSibling();
- }
-}
-
-const TiXmlNode* TiXmlNode::IterateChildren(const char * val, const TiXmlNode* previous) const
-{
- if (!previous)
- {
- return FirstChild(val);
- }
- else
- {
- assert(previous->parent == this);
- return previous->NextSibling(val);
- }
-}
-
-TiXmlNode* TiXmlNode::IterateChildren(const char * val, TiXmlNode* previous)
-{
- if (!previous)
- {
- return FirstChild(val);
- }
- else
- {
- assert(previous->parent == this);
- return previous->NextSibling(val);
- }
-}
-
-const TiXmlNode* TiXmlNode::NextSibling(const char * _value) const
-{
- const TiXmlNode* node;
- for (node = next; node; node = node->next)
- {
- if (strcmp(node->Value(), _value) == 0)
- return node;
- }
- return 0;
-}
-
-TiXmlNode* TiXmlNode::NextSibling(const char * _value)
-{
- TiXmlNode* node;
- for (node = next; node; node = node->next)
- {
- if (strcmp(node->Value(), _value) == 0)
- return node;
- }
- return 0;
-}
-
-const TiXmlNode* TiXmlNode::PreviousSibling(const char * _value) const
-{
- const TiXmlNode* node;
- for (node = prev; node; node = node->prev)
- {
- if (strcmp(node->Value(), _value) == 0)
- return node;
- }
- return 0;
-}
-
-TiXmlNode* TiXmlNode::PreviousSibling(const char * _value)
-{
- TiXmlNode* node;
- for (node = prev; node; node = node->prev)
- {
- if (strcmp(node->Value(), _value) == 0)
- return node;
- }
- return 0;
-}
-
-void TiXmlElement::RemoveAttribute(const char * name)
-{
- TIXML_STRING str(name);
- TiXmlAttribute* node = attributeSet.Find(str);
- if (node)
- {
- attributeSet.Remove(node);
- delete node;
- }
-}
-
-const TiXmlElement* TiXmlNode::FirstChildElement() const
-{
- const TiXmlNode* node;
-
- for ( node = FirstChild();
- node;
- node = node->NextSibling())
- {
- if (node->ToElement())
- return node->ToElement();
- }
- return 0;
-}
-
-TiXmlElement* TiXmlNode::FirstChildElement()
-{
- TiXmlNode* node;
-
- for ( node = FirstChild();
- node;
- node = node->NextSibling())
- {
- if (node->ToElement())
- return node->ToElement();
- }
- return 0;
-}
-
-const TiXmlElement* TiXmlNode::FirstChildElement(const char * _value) const
-{
- const TiXmlNode* node;
-
- for ( node = FirstChild(_value);
- node;
- node = node->NextSibling(_value))
- {
- if (node->ToElement())
- return node->ToElement();
- }
- return 0;
-}
-
-TiXmlElement* TiXmlNode::FirstChildElement(const char * _value)
-{
- TiXmlNode* node;
-
- for ( node = FirstChild(_value);
- node;
- node = node->NextSibling(_value))
- {
- if (node->ToElement())
- return node->ToElement();
- }
- return 0;
-}
-
-const TiXmlElement* TiXmlNode::NextSiblingElement() const
-{
- const TiXmlNode* node;
-
- for ( node = NextSibling();
- node;
- node = node->NextSibling())
- {
- if (node->ToElement())
- return node->ToElement();
- }
- return 0;
-}
-
-TiXmlElement* TiXmlNode::NextSiblingElement()
-{
- TiXmlNode* node;
-
- for ( node = NextSibling();
- node;
- node = node->NextSibling())
- {
- if (node->ToElement())
- return node->ToElement();
- }
- return 0;
-}
-
-const TiXmlElement* TiXmlNode::NextSiblingElement(const char * _value) const
-{
- const TiXmlNode* node;
-
- for ( node = NextSibling(_value);
- node;
- node = node->NextSibling(_value))
- {
- if (node->ToElement())
- return node->ToElement();
- }
- return 0;
-}
-
-TiXmlElement* TiXmlNode::NextSiblingElement(const char * _value)
-{
- TiXmlNode* node;
-
- for ( node = NextSibling(_value);
- node;
- node = node->NextSibling(_value))
- {
- if (node->ToElement())
- return node->ToElement();
- }
- return 0;
-}
-
-
-const TiXmlDocument* TiXmlNode::GetDocument() const
-{
- const TiXmlNode* node;
-
- for (node = this; node; node = node->parent)
- {
- if (node->ToDocument())
- return node->ToDocument();
- }
- return 0;
-}
-
-TiXmlDocument* TiXmlNode::GetDocument()
-{
- TiXmlNode* node;
-
- for (node = this; node; node = node->parent)
- {
- if (node->ToDocument())
- return node->ToDocument();
- }
- return 0;
-}
-
-TiXmlElement::TiXmlElement (const char * _value)
- : TiXmlNode(TiXmlNode::ELEMENT)
-{
- firstChild = lastChild = 0;
- value = _value;
-}
-
-
-#ifdef TIXML_USE_STL
-TiXmlElement::TiXmlElement(const std::string& _value)
- : TiXmlNode(TiXmlNode::ELEMENT)
-{
- firstChild = lastChild = 0;
- value = _value;
-}
-#endif
-
-
-TiXmlElement::TiXmlElement(const TiXmlElement& copy)
- : TiXmlNode(TiXmlNode::ELEMENT)
-{
- firstChild = lastChild = 0;
- copy.CopyTo(this);
-}
-
-
-void TiXmlElement::operator=(const TiXmlElement& base)
-{
- ClearThis();
- base.CopyTo(this);
-}
-
-
-TiXmlElement::~TiXmlElement()
-{
- ClearThis();
-}
-
-
-void TiXmlElement::ClearThis()
-{
- Clear();
- while (attributeSet.First())
- {
- TiXmlAttribute* node = attributeSet.First();
- attributeSet.Remove(node);
- delete node;
- }
-}
-
-
-const char * TiXmlElement::Attribute(const char * name) const
-{
- TIXML_STRING str(name);
- const TiXmlAttribute* node = attributeSet.Find(str);
-
- if (node)
- return node->Value();
-
- return 0;
-}
-
-
-const char * TiXmlElement::Attribute(const char * name, int* i) const
-{
- const char * s = Attribute(name);
- if (i)
- {
- if (s)
- *i = (int)_atoi64(s);
- else
- *i = 0;
- }
- return s;
-}
-
-
-const char * TiXmlElement::Attribute(const char * name, double* d) const
-{
- const char * s = Attribute(name);
- if (d)
- {
- if (s)
- *d = atof(s);
- else
- *d = 0;
- }
- return s;
-}
-
-
-int TiXmlElement::QueryIntAttribute(const char* name, int* ival) const
-{
- TIXML_STRING str(name);
- const TiXmlAttribute* node = attributeSet.Find(str);
- if (!node)
- return TIXML_NO_ATTRIBUTE;
-
- return node->QueryIntValue(ival);
-}
-
-
-int TiXmlElement::QueryDoubleAttribute(const char* name, double* dval) const
-{
- TIXML_STRING str(name);
- const TiXmlAttribute* node = attributeSet.Find(str);
- if (!node)
- return TIXML_NO_ATTRIBUTE;
-
- return node->QueryDoubleValue(dval);
-}
-
-
-void TiXmlElement::SetAttribute(const char * name, int val)
-{
- char buf[64];
- #if defined(TIXML_SNPRINTF)
- TIXML_SNPRINTF(buf, sizeof(buf), "%d", val);
- #else
- sprintf(buf, "%d", val);
- #endif
- SetAttribute(name, buf);
-}
-
-
-#ifdef TIXML_USE_STL
-void TiXmlElement::SetAttribute(const std::string& name, int val)
-{
- std::ostringstream oss;
- oss << val;
- SetAttribute(name, oss.str());
-}
-#endif
-
-
-void TiXmlElement::SetDoubleAttribute(const char * name, double val)
-{
- char buf[256];
- #if defined(TIXML_SNPRINTF)
- TIXML_SNPRINTF(buf, sizeof(buf), "%f", val);
- #else
- sprintf(buf, "%f", val);
- #endif
- SetAttribute(name, buf);
-}
-
-
-void TiXmlElement::SetAttribute(const char * cname, const char * cvalue)
-{
- TIXML_STRING _name(cname);
- TIXML_STRING _value(cvalue);
-
- TiXmlAttribute* node = attributeSet.Find(_name);
- if (node)
- {
- node->SetValue(cvalue);
- return;
- }
-
- TiXmlAttribute* attrib = new TiXmlAttribute(cname, cvalue);
- if (attrib)
- {
- attributeSet.Add(attrib);
- }
- else
- {
- TiXmlDocument* document = GetDocument();
- if (document) document->SetError(TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN);
- }
-}
-
-
-#ifdef TIXML_USE_STL
-void TiXmlElement::SetAttribute(const std::string& name, const std::string& _value)
-{
- TiXmlAttribute* node = attributeSet.Find(name);
- if (node)
- {
- node->SetValue(_value);
- return;
- }
-
- TiXmlAttribute* attrib = new TiXmlAttribute(name, _value);
- if (attrib)
- {
- attributeSet.Add(attrib);
- }
- else
- {
- TiXmlDocument* document = GetDocument();
- if (document) document->SetError(TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN);
- }
-}
-#endif
-
-
-void TiXmlElement::Print(FILE* cfile, int depth) const
-{
- int i;
- for (i=0; i<depth; i++)
- {
- fprintf(cfile, " ");
- }
-
- fprintf(cfile, "<%s", value.c_str());
-
- const TiXmlAttribute* attrib;
- for (attrib = attributeSet.First(); attrib; attrib = attrib->Next())
- {
- fprintf(cfile, " ");
- attrib->Print(cfile, depth);
- }
-
- // There are 3 different formatting approaches:
- // 1) An element without children is printed as a <foo /> node
- // 2) An element with only a text child is printed as <foo> text </foo>
- // 3) An element with children is printed on multiple lines.
- TiXmlNode* node;
- if (!firstChild)
- {
- fprintf(cfile, " />");
- }
- else if (firstChild == lastChild && firstChild->ToText())
- {
- fprintf(cfile, ">");
- firstChild->Print(cfile, depth + 1);
- fprintf(cfile, "</%s>", value.c_str());
- }
- else
- {
- fprintf(cfile, ">");
-
- for (node = firstChild; node; node=node->NextSibling())
- {
- if (!node->ToText())
- {
- fprintf(cfile, "\n");
- }
- node->Print(cfile, depth+1);
- }
- fprintf(cfile, "\n");
- for (i=0; i<depth; ++i)
- fprintf(cfile, " ");
- fprintf(cfile, "</%s>", value.c_str());
- }
-}
-
-void TiXmlElement::StreamOut(TIXML_OSTREAM * stream) const
-{
- (*stream) << "<" << value;
-
- const TiXmlAttribute* attrib;
- for (attrib = attributeSet.First(); attrib; attrib = attrib->Next())
- {
- (*stream) << " ";
- attrib->StreamOut(stream);
- }
-
- // If this node has children, give it a closing tag. Else
- // make it an empty tag.
- TiXmlNode* node;
- if (firstChild)
- {
- (*stream) << ">";
-
- for (node = firstChild; node; node=node->NextSibling())
- {
- node->StreamOut(stream);
- }
- (*stream) << "</" << value << ">";
- }
- else
- {
- (*stream) << " />";
- }
-}
-
-void TiXmlElement::FormattedStreamOut(TIXML_OSTREAM * stream, int depth) const
-{
- // Adding tabs to get the proper tree format
- int oldDepth = depth;
- StreamDepth(stream, depth);
-
- // Element name
- (*stream) << "<" << value;
-
- // Attributes
- const TiXmlAttribute* attrib;
- for (attrib = attributeSet.First(); attrib; attrib = attrib->Next())
- {
- (*stream) << " ";
- attrib->StreamOut(stream);
- }
-
- // There are 3 different formatting approaches:
- // 1) An element without children is printed as a <foo /> node
- // 2) An element with only a text child is printed as <foo> text </foo>
- // 3) An element with children is printed on multiple lines.
- TiXmlNode* node;
- if (!firstChild)
- {
- (*stream) << " />" << TIXML_ENDL;
- }
- else if (firstChild == lastChild && firstChild->ToText())
- {
- (*stream) << ">";
- firstChild->FormattedStreamOut(stream, depth + 1);
- (*stream) << "</" << value << ">" << TIXML_ENDL;
- }
- else
- {
- (*stream) << ">" << TIXML_ENDL;
-
- // Children
- depth++;
- for (node = firstChild; node; node=node->NextSibling())
- {
- node->FormattedStreamOut(stream, depth);
- }
- StreamDepth(stream, oldDepth);
- (*stream) << "</" << value << ">" << TIXML_ENDL;
- }
-}
-
-void TiXmlElement::CopyTo(TiXmlElement* target) const
-{
- // superclass:
- TiXmlNode::CopyTo(target);
-
- // Element class:
- // Clone the attributes, then clone the children.
- const TiXmlAttribute* attribute = 0;
- for ( attribute = attributeSet.First();
- attribute;
- attribute = attribute->Next())
- {
- target->SetAttribute(attribute->Name(), attribute->Value());
- }
-
- TiXmlNode* node = 0;
- for (node = firstChild; node; node = node->NextSibling())
- {
- target->LinkEndChild(node->Clone());
- }
-}
-
-
-TiXmlNode* TiXmlElement::Clone() const
-{
- TiXmlElement* clone = new TiXmlElement(Value());
- if (!clone)
- return 0;
-
- CopyTo(clone);
- return clone;
-}
-
-
-const char* TiXmlElement::GetText() const
-{
- const TiXmlNode* child = this->FirstChild();
- if (child) {
- const TiXmlText* childText = child->ToText();
- if (childText) {
- return childText->Value();
- }
- }
- return 0;
-}
-
-
-TiXmlDocument::TiXmlDocument() : TiXmlNode(TiXmlNode::DOCUMENT)
-{
- tabsize = 4;
- useMicrosoftBOM = false;
- ClearError();
-}
-
-TiXmlDocument::TiXmlDocument(const char * documentName) : TiXmlNode(TiXmlNode::DOCUMENT)
-{
- tabsize = 4;
- useMicrosoftBOM = false;
- value = documentName;
- ClearError();
-}
-
-
-#ifdef TIXML_USE_STL
-TiXmlDocument::TiXmlDocument(const std::string& documentName) : TiXmlNode(TiXmlNode::DOCUMENT)
-{
- tabsize = 4;
- useMicrosoftBOM = false;
- value = documentName;
- ClearError();
-}
-#endif
-
-
-TiXmlDocument::TiXmlDocument(const TiXmlDocument& copy) : TiXmlNode(TiXmlNode::DOCUMENT)
-{
- copy.CopyTo(this);
-}
-
-
-void TiXmlDocument::operator=(const TiXmlDocument& copy)
-{
- Clear();
- copy.CopyTo(this);
-}
-
-
-bool TiXmlDocument::LoadFile(TiXmlEncoding encoding)
-{
- // See STL_STRING_BUG below.
- StringToBuffer buf(value);
-
- if (buf.buffer && LoadFile(buf.buffer, encoding))
- return true;
-
- return false;
-}
-
-
-bool TiXmlDocument::SaveFile() const
-{
- // See STL_STRING_BUG below.
- StringToBuffer buf(value);
-
- if (buf.buffer && SaveFile(buf.buffer))
- return true;
-
- return false;
-}
-
-#ifdef TIXML_USE_STL
-std::string TiXmlDocument::GetAsString()
-{
- std::stringstream out;
- FormattedStreamOut(&out, 0);
- return out.str();
-}
-#endif
-
-bool TiXmlDocument::GetAsCharBuffer(char* buffer, size_t bufferSize)
-{
- #ifdef TIXML_USE_STL
- std::string data = GetAsString();
- #else
- TIXML_OSTREAM data;
- FormattedStreamOut(&data, 0);
- #endif
-
- if (bufferSize < data.length())
- {
- return false;
- }
- else
- {
- strcpy(buffer, data.c_str());
- return true;
- }
-}
-
-bool TiXmlDocument::LoadFile(const char* filename, TiXmlEncoding encoding)
-{
- // There was a really terrifying little bug here. The code:
- // value = filename
- // in the STL case, cause the assignment method of the std::string to
- // be called. What is strange, is that the std::string had the same
- // address as it's c_str() method, and so bad things happen. Looks
- // like a bug in the Microsoft STL implementation.
- // See STL_STRING_BUG above.
- // Fixed with the StringToBuffer class.
- value = filename;
-
- // reading in binary mode so that tinyxml can normalize the EOL
- FILE* file = fopen(value.c_str (), "rb");
-
- if (file)
- {
- bool result = LoadFile(file, encoding);
- fclose(file);
- return result;
- }
- else
- {
- SetError(TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN);
- return false;
- }
-}
-
-bool TiXmlDocument::LoadFile(FILE* file, TiXmlEncoding encoding)
-{
- if (!file)
- {
- SetError(TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN);
- return false;
- }
-
- // Delete the existing data:
- Clear();
- location.Clear();
-
- // Get the file size, so we can pre-allocate the string. HUGE speed impact.
- long length = 0;
- fseek(file, 0, SEEK_END);
- length = ftell(file);
- fseek(file, 0, SEEK_SET);
-
- // Strange case, but good to handle up front.
- if (length == 0)
- {
- SetError(TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN);
- return false;
- }
-
- // If we have a file, assume it is all one big XML file, and read it in.
- // The document parser may decide the document ends sooner than the entire file, however.
- TIXML_STRING data;
- data.reserve(length);
-
- // Subtle bug here. TinyXml did use fgets. But from the XML spec:
- // 2.11 End-of-Line Handling
- // <snip>
- // <quote>
- // ...the XML processor MUST behave as if it normalized all line breaks in external
- // parsed entities (including the document entity) on input, before parsing, by translating
- // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to
- // a single #xA character.
- // </quote>
- //
- // It is not clear fgets does that, and certainly isn't clear it works cross platform.
- // Generally, you expect fgets to translate from the convention of the OS to the c/unix
- // convention, and not work generally.
-
- /*
- while (fgets(buf, sizeof(buf), file))
- {
- data += buf;
- }
- */
-
- char* buf = new char[ length+1 ];
- buf[0] = 0;
-
- if (fread(buf, length, 1, file) != 1) {
- delete [] buf;
- SetError(TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN);
- return false;
- }
-
- const char* lastPos = buf;
- const char* p = buf;
-
- buf[length] = 0;
- while (*p) {
- assert(p < (buf+length));
- if (*p == 0xa) {
- // Newline character. No special rules for this. Append all the characters
- // since the last string, and include the newline.
- data.append(lastPos, (p-lastPos+1)); // append, include the newline
- ++p; // move past the newline
- lastPos = p; // and point to the new buffer (may be 0)
- assert(p <= (buf+length));
- }
- else if (*p == 0xd) {
- // Carriage return. Append what we have so far, then
- // handle moving forward in the buffer.
- if ((p-lastPos) > 0) {
- data.append(lastPos, p-lastPos); // do not add the CR
- }
- data += (char)0xa; // a proper newline
-
- if (*(p+1) == 0xa) {
- // Carriage return - new line sequence
- p += 2;
- lastPos = p;
- assert(p <= (buf+length));
- }
- else {
- // it was followed by something else...that is presumably characters again.
- ++p;
- lastPos = p;
- assert(p <= (buf+length));
- }
- }
- else {
- ++p;
- }
- }
- // Handle any left over characters.
- if (p-lastPos) {
- data.append(lastPos, p-lastPos);
- }
- delete [] buf;
- buf = 0;
-
- Parse(data.c_str(), 0, encoding);
-
- if ( Error())
- return false;
- else
- return true;
-}
-
-
-bool TiXmlDocument::SaveFile(const char * filename) const
-{
- // The old c stuff lives on...
- FILE* fp = fopen(filename, "w");
- if (fp)
- {
- bool result = SaveFile(fp);
- fclose(fp);
- return result;
- }
- return false;
-}
-
-
-bool TiXmlDocument::SaveFile(FILE* fp) const
-{
- if (useMicrosoftBOM)
- {
- const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
- const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
- const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
-
- fputc(TIXML_UTF_LEAD_0, fp);
- fputc(TIXML_UTF_LEAD_1, fp);
- fputc(TIXML_UTF_LEAD_2, fp);
- }
- Print(fp, 0);
- return true;
-}
-
-
-void TiXmlDocument::CopyTo(TiXmlDocument* target) const
-{
- TiXmlNode::CopyTo(target);
-
- target->error = error;
- target->errorDesc = errorDesc.c_str ();
-
- TiXmlNode* node = 0;
- for (node = firstChild; node; node = node->NextSibling())
- {
- target->LinkEndChild(node->Clone());
- }
-}
-
-
-TiXmlNode* TiXmlDocument::Clone() const
-{
- TiXmlDocument* clone = new TiXmlDocument();
- if (!clone)
- return 0;
-
- CopyTo(clone);
- return clone;
-}
-
-
-void TiXmlDocument::Print(FILE* cfile, int depth) const
-{
- const TiXmlNode* node;
- for (node=FirstChild(); node; node=node->NextSibling())
- {
- node->Print(cfile, depth);
- fprintf(cfile, "\n");
- }
-}
-
-void TiXmlDocument::StreamOut(TIXML_OSTREAM * out) const
-{
- const TiXmlNode* node;
- for (node=FirstChild(); node; node=node->NextSibling())
- {
- node->StreamOut(out);
-
- // Special rule for streams: stop after the root element.
- // The stream in code will only read one element, so don't
- // write more than one.
- if (node->ToElement())
- break;
- }
-}
-
-void TiXmlDocument::FormattedStreamOut(TIXML_OSTREAM * out, int depth) const
-{
- const TiXmlNode* node;
- for (node=FirstChild(); node; node=node->NextSibling())
- {
- node->FormattedStreamOut(out, depth);
-
- // Special rule for streams: stop after the root element.
- // The stream in code will only read one element, so don't
- // write more than one.
- if (node->ToElement())
- break;
- }
-}
-
-const TiXmlAttribute* TiXmlAttribute::Next() const
-{
- // We are using knowledge of the sentinel. The sentinel
- // have a value or name.
- if (next->value.empty() && next->name.empty())
- return 0;
- return next;
-}
-
-TiXmlAttribute* TiXmlAttribute::Next()
-{
- // We are using knowledge of the sentinel. The sentinel
- // have a value or name.
- if (next->value.empty() && next->name.empty())
- return 0;
- return next;
-}
-
-const TiXmlAttribute* TiXmlAttribute::Previous() const
-{
- // We are using knowledge of the sentinel. The sentinel
- // have a value or name.
- if (prev->value.empty() && prev->name.empty())
- return 0;
- return prev;
-}
-
-TiXmlAttribute* TiXmlAttribute::Previous()
-{
- // We are using knowledge of the sentinel. The sentinel
- // have a value or name.
- if (prev->value.empty() && prev->name.empty())
- return 0;
- return prev;
-}
-
-void TiXmlAttribute::Print(FILE* cfile, int /*depth*/) const
-{
- TIXML_STRING n, v;
-
- PutString(name, &n);
- PutString(value, &v);
-
- if (value.find ('\"') == TIXML_STRING::npos)
- fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str());
- else
- fprintf (cfile, "%s='%s'", n.c_str(), v.c_str());
-}
-
-
-void TiXmlAttribute::StreamOut(TIXML_OSTREAM * stream) const
-{
- if (value.find('\"') != TIXML_STRING::npos)
- {
- PutString(name, stream);
- (*stream) << "=" << "'";
- PutString(value, stream);
- (*stream) << "'";
- }
- else
- {
- PutString(name, stream);
- (*stream) << "=" << "\"";
- PutString(value, stream);
- (*stream) << "\"";
- }
-}
-
-int TiXmlAttribute::QueryIntValue(int* ival) const
-{
- if (sscanf(value.c_str(), "%d", ival) == 1)
- return TIXML_SUCCESS;
- return TIXML_WRONG_TYPE;
-}
-
-int TiXmlAttribute::QueryDoubleValue(double* dval) const
-{
- if (sscanf(value.c_str(), "%lf", dval) == 1)
- return TIXML_SUCCESS;
- return TIXML_WRONG_TYPE;
-}
-
-void TiXmlAttribute::SetIntValue(int _value)
-{
- char buf [64];
- #if defined(TIXML_SNPRINTF)
- TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value);
- #else
- sprintf (buf, "%d", _value);
- #endif
- SetValue (buf);
-}
-
-void TiXmlAttribute::SetDoubleValue(double _value)
-{
- char buf [256];
- #if defined(TIXML_SNPRINTF)
- TIXML_SNPRINTF(buf, sizeof(buf), "%lf", _value);
- #else
- sprintf (buf, "%lf", _value);
- #endif
- SetValue (buf);
-}
-
-int TiXmlAttribute::IntValue() const
-{
- return (int)_atoi64(value.c_str ());
-}
-
-double TiXmlAttribute::DoubleValue() const
-{
- return atof (value.c_str ());
-}
-
-
-TiXmlComment::TiXmlComment(const TiXmlComment& copy) : TiXmlNode(TiXmlNode::COMMENT)
-{
- copy.CopyTo(this);
-}
-
-
-void TiXmlComment::operator=(const TiXmlComment& base)
-{
- Clear();
- base.CopyTo(this);
-}
-
-
-void TiXmlComment::Print(FILE* cfile, int depth) const
-{
- for (int i=0; i<depth; i++)
- {
- fputs(" ", cfile);
- }
- fprintf(cfile, "<!--%s-->", value.c_str());
-}
-
-void TiXmlComment::StreamOut(TIXML_OSTREAM * stream) const
-{
- (*stream) << "<!--";
- //PutString(value, stream);
- (*stream) << value;
- (*stream) << "-->";
-}
-
-void TiXmlComment::FormattedStreamOut(TIXML_OSTREAM * stream, int depth) const
-{
- StreamDepth(stream, depth);
-
- StreamOut(stream);
-
- (*stream) << TIXML_ENDL;
-}
-
-void TiXmlComment::CopyTo(TiXmlComment* target) const
-{
- TiXmlNode::CopyTo(target);
-}
-
-
-TiXmlNode* TiXmlComment::Clone() const
-{
- TiXmlComment* clone = new TiXmlComment();
-
- if (!clone)
- return 0;
-
- CopyTo(clone);
- return clone;
-}
-
-
-void TiXmlText::Print(FILE* cfile, int depth) const
-{
- if (cdata)
- {
- int i;
- fprintf(cfile, "\n");
- for (i=0; i<depth; i++) {
- fprintf(cfile, " ");
- }
- fprintf(cfile, "<![CDATA[");
- fprintf(cfile, "%s", value.c_str()); // unformatted output
- fprintf(cfile, "]]>\n");
- }
- else
- {
- TIXML_STRING buffer;
- PutString(value, &buffer);
- fprintf(cfile, "%s", buffer.c_str());
- }
-}
-
-
-void TiXmlText::StreamOut(TIXML_OSTREAM * stream) const
-{
- if (cdata)
- {
- (*stream) << "<![CDATA[" << value << "]]>";
- }
- else
- {
- PutString(value, stream);
- }
-}
-
-void TiXmlText::FormattedStreamOut(TIXML_OSTREAM * stream, int depth) const
-{
- if (cdata)
- {
- (*stream) << TIXML_ENDL;
- StreamDepth(stream, depth);
- (*stream) << "<![CDATA[" << value << "]]>" << TIXML_ENDL;
- }
- else
- {
- PutString(value, stream);
- }
-}
-
-void TiXmlText::CopyTo(TiXmlText* target) const
-{
- TiXmlNode::CopyTo(target);
- target->cdata = cdata;
-}
-
-
-TiXmlNode* TiXmlText::Clone() const
-{
- TiXmlText* clone = 0;
- clone = new TiXmlText("");
-
- if (!clone)
- return 0;
-
- CopyTo(clone);
- return clone;
-}
-
-
-TiXmlDeclaration::TiXmlDeclaration(const char * _version,
- const char * _encoding,
- const char * _standalone)
- : TiXmlNode(TiXmlNode::DECLARATION)
-{
- version = _version;
- encoding = _encoding;
- standalone = _standalone;
-}
-
-
-#ifdef TIXML_USE_STL
-TiXmlDeclaration::TiXmlDeclaration( const std::string& _version,
- const std::string& _encoding,
- const std::string& _standalone)
- : TiXmlNode(TiXmlNode::DECLARATION)
-{
- version = _version;
- encoding = _encoding;
- standalone = _standalone;
-}
-#endif
-
-
-TiXmlDeclaration::TiXmlDeclaration(const TiXmlDeclaration& copy)
- : TiXmlNode(TiXmlNode::DECLARATION)
-{
- copy.CopyTo(this);
-}
-
-
-void TiXmlDeclaration::operator=(const TiXmlDeclaration& copy)
-{
- Clear();
- copy.CopyTo(this);
-}
-
-
-void TiXmlDeclaration::Print(FILE* cfile, int /*depth*/) const
-{
- fprintf (cfile, "<?xml ");
-
- if (!version.empty())
- fprintf (cfile, "version=\"%s\" ", version.c_str ());
- if (!encoding.empty())
- fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
- if (!standalone.empty())
- fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
- fprintf (cfile, "?>");
-}
-
-void TiXmlDeclaration::StreamOut(TIXML_OSTREAM * stream) const
-{
- (*stream) << "<?xml ";
-
- if (!version.empty())
- {
- (*stream) << "version=\"";
- PutString(version, stream);
- (*stream) << "\" ";
- }
- if (!encoding.empty())
- {
- (*stream) << "encoding=\"";
- PutString(encoding, stream);
- (*stream) << "\" ";
- }
- if (!standalone.empty())
- {
- (*stream) << "standalone=\"";
- PutString(standalone, stream);
- (*stream) << "\" ";
- }
- (*stream) << "?>";
-}
-
-void TiXmlDeclaration::FormattedStreamOut(TIXML_OSTREAM * stream, int depth) const
-{
- StreamDepth(stream, depth);
- StreamOut(stream);
- (*stream) << TIXML_ENDL;
-}
-
-void TiXmlDeclaration::CopyTo(TiXmlDeclaration* target) const
-{
- TiXmlNode::CopyTo(target);
-
- target->version = version;
- target->encoding = encoding;
- target->standalone = standalone;
-}
-
-
-TiXmlNode* TiXmlDeclaration::Clone() const
-{
- TiXmlDeclaration* clone = new TiXmlDeclaration();
-
- if (!clone)
- return 0;
-
- CopyTo(clone);
- return clone;
-}
-
-
-void TiXmlUnknown::Print(FILE* cfile, int depth) const
-{
- for (int i=0; i<depth; i++)
- fprintf(cfile, " ");
- fprintf(cfile, "<%s>", value.c_str());
-}
-
-
-void TiXmlUnknown::StreamOut(TIXML_OSTREAM * stream) const
-{
- (*stream) << "<" << value << ">"; // Don't use entities here! It is unknown.
-}
-
-void TiXmlUnknown::FormattedStreamOut(TIXML_OSTREAM * stream, int depth) const
-{
- StreamDepth(stream, depth);
- (*stream) << "<" << value << ">" << TIXML_ENDL; // Don't use entities here! It is unknown.
-}
-
-void TiXmlUnknown::CopyTo(TiXmlUnknown* target) const
-{
- TiXmlNode::CopyTo(target);
-}
-
-
-TiXmlNode* TiXmlUnknown::Clone() const
-{
- TiXmlUnknown* clone = new TiXmlUnknown();
-
- if (!clone)
- return 0;
-
- CopyTo(clone);
- return clone;
-}
-
-
-TiXmlAttributeSet::TiXmlAttributeSet()
-{
- sentinel.next = &sentinel;
- sentinel.prev = &sentinel;
-}
-
-
-TiXmlAttributeSet::~TiXmlAttributeSet()
-{
- assert(sentinel.next == &sentinel);
- assert(sentinel.prev == &sentinel);
-}
-
-
-void TiXmlAttributeSet::Add(TiXmlAttribute* addMe)
-{
- assert(!Find(TIXML_STRING(addMe->Name()))); // Shouldn't be multiply adding to the set.
-
- addMe->next = &sentinel;
- addMe->prev = sentinel.prev;
-
- sentinel.prev->next = addMe;
- sentinel.prev = addMe;
-}
-
-void TiXmlAttributeSet::Remove(TiXmlAttribute* removeMe)
-{
- TiXmlAttribute* node;
-
- for (node = sentinel.next; node != &sentinel; node = node->next)
- {
- if (node == removeMe)
- {
- node->prev->next = node->next;
- node->next->prev = node->prev;
- node->next = 0;
- node->prev = 0;
- return;
- }
- }
- assert(0); // we tried to remove a non-linked attribute.
-}
-
-const TiXmlAttribute* TiXmlAttributeSet::Find(const TIXML_STRING& name) const
-{
- const TiXmlAttribute* node;
-
- for (node = sentinel.next; node != &sentinel; node = node->next)
- {
- if (node->name == name)
- return node;
- }
- return 0;
-}
-
-TiXmlAttribute* TiXmlAttributeSet::Find(const TIXML_STRING& name)
-{
- TiXmlAttribute* node;
-
- for (node = sentinel.next; node != &sentinel; node = node->next)
- {
- if (node->name == name)
- return node;
- }
- return 0;
-}
-
-#ifdef TIXML_USE_STL
-TIXML_ISTREAM & operator >> (TIXML_ISTREAM & in, TiXmlNode & base)
-{
- TIXML_STRING tag;
- tag.reserve(8 * 1000);
- base.StreamIn(&in, &tag);
-
- base.Parse(tag.c_str(), 0, TIXML_DEFAULT_ENCODING);
- return in;
-}
-#endif
-
-
-TIXML_OSTREAM & operator<< (TIXML_OSTREAM & out, const TiXmlNode & base)
-{
- base.StreamOut (& out);
- return out;
-}
-
-
-#ifdef TIXML_USE_STL
-std::string & operator<< (std::string& out, const TiXmlNode& base)
-{
- std::ostringstream os_stream(std::ostringstream::out);
- base.StreamOut(&os_stream);
-
- out.append(os_stream.str());
- return out;
-}
-#endif
-
-
-TiXmlHandle TiXmlHandle::FirstChild() const
-{
- if (node)
- {
- TiXmlNode* child = node->FirstChild();
- if (child)
- return TiXmlHandle(child);
- }
- return TiXmlHandle(0);
-}
-
-
-TiXmlHandle TiXmlHandle::FirstChild(const char * value) const
-{
- if (node)
- {
- TiXmlNode* child = node->FirstChild(value);
- if (child)
- return TiXmlHandle(child);
- }
- return TiXmlHandle(0);
-}
-
-
-TiXmlHandle TiXmlHandle::FirstChildElement() const
-{
- if (node)
- {
- TiXmlElement* child = node->FirstChildElement();
- if (child)
- return TiXmlHandle(child);
- }
- return TiXmlHandle(0);
-}
-
-
-TiXmlHandle TiXmlHandle::FirstChildElement(const char * value) const
-{
- if (node)
- {
- TiXmlElement* child = node->FirstChildElement(value);
- if (child)
- return TiXmlHandle(child);
- }
- return TiXmlHandle(0);
-}
-
-
-TiXmlHandle TiXmlHandle::Child(int count) const
-{
- if (node)
- {
- int i;
- TiXmlNode* child = node->FirstChild();
- for ( i=0;
- child && i<count;
- child = child->NextSibling(), ++i)
- {
- // nothing
- }
- if (child)
- return TiXmlHandle(child);
- }
- return TiXmlHandle(0);
-}
-
-
-TiXmlHandle TiXmlHandle::Child(const char* value, int count) const
-{
- if (node)
- {
- int i;
- TiXmlNode* child = node->FirstChild(value);
- for ( i=0;
- child && i<count;
- child = child->NextSibling(value), ++i)
- {
- // nothing
- }
- if (child)
- return TiXmlHandle(child);
- }
- return TiXmlHandle(0);
-}
-
-
-TiXmlHandle TiXmlHandle::ChildElement(int count) const
-{
- if (node)
- {
- int i;
- TiXmlElement* child = node->FirstChildElement();
- for ( i=0;
- child && i<count;
- child = child->NextSiblingElement(), ++i)
- {
- // nothing
- }
- if (child)
- return TiXmlHandle(child);
- }
- return TiXmlHandle(0);
-}
-
-
-TiXmlHandle TiXmlHandle::ChildElement(const char* value, int count) const
-{
- if (node)
- {
- int i;
- TiXmlElement* child = node->FirstChildElement(value);
- for ( i=0;
- child && i<count;
- child = child->NextSiblingElement(value), ++i)
- {
- // nothing
- }
- if (child)
- return TiXmlHandle(child);
- }
- return TiXmlHandle(0);
-}
+
+bool TiXmlBase::condenseWhiteSpace = true;
+
+void TiXmlBase::StreamDepth(TIXML_OSTREAM* stream, int depth) const
+{
+ for (int i = 0; i < depth; ++i)
+ {
+ (*stream) << " ";
+ }
+}
+
+void TiXmlBase::PutString(const TIXML_STRING& str, TIXML_OSTREAM* stream)
+{
+ TIXML_STRING buffer;
+ PutString(str, &buffer);
+ (*stream) << buffer;
+}
+
+void TiXmlBase::PutString(const TIXML_STRING& str, TIXML_STRING* outString)
+{
+ int i=0;
+
+ while (i<(int)str.length())
+ {
+ unsigned char c = (unsigned char) str[i];
+
+ if ( c == '&'
+ && i < ((int)str.length() - 2)
+ && str[i+1] == '#'
+ && str[i+2] == 'x')
+ {
+ // Hexadecimal character reference.
+ // Pass through unchanged.
+ // &#xA9; -- copyright symbol, for example.
+ //
+ // The -1 is a bug fix from Rob Laveaux. It keeps
+ // an overflow from happening if there is no ';'.
+ // There are actually 2 ways to exit this loop -
+ // while fails (error case) and break (semicolon found).
+ // However, there is no mechanism (currently) for
+ // this function to return an error.
+ while (i<(int)str.length()-1)
+ {
+ outString->append(str.c_str() + i, 1);
+ ++i;
+ if (str[i] == ';')
+ break;
+ }
+ }
+ else if (c == '&')
+ {
+ outString->append(entity[0].str, entity[0].strLength);
+ ++i;
+ }
+ else if (c == '<')
+ {
+ outString->append(entity[1].str, entity[1].strLength);
+ ++i;
+ }
+ else if (c == '>')
+ {
+ outString->append(entity[2].str, entity[2].strLength);
+ ++i;
+ }
+ else if (c == '\"')
+ {
+ outString->append(entity[3].str, entity[3].strLength);
+ ++i;
+ }
+ else if (c == '\'')
+ {
+ outString->append(entity[4].str, entity[4].strLength);
+ ++i;
+ }
+ else if (c < 32)
+ {
+ // Easy pass at non-alpha/numeric/symbol
+ // Below 32 is symbolic.
+ char buf[32];
+ mir_snprintf(buf, SIZEOF(buf), "&#x%02X;", (unsigned) (c & 0xff));
+
+ //*ME: warning C4267: convert 'size_t' to 'int'
+ //*ME: Int-Cast to make compiler happy ...
+ outString->append(buf, (int)strlen(buf));
+ ++i;
+ }
+ else
+ {
+ //char realc = (char) c;
+ //outString->append(&realc, 1);
+ *outString += (char) c; // somewhat more efficient function call.
+ ++i;
+ }
+ }
+}
+
+
+// <-- Strange class for a bug fix. Search for STL_STRING_BUG
+TiXmlBase::StringToBuffer::StringToBuffer(const TIXML_STRING& str)
+{
+ buffer = new char[ str.length()+1 ];
+ if (buffer)
+ {
+ strcpy(buffer, str.c_str());
+ }
+}
+
+
+TiXmlBase::StringToBuffer::~StringToBuffer()
+{
+ delete [] buffer;
+}
+// End strange bug fix. -->
+
+
+TiXmlNode::TiXmlNode(NodeType _type) : TiXmlBase()
+{
+ parent = 0;
+ type = _type;
+ firstChild = 0;
+ lastChild = 0;
+ prev = 0;
+ next = 0;
+}
+
+
+TiXmlNode::~TiXmlNode()
+{
+ TiXmlNode* node = firstChild;
+ TiXmlNode* temp = 0;
+
+ while (node)
+ {
+ temp = node;
+ node = node->next;
+
+ delete temp;
+ }
+}
+
+
+void TiXmlNode::CopyTo(TiXmlNode* target) const
+{
+ target->SetValue (value.c_str());
+ target->userData = userData;
+}
+
+
+void TiXmlNode::Clear()
+{
+ TiXmlNode* node = firstChild;
+ TiXmlNode* temp = 0;
+
+ while (node)
+ {
+ temp = node;
+ node = node->next;
+ delete temp;
+ }
+
+ firstChild = 0;
+ lastChild = 0;
+}
+
+
+TiXmlNode* TiXmlNode::LinkEndChild(TiXmlNode* node)
+{
+ assert(node->parent == 0 || node->parent == this);
+ assert(node->GetDocument() == 0 || node->GetDocument() == this->GetDocument());
+
+ if (node->Type() == TiXmlNode::DOCUMENT)
+ {
+ delete node;
+ if (GetDocument()) GetDocument()->SetError(TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN);
+ return 0;
+ }
+
+ node->parent = this;
+
+ node->prev = lastChild;
+ node->next = 0;
+
+ if (lastChild)
+ lastChild->next = node;
+ else
+ firstChild = node; // it was an empty list.
+
+ lastChild = node;
+ return node;
+}
+
+
+TiXmlNode* TiXmlNode::InsertEndChild(const TiXmlNode& addThis)
+{
+ if (addThis.Type() == TiXmlNode::DOCUMENT)
+ {
+ if (GetDocument()) GetDocument()->SetError(TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN);
+ return 0;
+ }
+ TiXmlNode* node = addThis.Clone();
+ if (!node)
+ return 0;
+
+ return LinkEndChild(node);
+}
+
+
+TiXmlNode* TiXmlNode::InsertBeforeChild(TiXmlNode* beforeThis, const TiXmlNode& addThis)
+{
+ if (!beforeThis || beforeThis->parent != this) {
+ return 0;
+ }
+ if (addThis.Type() == TiXmlNode::DOCUMENT)
+ {
+ if (GetDocument()) GetDocument()->SetError(TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN);
+ return 0;
+ }
+
+ TiXmlNode* node = addThis.Clone();
+ if (!node)
+ return 0;
+ node->parent = this;
+
+ node->next = beforeThis;
+ node->prev = beforeThis->prev;
+ if (beforeThis->prev)
+ {
+ beforeThis->prev->next = node;
+ }
+ else
+ {
+ assert(firstChild == beforeThis);
+ firstChild = node;
+ }
+ beforeThis->prev = node;
+ return node;
+}
+
+
+TiXmlNode* TiXmlNode::InsertAfterChild(TiXmlNode* afterThis, const TiXmlNode& addThis)
+{
+ if (!afterThis || afterThis->parent != this) {
+ return 0;
+ }
+ if (addThis.Type() == TiXmlNode::DOCUMENT)
+ {
+ if (GetDocument()) GetDocument()->SetError(TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN);
+ return 0;
+ }
+
+ TiXmlNode* node = addThis.Clone();
+ if (!node)
+ return 0;
+ node->parent = this;
+
+ node->prev = afterThis;
+ node->next = afterThis->next;
+ if (afterThis->next)
+ {
+ afterThis->next->prev = node;
+ }
+ else
+ {
+ assert(lastChild == afterThis);
+ lastChild = node;
+ }
+ afterThis->next = node;
+ return node;
+}
+
+
+TiXmlNode* TiXmlNode::ReplaceChild(TiXmlNode* replaceThis, const TiXmlNode& withThis)
+{
+ if (replaceThis->parent != this)
+ return 0;
+
+ TiXmlNode* node = withThis.Clone();
+ if (!node)
+ return 0;
+
+ node->next = replaceThis->next;
+ node->prev = replaceThis->prev;
+
+ if (replaceThis->next)
+ replaceThis->next->prev = node;
+ else
+ lastChild = node;
+
+ if (replaceThis->prev)
+ replaceThis->prev->next = node;
+ else
+ firstChild = node;
+
+ delete replaceThis;
+ node->parent = this;
+ return node;
+}
+
+
+bool TiXmlNode::RemoveChild(TiXmlNode* removeThis)
+{
+ if (removeThis->parent != this)
+ {
+ assert(0);
+ return false;
+ }
+
+ if (removeThis->next)
+ removeThis->next->prev = removeThis->prev;
+ else
+ lastChild = removeThis->prev;
+
+ if (removeThis->prev)
+ removeThis->prev->next = removeThis->next;
+ else
+ firstChild = removeThis->next;
+
+ delete removeThis;
+ return true;
+}
+
+const TiXmlNode* TiXmlNode::FirstChild(const char * _value) const
+{
+ const TiXmlNode* node;
+ for (node = firstChild; node; node = node->next)
+ {
+ if (strcmp(node->Value(), _value) == 0)
+ return node;
+ }
+ return 0;
+}
+
+
+TiXmlNode* TiXmlNode::FirstChild(const char * _value)
+{
+ TiXmlNode* node;
+ for (node = firstChild; node; node = node->next)
+ {
+ if (strcmp(node->Value(), _value) == 0)
+ return node;
+ }
+ return 0;
+}
+
+
+const TiXmlNode* TiXmlNode::LastChild(const char * _value) const
+{
+ const TiXmlNode* node;
+ for (node = lastChild; node; node = node->prev)
+ {
+ if (strcmp(node->Value(), _value) == 0)
+ return node;
+ }
+ return 0;
+}
+
+TiXmlNode* TiXmlNode::LastChild(const char * _value)
+{
+ TiXmlNode* node;
+ for (node = lastChild; node; node = node->prev)
+ {
+ if (strcmp(node->Value(), _value) == 0)
+ return node;
+ }
+ return 0;
+}
+
+const TiXmlNode* TiXmlNode::IterateChildren(const TiXmlNode* previous) const
+{
+ if (!previous)
+ {
+ return FirstChild();
+ }
+ else
+ {
+ assert(previous->parent == this);
+ return previous->NextSibling();
+ }
+}
+
+TiXmlNode* TiXmlNode::IterateChildren(TiXmlNode* previous)
+{
+ if (!previous)
+ {
+ return FirstChild();
+ }
+ else
+ {
+ assert(previous->parent == this);
+ return previous->NextSibling();
+ }
+}
+
+const TiXmlNode* TiXmlNode::IterateChildren(const char * val, const TiXmlNode* previous) const
+{
+ if (!previous)
+ {
+ return FirstChild(val);
+ }
+ else
+ {
+ assert(previous->parent == this);
+ return previous->NextSibling(val);
+ }
+}
+
+TiXmlNode* TiXmlNode::IterateChildren(const char * val, TiXmlNode* previous)
+{
+ if (!previous)
+ {
+ return FirstChild(val);
+ }
+ else
+ {
+ assert(previous->parent == this);
+ return previous->NextSibling(val);
+ }
+}
+
+const TiXmlNode* TiXmlNode::NextSibling(const char * _value) const
+{
+ const TiXmlNode* node;
+ for (node = next; node; node = node->next)
+ {
+ if (strcmp(node->Value(), _value) == 0)
+ return node;
+ }
+ return 0;
+}
+
+TiXmlNode* TiXmlNode::NextSibling(const char * _value)
+{
+ TiXmlNode* node;
+ for (node = next; node; node = node->next)
+ {
+ if (strcmp(node->Value(), _value) == 0)
+ return node;
+ }
+ return 0;
+}
+
+const TiXmlNode* TiXmlNode::PreviousSibling(const char * _value) const
+{
+ const TiXmlNode* node;
+ for (node = prev; node; node = node->prev)
+ {
+ if (strcmp(node->Value(), _value) == 0)
+ return node;
+ }
+ return 0;
+}
+
+TiXmlNode* TiXmlNode::PreviousSibling(const char * _value)
+{
+ TiXmlNode* node;
+ for (node = prev; node; node = node->prev)
+ {
+ if (strcmp(node->Value(), _value) == 0)
+ return node;
+ }
+ return 0;
+}
+
+void TiXmlElement::RemoveAttribute(const char * name)
+{
+ TIXML_STRING str(name);
+ TiXmlAttribute* node = attributeSet.Find(str);
+ if (node)
+ {
+ attributeSet.Remove(node);
+ delete node;
+ }
+}
+
+const TiXmlElement* TiXmlNode::FirstChildElement() const
+{
+ const TiXmlNode* node;
+
+ for ( node = FirstChild();
+ node;
+ node = node->NextSibling())
+ {
+ if (node->ToElement())
+ return node->ToElement();
+ }
+ return 0;
+}
+
+TiXmlElement* TiXmlNode::FirstChildElement()
+{
+ TiXmlNode* node;
+
+ for ( node = FirstChild();
+ node;
+ node = node->NextSibling())
+ {
+ if (node->ToElement())
+ return node->ToElement();
+ }
+ return 0;
+}
+
+const TiXmlElement* TiXmlNode::FirstChildElement(const char * _value) const
+{
+ const TiXmlNode* node;
+
+ for ( node = FirstChild(_value);
+ node;
+ node = node->NextSibling(_value))
+ {
+ if (node->ToElement())
+ return node->ToElement();
+ }
+ return 0;
+}
+
+TiXmlElement* TiXmlNode::FirstChildElement(const char * _value)
+{
+ TiXmlNode* node;
+
+ for ( node = FirstChild(_value);
+ node;
+ node = node->NextSibling(_value))
+ {
+ if (node->ToElement())
+ return node->ToElement();
+ }
+ return 0;
+}
+
+const TiXmlElement* TiXmlNode::NextSiblingElement() const
+{
+ const TiXmlNode* node;
+
+ for ( node = NextSibling();
+ node;
+ node = node->NextSibling())
+ {
+ if (node->ToElement())
+ return node->ToElement();
+ }
+ return 0;
+}
+
+TiXmlElement* TiXmlNode::NextSiblingElement()
+{
+ TiXmlNode* node;
+
+ for ( node = NextSibling();
+ node;
+ node = node->NextSibling())
+ {
+ if (node->ToElement())
+ return node->ToElement();
+ }
+ return 0;
+}
+
+const TiXmlElement* TiXmlNode::NextSiblingElement(const char * _value) const
+{
+ const TiXmlNode* node;
+
+ for ( node = NextSibling(_value);
+ node;
+ node = node->NextSibling(_value))
+ {
+ if (node->ToElement())
+ return node->ToElement();
+ }
+ return 0;
+}
+
+TiXmlElement* TiXmlNode::NextSiblingElement(const char * _value)
+{
+ TiXmlNode* node;
+
+ for ( node = NextSibling(_value);
+ node;
+ node = node->NextSibling(_value))
+ {
+ if (node->ToElement())
+ return node->ToElement();
+ }
+ return 0;
+}
+
+
+const TiXmlDocument* TiXmlNode::GetDocument() const
+{
+ const TiXmlNode* node;
+
+ for (node = this; node; node = node->parent)
+ {
+ if (node->ToDocument())
+ return node->ToDocument();
+ }
+ return 0;
+}
+
+TiXmlDocument* TiXmlNode::GetDocument()
+{
+ TiXmlNode* node;
+
+ for (node = this; node; node = node->parent)
+ {
+ if (node->ToDocument())
+ return node->ToDocument();
+ }
+ return 0;
+}
+
+TiXmlElement::TiXmlElement (const char * _value)
+ : TiXmlNode(TiXmlNode::ELEMENT)
+{
+ firstChild = lastChild = 0;
+ value = _value;
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlElement::TiXmlElement(const std::string& _value)
+ : TiXmlNode(TiXmlNode::ELEMENT)
+{
+ firstChild = lastChild = 0;
+ value = _value;
+}
+#endif
+
+
+TiXmlElement::TiXmlElement(const TiXmlElement& copy)
+ : TiXmlNode(TiXmlNode::ELEMENT)
+{
+ firstChild = lastChild = 0;
+ copy.CopyTo(this);
+}
+
+
+void TiXmlElement::operator=(const TiXmlElement& base)
+{
+ ClearThis();
+ base.CopyTo(this);
+}
+
+
+TiXmlElement::~TiXmlElement()
+{
+ ClearThis();
+}
+
+
+void TiXmlElement::ClearThis()
+{
+ Clear();
+ while (attributeSet.First())
+ {
+ TiXmlAttribute* node = attributeSet.First();
+ attributeSet.Remove(node);
+ delete node;
+ }
+}
+
+
+const char * TiXmlElement::Attribute(const char * name) const
+{
+ TIXML_STRING str(name);
+ const TiXmlAttribute* node = attributeSet.Find(str);
+
+ if (node)
+ return node->Value();
+
+ return 0;
+}
+
+
+const char * TiXmlElement::Attribute(const char * name, int* i) const
+{
+ const char * s = Attribute(name);
+ if (i)
+ {
+ if (s)
+ *i = (int)_atoi64(s);
+ else
+ *i = 0;
+ }
+ return s;
+}
+
+
+const char * TiXmlElement::Attribute(const char * name, double* d) const
+{
+ const char * s = Attribute(name);
+ if (d)
+ {
+ if (s)
+ *d = atof(s);
+ else
+ *d = 0;
+ }
+ return s;
+}
+
+
+int TiXmlElement::QueryIntAttribute(const char* name, int* ival) const
+{
+ TIXML_STRING str(name);
+ const TiXmlAttribute* node = attributeSet.Find(str);
+ if (!node)
+ return TIXML_NO_ATTRIBUTE;
+
+ return node->QueryIntValue(ival);
+}
+
+
+int TiXmlElement::QueryDoubleAttribute(const char* name, double* dval) const
+{
+ TIXML_STRING str(name);
+ const TiXmlAttribute* node = attributeSet.Find(str);
+ if (!node)
+ return TIXML_NO_ATTRIBUTE;
+
+ return node->QueryDoubleValue(dval);
+}
+
+
+void TiXmlElement::SetAttribute(const char * name, int val)
+{
+ char buf[64];
+ mir_snprintf(buf, SIZEOF(buf), "%d", val);
+ SetAttribute(name, buf);
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlElement::SetAttribute(const std::string& name, int val)
+{
+ std::ostringstream oss;
+ oss << val;
+ SetAttribute(name, oss.str());
+}
+#endif
+
+
+void TiXmlElement::SetDoubleAttribute(const char * name, double val)
+{
+ char buf[256];
+ mir_snprintf(buf, SIZEOF(buf), "%f", val);
+ SetAttribute(name, buf);
+}
+
+
+void TiXmlElement::SetAttribute(const char * cname, const char * cvalue)
+{
+ TIXML_STRING _name(cname);
+ TIXML_STRING _value(cvalue);
+
+ TiXmlAttribute* node = attributeSet.Find(_name);
+ if (node)
+ {
+ node->SetValue(cvalue);
+ return;
+ }
+
+ TiXmlAttribute* attrib = new TiXmlAttribute(cname, cvalue);
+ if (attrib)
+ {
+ attributeSet.Add(attrib);
+ }
+ else
+ {
+ TiXmlDocument* document = GetDocument();
+ if (document) document->SetError(TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN);
+ }
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlElement::SetAttribute(const std::string& name, const std::string& _value)
+{
+ TiXmlAttribute* node = attributeSet.Find(name);
+ if (node)
+ {
+ node->SetValue(_value);
+ return;
+ }
+
+ TiXmlAttribute* attrib = new TiXmlAttribute(name, _value);
+ if (attrib)
+ {
+ attributeSet.Add(attrib);
+ }
+ else
+ {
+ TiXmlDocument* document = GetDocument();
+ if (document) document->SetError(TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN);
+ }
+}
+#endif
+
+
+void TiXmlElement::Print(FILE* cfile, int depth) const
+{
+ int i;
+ for (i=0; i<depth; i++)
+ {
+ fprintf(cfile, " ");
+ }
+
+ fprintf(cfile, "<%s", value.c_str());
+
+ const TiXmlAttribute* attrib;
+ for (attrib = attributeSet.First(); attrib; attrib = attrib->Next())
+ {
+ fprintf(cfile, " ");
+ attrib->Print(cfile, depth);
+ }
+
+ // There are 3 different formatting approaches:
+ // 1) An element without children is printed as a <foo /> node
+ // 2) An element with only a text child is printed as <foo> text </foo>
+ // 3) An element with children is printed on multiple lines.
+ TiXmlNode* node;
+ if (!firstChild)
+ {
+ fprintf(cfile, " />");
+ }
+ else if (firstChild == lastChild && firstChild->ToText())
+ {
+ fprintf(cfile, ">");
+ firstChild->Print(cfile, depth + 1);
+ fprintf(cfile, "</%s>", value.c_str());
+ }
+ else
+ {
+ fprintf(cfile, ">");
+
+ for (node = firstChild; node; node=node->NextSibling())
+ {
+ if (!node->ToText())
+ {
+ fprintf(cfile, "\n");
+ }
+ node->Print(cfile, depth+1);
+ }
+ fprintf(cfile, "\n");
+ for (i=0; i<depth; ++i)
+ fprintf(cfile, " ");
+ fprintf(cfile, "</%s>", value.c_str());
+ }
+}
+
+void TiXmlElement::StreamOut(TIXML_OSTREAM * stream) const
+{
+ (*stream) << "<" << value;
+
+ const TiXmlAttribute* attrib;
+ for (attrib = attributeSet.First(); attrib; attrib = attrib->Next())
+ {
+ (*stream) << " ";
+ attrib->StreamOut(stream);
+ }
+
+ // If this node has children, give it a closing tag. Else
+ // make it an empty tag.
+ TiXmlNode* node;
+ if (firstChild)
+ {
+ (*stream) << ">";
+
+ for (node = firstChild; node; node=node->NextSibling())
+ {
+ node->StreamOut(stream);
+ }
+ (*stream) << "</" << value << ">";
+ }
+ else
+ {
+ (*stream) << " />";
+ }
+}
+
+void TiXmlElement::FormattedStreamOut(TIXML_OSTREAM * stream, int depth) const
+{
+ // Adding tabs to get the proper tree format
+ int oldDepth = depth;
+ StreamDepth(stream, depth);
+
+ // Element name
+ (*stream) << "<" << value;
+
+ // Attributes
+ const TiXmlAttribute* attrib;
+ for (attrib = attributeSet.First(); attrib; attrib = attrib->Next())
+ {
+ (*stream) << " ";
+ attrib->StreamOut(stream);
+ }
+
+ // There are 3 different formatting approaches:
+ // 1) An element without children is printed as a <foo /> node
+ // 2) An element with only a text child is printed as <foo> text </foo>
+ // 3) An element with children is printed on multiple lines.
+ TiXmlNode* node;
+ if (!firstChild)
+ {
+ (*stream) << " />" << TIXML_ENDL;
+ }
+ else if (firstChild == lastChild && firstChild->ToText())
+ {
+ (*stream) << ">";
+ firstChild->FormattedStreamOut(stream, depth + 1);
+ (*stream) << "</" << value << ">" << TIXML_ENDL;
+ }
+ else
+ {
+ (*stream) << ">" << TIXML_ENDL;
+
+ // Children
+ depth++;
+ for (node = firstChild; node; node=node->NextSibling())
+ {
+ node->FormattedStreamOut(stream, depth);
+ }
+ StreamDepth(stream, oldDepth);
+ (*stream) << "</" << value << ">" << TIXML_ENDL;
+ }
+}
+
+void TiXmlElement::CopyTo(TiXmlElement* target) const
+{
+ // superclass:
+ TiXmlNode::CopyTo(target);
+
+ // Element class:
+ // Clone the attributes, then clone the children.
+ const TiXmlAttribute* attribute = 0;
+ for ( attribute = attributeSet.First();
+ attribute;
+ attribute = attribute->Next())
+ {
+ target->SetAttribute(attribute->Name(), attribute->Value());
+ }
+
+ TiXmlNode* node = 0;
+ for (node = firstChild; node; node = node->NextSibling())
+ {
+ target->LinkEndChild(node->Clone());
+ }
+}
+
+
+TiXmlNode* TiXmlElement::Clone() const
+{
+ TiXmlElement* clone = new TiXmlElement(Value());
+ if (!clone)
+ return 0;
+
+ CopyTo(clone);
+ return clone;
+}
+
+
+const char* TiXmlElement::GetText() const
+{
+ const TiXmlNode* child = this->FirstChild();
+ if (child) {
+ const TiXmlText* childText = child->ToText();
+ if (childText) {
+ return childText->Value();
+ }
+ }
+ return 0;
+}
+
+
+TiXmlDocument::TiXmlDocument() : TiXmlNode(TiXmlNode::DOCUMENT)
+{
+ tabsize = 4;
+ useMicrosoftBOM = false;
+ ClearError();
+}
+
+TiXmlDocument::TiXmlDocument(const char * documentName) : TiXmlNode(TiXmlNode::DOCUMENT)
+{
+ tabsize = 4;
+ useMicrosoftBOM = false;
+ value = documentName;
+ ClearError();
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlDocument::TiXmlDocument(const std::string& documentName) : TiXmlNode(TiXmlNode::DOCUMENT)
+{
+ tabsize = 4;
+ useMicrosoftBOM = false;
+ value = documentName;
+ ClearError();
+}
+#endif
+
+
+TiXmlDocument::TiXmlDocument(const TiXmlDocument& copy) : TiXmlNode(TiXmlNode::DOCUMENT)
+{
+ copy.CopyTo(this);
+}
+
+
+void TiXmlDocument::operator=(const TiXmlDocument& copy)
+{
+ Clear();
+ copy.CopyTo(this);
+}
+
+
+bool TiXmlDocument::LoadFile(TiXmlEncoding encoding)
+{
+ // See STL_STRING_BUG below.
+ StringToBuffer buf(value);
+
+ if (buf.buffer && LoadFile(buf.buffer, encoding))
+ return true;
+
+ return false;
+}
+
+
+bool TiXmlDocument::SaveFile() const
+{
+ // See STL_STRING_BUG below.
+ StringToBuffer buf(value);
+
+ if (buf.buffer && SaveFile(buf.buffer))
+ return true;
+
+ return false;
+}
+
+#ifdef TIXML_USE_STL
+std::string TiXmlDocument::GetAsString()
+{
+ std::stringstream out;
+ FormattedStreamOut(&out, 0);
+ return out.str();
+}
+#endif
+
+bool TiXmlDocument::GetAsCharBuffer(char* buffer, size_t bufferSize)
+{
+ #ifdef TIXML_USE_STL
+ std::string data = GetAsString();
+ #else
+ TIXML_OSTREAM data;
+ FormattedStreamOut(&data, 0);
+ #endif
+
+ if (bufferSize < data.length())
+ {
+ return false;
+ }
+ else
+ {
+ strcpy(buffer, data.c_str());
+ return true;
+ }
+}
+
+bool TiXmlDocument::LoadFile(const char* filename, TiXmlEncoding encoding)
+{
+ // There was a really terrifying little bug here. The code:
+ // value = filename
+ // in the STL case, cause the assignment method of the std::string to
+ // be called. What is strange, is that the std::string had the same
+ // address as it's c_str() method, and so bad things happen. Looks
+ // like a bug in the Microsoft STL implementation.
+ // See STL_STRING_BUG above.
+ // Fixed with the StringToBuffer class.
+ value = filename;
+
+ // reading in binary mode so that tinyxml can normalize the EOL
+ FILE* file = fopen(value.c_str (), "rb");
+
+ if (file)
+ {
+ bool result = LoadFile(file, encoding);
+ fclose(file);
+ return result;
+ }
+ else
+ {
+ SetError(TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN);
+ return false;
+ }
+}
+
+bool TiXmlDocument::LoadFile(FILE* file, TiXmlEncoding encoding)
+{
+ if (!file)
+ {
+ SetError(TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN);
+ return false;
+ }
+
+ // Delete the existing data:
+ Clear();
+ location.Clear();
+
+ // Get the file size, so we can pre-allocate the string. HUGE speed impact.
+ long length = 0;
+ fseek(file, 0, SEEK_END);
+ length = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ // Strange case, but good to handle up front.
+ if (length == 0)
+ {
+ SetError(TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN);
+ return false;
+ }
+
+ // If we have a file, assume it is all one big XML file, and read it in.
+ // The document parser may decide the document ends sooner than the entire file, however.
+ TIXML_STRING data;
+ data.reserve(length);
+
+ // Subtle bug here. TinyXml did use fgets. But from the XML spec:
+ // 2.11 End-of-Line Handling
+ // <snip>
+ // <quote>
+ // ...the XML processor MUST behave as if it normalized all line breaks in external
+ // parsed entities (including the document entity) on input, before parsing, by translating
+ // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to
+ // a single #xA character.
+ // </quote>
+ //
+ // It is not clear fgets does that, and certainly isn't clear it works cross platform.
+ // Generally, you expect fgets to translate from the convention of the OS to the c/unix
+ // convention, and not work generally.
+
+ /*
+ while (fgets(buf, sizeof(buf), file))
+ {
+ data += buf;
+ }
+ */
+
+ char* buf = new char[ length+1 ];
+ buf[0] = 0;
+
+ if (fread(buf, length, 1, file) != 1) {
+ delete [] buf;
+ SetError(TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN);
+ return false;
+ }
+
+ const char* lastPos = buf;
+ const char* p = buf;
+
+ buf[length] = 0;
+ while (*p) {
+ assert(p < (buf+length));
+ if (*p == 0xa) {
+ // Newline character. No special rules for this. Append all the characters
+ // since the last string, and include the newline.
+ data.append(lastPos, (p-lastPos+1)); // append, include the newline
+ ++p; // move past the newline
+ lastPos = p; // and point to the new buffer (may be 0)
+ assert(p <= (buf+length));
+ }
+ else if (*p == 0xd) {
+ // Carriage return. Append what we have so far, then
+ // handle moving forward in the buffer.
+ if ((p-lastPos) > 0) {
+ data.append(lastPos, p-lastPos); // do not add the CR
+ }
+ data += (char)0xa; // a proper newline
+
+ if (*(p+1) == 0xa) {
+ // Carriage return - new line sequence
+ p += 2;
+ lastPos = p;
+ assert(p <= (buf+length));
+ }
+ else {
+ // it was followed by something else...that is presumably characters again.
+ ++p;
+ lastPos = p;
+ assert(p <= (buf+length));
+ }
+ }
+ else {
+ ++p;
+ }
+ }
+ // Handle any left over characters.
+ if (p-lastPos) {
+ data.append(lastPos, p-lastPos);
+ }
+ delete [] buf;
+ buf = 0;
+
+ Parse(data.c_str(), 0, encoding);
+
+ if ( Error())
+ return false;
+ else
+ return true;
+}
+
+
+bool TiXmlDocument::SaveFile(const char * filename) const
+{
+ // The old c stuff lives on...
+ FILE* fp = fopen(filename, "w");
+ if (fp)
+ {
+ bool result = SaveFile(fp);
+ fclose(fp);
+ return result;
+ }
+ return false;
+}
+
+
+bool TiXmlDocument::SaveFile(FILE* fp) const
+{
+ if (useMicrosoftBOM)
+ {
+ const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
+ const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
+ const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
+
+ fputc(TIXML_UTF_LEAD_0, fp);
+ fputc(TIXML_UTF_LEAD_1, fp);
+ fputc(TIXML_UTF_LEAD_2, fp);
+ }
+ Print(fp, 0);
+ return true;
+}
+
+
+void TiXmlDocument::CopyTo(TiXmlDocument* target) const
+{
+ TiXmlNode::CopyTo(target);
+
+ target->error = error;
+ target->errorDesc = errorDesc.c_str ();
+
+ TiXmlNode* node = 0;
+ for (node = firstChild; node; node = node->NextSibling())
+ {
+ target->LinkEndChild(node->Clone());
+ }
+}
+
+
+TiXmlNode* TiXmlDocument::Clone() const
+{
+ TiXmlDocument* clone = new TiXmlDocument();
+ if (!clone)
+ return 0;
+
+ CopyTo(clone);
+ return clone;
+}
+
+
+void TiXmlDocument::Print(FILE* cfile, int depth) const
+{
+ const TiXmlNode* node;
+ for (node=FirstChild(); node; node=node->NextSibling())
+ {
+ node->Print(cfile, depth);
+ fprintf(cfile, "\n");
+ }
+}
+
+void TiXmlDocument::StreamOut(TIXML_OSTREAM * out) const
+{
+ const TiXmlNode* node;
+ for (node=FirstChild(); node; node=node->NextSibling())
+ {
+ node->StreamOut(out);
+
+ // Special rule for streams: stop after the root element.
+ // The stream in code will only read one element, so don't
+ // write more than one.
+ if (node->ToElement())
+ break;
+ }
+}
+
+void TiXmlDocument::FormattedStreamOut(TIXML_OSTREAM * out, int depth) const
+{
+ const TiXmlNode* node;
+ for (node=FirstChild(); node; node=node->NextSibling())
+ {
+ node->FormattedStreamOut(out, depth);
+
+ // Special rule for streams: stop after the root element.
+ // The stream in code will only read one element, so don't
+ // write more than one.
+ if (node->ToElement())
+ break;
+ }
+}
+
+const TiXmlAttribute* TiXmlAttribute::Next() const
+{
+ // We are using knowledge of the sentinel. The sentinel
+ // have a value or name.
+ if (next->value.empty() && next->name.empty())
+ return 0;
+ return next;
+}
+
+TiXmlAttribute* TiXmlAttribute::Next()
+{
+ // We are using knowledge of the sentinel. The sentinel
+ // have a value or name.
+ if (next->value.empty() && next->name.empty())
+ return 0;
+ return next;
+}
+
+const TiXmlAttribute* TiXmlAttribute::Previous() const
+{
+ // We are using knowledge of the sentinel. The sentinel
+ // have a value or name.
+ if (prev->value.empty() && prev->name.empty())
+ return 0;
+ return prev;
+}
+
+TiXmlAttribute* TiXmlAttribute::Previous()
+{
+ // We are using knowledge of the sentinel. The sentinel
+ // have a value or name.
+ if (prev->value.empty() && prev->name.empty())
+ return 0;
+ return prev;
+}
+
+void TiXmlAttribute::Print(FILE* cfile, int /*depth*/) const
+{
+ TIXML_STRING n, v;
+
+ PutString(name, &n);
+ PutString(value, &v);
+
+ if (value.find ('\"') == TIXML_STRING::npos)
+ fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str());
+ else
+ fprintf (cfile, "%s='%s'", n.c_str(), v.c_str());
+}
+
+
+void TiXmlAttribute::StreamOut(TIXML_OSTREAM * stream) const
+{
+ if (value.find('\"') != TIXML_STRING::npos)
+ {
+ PutString(name, stream);
+ (*stream) << "=" << "'";
+ PutString(value, stream);
+ (*stream) << "'";
+ }
+ else
+ {
+ PutString(name, stream);
+ (*stream) << "=" << "\"";
+ PutString(value, stream);
+ (*stream) << "\"";
+ }
+}
+
+int TiXmlAttribute::QueryIntValue(int* ival) const
+{
+ if (sscanf(value.c_str(), "%d", ival) == 1)
+ return TIXML_SUCCESS;
+ return TIXML_WRONG_TYPE;
+}
+
+int TiXmlAttribute::QueryDoubleValue(double* dval) const
+{
+ if (sscanf(value.c_str(), "%lf", dval) == 1)
+ return TIXML_SUCCESS;
+ return TIXML_WRONG_TYPE;
+}
+
+void TiXmlAttribute::SetIntValue(int _value)
+{
+ char buf[64];
+ mir_snprintf(buf, SIZEOF(buf), "%d", _value);
+ SetValue(buf);
+}
+
+void TiXmlAttribute::SetDoubleValue(double _value)
+{
+ char buf[256];
+ mir_snprintf(buf, SIZEOF(buf), "%lf", _value);
+ SetValue(buf);
+}
+
+int TiXmlAttribute::IntValue() const
+{
+ return (int)_atoi64(value.c_str ());
+}
+
+double TiXmlAttribute::DoubleValue() const
+{
+ return atof (value.c_str ());
+}
+
+
+TiXmlComment::TiXmlComment(const TiXmlComment& copy) : TiXmlNode(TiXmlNode::COMMENT)
+{
+ copy.CopyTo(this);
+}
+
+
+void TiXmlComment::operator=(const TiXmlComment& base)
+{
+ Clear();
+ base.CopyTo(this);
+}
+
+
+void TiXmlComment::Print(FILE* cfile, int depth) const
+{
+ for (int i=0; i<depth; i++)
+ {
+ fputs(" ", cfile);
+ }
+ fprintf(cfile, "<!--%s-->", value.c_str());
+}
+
+void TiXmlComment::StreamOut(TIXML_OSTREAM * stream) const
+{
+ (*stream) << "<!--";
+ //PutString(value, stream);
+ (*stream) << value;
+ (*stream) << "-->";
+}
+
+void TiXmlComment::FormattedStreamOut(TIXML_OSTREAM * stream, int depth) const
+{
+ StreamDepth(stream, depth);
+
+ StreamOut(stream);
+
+ (*stream) << TIXML_ENDL;
+}
+
+void TiXmlComment::CopyTo(TiXmlComment* target) const
+{
+ TiXmlNode::CopyTo(target);
+}
+
+
+TiXmlNode* TiXmlComment::Clone() const
+{
+ TiXmlComment* clone = new TiXmlComment();
+
+ if (!clone)
+ return 0;
+
+ CopyTo(clone);
+ return clone;
+}
+
+
+void TiXmlText::Print(FILE* cfile, int depth) const
+{
+ if (cdata)
+ {
+ int i;
+ fprintf(cfile, "\n");
+ for (i=0; i<depth; i++) {
+ fprintf(cfile, " ");
+ }
+ fprintf(cfile, "<![CDATA[");
+ fprintf(cfile, "%s", value.c_str()); // unformatted output
+ fprintf(cfile, "]]>\n");
+ }
+ else
+ {
+ TIXML_STRING buffer;
+ PutString(value, &buffer);
+ fprintf(cfile, "%s", buffer.c_str());
+ }
+}
+
+
+void TiXmlText::StreamOut(TIXML_OSTREAM * stream) const
+{
+ if (cdata)
+ {
+ (*stream) << "<![CDATA[" << value << "]]>";
+ }
+ else
+ {
+ PutString(value, stream);
+ }
+}
+
+void TiXmlText::FormattedStreamOut(TIXML_OSTREAM * stream, int depth) const
+{
+ if (cdata)
+ {
+ (*stream) << TIXML_ENDL;
+ StreamDepth(stream, depth);
+ (*stream) << "<![CDATA[" << value << "]]>" << TIXML_ENDL;
+ }
+ else
+ {
+ PutString(value, stream);
+ }
+}
+
+void TiXmlText::CopyTo(TiXmlText* target) const
+{
+ TiXmlNode::CopyTo(target);
+ target->cdata = cdata;
+}
+
+
+TiXmlNode* TiXmlText::Clone() const
+{
+ TiXmlText* clone = 0;
+ clone = new TiXmlText("");
+
+ if (!clone)
+ return 0;
+
+ CopyTo(clone);
+ return clone;
+}
+
+
+TiXmlDeclaration::TiXmlDeclaration(const char * _version,
+ const char * _encoding,
+ const char * _standalone)
+ : TiXmlNode(TiXmlNode::DECLARATION)
+{
+ version = _version;
+ encoding = _encoding;
+ standalone = _standalone;
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlDeclaration::TiXmlDeclaration( const std::string& _version,
+ const std::string& _encoding,
+ const std::string& _standalone)
+ : TiXmlNode(TiXmlNode::DECLARATION)
+{
+ version = _version;
+ encoding = _encoding;
+ standalone = _standalone;
+}
+#endif
+
+
+TiXmlDeclaration::TiXmlDeclaration(const TiXmlDeclaration& copy)
+ : TiXmlNode(TiXmlNode::DECLARATION)
+{
+ copy.CopyTo(this);
+}
+
+
+void TiXmlDeclaration::operator=(const TiXmlDeclaration& copy)
+{
+ Clear();
+ copy.CopyTo(this);
+}
+
+
+void TiXmlDeclaration::Print(FILE* cfile, int /*depth*/) const
+{
+ fprintf (cfile, "<?xml ");
+
+ if (!version.empty())
+ fprintf (cfile, "version=\"%s\" ", version.c_str ());
+ if (!encoding.empty())
+ fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
+ if (!standalone.empty())
+ fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
+ fprintf (cfile, "?>");
+}
+
+void TiXmlDeclaration::StreamOut(TIXML_OSTREAM * stream) const
+{
+ (*stream) << "<?xml ";
+
+ if (!version.empty())
+ {
+ (*stream) << "version=\"";
+ PutString(version, stream);
+ (*stream) << "\" ";
+ }
+ if (!encoding.empty())
+ {
+ (*stream) << "encoding=\"";
+ PutString(encoding, stream);
+ (*stream) << "\" ";
+ }
+ if (!standalone.empty())
+ {
+ (*stream) << "standalone=\"";
+ PutString(standalone, stream);
+ (*stream) << "\" ";
+ }
+ (*stream) << "?>";
+}
+
+void TiXmlDeclaration::FormattedStreamOut(TIXML_OSTREAM * stream, int depth) const
+{
+ StreamDepth(stream, depth);
+ StreamOut(stream);
+ (*stream) << TIXML_ENDL;
+}
+
+void TiXmlDeclaration::CopyTo(TiXmlDeclaration* target) const
+{
+ TiXmlNode::CopyTo(target);
+
+ target->version = version;
+ target->encoding = encoding;
+ target->standalone = standalone;
+}
+
+
+TiXmlNode* TiXmlDeclaration::Clone() const
+{
+ TiXmlDeclaration* clone = new TiXmlDeclaration();
+
+ if (!clone)
+ return 0;
+
+ CopyTo(clone);
+ return clone;
+}
+
+
+void TiXmlUnknown::Print(FILE* cfile, int depth) const
+{
+ for (int i=0; i<depth; i++)
+ fprintf(cfile, " ");
+ fprintf(cfile, "<%s>", value.c_str());
+}
+
+
+void TiXmlUnknown::StreamOut(TIXML_OSTREAM * stream) const
+{
+ (*stream) << "<" << value << ">"; // Don't use entities here! It is unknown.
+}
+
+void TiXmlUnknown::FormattedStreamOut(TIXML_OSTREAM * stream, int depth) const
+{
+ StreamDepth(stream, depth);
+ (*stream) << "<" << value << ">" << TIXML_ENDL; // Don't use entities here! It is unknown.
+}
+
+void TiXmlUnknown::CopyTo(TiXmlUnknown* target) const
+{
+ TiXmlNode::CopyTo(target);
+}
+
+
+TiXmlNode* TiXmlUnknown::Clone() const
+{
+ TiXmlUnknown* clone = new TiXmlUnknown();
+
+ if (!clone)
+ return 0;
+
+ CopyTo(clone);
+ return clone;
+}
+
+
+TiXmlAttributeSet::TiXmlAttributeSet()
+{
+ sentinel.next = &sentinel;
+ sentinel.prev = &sentinel;
+}
+
+
+TiXmlAttributeSet::~TiXmlAttributeSet()
+{
+ assert(sentinel.next == &sentinel);
+ assert(sentinel.prev == &sentinel);
+}
+
+
+void TiXmlAttributeSet::Add(TiXmlAttribute* addMe)
+{
+ assert(!Find(TIXML_STRING(addMe->Name()))); // Shouldn't be multiply adding to the set.
+
+ addMe->next = &sentinel;
+ addMe->prev = sentinel.prev;
+
+ sentinel.prev->next = addMe;
+ sentinel.prev = addMe;
+}
+
+void TiXmlAttributeSet::Remove(TiXmlAttribute* removeMe)
+{
+ TiXmlAttribute* node;
+
+ for (node = sentinel.next; node != &sentinel; node = node->next)
+ {
+ if (node == removeMe)
+ {
+ node->prev->next = node->next;
+ node->next->prev = node->prev;
+ node->next = 0;
+ node->prev = 0;
+ return;
+ }
+ }
+ assert(0); // we tried to remove a non-linked attribute.
+}
+
+const TiXmlAttribute* TiXmlAttributeSet::Find(const TIXML_STRING& name) const
+{
+ const TiXmlAttribute* node;
+
+ for (node = sentinel.next; node != &sentinel; node = node->next)
+ {
+ if (node->name == name)
+ return node;
+ }
+ return 0;
+}
+
+TiXmlAttribute* TiXmlAttributeSet::Find(const TIXML_STRING& name)
+{
+ TiXmlAttribute* node;
+
+ for (node = sentinel.next; node != &sentinel; node = node->next)
+ {
+ if (node->name == name)
+ return node;
+ }
+ return 0;
+}
+
+#ifdef TIXML_USE_STL
+TIXML_ISTREAM & operator >> (TIXML_ISTREAM & in, TiXmlNode & base)
+{
+ TIXML_STRING tag;
+ tag.reserve(8 * 1000);
+ base.StreamIn(&in, &tag);
+
+ base.Parse(tag.c_str(), 0, TIXML_DEFAULT_ENCODING);
+ return in;
+}
+#endif
+
+
+TIXML_OSTREAM & operator<< (TIXML_OSTREAM & out, const TiXmlNode & base)
+{
+ base.StreamOut (& out);
+ return out;
+}
+
+
+#ifdef TIXML_USE_STL
+std::string & operator<< (std::string& out, const TiXmlNode& base)
+{
+ std::ostringstream os_stream(std::ostringstream::out);
+ base.StreamOut(&os_stream);
+
+ out.append(os_stream.str());
+ return out;
+}
+#endif
+
+
+TiXmlHandle TiXmlHandle::FirstChild() const
+{
+ if (node)
+ {
+ TiXmlNode* child = node->FirstChild();
+ if (child)
+ return TiXmlHandle(child);
+ }
+ return TiXmlHandle(0);
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChild(const char * value) const
+{
+ if (node)
+ {
+ TiXmlNode* child = node->FirstChild(value);
+ if (child)
+ return TiXmlHandle(child);
+ }
+ return TiXmlHandle(0);
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChildElement() const
+{
+ if (node)
+ {
+ TiXmlElement* child = node->FirstChildElement();
+ if (child)
+ return TiXmlHandle(child);
+ }
+ return TiXmlHandle(0);
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChildElement(const char * value) const
+{
+ if (node)
+ {
+ TiXmlElement* child = node->FirstChildElement(value);
+ if (child)
+ return TiXmlHandle(child);
+ }
+ return TiXmlHandle(0);
+}
+
+
+TiXmlHandle TiXmlHandle::Child(int count) const
+{
+ if (node)
+ {
+ int i;
+ TiXmlNode* child = node->FirstChild();
+ for ( i=0;
+ child && i<count;
+ child = child->NextSibling(), ++i)
+ {
+ // nothing
+ }
+ if (child)
+ return TiXmlHandle(child);
+ }
+ return TiXmlHandle(0);
+}
+
+
+TiXmlHandle TiXmlHandle::Child(const char* value, int count) const
+{
+ if (node)
+ {
+ int i;
+ TiXmlNode* child = node->FirstChild(value);
+ for ( i=0;
+ child && i<count;
+ child = child->NextSibling(value), ++i)
+ {
+ // nothing
+ }
+ if (child)
+ return TiXmlHandle(child);
+ }
+ return TiXmlHandle(0);
+}
+
+
+TiXmlHandle TiXmlHandle::ChildElement(int count) const
+{
+ if (node)
+ {
+ int i;
+ TiXmlElement* child = node->FirstChildElement();
+ for ( i=0;
+ child && i<count;
+ child = child->NextSiblingElement(), ++i)
+ {
+ // nothing
+ }
+ if (child)
+ return TiXmlHandle(child);
+ }
+ return TiXmlHandle(0);
+}
+
+
+TiXmlHandle TiXmlHandle::ChildElement(const char* value, int count) const
+{
+ if (node)
+ {
+ int i;
+ TiXmlElement* child = node->FirstChildElement(value);
+ for ( i=0;
+ child && i<count;
+ child = child->NextSiblingElement(value), ++i)
+ {
+ // nothing
+ }
+ if (child)
+ return TiXmlHandle(child);
+ }
+ return TiXmlHandle(0);
+}