From ea734acf0b2dd4ad596081b494ae97afe6485a9c Mon Sep 17 00:00:00 2001 From: Dextinfire <> Date: Thu, 26 Sep 2024 21:17:02 -0700 Subject: [PATCH 1/4] Fix a few issues with physical file streams for write --- src/io/physicalfilestream.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/io/physicalfilestream.cpp b/src/io/physicalfilestream.cpp index cc4bfa3c..6ac6908d 100644 --- a/src/io/physicalfilestream.cpp +++ b/src/io/physicalfilestream.cpp @@ -64,18 +64,26 @@ int64_t PhysicalFileStream::Seek(int64_t offset, int origin) { } if (absPos < 0 || absPos > Meta.Size) return IoError_Fail; - int64_t err = SeekBuffered(absPos); - if (err < IoError_OK) { - BufferFill = 0; - BufferConsumed = 0; - err = SDL_RWseek(RW, absPos, + if (!IsWrite) { + int64_t err = SeekBuffered(absPos); + if (err < IoError_OK) { + BufferFill = 0; + BufferConsumed = 0; + err = + SDL_RWseek(RW, absPos, RW_SEEK_SET); // TODO: why does SDL_RWtell not match // Position here sometimes? This causes PNGs // with iTxT chunk to fail loading :thonk: + if (err < 0) return IoError_Fail; + Position = err; + } + return err; + } else { + int64_t err = SDL_RWseek(RW, absPos, RW_SEEK_SET); if (err < 0) return IoError_Fail; Position = err; + return err; } - return err; } IoError PhysicalFileStream::Duplicate(Stream** outStream) { @@ -100,6 +108,7 @@ IoError PhysicalFileStream::Duplicate(Stream** outStream) { int64_t PhysicalFileStream::Write(void* buffer, int64_t sz, int cnt) { // Todo: buffered write (SDL_RWwrite doesn't buffer system calls) int64_t written = SDL_RWwrite(RW, buffer, sz, cnt); + if (Meta.Size < Position + written) Meta.Size = Position + written; Seek(sz * cnt, SEEK_CUR); return written; } From 43676ed799c240eb71196ccb96264f83c8bbc4c9 Mon Sep 17 00:00:00 2001 From: Dextinfire <> Date: Thu, 26 Sep 2024 21:18:11 -0700 Subject: [PATCH 2/4] "System Data could not found. System Data are created" --- src/data/savesystem.cpp | 14 +++++++++++++ src/data/savesystem.h | 4 ++++ src/games/cclcc/savesystem.cpp | 38 ++++++++++++++++++++++++++++++++++ src/games/cclcc/savesystem.h | 3 +++ src/games/chlcc/savesystem.h | 2 ++ src/games/mo6tw/savesystem.h | 2 ++ src/vm/inst_system.cpp | 14 +++++++++++++ 7 files changed, 77 insertions(+) diff --git a/src/data/savesystem.cpp b/src/data/savesystem.cpp index a9c16e2b..c6636768 100644 --- a/src/data/savesystem.cpp +++ b/src/data/savesystem.cpp @@ -12,6 +12,20 @@ using namespace Impacto::Profile::SaveSystem; void Init() { Configure(); } +SaveError CreateSaveFile() { + if (Implementation) + return Implementation->CreateSaveFile(); + else + return SaveOK; // Just so we don't get stuck +} + +SaveError CheckSaveFile() { + if (Implementation) + return Implementation->CheckSaveFile(); + else + return SaveOK; +} + SaveError MountSaveFile() { if (Implementation) return Implementation->MountSaveFile(); diff --git a/src/data/savesystem.h b/src/data/savesystem.h index 5a8cd33b..efb10543 100644 --- a/src/data/savesystem.h +++ b/src/data/savesystem.h @@ -66,6 +66,8 @@ class SaveFileEntryBase { class SaveSystemBase { public: + virtual SaveError CreateSaveFile() = 0; + virtual SaveError CheckSaveFile() = 0; virtual SaveError MountSaveFile() = 0; virtual void SaveMemory() = 0; virtual void LoadEntry(SaveType type, int id) = 0; @@ -105,6 +107,8 @@ inline SaveSystemBase* Implementation = nullptr; void Init(); +SaveError CreateSaveFile(); +SaveError CheckSaveFile(); SaveError MountSaveFile(); void SaveMemory(); void LoadEntry(SaveType type, int id); diff --git a/src/games/cclcc/savesystem.cpp b/src/games/cclcc/savesystem.cpp index 7a9a1fed..1b5cb1c2 100644 --- a/src/games/cclcc/savesystem.cpp +++ b/src/games/cclcc/savesystem.cpp @@ -14,6 +14,7 @@ #include #include +#include namespace Impacto { namespace CCLCC { @@ -23,6 +24,43 @@ using namespace Impacto::Profile::SaveSystem; using namespace Impacto::Profile::ScriptVars; using namespace Impacto::Profile::Vm; +SaveError SaveSystem::CheckSaveFile() { + std::filesystem::path savePath(SaveFilePath); + if (!std::filesystem::exists(savePath)) { + return SaveNotFound; + } + if (std::filesystem::file_size(savePath) != SaveFileSize) { + return SaveCorrupted; + } + if (auto perms = std::filesystem::status(savePath).permissions(); + to_underlying(perms) & + (to_underlying(std::filesystem::perms::owner_read) | + to_underlying(std::filesystem::perms::owner_write)) == 0 && + to_underlying(perms) & + (to_underlying(std::filesystem::perms::group_read) | + to_underlying(std::filesystem::perms::group_write)) == 0) { + return SaveWrongUser; + } + return SaveOK; +} + +SaveError SaveSystem::CreateSaveFile() { + Io::Stream* stream; + IoError err = + Io::PhysicalFileStream::CreateWrite(SaveFilePath, &stream, false); + if (err != IoError_OK) { + return SaveFailed; + } + + assert(stream->Meta.Size == 0); + std::vector emptyData(SaveFileSize, 0); + Io::WriteArrayBE(emptyData.data(), stream, SaveFileSize); + assert(stream->Position == SaveFileSize); + delete stream; + + return MountSaveFile(); +} + SaveError SaveSystem::MountSaveFile() { Io::Stream* stream; IoError err = Io::PhysicalFileStream::Create(SaveFilePath, &stream); diff --git a/src/games/cclcc/savesystem.h b/src/games/cclcc/savesystem.h index c06a5e23..f0a86545 100644 --- a/src/games/cclcc/savesystem.h +++ b/src/games/cclcc/savesystem.h @@ -10,6 +10,7 @@ namespace CCLCC { using namespace Impacto::SaveSystem; +constexpr int SaveFileSize = 0x1b110 * MaxSaveEntries * 2 + 0x387c; constexpr int SaveThumbnailWidth = 240; constexpr int SaveThumbnailHeight = 135; @@ -25,6 +26,8 @@ class SaveFileEntry : public SaveFileEntryBase { class SaveSystem : public SaveSystemBase { public: + SaveError CreateSaveFile() override; + SaveError CheckSaveFile() override; SaveError MountSaveFile() override; void SaveMemory() override; void LoadEntry(SaveType type, int id) override; diff --git a/src/games/chlcc/savesystem.h b/src/games/chlcc/savesystem.h index 1b9a174b..6917c26e 100644 --- a/src/games/chlcc/savesystem.h +++ b/src/games/chlcc/savesystem.h @@ -17,6 +17,8 @@ class SaveFileEntry : public SaveFileEntryBase { class SaveSystem : public SaveSystemBase { public: + SaveError CreateSaveFile() override { return SaveOK; } // Todo + SaveError CheckSaveFile() override { return SaveOK; } // Todo SaveError MountSaveFile() override; void SaveMemory() override; void LoadEntry(SaveType type, int id) override; diff --git a/src/games/mo6tw/savesystem.h b/src/games/mo6tw/savesystem.h index 19c1f372..54c3c8ea 100644 --- a/src/games/mo6tw/savesystem.h +++ b/src/games/mo6tw/savesystem.h @@ -17,6 +17,8 @@ class SaveFileEntry : public SaveFileEntryBase { class SaveSystem : public SaveSystemBase { public: + SaveError CreateSaveFile() override { return SaveOK; } // Todo + SaveError CheckSaveFile() override { return SaveOK; } // Todo SaveError MountSaveFile() override; void SaveMemory() override; void LoadEntry(SaveType type, int id) override; diff --git a/src/vm/inst_system.cpp b/src/vm/inst_system.cpp index 1c7134ef..70c20640 100644 --- a/src/vm/inst_system.cpp +++ b/src/vm/inst_system.cpp @@ -258,6 +258,20 @@ VmInstruction(InstSave) { if (Profile::Vm::GameInstructionSet == +InstructionSet::CC) { LoadSaveFile(); } + case 30: + break; + case 31: + if (Profile::Vm::GameInstructionSet == +InstructionSet::CC) { + ScrWork[SW_SAVEERRORCODE] = CreateSaveFile(); + } + break; + case 80: + break; + case 81: { // SystemDataCheck + if (Profile::Vm::GameInstructionSet == +InstructionSet::CC) { + ScrWork[SW_SAVEERRORCODE] = CheckSaveFile(); + } + } break; default: ImpLogSlow(LL_Warning, LC_VMStub, "STUB instruction Save(type: %i)\n", type); From 6eb048ea9bc4bbad3dd6c43fe6c255fbcef87a77 Mon Sep 17 00:00:00 2001 From: Dextinfire <> Date: Fri, 27 Sep 2024 01:43:15 -0700 Subject: [PATCH 3/4] Test using fstreams instead of SDL_rw --- src/games/cclcc/savesystem.cpp | 5 +- src/games/chlcc/savesystem.cpp | 2 +- src/games/mo6tw/savesystem.cpp | 2 +- src/io/physicalfilestream.cpp | 142 ++++++++++++++++----------------- src/io/physicalfilestream.h | 47 ++++++----- src/io/stream.h | 1 - src/io/textarchive.cpp | 26 +++--- src/io/vfs.h | 2 - 8 files changed, 109 insertions(+), 118 deletions(-) diff --git a/src/games/cclcc/savesystem.cpp b/src/games/cclcc/savesystem.cpp index 1b5cb1c2..9b55a9c2 100644 --- a/src/games/cclcc/savesystem.cpp +++ b/src/games/cclcc/savesystem.cpp @@ -46,8 +46,7 @@ SaveError SaveSystem::CheckSaveFile() { SaveError SaveSystem::CreateSaveFile() { Io::Stream* stream; - IoError err = - Io::PhysicalFileStream::CreateWrite(SaveFilePath, &stream, false); + IoError err = Io::PhysicalFileStream::Create(SaveFilePath, &stream, false); if (err != IoError_OK) { return SaveFailed; } @@ -273,7 +272,7 @@ void SaveSystem::FlushWorkingSaveEntry(SaveType type, int id) { void SaveSystem::WriteSaveFile() { Io::Stream* stream; - IoError err = Io::PhysicalFileStream::CreateWrite(SaveFilePath, &stream); + IoError err = Io::PhysicalFileStream::Create(SaveFilePath, &stream); if (err != IoError_OK) { ImpLog(LL_Error, LC_IO, "Failed to open save file for writing\n"); return; diff --git a/src/games/chlcc/savesystem.cpp b/src/games/chlcc/savesystem.cpp index 0be2abcb..8e79cc8c 100644 --- a/src/games/chlcc/savesystem.cpp +++ b/src/games/chlcc/savesystem.cpp @@ -155,7 +155,7 @@ void SaveSystem::FlushWorkingSaveEntry(SaveType type, int id) { void SaveSystem::WriteSaveFile() { Io::Stream* stream; - IoError err = Io::PhysicalFileStream::CreateWrite(SaveFilePath, &stream); + IoError err = Io::PhysicalFileStream::Create(SaveFilePath, &stream); if (err != IoError_OK) { ImpLog(LL_Error, LC_IO, "Failed to open save file for writing\n"); return; diff --git a/src/games/mo6tw/savesystem.cpp b/src/games/mo6tw/savesystem.cpp index c62edaa0..f4c025a6 100644 --- a/src/games/mo6tw/savesystem.cpp +++ b/src/games/mo6tw/savesystem.cpp @@ -242,7 +242,7 @@ void SaveSystem::FlushWorkingSaveEntry(SaveType type, int id) { void SaveSystem::WriteSaveFile() { Io::PhysicalFileStream* stream; Io::Stream* instream; - IoError err = Io::PhysicalFileStream::CreateWrite(SaveFilePath, &instream); + IoError err = Io::PhysicalFileStream::Create(SaveFilePath, &instream); auto err1 = SDL_GetError(); if (err != IoError_OK) { ImpLog(LL_Error, LC_IO, "Failed to create save file, SDL error: %s\n", diff --git a/src/io/physicalfilestream.cpp b/src/io/physicalfilestream.cpp index 6ac6908d..f4d7219b 100644 --- a/src/io/physicalfilestream.cpp +++ b/src/io/physicalfilestream.cpp @@ -1,52 +1,51 @@ #include "physicalfilestream.h" +#include "../log.h" #include namespace Impacto { namespace Io { -PhysicalFileStream::~PhysicalFileStream() { SDL_RWclose(RW); } - -IoError PhysicalFileStream::Create(std::string const& fileName, Stream** out) { - SDL_RWops* rw = SDL_RWFromFile(fileName.c_str(), "rb"); - if (!rw) return IoError_Fail; - int64_t size = SDL_RWsize(rw); - if (size < 0) return IoError_Fail; - PhysicalFileStream* result = new PhysicalFileStream; - result->RW = rw; - result->Meta.Size = size; - result->SourceFileName = fileName; - result->Meta.FileName = fileName; - *out = (Stream*)result; - return IoError_OK; -} - -IoError PhysicalFileStream::CreateWrite(std::string const& fileName, - Stream** out, bool exists) { - SDL_RWops* rw = (exists) ? SDL_RWFromFile(fileName.c_str(), "r+b") - : SDL_RWFromFile(fileName.c_str(), "wb"); - if (!rw) return IoError_Fail; - int64_t size = SDL_RWsize(rw); - if (size < 0) return IoError_Fail; - PhysicalFileStream* result = new PhysicalFileStream; - result->RW = rw; - result->Meta.Size = size; - result->SourceFileName = fileName; - result->Meta.FileName = fileName; - result->IsWrite = true; +IoError PhysicalFileStream::Create(std::string const& fileName, Stream** out, + bool exists) { + std::error_code ec; + if (exists && !std::filesystem::exists(fileName, ec)) { + if (ec) { + ImpLog(LL_Error, LC_IO, "Error checking file existence: %s\n", + ec.message().c_str()); + return IoError_Fail; + } + return IoError_NotFound; + } + PhysicalFileStream* result = new PhysicalFileStream(fileName, !exists); + if (!result->FileStream) { + delete result; + return IoError_Fail; + } + result->Meta.Size = std::filesystem::file_size(result->SourceFileName, ec); + if (ec) { + delete result; + ImpLog(LL_Error, LC_IO, "Error getting file size: %s\n", + ec.message().c_str()); + return IoError_Fail; + } *out = (Stream*)result; return IoError_OK; } -IoError PhysicalFileStream::FillBuffer() { - int64_t read = SDL_RWread(RW, Buffer, 1, PhysicalBufferSize); - if (read < 0) return IoError_Fail; - BufferFill = read; - return IoError_OK; -} - int64_t PhysicalFileStream::Read(void* buffer, int64_t sz) { - return ReadBuffered(buffer, sz); + if (FileStream.eof()) { + return IoError_Eof; + } + FileStream.read((char*)buffer, sz); + if (!FileStream && !FileStream.eof()) { + ImpLog(LL_Error, LC_IO, "Read failed for file \"%s\" with error: \"%s\"\n", + SourceFileName.string().c_str(), std::strerror(errno)); + return IoError_Fail; + } + int64_t read = FileStream.gcount(); + Position += read; + return read; } int64_t PhysicalFileStream::Seek(int64_t offset, int origin) { @@ -59,57 +58,56 @@ int64_t PhysicalFileStream::Seek(int64_t offset, int origin) { absPos = Position + offset; break; case RW_SEEK_END: - absPos = Meta.Size - offset; + absPos = Meta.Size + offset; break; } if (absPos < 0 || absPos > Meta.Size) return IoError_Fail; - - if (!IsWrite) { - int64_t err = SeekBuffered(absPos); - if (err < IoError_OK) { - BufferFill = 0; - BufferConsumed = 0; - err = - SDL_RWseek(RW, absPos, - RW_SEEK_SET); // TODO: why does SDL_RWtell not match - // Position here sometimes? This causes PNGs - // with iTxT chunk to fail loading :thonk: - if (err < 0) return IoError_Fail; - Position = err; - } - return err; - } else { - int64_t err = SDL_RWseek(RW, absPos, RW_SEEK_SET); - if (err < 0) return IoError_Fail; - Position = err; - return err; + FileStream.seekg(absPos, std::ios::beg); + if (!FileStream) { + ImpLog(LL_Error, LC_IO, "Seek failed for file \"%s\" with error: \"%s\"\n", + SourceFileName.string().c_str(), std::strerror(errno)); + return IoError_Fail; } + Position = absPos; + return Position; } IoError PhysicalFileStream::Duplicate(Stream** outStream) { - SDL_RWops* rw = SDL_RWFromFile(SourceFileName.c_str(), "rb"); - if (!rw) return IoError_Fail; - int64_t filePos = SDL_RWtell(RW); - if (filePos < 0) { - SDL_RWclose(rw); + PhysicalFileStream* result = new PhysicalFileStream(*this); + std::error_code ec; + if (!result->FileStream) { + delete result; + ImpLog(LL_Error, LC_IO, "Failed to open file \"%s\"\n", + SourceFileName.string().c_str()); return IoError_Fail; } - int64_t pos = SDL_RWseek(rw, filePos, RW_SEEK_SET); - if (pos != filePos) { - SDL_RWclose(rw); + result->Meta.Size = std::filesystem::file_size(SourceFileName, ec); + if (ec) { + delete result; + ImpLog(LL_Error, LC_IO, "Error getting file size: %s\n", + ec.message().c_str()); + return IoError_Fail; + } + if (result->Seek(Position, RW_SEEK_SET) < 0) { + delete result; + ImpLog(LL_Error, LC_IO, "Seek failed for file \"%s\" with error: \"%s\"\n", + SourceFileName.string().c_str(), std::strerror(errno)); return IoError_Fail; } - PhysicalFileStream* result = new PhysicalFileStream(*this); - result->RW = rw; *outStream = (Stream*)result; return IoError_OK; } int64_t PhysicalFileStream::Write(void* buffer, int64_t sz, int cnt) { - // Todo: buffered write (SDL_RWwrite doesn't buffer system calls) - int64_t written = SDL_RWwrite(RW, buffer, sz, cnt); - if (Meta.Size < Position + written) Meta.Size = Position + written; - Seek(sz * cnt, SEEK_CUR); + FileStream.write((char*)buffer, sz * cnt); + if (!FileStream) { + ImpLog(LL_Error, LC_IO, "Write failed for file \"%s\" with error: \"%s\"\n", + SourceFileName.string().c_str(), std::strerror(errno)); + return IoError_Fail; + } + int64_t written = FileStream.gcount(); + Position += written; + Meta.Size = std::max(Position, Meta.Size); return written; } diff --git a/src/io/physicalfilestream.h b/src/io/physicalfilestream.h index 7d0cca53..e140d095 100644 --- a/src/io/physicalfilestream.h +++ b/src/io/physicalfilestream.h @@ -1,39 +1,44 @@ #pragma once #include "stream.h" -#include +#include +#include #include "buffering.h" namespace Impacto { namespace Io { -// TODO *optional* buffering - -class PhysicalFileStream : public Stream, public Buffering { - friend class Buffering; - +class PhysicalFileStream : public Stream { public: - ~PhysicalFileStream(); - - static IoError Create(std::string const& fileName, Stream** out); - static IoError CreateWrite(std::string const& fileName, Stream** out, - bool exists = true); + static IoError Create(std::string const& fileName, Stream** out, + bool exists = true); int64_t Read(void* buffer, int64_t sz) override; int64_t Seek(int64_t offset, int origin) override; IoError Duplicate(Stream** outStream) override; int64_t Write(void* buffer, int64_t sz, int cnt = 1) override; protected: - static int constexpr PhysicalBufferSize = 16 * 1024; - bool IsWrite = false; - PhysicalFileStream() : Buffering(PhysicalBufferSize) {} - PhysicalFileStream(PhysicalFileStream const& other) = default; - - IoError FillBuffer(); - IoError FlushBuffer(); - - SDL_RWops* RW; - std::string SourceFileName; + std::ios_base::openmode GetFileMode(bool truncate) { + // trunc will clear file if it exists, and allows creation of new file + return (truncate) ? std::ios::in | std::ios::out | std::ios::trunc | + std::ios::binary + : std::ios::in | std::ios::out | std::ios::binary; + } + PhysicalFileStream(std::filesystem::path filePath, bool truncate = false) + : Truncate(truncate), + SourceFileName(std::move(filePath)), + FileStream(SourceFileName, GetFileMode(truncate)) { + Meta.FileName = SourceFileName.string(); + } + + PhysicalFileStream(PhysicalFileStream const& other) + : SourceFileName(other.SourceFileName), + FileStream(other.SourceFileName, GetFileMode(other.Truncate)) { + Meta.FileName = SourceFileName.string(); + } + bool Truncate; + std::filesystem::path SourceFileName; + std::fstream FileStream; }; } // namespace Io diff --git a/src/io/stream.h b/src/io/stream.h index d2d6125d..e642c9d0 100644 --- a/src/io/stream.h +++ b/src/io/stream.h @@ -17,7 +17,6 @@ class Stream { virtual ~Stream() {} FileMeta Meta; int64_t Position = 0; - int64_t WritePosition = 0; bool IsSeekSlow = false; bool IsMemory = false; diff --git a/src/io/textarchive.cpp b/src/io/textarchive.cpp index be867eca..959c4eca 100644 --- a/src/io/textarchive.cpp +++ b/src/io/textarchive.cpp @@ -6,7 +6,7 @@ #include "vfs.h" #include "../util.h" #include -#include +#include namespace Impacto { namespace Io { @@ -34,22 +34,14 @@ IoError TextArchive::Open(FileMeta* file, Stream** outStream) { IoError TextArchive::GetCurrentSize(FileMeta* file, int64_t* outSize) { TextMetaEntry* entry = (TextMetaEntry*)file; - SDL_RWops* rw = SDL_RWFromFile(entry->FullPath.c_str(), "rb"); - if (!rw) { - ImpLog( - LL_Error, LC_IO, - "TextArchive file open (to get size) failed for file \"%s\" in archive " - "\"%s\"\n", - entry->FullPath.c_str(), BaseStream->Meta.FileName.c_str()); - return IoError_Fail; - } - *outSize = SDL_RWsize(rw); - SDL_RWclose(rw); - if (*outSize < 0) { - ImpLog( - LL_Error, LC_IO, - "TextArchive getting size failed for file \"%s\" in archive \"%s\"\n", - entry->FullPath.c_str(), BaseStream->Meta.FileName.c_str()); + std::error_code ec; + *outSize = std::filesystem::file_size(entry->FullPath, ec); + if (ec) { + ImpLog(LL_Error, LC_IO, + "TextArchive getting size failed for file \"%s\" in archive " + "\"%s\"\nerror: %s\n", + entry->FullPath.c_str(), BaseStream->Meta.FileName.c_str(), + ec.message().c_str()); return IoError_Fail; } return IoError_OK; diff --git a/src/io/vfs.h b/src/io/vfs.h index 6dc62bc2..a1d0e3e8 100644 --- a/src/io/vfs.h +++ b/src/io/vfs.h @@ -2,8 +2,6 @@ #include -#include - #include "../impacto.h" #include "io.h" From 80b5924337d8e4a3c06add0b0bebeb08676ecb0f Mon Sep 17 00:00:00 2001 From: Dextinfire <> Date: Fri, 27 Sep 2024 09:52:27 -0700 Subject: [PATCH 4/4] Fix include error --- src/io/physicalfilestream.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/io/physicalfilestream.cpp b/src/io/physicalfilestream.cpp index f4d7219b..2154ce42 100644 --- a/src/io/physicalfilestream.cpp +++ b/src/io/physicalfilestream.cpp @@ -1,6 +1,7 @@ #include "physicalfilestream.h" #include "../log.h" +#include #include namespace Impacto { @@ -19,14 +20,16 @@ IoError PhysicalFileStream::Create(std::string const& fileName, Stream** out, } PhysicalFileStream* result = new PhysicalFileStream(fileName, !exists); if (!result->FileStream) { + ImpLog(LL_Error, LC_IO, "Failed to open file \"%s\", error: \"%s\"\n", + fileName.c_str(), std::strerror(errno)); delete result; return IoError_Fail; } result->Meta.Size = std::filesystem::file_size(result->SourceFileName, ec); if (ec) { - delete result; ImpLog(LL_Error, LC_IO, "Error getting file size: %s\n", ec.message().c_str()); + delete result; return IoError_Fail; } *out = (Stream*)result; @@ -76,22 +79,22 @@ IoError PhysicalFileStream::Duplicate(Stream** outStream) { PhysicalFileStream* result = new PhysicalFileStream(*this); std::error_code ec; if (!result->FileStream) { + ImpLog(LL_Error, LC_IO, "Failed to open file \"%s\", error: \"%s\"\n", + SourceFileName.string().c_str(), std::strerror(errno)); delete result; - ImpLog(LL_Error, LC_IO, "Failed to open file \"%s\"\n", - SourceFileName.string().c_str()); return IoError_Fail; } result->Meta.Size = std::filesystem::file_size(SourceFileName, ec); if (ec) { - delete result; ImpLog(LL_Error, LC_IO, "Error getting file size: %s\n", ec.message().c_str()); + delete result; return IoError_Fail; } if (result->Seek(Position, RW_SEEK_SET) < 0) { - delete result; ImpLog(LL_Error, LC_IO, "Seek failed for file \"%s\" with error: \"%s\"\n", SourceFileName.string().c_str(), std::strerror(errno)); + delete result; return IoError_Fail; } *outStream = (Stream*)result;