Updated TinyXML
This commit is contained in:
parent
b28b7712c1
commit
c9a63ca606
|
@ -368,6 +368,19 @@ const char* StrPair::GetStr()
|
|||
|
||||
// --------- XMLUtil ----------- //
|
||||
|
||||
const char* XMLUtil::writeBoolTrue = "true";
|
||||
const char* XMLUtil::writeBoolFalse = "false";
|
||||
|
||||
void XMLUtil::SetBoolSerialization(const char* writeTrue, const char* writeFalse)
|
||||
{
|
||||
static const char* defTrue = "true";
|
||||
static const char* defFalse = "false";
|
||||
|
||||
writeBoolTrue = (writeTrue) ? writeTrue : defTrue;
|
||||
writeBoolFalse = (writeFalse) ? writeFalse : defFalse;
|
||||
}
|
||||
|
||||
|
||||
const char* XMLUtil::ReadBOM( const char* p, bool* bom )
|
||||
{
|
||||
TIXMLASSERT( p );
|
||||
|
@ -411,20 +424,24 @@ void XMLUtil::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length
|
|||
|
||||
output += *length;
|
||||
|
||||
// Scary scary fall throughs.
|
||||
// Scary scary fall throughs are annotated with carefully designed comments
|
||||
// to suppress compiler warnings such as -Wimplicit-fallthrough in gcc
|
||||
switch (*length) {
|
||||
case 4:
|
||||
--output;
|
||||
*output = (char)((input | BYTE_MARK) & BYTE_MASK);
|
||||
input >>= 6;
|
||||
//fall through
|
||||
case 3:
|
||||
--output;
|
||||
*output = (char)((input | BYTE_MARK) & BYTE_MASK);
|
||||
input >>= 6;
|
||||
//fall through
|
||||
case 2:
|
||||
--output;
|
||||
*output = (char)((input | BYTE_MARK) & BYTE_MASK);
|
||||
input >>= 6;
|
||||
//fall through
|
||||
case 1:
|
||||
--output;
|
||||
*output = (char)(input | FIRST_BYTE_MARK[*length]);
|
||||
|
@ -545,7 +562,7 @@ void XMLUtil::ToStr( unsigned v, char* buffer, int bufferSize )
|
|||
|
||||
void XMLUtil::ToStr( bool v, char* buffer, int bufferSize )
|
||||
{
|
||||
TIXML_SNPRINTF( buffer, bufferSize, "%s", v ? "true" : "false" );
|
||||
TIXML_SNPRINTF( buffer, bufferSize, "%s", v ? writeBoolTrue : writeBoolFalse);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -665,46 +682,34 @@ char* XMLDocument::Identify( char* p, XMLNode** node )
|
|||
TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLDeclaration ) ); // use same memory pool
|
||||
XMLNode* returnNode = 0;
|
||||
if ( XMLUtil::StringEqual( p, xmlHeader, xmlHeaderLen ) ) {
|
||||
TIXMLASSERT( sizeof( XMLDeclaration ) == _commentPool.ItemSize() );
|
||||
returnNode = new (_commentPool.Alloc()) XMLDeclaration( this );
|
||||
returnNode = CreateUnlinkedNode<XMLDeclaration>( _commentPool );
|
||||
returnNode->_parseLineNum = _parseCurLineNum;
|
||||
returnNode->_memPool = &_commentPool;
|
||||
p += xmlHeaderLen;
|
||||
}
|
||||
else if ( XMLUtil::StringEqual( p, commentHeader, commentHeaderLen ) ) {
|
||||
TIXMLASSERT( sizeof( XMLComment ) == _commentPool.ItemSize() );
|
||||
returnNode = new (_commentPool.Alloc()) XMLComment( this );
|
||||
returnNode = CreateUnlinkedNode<XMLComment>( _commentPool );
|
||||
returnNode->_parseLineNum = _parseCurLineNum;
|
||||
returnNode->_memPool = &_commentPool;
|
||||
p += commentHeaderLen;
|
||||
}
|
||||
else if ( XMLUtil::StringEqual( p, cdataHeader, cdataHeaderLen ) ) {
|
||||
TIXMLASSERT( sizeof( XMLText ) == _textPool.ItemSize() );
|
||||
XMLText* text = new (_textPool.Alloc()) XMLText( this );
|
||||
XMLText* text = CreateUnlinkedNode<XMLText>( _textPool );
|
||||
returnNode = text;
|
||||
returnNode->_parseLineNum = _parseCurLineNum;
|
||||
returnNode->_memPool = &_textPool;
|
||||
p += cdataHeaderLen;
|
||||
text->SetCData( true );
|
||||
}
|
||||
else if ( XMLUtil::StringEqual( p, dtdHeader, dtdHeaderLen ) ) {
|
||||
TIXMLASSERT( sizeof( XMLUnknown ) == _commentPool.ItemSize() );
|
||||
returnNode = new (_commentPool.Alloc()) XMLUnknown( this );
|
||||
returnNode = CreateUnlinkedNode<XMLUnknown>( _commentPool );
|
||||
returnNode->_parseLineNum = _parseCurLineNum;
|
||||
returnNode->_memPool = &_commentPool;
|
||||
p += dtdHeaderLen;
|
||||
}
|
||||
else if ( XMLUtil::StringEqual( p, elementHeader, elementHeaderLen ) ) {
|
||||
TIXMLASSERT( sizeof( XMLElement ) == _elementPool.ItemSize() );
|
||||
returnNode = new (_elementPool.Alloc()) XMLElement( this );
|
||||
returnNode = CreateUnlinkedNode<XMLElement>( _elementPool );
|
||||
returnNode->_parseLineNum = _parseCurLineNum;
|
||||
returnNode->_memPool = &_elementPool;
|
||||
p += elementHeaderLen;
|
||||
}
|
||||
else {
|
||||
TIXMLASSERT( sizeof( XMLText ) == _textPool.ItemSize() );
|
||||
returnNode = new (_textPool.Alloc()) XMLText( this );
|
||||
returnNode->_memPool = &_textPool;
|
||||
returnNode = CreateUnlinkedNode<XMLText>( _textPool );
|
||||
returnNode->_parseLineNum = _parseCurLineNum; // Report line of first non-whitespace character
|
||||
p = start; // Back it up, all the text counts.
|
||||
_parseCurLineNum = startLine;
|
||||
|
@ -771,6 +776,18 @@ void XMLNode::SetValue( const char* str, bool staticMem )
|
|||
}
|
||||
}
|
||||
|
||||
XMLNode* XMLNode::DeepClone(XMLDocument* target) const
|
||||
{
|
||||
XMLNode* clone = this->ShallowClone(target);
|
||||
if (!clone) return 0;
|
||||
|
||||
for (const XMLNode* child = this->FirstChild(); child; child = child->NextSibling()) {
|
||||
XMLNode* childClone = child->DeepClone(target);
|
||||
TIXMLASSERT(childClone);
|
||||
clone->InsertEndChild(childClone);
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
void XMLNode::DeleteChildren()
|
||||
{
|
||||
|
@ -800,6 +817,8 @@ void XMLNode::Unlink( XMLNode* child )
|
|||
if ( child->_next ) {
|
||||
child->_next->_prev = child->_prev;
|
||||
}
|
||||
child->_next = 0;
|
||||
child->_prev = 0;
|
||||
child->_parent = 0;
|
||||
}
|
||||
|
||||
|
@ -810,6 +829,9 @@ void XMLNode::DeleteChild( XMLNode* node )
|
|||
TIXMLASSERT( node->_document == _document );
|
||||
TIXMLASSERT( node->_parent == this );
|
||||
Unlink( node );
|
||||
TIXMLASSERT(node->_prev == 0);
|
||||
TIXMLASSERT(node->_next == 0);
|
||||
TIXMLASSERT(node->_parent == 0);
|
||||
DeleteNode( node );
|
||||
}
|
||||
|
||||
|
@ -954,7 +976,7 @@ const XMLElement* XMLNode::PreviousSiblingElement( const char* name ) const
|
|||
}
|
||||
|
||||
|
||||
char* XMLNode::ParseDeep( char* p, StrPair* parentEnd, int* curLineNumPtr )
|
||||
char* XMLNode::ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr )
|
||||
{
|
||||
// This is a recursive method, but thinking about it "at the current level"
|
||||
// it is a pretty simple flat list:
|
||||
|
@ -1019,8 +1041,8 @@ char* XMLNode::ParseDeep( char* p, StrPair* parentEnd, int* curLineNumPtr )
|
|||
if ( ele ) {
|
||||
// We read the end tag. Return it to the parent.
|
||||
if ( ele->ClosingType() == XMLElement::CLOSING ) {
|
||||
if ( parentEnd ) {
|
||||
ele->_value.TransferTo( parentEnd );
|
||||
if ( parentEndTag ) {
|
||||
ele->_value.TransferTo( parentEndTag );
|
||||
}
|
||||
node->_memPool->SetTracked(); // created and then immediately deleted.
|
||||
DeleteNode( node );
|
||||
|
@ -1054,11 +1076,16 @@ char* XMLNode::ParseDeep( char* p, StrPair* parentEnd, int* curLineNumPtr )
|
|||
return 0;
|
||||
}
|
||||
|
||||
void XMLNode::DeleteNode( XMLNode* node )
|
||||
/*static*/ void XMLNode::DeleteNode( XMLNode* node )
|
||||
{
|
||||
if ( node == 0 ) {
|
||||
return;
|
||||
}
|
||||
TIXMLASSERT(node->_document);
|
||||
if (!node->ToDocument()) {
|
||||
node->_document->MarkInUse(node);
|
||||
}
|
||||
|
||||
MemPool* pool = node->_memPool;
|
||||
node->~XMLNode();
|
||||
pool->Free( node );
|
||||
|
@ -1069,10 +1096,13 @@ void XMLNode::InsertChildPreamble( XMLNode* insertThis ) const
|
|||
TIXMLASSERT( insertThis );
|
||||
TIXMLASSERT( insertThis->_document == _document );
|
||||
|
||||
if ( insertThis->_parent )
|
||||
if (insertThis->_parent) {
|
||||
insertThis->_parent->Unlink( insertThis );
|
||||
else
|
||||
}
|
||||
else {
|
||||
insertThis->_document->MarkInUse(insertThis);
|
||||
insertThis->_memPool->SetTracked();
|
||||
}
|
||||
}
|
||||
|
||||
const XMLElement* XMLNode::ToElementWithName( const char* name ) const
|
||||
|
@ -1132,6 +1162,7 @@ XMLNode* XMLText::ShallowClone( XMLDocument* doc ) const
|
|||
|
||||
bool XMLText::ShallowEqual( const XMLNode* compare ) const
|
||||
{
|
||||
TIXMLASSERT( compare );
|
||||
const XMLText* text = compare->ToText();
|
||||
return ( text && XMLUtil::StringEqual( text->Value(), Value() ) );
|
||||
}
|
||||
|
@ -1447,7 +1478,7 @@ void XMLAttribute::SetAttribute( float v )
|
|||
|
||||
// --------- XMLElement ---------- //
|
||||
XMLElement::XMLElement( XMLDocument* doc ) : XMLNode( doc ),
|
||||
_closingType( 0 ),
|
||||
_closingType( OPEN ),
|
||||
_rootAttribute( 0 )
|
||||
{
|
||||
}
|
||||
|
@ -1837,6 +1868,7 @@ XMLAttribute* XMLElement::CreateAttribute()
|
|||
{
|
||||
TIXMLASSERT( sizeof( XMLAttribute ) == _document->_attributePool.ItemSize() );
|
||||
XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute();
|
||||
TIXMLASSERT( attrib );
|
||||
attrib->_memPool = &_document->_attributePool;
|
||||
attrib->_memPool->SetTracked();
|
||||
return attrib;
|
||||
|
@ -1846,7 +1878,7 @@ XMLAttribute* XMLElement::CreateAttribute()
|
|||
// <ele></ele>
|
||||
// <ele>foo<b>bar</b></ele>
|
||||
//
|
||||
char* XMLElement::ParseDeep( char* p, StrPair* strPair, int* curLineNumPtr )
|
||||
char* XMLElement::ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr )
|
||||
{
|
||||
// Read the element name.
|
||||
p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr );
|
||||
|
@ -1865,11 +1897,11 @@ char* XMLElement::ParseDeep( char* p, StrPair* strPair, int* curLineNumPtr )
|
|||
}
|
||||
|
||||
p = ParseAttributes( p, curLineNumPtr );
|
||||
if ( !p || !*p || _closingType ) {
|
||||
if ( !p || !*p || _closingType != OPEN ) {
|
||||
return p;
|
||||
}
|
||||
|
||||
p = XMLNode::ParseDeep( p, strPair, curLineNumPtr );
|
||||
p = XMLNode::ParseDeep( p, parentEndTag, curLineNumPtr );
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -1938,10 +1970,10 @@ const char* XMLDocument::_errorNames[XML_ERROR_COUNT] = {
|
|||
"XML_ERROR_FILE_NOT_FOUND",
|
||||
"XML_ERROR_FILE_COULD_NOT_BE_OPENED",
|
||||
"XML_ERROR_FILE_READ_ERROR",
|
||||
"XML_ERROR_ELEMENT_MISMATCH",
|
||||
"UNUSED_XML_ERROR_ELEMENT_MISMATCH",
|
||||
"XML_ERROR_PARSING_ELEMENT",
|
||||
"XML_ERROR_PARSING_ATTRIBUTE",
|
||||
"XML_ERROR_IDENTIFYING_TAG",
|
||||
"UNUSED_XML_ERROR_IDENTIFYING_TAG",
|
||||
"XML_ERROR_PARSING_TEXT",
|
||||
"XML_ERROR_PARSING_CDATA",
|
||||
"XML_ERROR_PARSING_COMMENT",
|
||||
|
@ -1955,13 +1987,15 @@ const char* XMLDocument::_errorNames[XML_ERROR_COUNT] = {
|
|||
};
|
||||
|
||||
|
||||
XMLDocument::XMLDocument( bool processEntities, Whitespace whitespace ) :
|
||||
XMLDocument::XMLDocument( bool processEntities, Whitespace whitespaceMode ) :
|
||||
XMLNode( 0 ),
|
||||
_writeBOM( false ),
|
||||
_processEntities( processEntities ),
|
||||
_errorID(XML_SUCCESS),
|
||||
_whitespace( whitespace ),
|
||||
_charBuffer( 0 )
|
||||
_whitespaceMode( whitespaceMode ),
|
||||
_errorLineNum( 0 ),
|
||||
_charBuffer( 0 ),
|
||||
_parseCurLineNum( 0 )
|
||||
{
|
||||
// avoid VC++ C4355 warning about 'this' in initializer list (C4355 is off by default in VS2012+)
|
||||
_document = this;
|
||||
|
@ -1974,9 +2008,25 @@ XMLDocument::~XMLDocument()
|
|||
}
|
||||
|
||||
|
||||
void XMLDocument::MarkInUse(XMLNode* node)
|
||||
{
|
||||
TIXMLASSERT(node);
|
||||
TIXMLASSERT(node->_parent == 0);
|
||||
|
||||
for (int i = 0; i < _unlinked.Size(); ++i) {
|
||||
if (node == _unlinked[i]) {
|
||||
_unlinked.SwapRemove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void XMLDocument::Clear()
|
||||
{
|
||||
DeleteChildren();
|
||||
while( _unlinked.Size()) {
|
||||
DeleteNode(_unlinked[0]); // Will remove from _unlinked as part of delete.
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
const bool hadError = Error();
|
||||
|
@ -2004,11 +2054,22 @@ void XMLDocument::Clear()
|
|||
}
|
||||
|
||||
|
||||
void XMLDocument::DeepCopy(XMLDocument* target)
|
||||
{
|
||||
TIXMLASSERT(target);
|
||||
if (target == this) {
|
||||
return; // technically success - a no-op.
|
||||
}
|
||||
|
||||
target->Clear();
|
||||
for (const XMLNode* node = this->FirstChild(); node; node = node->NextSibling()) {
|
||||
target->InsertEndChild(node->DeepClone(target));
|
||||
}
|
||||
}
|
||||
|
||||
XMLElement* XMLDocument::NewElement( const char* name )
|
||||
{
|
||||
TIXMLASSERT( sizeof( XMLElement ) == _elementPool.ItemSize() );
|
||||
XMLElement* ele = new (_elementPool.Alloc()) XMLElement( this );
|
||||
ele->_memPool = &_elementPool;
|
||||
XMLElement* ele = CreateUnlinkedNode<XMLElement>( _elementPool );
|
||||
ele->SetName( name );
|
||||
return ele;
|
||||
}
|
||||
|
@ -2016,9 +2077,7 @@ XMLElement* XMLDocument::NewElement( const char* name )
|
|||
|
||||
XMLComment* XMLDocument::NewComment( const char* str )
|
||||
{
|
||||
TIXMLASSERT( sizeof( XMLComment ) == _commentPool.ItemSize() );
|
||||
XMLComment* comment = new (_commentPool.Alloc()) XMLComment( this );
|
||||
comment->_memPool = &_commentPool;
|
||||
XMLComment* comment = CreateUnlinkedNode<XMLComment>( _commentPool );
|
||||
comment->SetValue( str );
|
||||
return comment;
|
||||
}
|
||||
|
@ -2026,9 +2085,7 @@ XMLComment* XMLDocument::NewComment( const char* str )
|
|||
|
||||
XMLText* XMLDocument::NewText( const char* str )
|
||||
{
|
||||
TIXMLASSERT( sizeof( XMLText ) == _textPool.ItemSize() );
|
||||
XMLText* text = new (_textPool.Alloc()) XMLText( this );
|
||||
text->_memPool = &_textPool;
|
||||
XMLText* text = CreateUnlinkedNode<XMLText>( _textPool );
|
||||
text->SetValue( str );
|
||||
return text;
|
||||
}
|
||||
|
@ -2036,9 +2093,7 @@ XMLText* XMLDocument::NewText( const char* str )
|
|||
|
||||
XMLDeclaration* XMLDocument::NewDeclaration( const char* str )
|
||||
{
|
||||
TIXMLASSERT( sizeof( XMLDeclaration ) == _commentPool.ItemSize() );
|
||||
XMLDeclaration* dec = new (_commentPool.Alloc()) XMLDeclaration( this );
|
||||
dec->_memPool = &_commentPool;
|
||||
XMLDeclaration* dec = CreateUnlinkedNode<XMLDeclaration>( _commentPool );
|
||||
dec->SetValue( str ? str : "xml version=\"1.0\" encoding=\"UTF-8\"" );
|
||||
return dec;
|
||||
}
|
||||
|
@ -2046,9 +2101,7 @@ XMLDeclaration* XMLDocument::NewDeclaration( const char* str )
|
|||
|
||||
XMLUnknown* XMLDocument::NewUnknown( const char* str )
|
||||
{
|
||||
TIXMLASSERT( sizeof( XMLUnknown ) == _commentPool.ItemSize() );
|
||||
XMLUnknown* unk = new (_commentPool.Alloc()) XMLUnknown( this );
|
||||
unk->_memPool = &_commentPool;
|
||||
XMLUnknown* unk = CreateUnlinkedNode<XMLUnknown>( _commentPool );
|
||||
unk->SetValue( str );
|
||||
return unk;
|
||||
}
|
||||
|
@ -2259,6 +2312,16 @@ void XMLDocument::SetError( XMLError error, const char* str1, const char* str2,
|
|||
return errorName;
|
||||
}
|
||||
|
||||
const char* XMLDocument::GetErrorStr1() const
|
||||
{
|
||||
return _errorStr1.GetStr();
|
||||
}
|
||||
|
||||
const char* XMLDocument::GetErrorStr2() const
|
||||
{
|
||||
return _errorStr2.GetStr();
|
||||
}
|
||||
|
||||
const char* XMLDocument::ErrorName() const
|
||||
{
|
||||
return ErrorIDToName(_errorID);
|
||||
|
|
|
@ -53,7 +53,7 @@ distribution.
|
|||
AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h
|
||||
*/
|
||||
|
||||
#if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__)
|
||||
#if defined( _DEBUG ) || defined (__DEBUG__)
|
||||
# ifndef DEBUG
|
||||
# define DEBUG
|
||||
# endif
|
||||
|
@ -98,7 +98,7 @@ distribution.
|
|||
/* Versioning, past 1.0.14:
|
||||
http://semver.org/
|
||||
*/
|
||||
static const int TIXML2_MAJOR_VERSION = 4;
|
||||
static const int TIXML2_MAJOR_VERSION = 5;
|
||||
static const int TIXML2_MINOR_VERSION = 0;
|
||||
static const int TIXML2_PATCH_VERSION = 1;
|
||||
|
||||
|
@ -264,6 +264,13 @@ public:
|
|||
return _allocated;
|
||||
}
|
||||
|
||||
void SwapRemove(int i) {
|
||||
TIXMLASSERT(i >= 0 && i < _size);
|
||||
TIXMLASSERT(_size > 0);
|
||||
_mem[i] = _mem[_size - 1];
|
||||
--_size;
|
||||
}
|
||||
|
||||
const T* Mem() const {
|
||||
TIXMLASSERT( _mem );
|
||||
return _mem;
|
||||
|
@ -284,6 +291,7 @@ private:
|
|||
TIXMLASSERT( cap <= INT_MAX / 2 );
|
||||
int newAllocated = cap * 2;
|
||||
T* newMem = new T[newAllocated];
|
||||
TIXMLASSERT( newAllocated >= _size );
|
||||
memcpy( newMem, _mem, sizeof(T)*_size ); // warning: not using constructors, only works for PODs
|
||||
if ( _mem != _pool ) {
|
||||
delete [] _mem;
|
||||
|
@ -333,8 +341,8 @@ public:
|
|||
void Clear() {
|
||||
// Delete the blocks.
|
||||
while( !_blockPtrs.Empty()) {
|
||||
Block* b = _blockPtrs.Pop();
|
||||
delete b;
|
||||
Block* lastBlock = _blockPtrs.Pop();
|
||||
delete lastBlock;
|
||||
}
|
||||
_root = 0;
|
||||
_currentAllocs = 0;
|
||||
|
@ -505,10 +513,10 @@ enum XMLError {
|
|||
XML_ERROR_FILE_NOT_FOUND,
|
||||
XML_ERROR_FILE_COULD_NOT_BE_OPENED,
|
||||
XML_ERROR_FILE_READ_ERROR,
|
||||
XML_ERROR_ELEMENT_MISMATCH,
|
||||
UNUSED_XML_ERROR_ELEMENT_MISMATCH, // remove at next major version
|
||||
XML_ERROR_PARSING_ELEMENT,
|
||||
XML_ERROR_PARSING_ATTRIBUTE,
|
||||
XML_ERROR_IDENTIFYING_TAG,
|
||||
UNUSED_XML_ERROR_IDENTIFYING_TAG, // remove at next major version
|
||||
XML_ERROR_PARSING_TEXT,
|
||||
XML_ERROR_PARSING_CDATA,
|
||||
XML_ERROR_PARSING_COMMENT,
|
||||
|
@ -527,7 +535,7 @@ enum XMLError {
|
|||
/*
|
||||
Utility functionality.
|
||||
*/
|
||||
class XMLUtil
|
||||
class TINYXML2_LIB XMLUtil
|
||||
{
|
||||
public:
|
||||
static const char* SkipWhiteSpace( const char* p, int* curLineNumPtr ) {
|
||||
|
@ -605,6 +613,17 @@ public:
|
|||
static bool ToFloat( const char* str, float* value );
|
||||
static bool ToDouble( const char* str, double* value );
|
||||
static bool ToInt64(const char* str, int64_t* value);
|
||||
|
||||
// Changes what is serialized for a boolean value.
|
||||
// Default to "true" and "false". Shouldn't be changed
|
||||
// unless you have a special testing or compatibility need.
|
||||
// Be careful: static, global, & not thread safe.
|
||||
// Be sure to set static const memory as parameters.
|
||||
static void SetBoolSerialization(const char* writeTrue, const char* writeFalse);
|
||||
|
||||
private:
|
||||
static const char* writeBoolTrue;
|
||||
static const char* writeBoolFalse;
|
||||
};
|
||||
|
||||
|
||||
|
@ -846,6 +865,21 @@ public:
|
|||
*/
|
||||
virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
|
||||
|
||||
/**
|
||||
Make a copy of this node and all its children.
|
||||
|
||||
If the 'target' is null, then the nodes will
|
||||
be allocated in the current document. If 'target'
|
||||
is specified, the memory will be allocated is the
|
||||
specified XMLDocument.
|
||||
|
||||
NOTE: This is probably not the correct tool to
|
||||
copy a document, since XMLDocuments can have multiple
|
||||
top level XMLNodes. You probably want to use
|
||||
XMLDocument::DeepCopy()
|
||||
*/
|
||||
XMLNode* DeepClone( XMLDocument* target ) const;
|
||||
|
||||
/**
|
||||
Test if 2 nodes are the same, but don't test children.
|
||||
The 2 nodes do not need to be in the same Document.
|
||||
|
@ -896,7 +930,7 @@ protected:
|
|||
XMLNode( XMLDocument* );
|
||||
virtual ~XMLNode();
|
||||
|
||||
virtual char* ParseDeep( char*, StrPair*, int* );
|
||||
virtual char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
|
||||
|
||||
XMLDocument* _document;
|
||||
XMLNode* _parent;
|
||||
|
@ -964,7 +998,7 @@ protected:
|
|||
XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {}
|
||||
virtual ~XMLText() {}
|
||||
|
||||
char* ParseDeep( char*, StrPair* endTag, int* curLineNumPtr );
|
||||
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
|
||||
|
||||
private:
|
||||
bool _isCData;
|
||||
|
@ -995,7 +1029,7 @@ protected:
|
|||
XMLComment( XMLDocument* doc );
|
||||
virtual ~XMLComment();
|
||||
|
||||
char* ParseDeep( char*, StrPair* endTag, int* curLineNumPtr);
|
||||
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
|
||||
|
||||
private:
|
||||
XMLComment( const XMLComment& ); // not supported
|
||||
|
@ -1034,7 +1068,7 @@ protected:
|
|||
XMLDeclaration( XMLDocument* doc );
|
||||
virtual ~XMLDeclaration();
|
||||
|
||||
char* ParseDeep( char*, StrPair* endTag, int* curLineNumPtr );
|
||||
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
|
||||
|
||||
private:
|
||||
XMLDeclaration( const XMLDeclaration& ); // not supported
|
||||
|
@ -1069,7 +1103,7 @@ protected:
|
|||
XMLUnknown( XMLDocument* doc );
|
||||
virtual ~XMLUnknown();
|
||||
|
||||
char* ParseDeep( char*, StrPair* endTag, int* curLineNumPtr );
|
||||
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
|
||||
|
||||
private:
|
||||
XMLUnknown( const XMLUnknown& ); // not supported
|
||||
|
@ -1177,7 +1211,7 @@ public:
|
|||
private:
|
||||
enum { BUF_SIZE = 200 };
|
||||
|
||||
XMLAttribute() : _next( 0 ), _memPool( 0 ) {}
|
||||
XMLAttribute() : _parseLineNum( 0 ), _next( 0 ), _memPool( 0 ) {}
|
||||
virtual ~XMLAttribute() {}
|
||||
|
||||
XMLAttribute( const XMLAttribute& ); // not supported
|
||||
|
@ -1548,19 +1582,19 @@ public:
|
|||
float FloatText(float defaultValue = 0) const;
|
||||
|
||||
// internal:
|
||||
enum {
|
||||
enum ElementClosingType {
|
||||
OPEN, // <foo>
|
||||
CLOSED, // <foo/>
|
||||
CLOSING // </foo>
|
||||
};
|
||||
int ClosingType() const {
|
||||
ElementClosingType ClosingType() const {
|
||||
return _closingType;
|
||||
}
|
||||
virtual XMLNode* ShallowClone( XMLDocument* document ) const;
|
||||
virtual bool ShallowEqual( const XMLNode* compare ) const;
|
||||
|
||||
protected:
|
||||
char* ParseDeep( char* p, StrPair* endTag, int* curLineNumPtr );
|
||||
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
|
||||
|
||||
private:
|
||||
XMLElement( XMLDocument* doc );
|
||||
|
@ -1578,7 +1612,7 @@ private:
|
|||
XMLAttribute* CreateAttribute();
|
||||
|
||||
enum { BUF_SIZE = 200 };
|
||||
int _closingType;
|
||||
ElementClosingType _closingType;
|
||||
// The attribute list is ordered; there is no 'lastAttribute'
|
||||
// because the list needs to be scanned for dupes before adding
|
||||
// a new attribute.
|
||||
|
@ -1602,7 +1636,7 @@ class TINYXML2_LIB XMLDocument : public XMLNode
|
|||
friend class XMLElement;
|
||||
public:
|
||||
/// constructor
|
||||
XMLDocument( bool processEntities = true, Whitespace = PRESERVE_WHITESPACE );
|
||||
XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE );
|
||||
~XMLDocument();
|
||||
|
||||
virtual XMLDocument* ToDocument() {
|
||||
|
@ -1666,7 +1700,7 @@ public:
|
|||
return _processEntities;
|
||||
}
|
||||
Whitespace WhitespaceMode() const {
|
||||
return _whitespace;
|
||||
return _whitespaceMode;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1769,13 +1803,11 @@ public:
|
|||
static const char* ErrorIDToName(XMLError errorID);
|
||||
|
||||
/// Return a possibly helpful diagnostic location or string.
|
||||
const char* GetErrorStr1() const {
|
||||
return _errorStr1.GetStr();
|
||||
}
|
||||
const char* GetErrorStr1() const;
|
||||
|
||||
/// Return a possibly helpful secondary diagnostic location or string.
|
||||
const char* GetErrorStr2() const {
|
||||
return _errorStr2.GetStr();
|
||||
}
|
||||
const char* GetErrorStr2() const;
|
||||
|
||||
/// Return the line where the error occured, or zero if unknown.
|
||||
int GetErrorLineNum() const
|
||||
{
|
||||
|
@ -1787,9 +1819,21 @@ public:
|
|||
/// Clear the document, resetting it to the initial state.
|
||||
void Clear();
|
||||
|
||||
/**
|
||||
Copies this document to a target document.
|
||||
The target will be completely cleared before the copy.
|
||||
If you want to copy a sub-tree, see XMLNode::DeepClone().
|
||||
|
||||
NOTE: that the 'target' must be non-null.
|
||||
*/
|
||||
void DeepCopy(XMLDocument* target);
|
||||
|
||||
// internal
|
||||
char* Identify( char* p, XMLNode** node );
|
||||
|
||||
// internal
|
||||
void MarkInUse(XMLNode*);
|
||||
|
||||
virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const {
|
||||
return 0;
|
||||
}
|
||||
|
@ -1804,12 +1848,19 @@ private:
|
|||
bool _writeBOM;
|
||||
bool _processEntities;
|
||||
XMLError _errorID;
|
||||
Whitespace _whitespace;
|
||||
Whitespace _whitespaceMode;
|
||||
mutable StrPair _errorStr1;
|
||||
mutable StrPair _errorStr2;
|
||||
int _errorLineNum;
|
||||
char* _charBuffer;
|
||||
int _parseCurLineNum;
|
||||
// Memory tracking does add some overhead.
|
||||
// However, the code assumes that you don't
|
||||
// have a bunch of unlinked nodes around.
|
||||
// Therefore it takes less memory to track
|
||||
// in the document vs. a linked list in the XMLNode,
|
||||
// and the performance is the same.
|
||||
DynArray<XMLNode*, 10> _unlinked;
|
||||
|
||||
MemPoolT< sizeof(XMLElement) > _elementPool;
|
||||
MemPoolT< sizeof(XMLAttribute) > _attributePool;
|
||||
|
@ -1819,8 +1870,23 @@ private:
|
|||
static const char* _errorNames[XML_ERROR_COUNT];
|
||||
|
||||
void Parse();
|
||||
|
||||
template<class NodeType, int PoolElementSize>
|
||||
NodeType* CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool );
|
||||
};
|
||||
|
||||
template<class NodeType, int PoolElementSize>
|
||||
inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool )
|
||||
{
|
||||
TIXMLASSERT( sizeof( NodeType ) == PoolElementSize );
|
||||
TIXMLASSERT( sizeof( NodeType ) == pool.ItemSize() );
|
||||
NodeType* returnNode = new (pool.Alloc()) NodeType( this );
|
||||
TIXMLASSERT( returnNode );
|
||||
returnNode->_memPool = &pool;
|
||||
|
||||
_unlinked.Push(returnNode);
|
||||
return returnNode;
|
||||
}
|
||||
|
||||
/**
|
||||
A XMLHandle is a class that wraps a node pointer with null checks; this is
|
||||
|
@ -2152,6 +2218,7 @@ public:
|
|||
void ClearBuffer() {
|
||||
_buffer.Clear();
|
||||
_buffer.Push(0);
|
||||
_firstElement = true;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
Loading…
Reference in New Issue