@@ -68,19 +68,13 @@ void BasicIo::seekOrThrow(int64_t offset, Position pos, ErrorCode err) {
6868class FileIo ::Impl {
6969 public:
7070 // ! Constructor
71- explicit Impl (std::string path);
72- #ifdef _WIN32
73- explicit Impl (std::wstring path);
74- #endif
71+ explicit Impl (fs::path path);
7572 ~Impl () = default ;
7673 // Enumerations
7774 // ! Mode of operation
7875 enum OpMode { opRead, opWrite, opSeek };
7976 // DATA
80- std::string path_; // !< (Standard) path
81- #ifdef _WIN32
82- std::wstring wpath_; // !< UCS2 path
83- #endif
77+ fs::path path_; // !< (Standard) path
8478 std::string openMode_; // !< File open mode
8579 FILE* fp_{}; // !< File stream pointer
8680 OpMode opMode_{opSeek}; // !< File open mode
@@ -114,21 +108,8 @@ class FileIo::Impl {
114108 Impl& operator =(const Impl&) = delete ; // !< Assignment
115109};
116110
117- FileIo::Impl::Impl (std::string path) : path_(std::move(path)) {
118- #ifdef _WIN32
119- wchar_t t[512 ];
120- const auto nw = MultiByteToWideChar (CP_UTF8, 0 , path_.data (), static_cast <int >(path_.size ()), t, 512 );
121- wpath_.assign (t, nw);
122- #endif
123- }
124- #ifdef _WIN32
125- FileIo::Impl::Impl (std::wstring path) : wpath_(std::move(path)) {
126- char t[1024 ];
127- const auto nc =
128- WideCharToMultiByte (CP_UTF8, 0 , wpath_.data (), static_cast <int >(wpath_.size ()), t, 1024 , nullptr , nullptr );
129- path_.assign (t, nc);
111+ FileIo::Impl::Impl (fs::path path) : path_(std::move(path)) {
130112}
131- #endif
132113
133114int FileIo::Impl::switchMode (OpMode opMode) {
134115 if (opMode_ == opMode)
@@ -178,7 +159,7 @@ int FileIo::Impl::switchMode(OpMode opMode) {
178159 openMode_ = " r+b" ;
179160 opMode_ = opSeek;
180161#ifdef _WIN32
181- if (_wfopen_s (&fp_, wpath_ .c_str (), L" r+b" ))
162+ if (_wfopen_s (&fp_, path_ .c_str (), L" r+b" ))
182163 return 1 ;
183164 return _fseeki64 (fp_, offset, SEEK_SET);
184165#else
@@ -190,11 +171,7 @@ int FileIo::Impl::switchMode(OpMode opMode) {
190171} // FileIo::Impl::switchMode
191172
192173int FileIo::Impl::stat (StructStat& buf) const {
193- #ifdef _WIN32
194- const auto & file = wpath_;
195- #else
196174 const auto & file = path_;
197- #endif
198175 try {
199176 buf.st_size = fs::file_size (file);
200177 buf.st_mode = fs::status (file).permissions ();
@@ -321,21 +298,12 @@ byte* FileIo::mmap(bool isWriteable) {
321298void FileIo::setPath (const std::string& path) {
322299 close ();
323300 p_->path_ = path;
324- #ifdef _WIN32
325- wchar_t t[512 ];
326- const auto nw = MultiByteToWideChar (CP_UTF8, 0 , p_->path_ .data (), static_cast <int >(p_->path_ .size ()), t, 512 );
327- p_->wpath_ .assign (t, nw);
328- #endif
329301}
330302
331303#ifdef _WIN32
332304void FileIo::setPath (const std::wstring& path) {
333305 close ();
334- p_->wpath_ = path;
335- char t[1024 ];
336- const auto nc = WideCharToMultiByte (CP_UTF8, 0 , p_->wpath_ .data (), static_cast <int >(p_->wpath_ .size ()), t, 1024 ,
337- nullptr , nullptr );
338- p_->path_ .assign (t, nc);
306+ p_->path_ = path;
339307}
340308#endif
341309
@@ -447,7 +415,7 @@ void FileIo::transfer(BasicIo& src) {
447415
448416 if (wasOpen) {
449417 if (open (lastMode) != 0 ) {
450- throw Error (ErrorCode::kerFileOpenFailed, path (), lastMode, strError ());
418+ throw Error (ErrorCode::kerFileOpenFailed, path (), strError ());
451419 }
452420 } else
453421 close ();
@@ -522,15 +490,28 @@ int FileIo::open(const std::string& mode) {
522490 p_->openMode_ = mode;
523491 p_->opMode_ = Impl::opSeek;
524492#ifdef _WIN32
525- wchar_t wmode[10 ];
526- MultiByteToWideChar (CP_UTF8, 0 , mode.c_str (), -1 , wmode, 10 );
527- if (_wfopen_s (&p_->fp_ , p_->wpath_ .c_str (), wmode))
528- return 1 ;
493+ auto wMode = [&] {
494+ if (mode == " ab" )
495+ return L" ab" ;
496+ if (mode == " rb" )
497+ return L" rb" ;
498+ if (mode == " wb" )
499+ return L" wb" ;
500+ if (mode == " a+b" )
501+ return L" a+b" ;
502+ if (mode == " r+b" )
503+ return L" r+b" ;
504+ if (mode == " w+b" )
505+ return L" w+b" ;
506+ return L" " ;
507+ }();
508+
509+ if (_wfopen_s (&p_->fp_ , p_->path_ .c_str (), wMode))
529510#else
530- p_->fp_ = ::fopen (path ().c_str (), mode.c_str ());
511+ p_->fp_ = std ::fopen (path ().c_str (), mode.c_str ());
531512 if (!p_->fp_ )
532- return 1 ;
533513#endif
514+ return 1 ;
534515 return 0 ;
535516}
536517
@@ -584,7 +565,9 @@ bool FileIo::eof() const {
584565}
585566
586567const std::string& FileIo::path () const noexcept {
587- return p_->path_ ;
568+ static thread_local std::string p;
569+ p = p_->path_ .string ();
570+ return p;
588571}
589572
590573void FileIo::populateFakeData () {
@@ -871,7 +854,7 @@ bool MemIo::eof() const {
871854}
872855
873856const std::string& MemIo::path () const noexcept {
874- static std::string _path{" MemIo" };
857+ static const std::string _path{" MemIo" };
875858 return _path;
876859}
877860
@@ -1678,6 +1661,28 @@ size_t writeFile(const DataBuf& buf, const std::string& path) {
16781661 }
16791662 return file.write (buf.c_data (), buf.size ());
16801663}
1664+
1665+ #ifdef _WIN32
1666+ DataBuf readFile (const std::wstring& path) {
1667+ FileIo file (path);
1668+ if (file.open (" rb" ) != 0 ) {
1669+ throw Error (ErrorCode::kerFileOpenFailed, " rb" , strError ());
1670+ }
1671+ DataBuf buf (static_cast <size_t >(fs::file_size (path)));
1672+ if (file.read (buf.data (), buf.size ()) != buf.size ()) {
1673+ throw Error (ErrorCode::kerCallFailed, strError (), " FileIo::read" );
1674+ }
1675+ return buf;
1676+ }
1677+
1678+ size_t writeFile (const DataBuf& buf, const std::wstring& path) {
1679+ FileIo file (path);
1680+ if (file.open (" wb" ) != 0 ) {
1681+ throw Error (ErrorCode::kerFileOpenFailed, " wb" , strError ());
1682+ }
1683+ return file.write (buf.c_data (), buf.size ());
1684+ }
1685+ #endif
16811686#endif
16821687
16831688#ifdef EXV_USE_CURL
0 commit comments