Skip to content

Commit c2aaba9

Browse files
committed
maybe?
Signed-off-by: Rosen Penev <[email protected]>
1 parent 9680bb4 commit c2aaba9

File tree

3 files changed

+44
-11
lines changed

3 files changed

+44
-11
lines changed

include/exiv2/basicio.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,9 @@ class EXIV2API FileIo : public BasicIo {
310310
Nonzero if failure.
311311
*/
312312
int open(const std::string& mode);
313+
#ifdef _WIN32
314+
int open(const std::wstring& mode);
315+
#endif
313316
/*!
314317
@brief Open the file using the default access mode of "rb".
315318
This method can also be used to "reopen" a file which will flush

include/exiv2/image.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,9 @@ class EXIV2API ImageFactory {
582582
@throw Error If the image type is not supported.
583583
*/
584584
static Image::UniquePtr create(ImageType type, const std::string& path);
585+
#ifdef _WIN32
586+
static Image::UniquePtr create(ImageType type, const std::wstring& path);
587+
#endif
585588
/*!
586589
@brief Create an Image subclass of the requested type by creating a
587590
new image in memory.

src/basicio.cpp

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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

466481
size_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

482501
int 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

487510
int 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+
504531
bool FileIo::isopen() const {
505532
return p_->fp_ != nullptr;
506533
}

0 commit comments

Comments
 (0)