@@ -73,10 +73,11 @@ class FileIo::Impl {
7373 // ! Mode of operation
7474 enum OpMode { opRead, opWrite, opSeek };
7575 // DATA
76- fs::path path_; // !< (Standard) path
77- std::string openMode_; // !< File open mode
78- FILE* fp_{}; // !< File stream pointer
79- OpMode opMode_{opSeek}; // !< File open mode
76+ fs::path path_; // !< (Standard) path
77+ std::string openMode_; // !< File open mode
78+ std::wstring wOpenMode_; // !< File open mode (wide)
79+ FILE* fp_{}; // !< File stream pointer
80+ OpMode opMode_{opSeek}; // !< File open mode
8081
8182#if defined _WIN32
8283 HANDLE hFile_{}; // !< Duplicated fd
@@ -118,6 +119,19 @@ int FileIo::Impl::switchMode(OpMode opMode) {
118119
119120 bool reopen = true ;
120121 switch (opMode) {
122+ #ifdef _WIN32
123+ case opRead:
124+ // Flush if current mode allows reading, else reopen (in mode "r+b"
125+ // as in this case we know that we can write to the file)
126+ if (wOpenMode_.front () == L' r' || wOpenMode_.at (1 ) == L' +' )
127+ reopen = false ;
128+ break ;
129+ case opWrite:
130+ // Flush if current mode allows writing, else reopen
131+ if (wOpenMode_.front () != L' r' || wOpenMode_.at (1 ) == L' +' )
132+ reopen = false ;
133+ break ;
134+ #else
121135 case opRead:
122136 // Flush if current mode allows reading, else reopen (in mode "r+b"
123137 // as in this case we know that we can write to the file)
@@ -129,6 +143,7 @@ int FileIo::Impl::switchMode(OpMode opMode) {
129143 if (openMode_.front () != ' r' || openMode_.at (1 ) == ' +' )
130144 reopen = false ;
131145 break ;
146+ #endif
132147 case opSeek:
133148 reopen = false ;
134149 break ;
@@ -465,7 +480,11 @@ size_t FileIo::tell() const {
465480
466481size_t FileIo::size () const {
467482 // Flush and commit only if the file is open for writing
483+ #ifdef _WIN32
484+ if (p_->fp_ && (p_->wOpenMode_ .front () != L' r' || p_->wOpenMode_ .at (1 ) == L' +' )) {
485+ #else
468486 if (p_->fp_ && (p_->openMode_ .front () != ' r' || p_->openMode_ .at (1 ) == ' +' )) {
487+ #endif
469488 std::fflush (p_->fp_ );
470489#ifdef _MSC_VER
471490 // This is required on msvcrt before stat after writing to a file
@@ -481,26 +500,34 @@ size_t FileIo::size() const {
481500
482501int FileIo::open () {
483502 // Default open is in read-only binary mode
503+ #ifdef _WIN32
504+ return open (L" rb" );
505+ #else
484506 return open (" rb" );
507+ #endif
485508}
486509
487510int FileIo::open (const std::string& mode) {
488511 close ();
489512 p_->openMode_ = mode;
490513 p_->opMode_ = Impl::opSeek;
491- #ifdef _WIN32
492- wchar_t wmode[10 ];
493- MultiByteToWideChar (CP_UTF8, 0 , mode.c_str (), -1 , wmode, 10 );
494- if (_wfopen_s (&p_->fp_ , p_->path_ .c_str (), wmode))
495- return 1 ;
496- #else
497514 p_->fp_ = ::fopen (path ().c_str (), mode.c_str ());
498515 if (!p_->fp_ )
499516 return 1 ;
500- #endif
501517 return 0 ;
502518}
503519
520+ #ifdef _WIN32
521+ int FileIo::open (const std::wstring& mode) {
522+ close ();
523+ p_->wOpenMode_ = mode;
524+ p_->opMode_ = Impl::opSeek;
525+ if (_wfopen_s (&p_->fp_ , p_->path_ .c_str (), mode.c_str ()))
526+ return 1 ;
527+ return 0 ;
528+ }
529+ #endif
530+
504531bool FileIo::isopen () const {
505532 return p_->fp_ != nullptr ;
506533}
0 commit comments