Fix previous session lost issue after MS update restarting Windows

Use Windows IO API instaed POSIX IO (output only) on tinyXml component for writting xml file (config.xml, session.xml, etc...).

Fix #10402, close #10612
This commit is contained in:
Don Ho 2021-10-01 01:13:34 +02:00
parent f1837474ca
commit 11b2dd0f6b
2 changed files with 144 additions and 44 deletions

View File

@ -551,20 +551,37 @@ void TiXmlElement::SetAttribute( const TCHAR * name, const TCHAR * _value )
} }
} }
void TiXmlElement::Print( FILE* cfile, int depth ) const const char one_ws[] = " ";
const char four_ws[] = " ";
const char eol[] = "\r\n";
const generic_string tagOpenSymb = TEXT("<");
const generic_string tagOpenSlash = TEXT("</");
const generic_string tagCloseSymb = TEXT(">");
const char tagCloseChar[] = ">";
const char tagCloseSymbFinal[] = " />";
void TiXmlElement::Print( CFile& cfile, int depth ) const
{ {
int i; int i;
for ( i=0; i<depth; i++ ) for ( i=0; i<depth; i++ )
{ {
generic_fprintf( cfile, TEXT(" ") ); cfile.Write(four_ws, 4);
//generic_fprintf( cfile, TEXT(" ") );
} }
generic_fprintf( cfile, TEXT("<%ls"), value.c_str() ); generic_string tagOpenValue = tagOpenSymb + value;
std::string tagOpenValueA = wstring2string(tagOpenValue, CP_UTF8);
cfile.Write(tagOpenValueA.c_str(), static_cast<unsigned long>(tagOpenValueA.length()));
//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() )
{ {
generic_fprintf( cfile, TEXT(" ") ); cfile.Write(one_ws, 1);
//generic_fprintf(cfile, TEXT(" "));
attrib->Print( cfile, depth ); attrib->Print( cfile, depth );
} }
@ -575,30 +592,46 @@ void TiXmlElement::Print( FILE* cfile, int depth ) const
TiXmlNode* node; TiXmlNode* node;
if ( !firstChild ) if ( !firstChild )
{ {
generic_fprintf( cfile, TEXT(" />") ); cfile.Write(tagCloseSymbFinal, 3);
//generic_fprintf( cfile, TEXT(" />") );
} }
else if ( firstChild == lastChild && firstChild->ToText() ) else if ( firstChild == lastChild && firstChild->ToText() )
{ {
generic_fprintf( cfile, TEXT(">") ); cfile.Write(tagCloseChar, 1);
//generic_fprintf( cfile, TEXT(">") );
firstChild->Print( cfile, depth + 1 ); firstChild->Print( cfile, depth + 1 );
generic_fprintf( cfile, TEXT("</%ls>"), value.c_str() );
generic_string tagCloseWithValue = tagOpenSlash + value + tagCloseSymb;
std::string tagCloseWithValueA = wstring2string(tagCloseWithValue, CP_UTF8);
cfile.Write(tagCloseWithValueA.c_str(), static_cast<unsigned long>(tagCloseWithValueA.length()));
//generic_fprintf( cfile, TEXT("</%ls>"), value.c_str() );
} }
else else
{ {
generic_fprintf( cfile, TEXT(">") ); cfile.Write(tagCloseChar, 1);
//generic_fprintf( cfile, TEXT(">") );
for ( node = firstChild; node; node=node->NextSibling() ) for ( node = firstChild; node; node=node->NextSibling() )
{ {
if ( !node->ToText() ) if ( !node->ToText() )
{ {
generic_fprintf( cfile, TEXT("\n") ); cfile.Write(eol, 2);
//generic_fprintf( cfile, TEXT("\n") );
} }
node->Print( cfile, depth+1 ); node->Print( cfile, depth+1 );
} }
generic_fprintf( cfile, TEXT("\n") ); cfile.Write(eol, 2);
//generic_fprintf( cfile, TEXT("\n") );
for( i=0; i<depth; ++i ) for( i=0; i<depth; ++i )
generic_fprintf( cfile, TEXT(" ") ); cfile.Write(four_ws, 4);
generic_fprintf( cfile, TEXT("</%ls>"), value.c_str() ); // generic_fprintf( cfile, TEXT(" ") );
generic_string tagCloseWithValue = tagOpenSlash + value + tagCloseSymb;
std::string tagCloseWithValueA = wstring2string(tagCloseWithValue, CP_UTF8);
cfile.Write(tagCloseWithValueA.c_str(), static_cast<unsigned long>(tagCloseWithValueA.length()));
//generic_fprintf( cfile, TEXT("</%ls>"), value.c_str() );
} }
} }
@ -754,6 +787,7 @@ bool TiXmlDocument::LoadFile( const TCHAR* filename )
bool TiXmlDocument::SaveFile( const TCHAR * filename ) const bool TiXmlDocument::SaveFile( const TCHAR * filename ) const
{ {
/*
// The old c stuff lives on... // The old c stuff lives on...
FILE* fp = generic_fopen( filename, TEXT("wc") ); FILE* fp = generic_fopen( filename, TEXT("wc") );
if ( fp ) if ( fp )
@ -764,6 +798,17 @@ bool TiXmlDocument::SaveFile( const TCHAR * filename ) const
return true; return true;
} }
return false; return false;
*/
CFile file(filename, CFile::Mode::WRITE);
if (file.IsOpened())
{
Print(file, 0);
return true;
}
return false;
} }
@ -786,13 +831,15 @@ TiXmlNode* TiXmlDocument::Clone() const
} }
void TiXmlDocument::Print( FILE* cfile, int depth ) const void TiXmlDocument::Print( CFile& cfile, 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( cfile, depth );
generic_fprintf( cfile, TEXT("\n") );
cfile.Write(eol, 2);
//generic_fprintf( cfile, TEXT("\n") );
} }
} }
@ -832,17 +879,30 @@ TiXmlAttribute* TiXmlAttribute::Previous() const
} }
void TiXmlAttribute::Print( FILE* cfile, int /*depth*/ ) const void TiXmlAttribute::Print( CFile& cfile, int /*depth*/ ) const
{ {
TIXML_STRING n, v; TIXML_STRING n, v;
PutString( Name(), &n ); PutString( Name(), &n );
PutString( Value(), &v ); PutString( Value(), &v );
if (value.find ('\"') == TIXML_STRING::npos) generic_string attrVsValue = n;
generic_fprintf (cfile, TEXT("%ls=\"%ls\""), n.c_str(), v.c_str() ); if (value.find('\"') == TIXML_STRING::npos)
{
attrVsValue += TEXT("=\"");
attrVsValue += v;
attrVsValue += TEXT("\"");
//generic_fprintf(cfile, TEXT("%ls=\"%ls\""), n.c_str(), v.c_str());
}
else else
generic_fprintf (cfile, TEXT("%ls='%ls'"), n.c_str(), v.c_str() ); {
attrVsValue += TEXT("='");
attrVsValue += v;
attrVsValue += TEXT("'");
//generic_fprintf(cfile, TEXT("%ls='%ls'"), n.c_str(), v.c_str());
}
std::string attrVsValueA = wstring2string(attrVsValue, CP_UTF8);
cfile.Write(attrVsValueA.c_str(), static_cast<unsigned long>(attrVsValueA.length()));
} }
@ -902,13 +962,20 @@ const double TiXmlAttribute::DoubleValue() const
return generic_atof (value.c_str ()); return generic_atof (value.c_str ());
} }
void TiXmlComment::Print( FILE* cfile, int depth ) const void TiXmlComment::Print( CFile& cfile, int depth ) const
{ {
for ( int i=0; i<depth; i++ ) for ( int i=0; i<depth; i++ )
{ {
generic_fprintf( cfile, TEXT(" ") ); cfile.Write(four_ws, 4);
//generic_fprintf( cfile, TEXT(" ") );
} }
generic_fprintf( cfile, TEXT("<!--%ls-->"), value.c_str() );
generic_string comment = TEXT("<!--");
comment += value;
comment += TEXT("-->");
std::string commentA = wstring2string(comment, CP_UTF8);
cfile.Write(commentA.c_str(), static_cast<unsigned long>(commentA.length()));
//generic_fprintf( cfile, TEXT("<!--%ls-->"), value.c_str() );
} }
void TiXmlComment::StreamOut( TIXML_OSTREAM * stream ) const void TiXmlComment::StreamOut( TIXML_OSTREAM * stream ) const
@ -930,11 +997,14 @@ TiXmlNode* TiXmlComment::Clone() const
} }
void TiXmlText::Print( FILE* cfile, int /*depth*/ ) const void TiXmlText::Print( CFile& cfile, int /*depth*/ ) const
{ {
TIXML_STRING buffer; TIXML_STRING buffer;
PutString( value, &buffer ); PutString( value, &buffer );
generic_fprintf( cfile, TEXT("%ls"), buffer.c_str() );
std::string bufferA = wstring2string(buffer, CP_UTF8);
cfile.Write(bufferA.c_str(), static_cast<unsigned long>(bufferA.length()));
//generic_fprintf( cfile, TEXT("%ls"), buffer.c_str() );
} }
@ -967,18 +1037,43 @@ TiXmlDeclaration::TiXmlDeclaration( const TCHAR * _version,
standalone = _standalone; standalone = _standalone;
} }
const generic_string xmlDclOpen = TEXT("<?xml ");
const generic_string xmlDclClose = TEXT("?>");
void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/ ) const
void TiXmlDeclaration::Print( CFile& cfile, int /*depth*/ ) const
{ {
generic_fprintf (cfile, TEXT("<?xml ")); generic_string xmlDcl = xmlDclOpen;
//generic_fprintf (cfile, TEXT("<?xml "));
if ( !version.empty() ) if (!version.empty())
generic_fprintf (cfile, TEXT("version=\"%ls\" "), version.c_str ()); {
if ( !encoding.empty() ) xmlDcl += TEXT("version=\"");
generic_fprintf (cfile, TEXT("encoding=\"%ls\" "), encoding.c_str ()); xmlDcl += version;
if ( !standalone.empty() ) xmlDcl += TEXT("\" ");
generic_fprintf (cfile, TEXT("standalone=\"%ls\" "), standalone.c_str ()); //generic_fprintf(cfile, TEXT("version=\"%ls\" "), version.c_str());
generic_fprintf (cfile, TEXT("?>")); }
if (!encoding.empty())
{
xmlDcl += TEXT("encoding=\"");
xmlDcl += encoding;
xmlDcl += TEXT("\" ");
//generic_fprintf(cfile, TEXT("encoding=\"%ls\" "), encoding.c_str());
}
if (!standalone.empty())
{
xmlDcl += TEXT("standalone=\"");
xmlDcl += standalone;
xmlDcl += TEXT("\" ");
//generic_fprintf(cfile, TEXT("standalone=\"%ls\" "), standalone.c_str());
}
xmlDcl += xmlDclClose;
//generic_fprintf (cfile, TEXT("?>"));
std::string xmlDclA = wstring2string(xmlDcl, CP_UTF8);
cfile.Write(xmlDclA.c_str(), static_cast<unsigned long>(xmlDclA.length()));
} }
void TiXmlDeclaration::StreamOut( TIXML_OSTREAM * stream ) const void TiXmlDeclaration::StreamOut( TIXML_OSTREAM * stream ) const
@ -1021,11 +1116,15 @@ TiXmlNode* TiXmlDeclaration::Clone() const
} }
void TiXmlUnknown::Print( FILE* cfile, int depth ) const void TiXmlUnknown::Print( CFile& cfile, int depth ) const
{ {
for ( int i=0; i<depth; i++ ) for ( int i=0; i<depth; i++ )
generic_fprintf( cfile, TEXT(" ") ); cfile.Write(four_ws, 4);
generic_fprintf( cfile, TEXT("%ls"), value.c_str() ); //generic_fprintf( cfile, TEXT(" ") );
std::string valueA = wstring2string(value, CP_UTF8);
cfile.Write(valueA.c_str(), static_cast<unsigned long>(valueA.length()));
//generic_fprintf( cfile, TEXT("%ls"), value.c_str() );
} }
void TiXmlUnknown::StreamOut( TIXML_OSTREAM * stream ) const void TiXmlUnknown::StreamOut( TIXML_OSTREAM * stream ) const

View File

@ -62,6 +62,7 @@ distribution.
#include <string> #include <string>
#include "Common.h" #include "Common.h"
#include "FileInterface.h"
class TiXmlDocument; class TiXmlDocument;
class TiXmlElement; class TiXmlElement;
@ -131,7 +132,7 @@ public:
(For an unformatted stream, use the << operator.) (For an unformatted stream, use the << operator.)
*/ */
virtual void Print( FILE* cfile, int depth ) const = 0; virtual void Print( CFile& cfile, 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
@ -639,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( FILE* cfile, int depth ) const; virtual void Print( CFile& cfile, int depth ) const;
virtual void StreamOut( TIXML_OSTREAM * out ) const; virtual void StreamOut( TIXML_OSTREAM * out ) const;
// [internal use] // [internal use]
@ -783,7 +784,7 @@ public:
virtual TiXmlNode* Clone() const; virtual TiXmlNode* Clone() const;
// [internal use] // [internal use]
virtual void Print( FILE* cfile, int depth ) const; virtual void Print( CFile& cfile, int depth ) const;
protected: protected:
@ -822,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( FILE* cfile, int depth ) const; virtual void Print( CFile& cfile, int depth ) const;
protected: protected:
// used to be public // used to be public
#ifdef TIXML_USE_STL #ifdef TIXML_USE_STL
@ -859,7 +860,7 @@ public:
#endif #endif
// [internal use] // [internal use]
virtual void Print( FILE* cfile, int depth ) const; virtual void Print( CFile& cfile, int depth ) const;
protected : protected :
// [internal use] Creates a new Element and returns it. // [internal use] Creates a new Element and returns it.
@ -928,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( FILE* cfile, int depth ) const; virtual void Print( CFile& cfile, int depth ) const;
protected: protected:
// used to be public // used to be public
@ -963,7 +964,7 @@ public:
// [internal use] // [internal use]
virtual TiXmlNode* Clone() const; virtual TiXmlNode* Clone() const;
// [internal use] // [internal use]
virtual void Print( FILE* cfile, int depth ) const; virtual void Print( CFile& cfile, 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 );
@ -1097,10 +1098,10 @@ public:
} }
/** Dump the document to standard out. */ /** Dump the document to standard out. */
void Print() const { Print( stdout, 0 ); } void Print() const { /*Print(stdout, 0);*/ }
// [internal use] // [internal use]
virtual void Print( FILE* cfile, int depth = 0 ) const; virtual void Print( CFile& cfile, 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 );