Fix config files (XML) saving performance regression
Instead of writting on hard disk little by little all the time, all data is collected in a string buffer to write once on the disk at the end. Fix #10678, fix #10674, close #10691
This commit is contained in:
parent
5d086f93a8
commit
386366d7f2
|
@ -23,6 +23,7 @@ distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <memory>
|
||||||
#include "tinyxml.h"
|
#include "tinyxml.h"
|
||||||
|
|
||||||
bool TiXmlBase::condenseWhiteSpace = true;
|
bool TiXmlBase::condenseWhiteSpace = true;
|
||||||
|
@ -551,27 +552,27 @@ void TiXmlElement::SetAttribute( const TCHAR * name, const TCHAR * _value )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TiXmlElement::Print( Win32_IO_File& cfile, int depth ) const
|
void TiXmlElement::Print( std::string& outputStream, int depth ) const
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for ( i=0; i<depth; i++ )
|
for ( i=0; i<depth; i++ )
|
||||||
{
|
{
|
||||||
cfile.writeStr(" ");
|
outputStream += " ";
|
||||||
//generic_fprintf( cfile, TEXT(" ") );
|
//generic_fprintf( cfile, TEXT(" ") );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tagOpenValue = "<";
|
std::string tagOpenValue = "<";
|
||||||
tagOpenValue += wstring2string(value, CP_UTF8);
|
tagOpenValue += wstring2string(value, CP_UTF8);
|
||||||
cfile.writeStr(tagOpenValue);
|
outputStream += tagOpenValue;
|
||||||
//generic_fprintf( cfile, TEXT("<%ls"), value.c_str() );
|
//generic_fprintf( cfile, TEXT("<%ls"), value.c_str() );
|
||||||
|
|
||||||
TiXmlAttribute* attrib;
|
TiXmlAttribute* attrib;
|
||||||
for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
|
for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
|
||||||
{
|
{
|
||||||
cfile.writeStr(" ");
|
outputStream += " ";
|
||||||
//generic_fprintf(cfile, TEXT(" "));
|
//generic_fprintf(cfile, TEXT(" "));
|
||||||
|
|
||||||
attrib->Print( cfile, depth );
|
attrib->Print(outputStream, depth );
|
||||||
}
|
}
|
||||||
|
|
||||||
// There are 3 different formatting approaches:
|
// There are 3 different formatting approaches:
|
||||||
|
@ -581,45 +582,45 @@ void TiXmlElement::Print( Win32_IO_File& cfile, int depth ) const
|
||||||
TiXmlNode* node;
|
TiXmlNode* node;
|
||||||
if ( !firstChild )
|
if ( !firstChild )
|
||||||
{
|
{
|
||||||
cfile.writeStr(" />");
|
outputStream += " />";
|
||||||
//generic_fprintf( cfile, TEXT(" />") );
|
//generic_fprintf( cfile, TEXT(" />") );
|
||||||
}
|
}
|
||||||
else if ( firstChild == lastChild && firstChild->ToText() )
|
else if ( firstChild == lastChild && firstChild->ToText() )
|
||||||
{
|
{
|
||||||
cfile.writeStr(">");
|
outputStream += ">";
|
||||||
//generic_fprintf( cfile, TEXT(">") );
|
//generic_fprintf( cfile, TEXT(">") );
|
||||||
|
|
||||||
firstChild->Print( cfile, depth + 1 );
|
firstChild->Print(outputStream, depth + 1 );
|
||||||
|
|
||||||
std::string tagCloseWithValue = "</";
|
std::string tagCloseWithValue = "</";
|
||||||
tagCloseWithValue += wstring2string(value, CP_UTF8) + ">";
|
tagCloseWithValue += wstring2string(value, CP_UTF8) + ">";
|
||||||
cfile.writeStr(tagCloseWithValue);
|
outputStream += tagCloseWithValue;
|
||||||
//generic_fprintf( cfile, TEXT("</%ls>"), value.c_str() );
|
//generic_fprintf( cfile, TEXT("</%ls>"), value.c_str() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cfile.writeStr(">");
|
outputStream += ">";
|
||||||
//generic_fprintf( cfile, TEXT(">") );
|
//generic_fprintf( cfile, TEXT(">") );
|
||||||
|
|
||||||
for ( node = firstChild; node; node=node->NextSibling() )
|
for ( node = firstChild; node; node=node->NextSibling() )
|
||||||
{
|
{
|
||||||
if ( !node->ToText() )
|
if ( !node->ToText() )
|
||||||
{
|
{
|
||||||
cfile.writeStr("\r\n");
|
outputStream += "\r\n";
|
||||||
//generic_fprintf( cfile, TEXT("\n") );
|
//generic_fprintf( cfile, TEXT("\n") );
|
||||||
}
|
}
|
||||||
node->Print( cfile, depth+1 );
|
node->Print(outputStream, depth+1 );
|
||||||
}
|
}
|
||||||
cfile.writeStr("\r\n");
|
outputStream += "\r\n";
|
||||||
//generic_fprintf( cfile, TEXT("\n") );
|
//generic_fprintf( cfile, TEXT("\n") );
|
||||||
|
|
||||||
for( i=0; i<depth; ++i )
|
for( i=0; i<depth; ++i )
|
||||||
cfile.writeStr(" ");
|
outputStream += " ";
|
||||||
// generic_fprintf( cfile, TEXT(" ") );
|
// generic_fprintf( cfile, TEXT(" ") );
|
||||||
|
|
||||||
std::string tagCloseWithValue = "</";
|
std::string tagCloseWithValue = "</";
|
||||||
tagCloseWithValue += wstring2string(value, CP_UTF8) + ">";
|
tagCloseWithValue += wstring2string(value, CP_UTF8) + ">";
|
||||||
cfile.writeStr(tagCloseWithValue);
|
outputStream += tagCloseWithValue;
|
||||||
//generic_fprintf( cfile, TEXT("</%ls>"), value.c_str() );
|
//generic_fprintf( cfile, TEXT("</%ls>"), value.c_str() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -793,7 +794,10 @@ bool TiXmlDocument::SaveFile( const TCHAR * filename ) const
|
||||||
|
|
||||||
if (file.isOpened())
|
if (file.isOpened())
|
||||||
{
|
{
|
||||||
Print(file, 0);
|
std::unique_ptr<std::string> outputStr = std::make_unique<std::string>();
|
||||||
|
Print(*outputStr, 0);
|
||||||
|
if (!outputStr->empty())
|
||||||
|
file.writeStr(*outputStr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -820,14 +824,14 @@ TiXmlNode* TiXmlDocument::Clone() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TiXmlDocument::Print( Win32_IO_File& cfile, int depth ) const
|
void TiXmlDocument::Print( std::string& outputStream, int depth ) const
|
||||||
{
|
{
|
||||||
TiXmlNode* node;
|
TiXmlNode* node;
|
||||||
for ( node=FirstChild(); node; node=node->NextSibling() )
|
for ( node=FirstChild(); node; node=node->NextSibling() )
|
||||||
{
|
{
|
||||||
node->Print( cfile, depth );
|
node->Print(outputStream, depth );
|
||||||
|
|
||||||
cfile.writeStr("\r\n");
|
outputStream += "\r\n";
|
||||||
//generic_fprintf( cfile, TEXT("\n") );
|
//generic_fprintf( cfile, TEXT("\n") );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -868,7 +872,7 @@ TiXmlAttribute* TiXmlAttribute::Previous() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TiXmlAttribute::Print( Win32_IO_File& cfile, int /*depth*/ ) const
|
void TiXmlAttribute::Print( std::string& outputStream, int /*depth*/ ) const
|
||||||
{
|
{
|
||||||
TIXML_STRING n, v;
|
TIXML_STRING n, v;
|
||||||
|
|
||||||
|
@ -890,7 +894,7 @@ void TiXmlAttribute::Print( Win32_IO_File& cfile, int /*depth*/ ) const
|
||||||
attrVsValue += "'";
|
attrVsValue += "'";
|
||||||
//generic_fprintf(cfile, TEXT("%ls='%ls'"), n.c_str(), v.c_str());
|
//generic_fprintf(cfile, TEXT("%ls='%ls'"), n.c_str(), v.c_str());
|
||||||
}
|
}
|
||||||
cfile.writeStr(attrVsValue);
|
outputStream += attrVsValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -950,18 +954,18 @@ const double TiXmlAttribute::DoubleValue() const
|
||||||
return generic_atof (value.c_str ());
|
return generic_atof (value.c_str ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TiXmlComment::Print( Win32_IO_File& cfile, int depth ) const
|
void TiXmlComment::Print( std::string& outputStream, int depth ) const
|
||||||
{
|
{
|
||||||
for ( int i=0; i<depth; i++ )
|
for ( int i=0; i<depth; i++ )
|
||||||
{
|
{
|
||||||
cfile.writeStr(" ");
|
outputStream += " ";
|
||||||
//generic_fprintf( cfile, TEXT(" ") );
|
//generic_fprintf( cfile, TEXT(" ") );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string comment = "<!--";
|
std::string comment = "<!--";
|
||||||
comment += wstring2string(value, CP_UTF8);
|
comment += wstring2string(value, CP_UTF8);
|
||||||
comment += "-->";
|
comment += "-->";
|
||||||
cfile.writeStr(comment);
|
outputStream += comment;
|
||||||
//generic_fprintf( cfile, TEXT("<!--%ls-->"), value.c_str() );
|
//generic_fprintf( cfile, TEXT("<!--%ls-->"), value.c_str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -984,12 +988,12 @@ TiXmlNode* TiXmlComment::Clone() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TiXmlText::Print( Win32_IO_File& cfile, int /*depth*/ ) const
|
void TiXmlText::Print( std::string& outputStream, int /*depth*/ ) const
|
||||||
{
|
{
|
||||||
TIXML_STRING buffer;
|
TIXML_STRING buffer;
|
||||||
PutString( value, &buffer );
|
PutString( value, &buffer );
|
||||||
|
|
||||||
cfile.writeStr(wstring2string(buffer, CP_UTF8));
|
outputStream += wstring2string(buffer, CP_UTF8);
|
||||||
//generic_fprintf( cfile, TEXT("%ls"), buffer.c_str() );
|
//generic_fprintf( cfile, TEXT("%ls"), buffer.c_str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1023,7 +1027,7 @@ TiXmlDeclaration::TiXmlDeclaration( const TCHAR * _version,
|
||||||
standalone = _standalone;
|
standalone = _standalone;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TiXmlDeclaration::Print( Win32_IO_File& cfile, int /*depth*/ ) const
|
void TiXmlDeclaration::Print( std::string& outputStream, int /*depth*/ ) const
|
||||||
{
|
{
|
||||||
std::string xmlDcl = "<?xml ";
|
std::string xmlDcl = "<?xml ";
|
||||||
//generic_fprintf (cfile, TEXT("<?xml "));
|
//generic_fprintf (cfile, TEXT("<?xml "));
|
||||||
|
@ -1054,7 +1058,7 @@ void TiXmlDeclaration::Print( Win32_IO_File& cfile, int /*depth*/ ) const
|
||||||
xmlDcl += "?>";
|
xmlDcl += "?>";
|
||||||
//generic_fprintf (cfile, TEXT("?>"));
|
//generic_fprintf (cfile, TEXT("?>"));
|
||||||
|
|
||||||
cfile.writeStr(xmlDcl);
|
outputStream += xmlDcl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TiXmlDeclaration::StreamOut( TIXML_OSTREAM * stream ) const
|
void TiXmlDeclaration::StreamOut( TIXML_OSTREAM * stream ) const
|
||||||
|
@ -1097,13 +1101,13 @@ TiXmlNode* TiXmlDeclaration::Clone() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TiXmlUnknown::Print( Win32_IO_File& cfile, int depth ) const
|
void TiXmlUnknown::Print( std::string& outputStream, int depth ) const
|
||||||
{
|
{
|
||||||
for ( int i=0; i<depth; i++ )
|
for ( int i=0; i<depth; i++ )
|
||||||
cfile.writeStr(" ");
|
outputStream += " ";
|
||||||
//generic_fprintf( cfile, TEXT(" ") );
|
//generic_fprintf( cfile, TEXT(" ") );
|
||||||
|
|
||||||
cfile.writeStr(wstring2string(value, CP_UTF8));
|
outputStream += wstring2string(value, CP_UTF8);
|
||||||
//generic_fprintf( cfile, TEXT("%ls"), value.c_str() );
|
//generic_fprintf( cfile, TEXT("%ls"), value.c_str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,7 +132,7 @@ public:
|
||||||
|
|
||||||
(For an unformatted stream, use the << operator.)
|
(For an unformatted stream, use the << operator.)
|
||||||
*/
|
*/
|
||||||
virtual void Print( Win32_IO_File& cfile, int depth ) const = 0;
|
virtual void Print( std::string& outputStream, int depth ) const = 0;
|
||||||
|
|
||||||
/** The world does not agree on whether white space should be kept or
|
/** The world does not agree on whether white space should be kept or
|
||||||
not. In order to make everyone happy, these global, static functions
|
not. In order to make everyone happy, these global, static functions
|
||||||
|
@ -640,7 +640,7 @@ public:
|
||||||
virtual const TCHAR* Parse( const TCHAR* p, TiXmlParsingData* data );
|
virtual const TCHAR* Parse( const TCHAR* p, TiXmlParsingData* data );
|
||||||
|
|
||||||
// [internal use]
|
// [internal use]
|
||||||
virtual void Print( Win32_IO_File& cfile, int depth ) const;
|
virtual void Print( std::string& outputStream, int depth ) const;
|
||||||
|
|
||||||
virtual void StreamOut( TIXML_OSTREAM * out ) const;
|
virtual void StreamOut( TIXML_OSTREAM * out ) const;
|
||||||
// [internal use]
|
// [internal use]
|
||||||
|
@ -784,7 +784,7 @@ public:
|
||||||
virtual TiXmlNode* Clone() const;
|
virtual TiXmlNode* Clone() const;
|
||||||
// [internal use]
|
// [internal use]
|
||||||
|
|
||||||
virtual void Print( Win32_IO_File& cfile, int depth ) const;
|
virtual void Print( std::string& outputStream, int depth ) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -823,7 +823,7 @@ public:
|
||||||
// [internal use] Creates a new Element and returs it.
|
// [internal use] Creates a new Element and returs it.
|
||||||
virtual TiXmlNode* Clone() const;
|
virtual TiXmlNode* Clone() const;
|
||||||
// [internal use]
|
// [internal use]
|
||||||
virtual void Print( Win32_IO_File& cfile, int depth ) const;
|
virtual void Print( std::string& outputStream, int depth ) const;
|
||||||
protected:
|
protected:
|
||||||
// used to be public
|
// used to be public
|
||||||
#ifdef TIXML_USE_STL
|
#ifdef TIXML_USE_STL
|
||||||
|
@ -860,7 +860,7 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// [internal use]
|
// [internal use]
|
||||||
virtual void Print( Win32_IO_File& cfile, int depth ) const;
|
virtual void Print( std::string& outputStream, int depth ) const;
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
// [internal use] Creates a new Element and returns it.
|
// [internal use] Creates a new Element and returns it.
|
||||||
|
@ -929,7 +929,7 @@ public:
|
||||||
// [internal use] Creates a new Element and returs it.
|
// [internal use] Creates a new Element and returs it.
|
||||||
virtual TiXmlNode* Clone() const;
|
virtual TiXmlNode* Clone() const;
|
||||||
// [internal use]
|
// [internal use]
|
||||||
virtual void Print( Win32_IO_File& cfile, int depth ) const;
|
virtual void Print( std::string& outputStream, int depth ) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// used to be public
|
// used to be public
|
||||||
|
@ -964,7 +964,7 @@ public:
|
||||||
// [internal use]
|
// [internal use]
|
||||||
virtual TiXmlNode* Clone() const;
|
virtual TiXmlNode* Clone() const;
|
||||||
// [internal use]
|
// [internal use]
|
||||||
virtual void Print( Win32_IO_File& cfile, int depth ) const;
|
virtual void Print( std::string& outputStream, int depth ) const;
|
||||||
protected:
|
protected:
|
||||||
#ifdef TIXML_USE_STL
|
#ifdef TIXML_USE_STL
|
||||||
virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
|
virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
|
||||||
|
@ -1101,7 +1101,7 @@ public:
|
||||||
void Print() const { /*Print(stdout, 0);*/ }
|
void Print() const { /*Print(stdout, 0);*/ }
|
||||||
|
|
||||||
// [internal use]
|
// [internal use]
|
||||||
virtual void Print( Win32_IO_File& cfile, int depth = 0 ) const;
|
virtual void Print( std::string& outputStream, int depth = 0 ) const;
|
||||||
// [internal use]
|
// [internal use]
|
||||||
void SetError( int err, const TCHAR* errorLocation, TiXmlParsingData* prevData );
|
void SetError( int err, const TCHAR* errorLocation, TiXmlParsingData* prevData );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue