@@ -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