From 11b2dd0f6b81c5089df9b386f878961448fa8985 Mon Sep 17 00:00:00 2001 From: Don Ho Date: Fri, 1 Oct 2021 01:13:34 +0200 Subject: [PATCH] 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 --- PowerEditor/src/TinyXml/tinyxml.cpp | 169 ++++++++++++++++++++++------ PowerEditor/src/TinyXml/tinyxml.h | 19 ++-- 2 files changed, 144 insertions(+), 44 deletions(-) diff --git a/PowerEditor/src/TinyXml/tinyxml.cpp b/PowerEditor/src/TinyXml/tinyxml.cpp index 6f34b7b57..386aeb4b2 100644 --- a/PowerEditor/src/TinyXml/tinyxml.cpp +++ b/PowerEditor/src/TinyXml/tinyxml.cpp @@ -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 char tagCloseChar[] = ">"; +const char tagCloseSymbFinal[] = " />"; + +void TiXmlElement::Print( CFile& cfile, int depth ) const { int i; for ( i=0; i(tagOpenValueA.length())); + //generic_fprintf( cfile, TEXT("<%ls"), value.c_str() ); TiXmlAttribute* attrib; 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 ); } @@ -575,30 +592,46 @@ void TiXmlElement::Print( FILE* cfile, int depth ) const TiXmlNode* node; if ( !firstChild ) { - generic_fprintf( cfile, TEXT(" />") ); + cfile.Write(tagCloseSymbFinal, 3); + //generic_fprintf( cfile, TEXT(" />") ); } else if ( firstChild == lastChild && firstChild->ToText() ) { - generic_fprintf( cfile, TEXT(">") ); + cfile.Write(tagCloseChar, 1); + //generic_fprintf( cfile, TEXT(">") ); + firstChild->Print( cfile, depth + 1 ); - generic_fprintf( cfile, TEXT(""), value.c_str() ); + + generic_string tagCloseWithValue = tagOpenSlash + value + tagCloseSymb; + std::string tagCloseWithValueA = wstring2string(tagCloseWithValue, CP_UTF8); + cfile.Write(tagCloseWithValueA.c_str(), static_cast(tagCloseWithValueA.length())); + //generic_fprintf( cfile, TEXT(""), value.c_str() ); } else { - generic_fprintf( cfile, TEXT(">") ); + cfile.Write(tagCloseChar, 1); + //generic_fprintf( cfile, TEXT(">") ); for ( node = firstChild; node; node=node->NextSibling() ) { if ( !node->ToText() ) { - generic_fprintf( cfile, TEXT("\n") ); + cfile.Write(eol, 2); + //generic_fprintf( cfile, TEXT("\n") ); } node->Print( cfile, depth+1 ); } - generic_fprintf( cfile, TEXT("\n") ); + cfile.Write(eol, 2); + //generic_fprintf( cfile, TEXT("\n") ); + for( i=0; i"), value.c_str() ); + cfile.Write(four_ws, 4); + // generic_fprintf( cfile, TEXT(" ") ); + + generic_string tagCloseWithValue = tagOpenSlash + value + tagCloseSymb; + std::string tagCloseWithValueA = wstring2string(tagCloseWithValue, CP_UTF8); + cfile.Write(tagCloseWithValueA.c_str(), static_cast(tagCloseWithValueA.length())); + //generic_fprintf( cfile, TEXT(""), value.c_str() ); } } @@ -754,6 +787,7 @@ bool TiXmlDocument::LoadFile( const TCHAR* filename ) bool TiXmlDocument::SaveFile( const TCHAR * filename ) const { + /* // The old c stuff lives on... FILE* fp = generic_fopen( filename, TEXT("wc") ); if ( fp ) @@ -764,6 +798,17 @@ bool TiXmlDocument::SaveFile( const TCHAR * filename ) const return true; } 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; for ( node=FirstChild(); node; node=node->NextSibling() ) { 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; PutString( Name(), &n ); PutString( Value(), &v ); - if (value.find ('\"') == TIXML_STRING::npos) - generic_fprintf (cfile, TEXT("%ls=\"%ls\""), n.c_str(), v.c_str() ); + generic_string attrVsValue = n; + 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 - 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(attrVsValueA.length())); } @@ -902,13 +962,20 @@ const double TiXmlAttribute::DoubleValue() const 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"), value.c_str() ); + + generic_string comment = TEXT(""); + std::string commentA = wstring2string(comment, CP_UTF8); + cfile.Write(commentA.c_str(), static_cast(commentA.length())); + //generic_fprintf( cfile, TEXT(""), value.c_str() ); } 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; 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(bufferA.length())); + //generic_fprintf( cfile, TEXT("%ls"), buffer.c_str() ); } @@ -967,18 +1037,43 @@ TiXmlDeclaration::TiXmlDeclaration( const TCHAR * _version, standalone = _standalone; } +const generic_string xmlDclOpen = TEXT(""); -void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/ ) const + +void TiXmlDeclaration::Print( CFile& cfile, int /*depth*/ ) const { - generic_fprintf (cfile, TEXT("")); + if (!version.empty()) + { + xmlDcl += TEXT("version=\""); + xmlDcl += version; + xmlDcl += TEXT("\" "); + //generic_fprintf(cfile, TEXT("version=\"%ls\" "), version.c_str()); + } + + 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(xmlDclA.length())); } 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(valueA.length())); + //generic_fprintf( cfile, TEXT("%ls"), value.c_str() ); } void TiXmlUnknown::StreamOut( TIXML_OSTREAM * stream ) const diff --git a/PowerEditor/src/TinyXml/tinyxml.h b/PowerEditor/src/TinyXml/tinyxml.h index 2c8bfe200..8fdc5d34d 100644 --- a/PowerEditor/src/TinyXml/tinyxml.h +++ b/PowerEditor/src/TinyXml/tinyxml.h @@ -62,6 +62,7 @@ distribution. #include #include "Common.h" +#include "FileInterface.h" class TiXmlDocument; class TiXmlElement; @@ -131,7 +132,7 @@ public: (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 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 ); // [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; // [internal use] @@ -783,7 +784,7 @@ public: virtual TiXmlNode* Clone() const; // [internal use] - virtual void Print( FILE* cfile, int depth ) const; + virtual void Print( CFile& cfile, int depth ) const; protected: @@ -822,7 +823,7 @@ public: // [internal use] Creates a new Element and returs it. virtual TiXmlNode* Clone() const; // [internal use] - virtual void Print( FILE* cfile, int depth ) const; + virtual void Print( CFile& cfile, int depth ) const; protected: // used to be public #ifdef TIXML_USE_STL @@ -859,7 +860,7 @@ public: #endif // [internal use] - virtual void Print( FILE* cfile, int depth ) const; + virtual void Print( CFile& cfile, int depth ) const; protected : // [internal use] Creates a new Element and returns it. @@ -928,7 +929,7 @@ public: // [internal use] Creates a new Element and returs it. virtual TiXmlNode* Clone() const; // [internal use] - virtual void Print( FILE* cfile, int depth ) const; + virtual void Print( CFile& cfile, int depth ) const; protected: // used to be public @@ -963,7 +964,7 @@ public: // [internal use] virtual TiXmlNode* Clone() const; // [internal use] - virtual void Print( FILE* cfile, int depth ) const; + virtual void Print( CFile& cfile, int depth ) const; protected: #ifdef TIXML_USE_STL virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); @@ -1097,10 +1098,10 @@ public: } /** Dump the document to standard out. */ - void Print() const { Print( stdout, 0 ); } + void Print() const { /*Print(stdout, 0);*/ } // [internal use] - virtual void Print( FILE* cfile, int depth = 0 ) const; + virtual void Print( CFile& cfile, int depth = 0 ) const; // [internal use] void SetError( int err, const TCHAR* errorLocation, TiXmlParsingData* prevData );