diff --git a/Source/Core/DiscIO/Blob.cpp b/Source/Core/DiscIO/Blob.cpp index d1dd0e7c1e..e40b530233 100644 --- a/Source/Core/DiscIO/Blob.cpp +++ b/Source/Core/DiscIO/Blob.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "Common/CDUtils.h" #include "Common/CommonTypes.h" @@ -192,15 +193,15 @@ std::unique_ptr CreateBlobReader(const std::string& filename) switch (magic) { case CISO_MAGIC: - return CISOFileReader::Create(filename); + return CISOFileReader::Create(std::move(file)); case GCZ_MAGIC: - return CompressedBlobReader::Create(filename); + return CompressedBlobReader::Create(std::move(file), filename); case TGC_MAGIC: - return TGCFileReader::Create(filename); + return TGCFileReader::Create(std::move(file)); case WBFS_MAGIC: return WbfsFileReader::Create(filename); default: - return PlainFileReader::Create(filename); + return PlainFileReader::Create(std::move(file)); } } diff --git a/Source/Core/DiscIO/Blob.h b/Source/Core/DiscIO/Blob.h index fa068c33ef..7f954cd65b 100644 --- a/Source/Core/DiscIO/Blob.h +++ b/Source/Core/DiscIO/Blob.h @@ -159,10 +159,10 @@ std::unique_ptr CreateBlobReader(const std::string& filename); typedef bool (*CompressCB)(const std::string& text, float percent, void* arg); -bool CompressFileToBlob(const std::string& infile, const std::string& outfile, u32 sub_type = 0, - int sector_size = 16384, CompressCB callback = nullptr, +bool CompressFileToBlob(const std::string& infile_path, const std::string& outfile_path, + u32 sub_type = 0, int sector_size = 16384, CompressCB callback = nullptr, void* arg = nullptr); -bool DecompressBlobToFile(const std::string& infile, const std::string& outfile, +bool DecompressBlobToFile(const std::string& infile_path, const std::string& outfile_path, CompressCB callback = nullptr, void* arg = nullptr); } // namespace diff --git a/Source/Core/DiscIO/CISOBlob.cpp b/Source/Core/DiscIO/CISOBlob.cpp index 388fd71d60..846952ce8a 100644 --- a/Source/Core/DiscIO/CISOBlob.cpp +++ b/Source/Core/DiscIO/CISOBlob.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "Common/CommonTypes.h" #include "Common/FileUtil.h" @@ -12,11 +13,12 @@ namespace DiscIO { -CISOFileReader::CISOFileReader(std::FILE* file) : m_file(file) +CISOFileReader::CISOFileReader(File::IOFile file) : m_file(std::move(file)) { m_size = m_file.GetSize(); CISOHeader header; + m_file.Seek(0, SEEK_SET); m_file.ReadArray(&header, 1); m_block_size = header.block_size; @@ -26,12 +28,11 @@ CISOFileReader::CISOFileReader(std::FILE* file) : m_file(file) m_ciso_map[idx] = (1 == header.map[idx]) ? count++ : UNUSED_BLOCK_ID; } -std::unique_ptr CISOFileReader::Create(const std::string& filename) +std::unique_ptr CISOFileReader::Create(File::IOFile file) { - File::IOFile f(filename, "rb"); CISOHeader header; - if (f.ReadArray(&header, 1) && header.magic == CISO_MAGIC) - return std::unique_ptr(new CISOFileReader(f.ReleaseHandle())); + if (file.Seek(0, SEEK_SET) && file.ReadArray(&header, 1) && header.magic == CISO_MAGIC) + return std::unique_ptr(new CISOFileReader(std::move(file))); return nullptr; } diff --git a/Source/Core/DiscIO/CISOBlob.h b/Source/Core/DiscIO/CISOBlob.h index 33791bab18..b8c0ebd816 100644 --- a/Source/Core/DiscIO/CISOBlob.h +++ b/Source/Core/DiscIO/CISOBlob.h @@ -34,7 +34,7 @@ struct CISOHeader class CISOFileReader : public IBlobReader { public: - static std::unique_ptr Create(const std::string& filename); + static std::unique_ptr Create(File::IOFile file); BlobType GetBlobType() const override { return BlobType::CISO; } // The CISO format does not save the original file size. @@ -45,7 +45,7 @@ public: bool Read(u64 offset, u64 nbytes, u8* out_ptr) override; private: - CISOFileReader(std::FILE* file); + CISOFileReader(File::IOFile file); typedef u16 MapType; static const MapType UNUSED_BLOCK_ID = -1; diff --git a/Source/Core/DiscIO/CompressedBlob.cpp b/Source/Core/DiscIO/CompressedBlob.cpp index 4a749a7ebe..0cf8dbc5b3 100644 --- a/Source/Core/DiscIO/CompressedBlob.cpp +++ b/Source/Core/DiscIO/CompressedBlob.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -28,12 +29,13 @@ namespace DiscIO { -bool IsGCZBlob(const std::string& filename); +bool IsGCZBlob(File::IOFile& file); -CompressedBlobReader::CompressedBlobReader(const std::string& filename) : m_file_name(filename) +CompressedBlobReader::CompressedBlobReader(File::IOFile file, const std::string& filename) + : m_file(std::move(file)), m_file_name(filename) { - m_file.Open(filename, "rb"); - m_file_size = File::GetSize(filename); + m_file_size = m_file.GetSize(); + m_file.Seek(0, SEEK_SET); m_file.ReadArray(&m_header, 1); SetSectorSize(m_header.block_size); @@ -55,10 +57,12 @@ CompressedBlobReader::CompressedBlobReader(const std::string& filename) : m_file m_zlib_buffer.resize(zlib_buffer_size); } -std::unique_ptr CompressedBlobReader::Create(const std::string& filename) +std::unique_ptr CompressedBlobReader::Create(File::IOFile file, + const std::string& filename) { - if (IsGCZBlob(filename)) - return std::unique_ptr(new CompressedBlobReader(filename)); + if (IsGCZBlob(file)) + return std::unique_ptr( + new CompressedBlobReader(std::move(file), filename)); return nullptr; } @@ -147,40 +151,41 @@ bool CompressedBlobReader::GetBlock(u64 block_num, u8* out_ptr) return true; } -bool CompressFileToBlob(const std::string& infile, const std::string& outfile, u32 sub_type, - int block_size, CompressCB callback, void* arg) +bool CompressFileToBlob(const std::string& infile_path, const std::string& outfile_path, + u32 sub_type, int block_size, CompressCB callback, void* arg) { bool scrubbing = false; + File::IOFile infile(infile_path, "rb"); if (IsGCZBlob(infile)) { - PanicAlertT("\"%s\" is already compressed! Cannot compress it further.", infile.c_str()); + PanicAlertT("\"%s\" is already compressed! Cannot compress it further.", infile_path.c_str()); return false; } - File::IOFile inf(infile, "rb"); - if (!inf) + if (!infile) { - PanicAlertT("Failed to open the input file \"%s\".", infile.c_str()); + PanicAlertT("Failed to open the input file \"%s\".", infile_path.c_str()); return false; } - File::IOFile f(outfile, "wb"); - if (!f) + File::IOFile outfile(outfile_path, "wb"); + if (!outfile) { PanicAlertT("Failed to open the output file \"%s\".\n" "Check that you have permissions to write the target folder and that the media can " "be written.", - outfile.c_str()); + outfile_path.c_str()); return false; } DiscScrubber disc_scrubber; if (sub_type == 1) { - if (!disc_scrubber.SetupScrub(infile, block_size)) + if (!disc_scrubber.SetupScrub(infile_path, block_size)) { - PanicAlertT("\"%s\" failed to be scrubbed. Probably the image is corrupt.", infile.c_str()); + PanicAlertT("\"%s\" failed to be scrubbed. Probably the image is corrupt.", + infile_path.c_str()); return false; } @@ -197,7 +202,7 @@ bool CompressFileToBlob(const std::string& infile, const std::string& outfile, u header.magic_cookie = GCZ_MAGIC; header.sub_type = sub_type; header.block_size = block_size; - header.data_size = File::GetSize(infile); + header.data_size = infile.GetSize(); // round upwards! header.num_blocks = (u32)((header.data_size + (block_size - 1)) / block_size); @@ -208,9 +213,9 @@ bool CompressFileToBlob(const std::string& infile, const std::string& outfile, u std::vector in_buf(block_size); // seek past the header (we will write it at the end) - f.Seek(sizeof(CompressedBlobHeader), SEEK_CUR); + outfile.Seek(sizeof(CompressedBlobHeader), SEEK_CUR); // seek past the offset and hash tables (we will write them at the end) - f.Seek((sizeof(u64) + sizeof(u32)) * header.num_blocks, SEEK_CUR); + outfile.Seek((sizeof(u64) + sizeof(u32)) * header.num_blocks, SEEK_CUR); // Now we are ready to write compressed data! u64 position = 0; @@ -223,7 +228,7 @@ bool CompressFileToBlob(const std::string& infile, const std::string& outfile, u { if (i % progress_monitor == 0) { - const u64 inpos = inf.Tell(); + const u64 inpos = infile.Tell(); int ratio = 0; if (inpos != 0) ratio = (int)(100 * position / inpos); @@ -243,9 +248,9 @@ bool CompressFileToBlob(const std::string& infile, const std::string& outfile, u size_t read_bytes; if (scrubbing) - read_bytes = disc_scrubber.GetNextBlock(inf, in_buf.data()); + read_bytes = disc_scrubber.GetNextBlock(infile, in_buf.data()); else - inf.ReadArray(in_buf.data(), header.block_size, &read_bytes); + infile.ReadArray(in_buf.data(), header.block_size, &read_bytes); if (read_bytes < header.block_size) std::fill(in_buf.begin() + read_bytes, in_buf.begin() + header.block_size, 0); @@ -285,11 +290,11 @@ bool CompressFileToBlob(const std::string& infile, const std::string& outfile, u num_compressed++; } - if (!f.WriteBytes(write_buf, write_size)) + if (!outfile.WriteBytes(write_buf, write_size)) { PanicAlertT("Failed to write the output file \"%s\".\n" "Check that you have enough space available on the target drive.", - outfile.c_str()); + outfile_path.c_str()); success = false; break; } @@ -304,16 +309,16 @@ bool CompressFileToBlob(const std::string& infile, const std::string& outfile, u if (!success) { // Remove the incomplete output file. - f.Close(); - File::Delete(outfile); + outfile.Close(); + File::Delete(outfile_path); } else { // Okay, go back and fill in headers - f.Seek(0, SEEK_SET); - f.WriteArray(&header, 1); - f.WriteArray(offsets.data(), header.num_blocks); - f.WriteArray(hashes.data(), header.num_blocks); + outfile.Seek(0, SEEK_SET); + outfile.WriteArray(&header, 1); + outfile.WriteArray(offsets.data(), header.num_blocks); + outfile.WriteArray(hashes.data(), header.num_blocks); } // Cleanup @@ -326,29 +331,34 @@ bool CompressFileToBlob(const std::string& infile, const std::string& outfile, u return success; } -bool DecompressBlobToFile(const std::string& infile, const std::string& outfile, +bool DecompressBlobToFile(const std::string& infile_path, const std::string& outfile_path, CompressCB callback, void* arg) { - if (!IsGCZBlob(infile)) + std::unique_ptr reader; { - PanicAlertT("File not compressed"); - return false; + File::IOFile infile(infile_path, "rb"); + if (!IsGCZBlob(infile)) + { + PanicAlertT("File not compressed"); + return false; + } + + reader = CompressedBlobReader::Create(std::move(infile), infile_path); } - std::unique_ptr reader(CompressedBlobReader::Create(infile)); if (!reader) { - PanicAlertT("Failed to open the input file \"%s\".", infile.c_str()); + PanicAlertT("Failed to open the input file \"%s\".", infile_path.c_str()); return false; } - File::IOFile f(outfile, "wb"); - if (!f) + File::IOFile outfile(outfile_path, "wb"); + if (!outfile) { PanicAlertT("Failed to open the output file \"%s\".\n" "Check that you have permissions to write the target folder and that the media can " "be written.", - outfile.c_str()); + outfile_path.c_str()); return false; } @@ -374,11 +384,11 @@ bool DecompressBlobToFile(const std::string& infile, const std::string& outfile, } const size_t sz = i == num_buffers - 1 ? last_buffer_size : buffer_size; reader->Read(i * buffer_size, sz, buffer.data()); - if (!f.WriteBytes(buffer.data(), sz)) + if (!outfile.WriteBytes(buffer.data(), sz)) { PanicAlertT("Failed to write the output file \"%s\".\n" "Check that you have enough space available on the target drive.", - outfile.c_str()); + outfile_path.c_str()); success = false; break; } @@ -387,23 +397,21 @@ bool DecompressBlobToFile(const std::string& infile, const std::string& outfile, if (!success) { // Remove the incomplete output file. - f.Close(); - File::Delete(outfile); + outfile.Close(); + File::Delete(outfile_path); } else { - f.Resize(header.data_size); + outfile.Resize(header.data_size); } return true; } -bool IsGCZBlob(const std::string& filename) +bool IsGCZBlob(File::IOFile& file) { - File::IOFile f(filename, "rb"); - CompressedBlobHeader header; - return f.ReadArray(&header, 1) && (header.magic_cookie == GCZ_MAGIC); + return file.Seek(0, SEEK_SET) && file.ReadArray(&header, 1) && header.magic_cookie == GCZ_MAGIC; } } // namespace diff --git a/Source/Core/DiscIO/CompressedBlob.h b/Source/Core/DiscIO/CompressedBlob.h index 7769a9d8cd..281db6c64a 100644 --- a/Source/Core/DiscIO/CompressedBlob.h +++ b/Source/Core/DiscIO/CompressedBlob.h @@ -44,7 +44,8 @@ struct CompressedBlobHeader // 32 bytes class CompressedBlobReader : public SectorReader { public: - static std::unique_ptr Create(const std::string& filename); + static std::unique_ptr Create(File::IOFile file, + const std::string& filename); ~CompressedBlobReader(); const CompressedBlobHeader& GetHeader() const { return m_header; } BlobType GetBlobType() const override { return BlobType::GCZ; } @@ -54,7 +55,7 @@ public: bool GetBlock(u64 block_num, u8* out_ptr) override; private: - CompressedBlobReader(const std::string& filename); + CompressedBlobReader(File::IOFile file, const std::string& filename); CompressedBlobHeader m_header; std::vector m_block_pointers; diff --git a/Source/Core/DiscIO/FileBlob.cpp b/Source/Core/DiscIO/FileBlob.cpp index 7d1dabe198..3547ef658d 100644 --- a/Source/Core/DiscIO/FileBlob.cpp +++ b/Source/Core/DiscIO/FileBlob.cpp @@ -2,22 +2,23 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. -#include "DiscIO/FileBlob.h" #include #include +#include + +#include "DiscIO/FileBlob.h" namespace DiscIO { -PlainFileReader::PlainFileReader(std::FILE* file) : m_file(file) +PlainFileReader::PlainFileReader(File::IOFile file) : m_file(std::move(file)) { m_size = m_file.GetSize(); } -std::unique_ptr PlainFileReader::Create(const std::string& filename) +std::unique_ptr PlainFileReader::Create(File::IOFile file) { - File::IOFile f(filename, "rb"); - if (f) - return std::unique_ptr(new PlainFileReader(f.ReleaseHandle())); + if (file) + return std::unique_ptr(new PlainFileReader(std::move(file))); return nullptr; } diff --git a/Source/Core/DiscIO/FileBlob.h b/Source/Core/DiscIO/FileBlob.h index 3a85799651..22cd614ec6 100644 --- a/Source/Core/DiscIO/FileBlob.h +++ b/Source/Core/DiscIO/FileBlob.h @@ -17,7 +17,7 @@ namespace DiscIO class PlainFileReader : public IBlobReader { public: - static std::unique_ptr Create(const std::string& filename); + static std::unique_ptr Create(File::IOFile file); BlobType GetBlobType() const override { return BlobType::PLAIN; } u64 GetDataSize() const override { return m_size; } @@ -25,7 +25,7 @@ public: bool Read(u64 offset, u64 nbytes, u8* out_ptr) override; private: - PlainFileReader(std::FILE* file); + PlainFileReader(File::IOFile file); File::IOFile m_file; s64 m_size; diff --git a/Source/Core/DiscIO/TGCBlob.cpp b/Source/Core/DiscIO/TGCBlob.cpp index 04ef3a1a9d..886bbb6a78 100644 --- a/Source/Core/DiscIO/TGCBlob.cpp +++ b/Source/Core/DiscIO/TGCBlob.cpp @@ -4,6 +4,7 @@ #include #include +#include #include "Common/CommonFuncs.h" #include "Common/FileUtil.h" @@ -56,18 +57,18 @@ void Replace32(u64 offset, u64 nbytes, u8* out_ptr, u64 replace_offset, u32 repl namespace DiscIO { -std::unique_ptr TGCFileReader::Create(const std::string& path) +std::unique_ptr TGCFileReader::Create(File::IOFile file) { - File::IOFile file(path, "rb"); TGCHeader header; - if (file.ReadArray(&header, 1) && header.magic == TGC_MAGIC) + if (file.Seek(0, SEEK_SET) && file.ReadArray(&header, 1) && header.magic == TGC_MAGIC) return std::unique_ptr(new TGCFileReader(std::move(file))); return nullptr; } -TGCFileReader::TGCFileReader(File::IOFile&& file) : m_file(std::move(file)) +TGCFileReader::TGCFileReader(File::IOFile file) : m_file(std::move(file)) { + m_file.Seek(0, SEEK_SET); m_file.ReadArray(&m_header, 1); u32 header_size = Common::swap32(m_header.header_size); m_size = m_file.GetSize(); diff --git a/Source/Core/DiscIO/TGCBlob.h b/Source/Core/DiscIO/TGCBlob.h index 62fd0cd759..86c0a85033 100644 --- a/Source/Core/DiscIO/TGCBlob.h +++ b/Source/Core/DiscIO/TGCBlob.h @@ -40,7 +40,7 @@ struct TGCHeader class TGCFileReader final : public IBlobReader { public: - static std::unique_ptr Create(const std::string& filename); + static std::unique_ptr Create(File::IOFile file); BlobType GetBlobType() const override { return BlobType::TGC; } u64 GetDataSize() const override; @@ -48,7 +48,7 @@ public: bool Read(u64 offset, u64 nbytes, u8* out_ptr) override; private: - TGCFileReader(File::IOFile&& file); + TGCFileReader(File::IOFile file); bool InternalRead(u64 offset, u64 nbytes, u8* out_ptr);