CDVD: Remove wx from file access

This commit is contained in:
Connor McLaughlin 2021-10-09 17:27:46 +10:00 committed by refractionpcsx2
parent 16af078b3b
commit 8d44e1af0e
28 changed files with 369 additions and 351 deletions

View File

@ -24,21 +24,22 @@
# include <aio.h>
#endif
#include <memory>
#include <string>
class AsyncFileReader
{
protected:
AsyncFileReader() : m_dataoffset(0), m_blocksize(0) {}
wxString m_filename;
std::string m_filename;
int m_dataoffset;
uint m_blocksize;
public:
virtual ~AsyncFileReader(void) {};
virtual ~AsyncFileReader() {};
virtual bool Open(const wxString& fileName)=0;
virtual bool Open(std::string fileName)=0;
virtual int ReadSync(void* pBuffer, uint sector, uint count)=0;
@ -55,7 +56,7 @@ public:
uint GetBlockSize() const { return m_blocksize; }
const wxString& GetFilename() const
const std::string& GetFilename() const
{
return m_filename;
}
@ -86,22 +87,22 @@ class FlatFileReader : public AsyncFileReader
public:
FlatFileReader(bool shareWrite = false);
virtual ~FlatFileReader(void);
virtual ~FlatFileReader() override;
virtual bool Open(const wxString& fileName);
virtual bool Open(std::string fileName) override;
virtual int ReadSync(void* pBuffer, uint sector, uint count);
virtual int ReadSync(void* pBuffer, uint sector, uint count) override;
virtual void BeginRead(void* pBuffer, uint sector, uint count);
virtual int FinishRead(void);
virtual void CancelRead(void);
virtual void BeginRead(void* pBuffer, uint sector, uint count) override;
virtual int FinishRead(void) override;
virtual void CancelRead(void) override;
virtual void Close(void);
virtual void Close(void) override;
virtual uint GetBlockCount(void) const;
virtual uint GetBlockCount(void) const override;
virtual void SetBlockSize(uint bytes) { m_blocksize = bytes; }
virtual void SetDataOffset(int bytes) { m_dataoffset = bytes; }
virtual void SetBlockSize(uint bytes) override { m_blocksize = bytes; }
virtual void SetDataOffset(int bytes) override { m_dataoffset = bytes; }
};
class MultipartFileReader : public AsyncFileReader
@ -123,21 +124,21 @@ class MultipartFileReader : public AsyncFileReader
public:
MultipartFileReader(AsyncFileReader* firstPart);
virtual ~MultipartFileReader(void);
virtual ~MultipartFileReader() override;
virtual bool Open(const wxString& fileName);
virtual bool Open(std::string fileName) override;
virtual int ReadSync(void* pBuffer, uint sector, uint count);
virtual int ReadSync(void* pBuffer, uint sector, uint count) override;
virtual void BeginRead(void* pBuffer, uint sector, uint count);
virtual int FinishRead(void);
virtual void CancelRead(void);
virtual void BeginRead(void* pBuffer, uint sector, uint count) override;
virtual int FinishRead(void) override;
virtual void CancelRead(void) override;
virtual void Close(void);
virtual void Close(void) override;
virtual uint GetBlockCount(void) const;
virtual uint GetBlockCount(void) const override;
virtual void SetBlockSize(uint bytes);
virtual void SetBlockSize(uint bytes) override;
static AsyncFileReader* DetectMultipart(AsyncFileReader* reader);
};
@ -146,7 +147,7 @@ class BlockdumpFileReader : public AsyncFileReader
{
DeclareNoncopyableObject( BlockdumpFileReader );
wxFileInputStream* m_file;
std::FILE* m_file;
// total number of blocks in the ISO image (including all parts)
u32 m_blocks;
@ -159,20 +160,20 @@ class BlockdumpFileReader : public AsyncFileReader
int m_lresult;
public:
BlockdumpFileReader(void);
virtual ~BlockdumpFileReader(void);
BlockdumpFileReader();
virtual ~BlockdumpFileReader() override;
virtual bool Open(const wxString& fileName);
virtual bool Open(std::string fileName) override;
virtual int ReadSync(void* pBuffer, uint sector, uint count);
virtual int ReadSync(void* pBuffer, uint sector, uint count) override;
virtual void BeginRead(void* pBuffer, uint sector, uint count);
virtual int FinishRead(void);
virtual void CancelRead(void);
virtual void BeginRead(void* pBuffer, uint sector, uint count) override;
virtual int FinishRead(void) override;
virtual void CancelRead(void) override;
virtual void Close(void);
virtual void Close(void) override;
virtual uint GetBlockCount(void) const;
virtual uint GetBlockCount(void) const override;
static bool DetectBlockdump(AsyncFileReader* reader);

View File

@ -17,6 +17,7 @@
#include "AsyncFileReader.h"
#include "IopCommon.h"
#include "IsoFileFormats.h"
#include "common/FileSystem.h"
#include <errno.h>
@ -59,48 +60,45 @@ BlockdumpFileReader::~BlockdumpFileReader(void)
Close();
}
bool BlockdumpFileReader::Open(const wxString& fileName)
bool BlockdumpFileReader::Open(std::string fileName)
{
char buf[32];
char signature[4];
m_filename = fileName;
m_file = new wxFileInputStream(m_filename);
m_file->SeekI(0);
m_file->Read(buf, 4);
if (strncmp(buf, "BDV2", 4) != 0)
m_filename = std::move(fileName);
m_file = FileSystem::OpenCFile(m_filename.c_str(), "rb");
if (!m_file || std::fread(signature, sizeof(signature), 1, m_file) != 1 || std::memcmp(signature, "BDV2", sizeof(signature)) != 0)
{
return false;
}
//m_flags = ISOFLAGS_BLOCKDUMP_V2;
m_file->Read(&m_blocksize, sizeof(m_blocksize));
m_file->Read(&m_blocks, sizeof(m_blocks));
m_file->Read(&m_blockofs, sizeof(m_blockofs));
if (std::fread(&m_blocksize, sizeof(m_blocksize), 1, m_file) != 1 ||
std::fread(&m_blocks, sizeof(m_blocks), 1, m_file) != 1 ||
std::fread(&m_blockofs, sizeof(m_blockofs), 1, m_file) != 1)
{
return false;
}
wxFileOffset flen = m_file->GetLength();
static const wxFileOffset datalen = flen - BlockDumpHeaderSize;
const s64 flen = FileSystem::FSize64(m_file);
const s64 datalen = flen - BlockDumpHeaderSize;
pxAssert((datalen % (m_blocksize + 4)) == 0);
m_dtablesize = datalen / (m_blocksize + 4);
m_dtable = std::unique_ptr<u32[]>(new u32[m_dtablesize]);
m_dtable = std::make_unique<u32[]>(m_dtablesize);
m_file->SeekI(BlockDumpHeaderSize);
if (FileSystem::FSeek64(m_file, BlockDumpHeaderSize, SEEK_SET) != 0)
return false;
u32 bs = 1024 * 1024;
u32 off = 0;
u32 has = 0;
int i = 0;
std::unique_ptr<u8[]> buffer(new u8[bs]);
std::unique_ptr<u8[]> buffer = std::make_unique<u8[]>(bs);
do
{
m_file->Read(buffer.get(), bs);
has = m_file->LastRead();
has = static_cast<u32>(std::fread(buffer.get(), 1, bs, m_file));
while (i < m_dtablesize && off < has)
{
m_dtable[i++] = *reinterpret_cast<u32*>(buffer.get() + off);
@ -132,15 +130,17 @@ int BlockdumpFileReader::ReadSync(void* pBuffer, uint lsn, uint count)
// seek position ends up being based on (m_blocksize + 4) instead of just m_blocksize.
#ifdef PCSX2_DEBUG
u32 check_lsn;
m_file->SeekI(BlockDumpHeaderSize + (i * (m_blocksize + 4)));
m_file->Read(&check_lsn, sizeof(check_lsn));
u32 check_lsn = 0;
FileSystem::FSeek64(m_file, BlockDumpHeaderSize + (i * (m_blocksize + 4)), SEEK_SET);
std::fread(&check_lsn, sizeof(check_lsn), 1, m_file);
pxAssert(check_lsn == lsn);
#else
m_file->SeekI(BlockDumpHeaderSize + (i * (m_blocksize + 4)) + 4);
if (FileSystem::FSeek64(m_file, BlockDumpHeaderSize + (i * (m_blocksize + 4)) + 4, SEEK_SET) != 0)
break;
#endif
m_file->Read(dst, m_blocksize);
if (std::fread(dst, m_blocksize, 1, m_file) != 1)
break;
ok = true;
break;
@ -178,7 +178,7 @@ void BlockdumpFileReader::Close(void)
{
if (m_file)
{
delete m_file;
std::fclose(m_file);
m_file = NULL;
}
}

View File

@ -151,7 +151,7 @@ NVMLayout* getNvmLayout()
static void cdvdCreateNewNVM(std::FILE* fp)
{
u8 zero[1024] = { 0 };
u8 zero[1024] = {};
std::fwrite(zero, sizeof(zero), 1, fp);
// Write NVM ILink area with dummy data (Age of Empires 2)
@ -195,10 +195,9 @@ static void cdvdNVM(u8* buffer, int offset, size_t bytes, bool read)
u8 zero[16] = {0};
NVMLayout* nvmLayout = getNvmLayout();
std::fseek(fp.get(), *(s32*)(((u8*)nvmLayout) + offsetof(NVMLayout, config1)) + 0x10, SEEK_SET);
std::fread(LanguageParams, 16, 1, fp.get());
if (memcmp(LanguageParams, zero, sizeof(LanguageParams)) == 0)
if (std::fseek(fp.get(), *(s32*)(((u8*)nvmLayout) + offsetof(NVMLayout, config1)) + 0x10, SEEK_SET) != 0 ||
std::fread(LanguageParams, 16, 1, fp.get()) != 1 ||
std::memcmp(LanguageParams, zero, sizeof(LanguageParams)) == 0)
{
Console.Warning("Language Parameters missing, filling in defaults");

View File

@ -33,6 +33,7 @@
#include "IsoFS/IsoFSCDVD.h"
#include "CDVDisoReader.h"
#include "common/FileSystem.h"
#include "common/StringUtil.h"
#include "DebugTools/SymbolMap.h"
#include "Config.h"
@ -376,33 +377,33 @@ bool DoCDVDopen()
return true;
}
wxString somepick(Path::GetFilenameWithoutExt(fromUTF8(m_SourceFilename[CurrentSourceType])));
std::string somepick(FileSystem::StripExtension(FileSystem::GetDisplayNameFromPath(m_SourceFilename[CurrentSourceType])));
//FWIW Disc serial availability doesn't seem reliable enough, sometimes it's there and sometime it's just null
//Shouldn't the serial be available all time? Potentially need to look into Elfreloadinfo() reliability
//TODO: Add extra fallback case for CRC.
if (somepick.IsEmpty() && !DiscSerial.IsEmpty())
somepick = L"Untitled-" + DiscSerial;
else if (somepick.IsEmpty())
somepick = L"Untitled";
if (somepick.empty() && !DiscSerial.IsEmpty())
somepick = StringUtil::StdStringFromFormat("Untitled-%s", DiscSerial.ToUTF8().data());
else if (somepick.empty())
somepick = "Untitled";
if (EmuConfig.CurrentBlockdump.empty())
EmuConfig.CurrentBlockdump = StringUtil::wxStringToUTF8String(wxGetCwd());
EmuConfig.CurrentBlockdump = FileSystem::GetWorkingDirectory();
wxString temp(Path::Combine(StringUtil::UTF8StringToWxString(EmuConfig.CurrentBlockdump), somepick));
std::string temp(Path::CombineStdString(EmuConfig.CurrentBlockdump, somepick));
#ifdef ENABLE_TIMESTAMPS
wxDateTime curtime(wxDateTime::GetTimeNow());
temp += pxsFmt(L" (%04d-%02d-%02d %02d-%02d-%02d)",
curtime.GetYear(), curtime.GetMonth(), curtime.GetDay(),
curtime.GetHour(), curtime.GetMinute(), curtime.GetSecond());
temp += StringUtil::StdStringFromFormat(" (%04d-%02d-%02d %02d-%02d-%02d)",
curtime.GetYear(), curtime.GetMonth(), curtime.GetDay(),
curtime.GetHour(), curtime.GetMinute(), curtime.GetSecond());
#endif
temp += L".dump";
temp += ".dump";
cdvdTD td;
CDVD->getTD(0, &td);
blockDumpFile.Create(temp, 2);
blockDumpFile.Create(std::move(temp), 2);
if (blockDumpFile.IsOpened())
{
@ -432,7 +433,12 @@ bool DoCDVDopen()
void DoCDVDclose()
{
CheckNullCDVD();
//blockDumpFile.Close();
#ifdef PCSX2_CORE
// This was commented out, presumably because pausing/resuming in wx reopens CDVD.
// This is a non-issue in Qt, so we'll leave it behind the ifdef.
blockDumpFile.Close();
#endif
if (CDVD->close != NULL)
CDVD->close();

View File

@ -52,7 +52,7 @@ s32 CALLBACK ISOopen(const char* pTitle)
try
{
iso.Open(fromUTF8(pTitle));
iso.Open(pTitle);
}
catch (BaseException& ex)
{

View File

@ -16,71 +16,98 @@
#include "PrecompiledHeader.h"
#include "ChdFileReader.h"
#include "CDVD/CompressedFileReaderUtils.h"
#include "common/FileSystem.h"
#include "common/StringUtil.h"
#include <wx/dir.h>
bool ChdFileReader::CanHandle(const wxString& fileName)
ChdFileReader::~ChdFileReader()
{
if (!wxFileName::FileExists(fileName) || !fileName.Lower().EndsWith(L".chd"))
{
Close();
for (std::FILE* fp : m_files)
std::fclose(fp);
}
bool ChdFileReader::CanHandle(const std::string& fileName, const std::string& displayName)
{
if (!StringUtil::EndsWith(displayName, ".chd"))
return false;
}
return true;
}
bool ChdFileReader::Open2(const wxString& fileName)
static chd_error chd_open_wrapper(const char* filename, std::FILE** fp, int mode, chd_file* parent, chd_file** chd)
{
*fp = FileSystem::OpenCFile(filename, "rb");
if (!*fp)
return CHDERR_FILE_NOT_FOUND;
const chd_error err = chd_open_file(*fp, mode, parent, chd);
if (err == CHDERR_NONE)
return err;
std::fclose(*fp);
*fp = nullptr;
return err;
}
bool ChdFileReader::Open2(std::string fileName)
{
Close2();
m_filename = fileName;
m_filename = std::move(fileName);
chd_file* child = NULL;
chd_file* parent = NULL;
chd_file* child = nullptr;
chd_file* parent = nullptr;
std::FILE* fp = nullptr;
chd_header header;
chd_header parent_header;
wxString chds[8];
chds[0] = fileName;
std::string chds[8];
chds[0] = m_filename;
int chd_depth = 0;
chd_error error;
// TODO: Unicode correctness on Windows
while (CHDERR_REQUIRES_PARENT == (error = chd_open(chds[chd_depth].c_str(), CHD_OPEN_READ, NULL, &child)))
std::string dirname;
FileSystem::FindResultsArray results;
while (CHDERR_REQUIRES_PARENT == (error = chd_open_wrapper(chds[chd_depth].c_str(), &fp, CHD_OPEN_READ, NULL, &child)))
{
if (chd_depth >= static_cast<int>(std::size(chds) - 1))
{
Console.Error(L"CDVD: chd_open hit recursion limit searching for parents");
Console.Error("CDVD: chd_open hit recursion limit searching for parents");
return false;
}
// TODO: This is still broken on Windows. Needs to be fixed in libchdr.
if (chd_read_header(chds[chd_depth].c_str(), &header) != CHDERR_NONE)
{
Console.Error(L"CDVD: chd_open chd_read_header error: %s: %s", chd_error_string(error), WX_STR(chds[chd_depth]));
Console.Error("CDVD: chd_open chd_read_header error: %s: %s", chd_error_string(error), chds[chd_depth].c_str());
return false;
}
bool found_parent = false;
wxFileName wxfilename(chds[chd_depth]);
wxString dir_path = wxfilename.GetPath();
wxDir dir(dir_path);
if (dir.IsOpened())
dirname = FileSystem::GetPathDirectory(chds[chd_depth]);
if (FileSystem::FindFiles(dirname.c_str(), "*.*", FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES, &results))
{
wxString parent_fileName;
bool cont = dir.GetFirst(&parent_fileName, wxString("*.") + wxfilename.GetExt(), wxDIR_FILES | wxDIR_HIDDEN);
for (; cont; cont = dir.GetNext(&parent_fileName))
for (const FILESYSTEM_FIND_DATA& fd : results)
{
parent_fileName = wxFileName(dir_path, parent_fileName).GetFullPath();
if (chd_read_header(parent_fileName.c_str(), &parent_header) == CHDERR_NONE &&
const std::string_view extension(FileSystem::GetExtension(fd.FileName));
if (extension.empty() || StringUtil::Strncasecmp(extension.data(), "chd", 3) != 0)
continue;
if (chd_read_header(fd.FileName.c_str(), &parent_header) == CHDERR_NONE &&
memcmp(parent_header.sha1, header.parentsha1, sizeof(parent_header.sha1)) == 0)
{
found_parent = true;
chds[++chd_depth] = wxString(parent_fileName);
chds[++chd_depth] = std::move(fd.FileName);
break;
}
}
}
if (!found_parent)
{
Console.Error(L"CDVD: chd_open no parent for: %s", WX_STR(chds[chd_depth]));
Console.Error("CDVD: chd_open no parent for: %s", chds[chd_depth].c_str());
break;
}
}
@ -91,11 +118,17 @@ bool ChdFileReader::Open2(const wxString& fileName)
return false;
}
if (child)
{
pxAssert(fp != nullptr);
m_files.push_back(fp);
}
for (int d = chd_depth - 1; d >= 0; d--)
{
parent = child;
child = NULL;
error = chd_open(chds[d].c_str(), CHD_OPEN_READ, parent, &child);
error = chd_open_wrapper(chds[d].c_str(), &fp, CHD_OPEN_READ, parent, &child);
if (error != CHDERR_NONE)
{
Console.Error(L"CDVD: chd_open return error: %s", chd_error_string(error));
@ -103,19 +136,17 @@ bool ChdFileReader::Open2(const wxString& fileName)
chd_close(parent);
return false;
}
m_files.push_back(fp);
}
ChdFile = child;
if (chd_read_header(chds[0].c_str(), &header) != CHDERR_NONE)
{
Console.Error(L"CDVD: chd_open chd_read_header error: %s: %s", chd_error_string(error), WX_STR(chds[0]));
return false;
}
file_size = static_cast<u64>(header.unitbytes) * header.unitcount;
hunk_size = header.hunkbytes;
const chd_header* chd_header = chd_get_header(ChdFile);
file_size = static_cast<u64>(chd_header->unitbytes) * chd_header->unitcount;
hunk_size = chd_header->hunkbytes;
// CHD likes to use full 2448 byte blocks, but keeps the +24 offset of source ISOs
// The rest of PCSX2 likes to use 2448 byte buffers, which can't fit that so trim blocks instead
m_internalBlockSize = header.unitbytes;
m_internalBlockSize = chd_header->unitbytes;
return true;
}
@ -136,7 +167,7 @@ ThreadedFileReader::Chunk ChdFileReader::ChunkForOffset(u64 offset)
return chunk;
}
int ChdFileReader::ReadChunk(void *dst, s64 chunkID)
int ChdFileReader::ReadChunk(void* dst, s64 chunkID)
{
if (chunkID < 0)
return -1;

View File

@ -16,16 +16,17 @@
#pragma once
#include "ThreadedFileReader.h"
#include "libchdr/chd.h"
#include <vector>
class ChdFileReader : public ThreadedFileReader
{
DeclareNoncopyableObject(ChdFileReader);
public:
virtual ~ChdFileReader(void) { Close(); };
virtual ~ChdFileReader() override;;
static bool CanHandle(const wxString& fileName);
bool Open2(const wxString& fileName) override;
static bool CanHandle(const std::string& fileName, const std::string& displayName);
bool Open2(std::string fileName) override;
Chunk ChunkForOffset(u64 offset) override;
int ReadChunk(void *dst, s64 blockID) override;
@ -38,4 +39,5 @@ private:
chd_file* ChdFile;
u64 file_size;
u32 hunk_size;
std::vector<std::FILE*> m_files;
};

View File

@ -18,7 +18,7 @@
void ChunksCache::SetLimit(uint megabytes)
{
m_limit = (PX_off_t)megabytes * 1024 * 1024;
m_limit = (s64)megabytes * 1024 * 1024;
MatchLimit();
}
@ -34,7 +34,7 @@ void ChunksCache::MatchLimit(bool removeAll)
}
}
void ChunksCache::Take(void* pMallocedSrc, PX_off_t offset, int length, int coverage)
void ChunksCache::Take(void* pMallocedSrc, s64 offset, int length, int coverage)
{
m_entries.push_front(new CacheEntry(pMallocedSrc, offset, length, coverage));
m_size += length;
@ -42,7 +42,7 @@ void ChunksCache::Take(void* pMallocedSrc, PX_off_t offset, int length, int cove
}
// By design, succeed only if the entire request is in a single cached chunk
int ChunksCache::Read(void* pDest, PX_off_t offset, int length)
int ChunksCache::Read(void* pDest, s64 offset, int length)
{
for (auto it = m_entries.begin(); it != m_entries.end(); it++)
{

View File

@ -30,11 +30,11 @@ public:
void SetLimit(uint megabytes);
void Clear() { MatchLimit(true); };
void Take(void* pMallocedSrc, PX_off_t offset, int length, int coverage);
int Read(void* pDest, PX_off_t offset, int length);
void Take(void* pMallocedSrc, s64 offset, int length, int coverage);
int Read(void* pDest, s64 offset, int length);
static int CopyAvailable(void* pSrc, PX_off_t srcOffset, int srcSize,
void* pDst, PX_off_t dstOffset, int maxCopySize)
static int CopyAvailable(void* pSrc, s64 srcOffset, int srcSize,
void* pDst, s64 dstOffset, int maxCopySize)
{
int available = CLAMP(maxCopySize, 0, (int)(srcOffset + srcSize - dstOffset));
memcpy(pDst, (char*)pSrc + (dstOffset - srcOffset), available);
@ -45,7 +45,7 @@ private:
class CacheEntry
{
public:
CacheEntry(void* pMallocedSrc, PX_off_t offset, int length, int coverage)
CacheEntry(void* pMallocedSrc, s64 offset, int length, int coverage)
: data(pMallocedSrc)
, offset(offset)
, coverage(coverage)
@ -58,15 +58,15 @@ private:
};
void* data;
PX_off_t offset;
s64 offset;
int coverage;
int size;
};
std::list<CacheEntry*> m_entries;
void MatchLimit(bool removeAll = false);
PX_off_t m_size;
PX_off_t m_limit;
s64 m_size;
s64 m_limit;
};
#undef CLAMP

View File

@ -19,19 +19,27 @@
#include "ChdFileReader.h"
#include "CsoFileReader.h"
#include "GzippedFileReader.h"
#include "common/FileSystem.h"
#include <cctype>
// CompressedFileReader factory.
AsyncFileReader* CompressedFileReader::GetNewReader(const wxString& fileName)
AsyncFileReader* CompressedFileReader::GetNewReader(const std::string& fileName)
{
if (ChdFileReader::CanHandle(fileName))
if (!FileSystem::FileExists(fileName.c_str()))
return nullptr;
std::string displayName(FileSystem::GetDisplayNameFromPath(fileName));
std::transform(displayName.begin(), displayName.end(), displayName.begin(), tolower);
if (ChdFileReader::CanHandle(fileName, displayName))
{
return new ChdFileReader();
}
if (GzippedFileReader::CanHandle(fileName))
if (GzippedFileReader::CanHandle(fileName, displayName))
{
return new GzippedFileReader();
}
if (CsoFileReader::CanHandle(fileName))
if (CsoFileReader::CanHandle(fileName, displayName))
{
return new CsoFileReader();
}

View File

@ -14,6 +14,7 @@
*/
#pragma once
#include <string>
// Factory - creates an AsyncFileReader derived instance which can read a compressed file
class CompressedFileReader
@ -23,7 +24,7 @@ public:
// If no matching handler is found, NULL is returned.
// The returned instance still needs ->Open(filename) before usage.
// Open(filename) may still fail.
static AsyncFileReader* GetNewReader(const wxString& fileName);
static AsyncFileReader* GetNewReader(const std::string& fileName);
private:
virtual ~CompressedFileReader() = 0;

View File

@ -1,44 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2014 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "common/Pcsx2Types.h"
/////////// Some complementary utilities for zlib_indexed.c //////////
// This is ugly, but it's hard to find something which will work/compile for both
// windows and *nix and work with non-english file names.
// Maybe some day we'll convert all file related ops to wxWidgets, which means also the
// instances at zlib_indexed.h (which use plain stdio FILE*)
#ifdef _WIN32
#define PX_wfilename(name_wxstr) (name_wxstr.wc_str())
#define PX_fopen_rb(name_wxstr) (_wfopen(PX_wfilename(name_wxstr), L"rb"))
#else
#define PX_wfilename(name_wxstr) (name_wxstr.mbc_str())
#define PX_fopen_rb(name_wxstr) (fopen(PX_wfilename(name_wxstr), "rb"))
#endif
#ifdef _WIN32
#define PX_fseeko _fseeki64
#define PX_ftello _ftelli64
#define PX_off_t s64 /* __int64 */
#else
#define PX_fseeko fseeko
#define PX_ftello ftello
#define PX_off_t off_t
#endif
/////////// End of complementary utilities for zlib_indexed.c //////////

View File

@ -15,9 +15,10 @@
#include "PrecompiledHeader.h"
#include "AsyncFileReader.h"
#include "CompressedFileReaderUtils.h"
#include "CsoFileReader.h"
#include "common/Pcsx2Types.h"
#include "common/FileSystem.h"
#include "common/StringUtil.h"
#ifdef __POSIX__
#include <zlib.h>
#else
@ -39,12 +40,12 @@ struct CsoHeader
static const u32 CSO_READ_BUFFER_SIZE = 256 * 1024;
bool CsoFileReader::CanHandle(const wxString& fileName)
bool CsoFileReader::CanHandle(const std::string& fileName, const std::string& displayName)
{
bool supported = false;
if (wxFileName::FileExists(fileName) && fileName.Lower().EndsWith(L".cso"))
if (StringUtil::EndsWith(displayName, ".cso"))
{
FILE* fp = PX_fopen_rb(fileName);
FILE* fp = FileSystem::OpenCFile(fileName.c_str(), "rb");
CsoHeader hdr;
if (fp)
{
@ -67,17 +68,17 @@ bool CsoFileReader::ValidateHeader(const CsoHeader& hdr)
}
if (hdr.ver > 1)
{
Console.Error(L"Only CSOv1 files are supported.");
Console.Error("Only CSOv1 files are supported.");
return false;
}
if ((hdr.frame_size & (hdr.frame_size - 1)) != 0)
{
Console.Error(L"CSO frame size must be a power of two.");
Console.Error("CSO frame size must be a power of two.");
return false;
}
if (hdr.frame_size < 2048)
{
Console.Error(L"CSO frame size must be at least one sector.");
Console.Error("CSO frame size must be at least one sector.");
return false;
}
@ -85,11 +86,11 @@ bool CsoFileReader::ValidateHeader(const CsoHeader& hdr)
return true;
}
bool CsoFileReader::Open2(const wxString& fileName)
bool CsoFileReader::Open2(std::string fileName)
{
Close2();
m_filename = fileName;
m_src = PX_fopen_rb(m_filename);
m_filename = std::move(fileName);
m_src = FileSystem::OpenCFile(m_filename.c_str(), "rb");
bool success = false;
if (m_src && ReadFileHeader() && InitializeBuffers())
@ -109,16 +110,15 @@ bool CsoFileReader::ReadFileHeader()
{
CsoHeader hdr = {};
PX_fseeko(m_src, m_dataoffset, SEEK_SET);
if (fread(&hdr, 1, sizeof(hdr), m_src) != sizeof(hdr))
if (FileSystem::FSeek64(m_src, m_dataoffset, SEEK_SET) != 0 || std::fread(&hdr, 1, sizeof(hdr), m_src) != sizeof(hdr))
{
Console.Error(L"Failed to read CSO file header.");
Console.Error("Failed to read CSO file header.");
return false;
}
if (!ValidateHeader(hdr))
{
Console.Error(L"CSO has invalid header.");
Console.Error("CSO has invalid header.");
return false;
}
@ -156,7 +156,7 @@ bool CsoFileReader::InitializeBuffers()
m_index = new u32[indexSize];
if (fread(m_index, sizeof(u32), indexSize, m_src) != indexSize)
{
Console.Error(L"Unable to read index data from CSO.");
Console.Error("Unable to read index data from CSO.");
return false;
}
@ -175,7 +175,7 @@ bool CsoFileReader::InitializeBuffers()
void CsoFileReader::Close2()
{
m_filename.Empty();
m_filename.clear();
if (m_src)
{
@ -235,7 +235,7 @@ int CsoFileReader::ReadChunk(void *dst, s64 chunkID)
if (!compressed)
{
// Just read directly, easy.
if (PX_fseeko(m_src, frameRawPos, SEEK_SET) != 0)
if (FileSystem::FSeek64(m_src, frameRawPos, SEEK_SET) != 0)
{
Console.Error("Unable to seek to uncompressed CSO data.");
return 0;
@ -244,7 +244,7 @@ int CsoFileReader::ReadChunk(void *dst, s64 chunkID)
}
else
{
if (PX_fseeko(m_src, frameRawPos, SEEK_SET) != 0)
if (FileSystem::FSeek64(m_src, frameRawPos, SEEK_SET) != 0)
{
Console.Error("Unable to seek to compressed CSO data.");
return 0;

View File

@ -52,8 +52,8 @@ public:
~CsoFileReader(void) { Close(); };
static bool CanHandle(const wxString& fileName);
bool Open2(const wxString& fileName) override;
static bool CanHandle(const std::string& fileName, const std::string& displayName);
bool Open2(std::string fileName) override;
Chunk ChunkForOffset(u64 offset) override;
int ReadChunk(void *dst, s64 chunkID) override;

View File

@ -14,29 +14,17 @@
*/
#include "PrecompiledHeader.h"
#include <fstream>
#include <wx/stdpaths.h>
#include <fstream>
#include "common/FileSystem.h"
#include "common/StringUtil.h"
#include "Config.h"
#include "ChunksCache.h"
#include "CompressedFileReaderUtils.h"
#include "GzippedFileReader.h"
#include "zlib_indexed.h"
#define CLAMP(val, minval, maxval) (std::min(maxval, std::max(minval, val)))
static s64 fsize(const wxString& filename)
{
if (!wxFileName::FileExists(filename))
return -1;
std::ifstream f(PX_wfilename(filename), std::ifstream::binary);
f.seekg(0, f.end);
s64 size = f.tellg();
f.close();
return size;
}
#define GZIP_ID "PCSX2.index.gzip.v1|"
#define GZIP_ID_LEN (sizeof(GZIP_ID) - 1) /* sizeof includes the \0 terminator */
@ -44,71 +32,75 @@ static s64 fsize(const wxString& filename)
// - [GZIP_ID_LEN] GZIP_ID (no \0)
// - [sizeof(Access)] index (should be allocated, contains various sizes)
// - [rest] the indexed data points (should be allocated, index->list should then point to it)
static Access* ReadIndexFromFile(const wxString& filename)
static Access* ReadIndexFromFile(const char* filename)
{
s64 size = fsize(filename);
if (size <= 0)
auto fp = FileSystem::OpenManagedCFile(filename, "rb");
s64 size;
if (!fp || (size = FileSystem::FSize64(fp.get())) <= 0)
{
Console.Error(L"Error: Can't open index file: '%s'", WX_STR(filename));
Console.Error("Error: Can't open index file: '%s'", filename);
return 0;
}
std::ifstream infile(PX_wfilename(filename), std::ifstream::binary);
char fileId[GZIP_ID_LEN + 1] = {0};
infile.read(fileId, GZIP_ID_LEN);
if (wxString::From8BitData(GZIP_ID) != wxString::From8BitData(fileId))
if (std::fread(fileId, GZIP_ID_LEN, 1, fp.get()) != 1 || std::memcmp(fileId, GZIP_ID, 4) != 0)
{
Console.Error(L"Error: Incompatible gzip index, please delete it manually: '%s'", WX_STR(filename));
infile.close();
Console.Error("Error: Incompatible gzip index, please delete it manually: '%s'", filename);
return 0;
}
Access* index = (Access*)malloc(sizeof(Access));
infile.read((char*)index, sizeof(Access));
s64 datasize = size - GZIP_ID_LEN - sizeof(Access);
if (datasize != (s64)index->have * sizeof(Point))
Access* const index = (Access*)malloc(sizeof(Access));
const s64 datasize = size - GZIP_ID_LEN - sizeof(Access);
if (std::fread(index, sizeof(Access), 1, fp.get()) != 1 ||
datasize != static_cast<s64>(index->have) * static_cast<s64>(sizeof(Point)))
{
Console.Error(L"Error: unexpected size of gzip index, please delete it manually: '%s'.", WX_STR(filename));
infile.close();
Console.Error("Error: unexpected size of gzip index, please delete it manually: '%s'.", filename);
free(index);
return 0;
}
char* buffer = (char*)malloc(datasize);
infile.read(buffer, datasize);
infile.close();
if (std::fread(buffer, datasize, 1, fp.get()) != 1)
{
Console.Error("Error: failed read of gzip index, please delete it manually: '%s'.", filename);
free(buffer);
free(index);
return 0;
}
index->list = (Point*)buffer; // adjust list pointer
return index;
}
static void WriteIndexToFile(Access* index, const wxString filename)
static void WriteIndexToFile(Access* index, const char* filename)
{
if (wxFileName::FileExists(filename))
if (FileSystem::FileExists(filename))
{
Console.Warning(L"WARNING: Won't write index - file name exists (please delete it manually): '%s'", WX_STR(filename));
Console.Warning("WARNING: Won't write index - file name exists (please delete it manually): '%s'", filename);
return;
}
std::ofstream outfile(PX_wfilename(filename), std::ofstream::binary);
outfile.write(GZIP_ID, GZIP_ID_LEN);
auto fp = FileSystem::OpenManagedCFile(filename, "rb");
if (!fp)
return;
bool success = (std::fwrite(GZIP_ID, GZIP_ID_LEN, 1, fp.get()) == 1);
Point* tmp = index->list;
index->list = 0; // current pointer is useless on disk, normalize it as 0.
outfile.write((char*)index, sizeof(Access));
std::fwrite((char*)index, sizeof(Access), 1, fp.get());
index->list = tmp;
outfile.write((char*)index->list, sizeof(Point) * index->have);
outfile.close();
success = success && (std::fwrite((char*)index->list, sizeof(Point) * index->have, 1, fp.get()) == 1);
// Verify
if (fsize(filename) != (s64)GZIP_ID_LEN + sizeof(Access) + sizeof(Point) * index->have)
if (!success)
{
Console.Warning(L"Warning: Can't write index file to disk: '%s'", WX_STR(filename));
Console.Warning("Warning: Can't write index file to disk: '%s'", filename);
}
else
{
Console.WriteLn(Color_Green, L"OK: Gzip quick access index file saved to disk: '%s'", WX_STR(filename));
Console.WriteLn(Color_Green, "OK: Gzip quick access index file saved to disk: '%s'", filename);
}
}
@ -123,10 +115,10 @@ static wxString INDEX_TEMPLATE_KEY(L"$(f)");
// No checks are performed if the result file name can be created.
// If this proves useful, we can move it into Path:: . Right now there's no need.
static wxString ApplyTemplate(const wxString& name, const wxDirName& base,
const wxString& fileTemplate, const wxString& filename,
const std::string& fileTemplate, const std::string& filename,
bool canEndWithKey)
{
wxString tem(fileTemplate);
wxString tem(StringUtil::UTF8StringToWxString(fileTemplate));
wxString key = INDEX_TEMPLATE_KEY;
tem = tem.Trim(true).Trim(false); // both sides
@ -141,7 +133,7 @@ static wxString ApplyTemplate(const wxString& name, const wxDirName& base,
return L"";
}
wxString fname(filename);
wxString fname(StringUtil::UTF8StringToWxString(filename));
if (first > 0)
fname = Path::GetFilename(fname); // without path
@ -179,13 +171,13 @@ static void TestTemplate(const wxDirName &base, const wxString &fname, bool canE
}
*/
static wxString iso2indexname(const wxString& isoname)
static std::string iso2indexname(const std::string& isoname)
{
//testTemplate(isoname);
wxDirName appRoot = // TODO: have only one of this in PCSX2. Right now have few...
(wxDirName)(wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath());
//TestTemplate(appRoot, isoname, false);
return ApplyTemplate(L"gzip index", appRoot, fromUTF8(EmuConfig.GzipIsoIndexTemplate), isoname, false);
return StringUtil::wxStringToUTF8String(ApplyTemplate(L"gzip index", appRoot, EmuConfig.GzipIsoIndexTemplate, isoname, false));
}
GzippedFileReader::GzippedFileReader(void)
@ -218,7 +210,7 @@ void GzippedFileReader::InitZstates()
void GzippedFileReader::AsyncPrefetchReset(){};
void GzippedFileReader::AsyncPrefetchOpen(){};
void GzippedFileReader::AsyncPrefetchClose(){};
void GzippedFileReader::AsyncPrefetchChunk(PX_off_t dummy){};
void GzippedFileReader::AsyncPrefetchChunk(s64 dummy){};
void GzippedFileReader::AsyncPrefetchCancel(){};
#else
// AsyncPrefetch works as follows:
@ -239,7 +231,7 @@ void GzippedFileReader::AsyncPrefetchReset()
void GzippedFileReader::AsyncPrefetchOpen()
{
hOverlappedFile = CreateFile(
m_filename,
StringUtil::UTF8StringToWideString(m_filename).c_str(),
GENERIC_READ,
FILE_SHARE_READ,
NULL,
@ -258,7 +250,7 @@ void GzippedFileReader::AsyncPrefetchClose()
AsyncPrefetchReset();
};
void GzippedFileReader::AsyncPrefetchChunk(PX_off_t start)
void GzippedFileReader::AsyncPrefetchChunk(s64 start)
{
if (hOverlappedFile == INVALID_HANDLE_VALUE || asyncInProgress)
{
@ -296,9 +288,9 @@ void GzippedFileReader::AsyncPrefetchCancel()
#endif /* _WIN32 */
// TODO: do better than just checking existance and extension
bool GzippedFileReader::CanHandle(const wxString& fileName)
bool GzippedFileReader::CanHandle(const std::string& fileName, const std::string& displayName)
{
return wxFileName::FileExists(fileName) && fileName.Lower().EndsWith(L".gz");
return StringUtil::EndsWith(fileName, ".gz");
}
bool GzippedFileReader::OkIndex()
@ -307,29 +299,29 @@ bool GzippedFileReader::OkIndex()
return true;
// Try to read index from disk
wxString indexfile = iso2indexname(m_filename);
if (indexfile.length() == 0)
const std::string indexfile(iso2indexname(m_filename));
if (indexfile.empty() == 0)
return false; // iso2indexname(...) will print errors if it can't apply the template
if (wxFileName::FileExists(indexfile) && (m_pIndex = ReadIndexFromFile(indexfile)))
if (FileSystem::FileExists(indexfile.c_str()) && (m_pIndex = ReadIndexFromFile(indexfile.c_str())))
{
Console.WriteLn(Color_Green, L"OK: Gzip quick access index read from disk: '%s'", WX_STR(indexfile));
Console.WriteLn(Color_Green, "OK: Gzip quick access index read from disk: '%s'", indexfile.c_str());
if (m_pIndex->span != GZFILE_SPAN_DEFAULT)
{
Console.Warning(L"Note: This index has %1.1f MB intervals, while the current default for new indexes is %1.1f MB.",
Console.Warning("Note: This index has %1.1f MB intervals, while the current default for new indexes is %1.1f MB.",
(float)m_pIndex->span / 1024 / 1024, (float)GZFILE_SPAN_DEFAULT / 1024 / 1024);
Console.Warning(L"It will work fine, but if you want to generate a new index with default intervals, delete this index file.");
Console.Warning(L"(smaller intervals mean bigger index file and quicker but more frequent decompressions)");
Console.Warning("It will work fine, but if you want to generate a new index with default intervals, delete this index file.");
Console.Warning("(smaller intervals mean bigger index file and quicker but more frequent decompressions)");
}
InitZstates();
return true;
}
// No valid index file. Generate an index
Console.Warning(L"This may take a while (but only once). Scanning compressed file to generate a quick access index...");
Console.Warning("This may take a while (but only once). Scanning compressed file to generate a quick access index...");
Access* index;
FILE* infile = PX_fopen_rb(m_filename);
FILE* infile = FileSystem::OpenCFile(m_filename.c_str(), "rb");
int len = build_index(infile, GZFILE_SPAN_DEFAULT, &index);
printf("\n"); // build_index prints progress without \n's
fclose(infile);
@ -337,11 +329,11 @@ bool GzippedFileReader::OkIndex()
if (len >= 0)
{
m_pIndex = index;
WriteIndexToFile((Access*)m_pIndex, indexfile);
WriteIndexToFile((Access*)m_pIndex, indexfile.c_str());
}
else
{
Console.Error(L"ERROR (%d): index could not be generated for file '%s'", len, WX_STR(m_filename));
Console.Error("ERROR (%d): index could not be generated for file '%s'", len, m_filename.c_str());
free_index(index);
InitZstates();
return false;
@ -351,11 +343,11 @@ bool GzippedFileReader::OkIndex()
return true;
}
bool GzippedFileReader::Open(const wxString& fileName)
bool GzippedFileReader::Open(std::string fileName)
{
Close();
m_filename = fileName;
if (!(m_src = PX_fopen_rb(m_filename)) || !CanHandle(fileName) || !OkIndex())
m_filename = std::move(fileName);
if (!(m_src = FileSystem::OpenCFile(m_filename.c_str(), "rb")) || !OkIndex())
{
Close();
return false;
@ -384,7 +376,7 @@ int GzippedFileReader::FinishRead(void)
int GzippedFileReader::ReadSync(void* pBuffer, uint sector, uint count)
{
PX_off_t offset = (s64)sector * m_blocksize + m_dataoffset;
s64 offset = (s64)sector * m_blocksize + m_dataoffset;
int bytesToRead = count * m_blocksize;
int res = _ReadSync(pBuffer, offset, bytesToRead);
if (res < 0)
@ -393,11 +385,11 @@ int GzippedFileReader::ReadSync(void* pBuffer, uint sector, uint count)
}
// If we have a valid and adequate zstate for this span, use it, else, use the index
PX_off_t GzippedFileReader::GetOptimalExtractionStart(PX_off_t offset)
s64 GzippedFileReader::GetOptimalExtractionStart(s64 offset)
{
int span = m_pIndex->span;
Czstate& cstate = m_zstates[offset / span];
PX_off_t stateOffset = cstate.state.isValid ? cstate.state.out_offset : 0;
s64 stateOffset = cstate.state.isValid ? cstate.state.out_offset : 0;
if (stateOffset && stateOffset <= offset)
return stateOffset; // state is faster than indexed
@ -409,7 +401,7 @@ PX_off_t GzippedFileReader::GetOptimalExtractionStart(PX_off_t offset)
return span * (offset / span); // index direct access boundaries
}
int GzippedFileReader::_ReadSync(void* pBuffer, PX_off_t offset, uint bytesToRead)
int GzippedFileReader::_ReadSync(void* pBuffer, s64 offset, uint bytesToRead)
{
if (!OkIndex())
return -1;
@ -441,7 +433,7 @@ int GzippedFileReader::_ReadSync(void* pBuffer, PX_off_t offset, uint bytesToRea
// Not available from cache. Decompress from optimal starting
// point in GZFILE_READ_CHUNK_SIZE chunks and cache each chunk.
PTT s = NOW();
PX_off_t extractOffset = GetOptimalExtractionStart(offset); // guaranteed in GZFILE_READ_CHUNK_SIZE boundaries
s64 extractOffset = GetOptimalExtractionStart(offset); // guaranteed in GZFILE_READ_CHUNK_SIZE boundaries
int size = offset + maxInChunk - extractOffset;
unsigned char* extracted = (unsigned char*)malloc(size);
@ -501,7 +493,7 @@ int GzippedFileReader::_ReadSync(void* pBuffer, PX_off_t offset, uint bytesToRea
void GzippedFileReader::Close()
{
m_filename.Empty();
m_filename.clear();
if (m_pIndex)
{
free_index((Access*)m_pIndex);

View File

@ -34,8 +34,8 @@ public:
virtual ~GzippedFileReader(void) { Close(); };
static bool CanHandle(const wxString& fileName);
virtual bool Open(const wxString& fileName);
static bool CanHandle(const std::string& fileName, const std::string& displayName);
virtual bool Open(std::string fileName);
virtual int ReadSync(void* pBuffer, uint sector, uint count);
@ -71,8 +71,8 @@ private:
};
bool OkIndex(); // Verifies that we have an index, or try to create one
PX_off_t GetOptimalExtractionStart(PX_off_t offset);
int _ReadSync(void* pBuffer, PX_off_t offset, uint bytesToRead);
s64 GetOptimalExtractionStart(s64 offset);
int _ReadSync(void* pBuffer, s64 offset, uint bytesToRead);
void InitZstates();
int mBytesRead; // Temp sync read result when simulating async read
@ -93,6 +93,6 @@ private:
void AsyncPrefetchReset();
void AsyncPrefetchOpen();
void AsyncPrefetchClose();
void AsyncPrefetchChunk(PX_off_t dummy);
void AsyncPrefetchChunk(s64 dummy);
void AsyncPrefetchCancel();
};

View File

@ -194,19 +194,16 @@ void InputIsoFile::_init()
//
// Note that this is a member method, and that it will clobber any existing ISO state.
// (assertions are generated in debug mode if the object state is not already closed).
bool InputIsoFile::Test(const wxString& srcfile)
bool InputIsoFile::Test(std::string srcfile)
{
Close();
m_filename = srcfile;
return Open(srcfile, true);
return Open(std::move(srcfile), true);
}
bool InputIsoFile::Open(const wxString& srcfile, bool testOnly)
bool InputIsoFile::Open(std::string srcfile, bool testOnly)
{
Close();
m_filename = srcfile;
m_reader = NULL;
m_filename = std::move(srcfile);
bool isBlockdump = false;
bool isCompressed = false;
@ -270,7 +267,7 @@ bool InputIsoFile::Open(const wxString& srcfile, bool testOnly)
m_blocks = m_reader->GetBlockCount();
Console.WriteLn(Color_StrongBlue, L"isoFile open ok: %s", WX_STR(m_filename));
Console.WriteLn(Color_StrongBlue, "isoFile open ok: %s", m_filename.c_str());
ConsoleIndentScope indent;

View File

@ -16,10 +16,10 @@
#pragma once
#include "CDVD.h"
#include "wx/wfstream.h"
#include "AsyncFileReader.h"
#include "CompressedFileReader.h"
#include <memory>
#include <string>
enum isoType
{
@ -45,7 +45,7 @@ protected:
uint ReadUnit;
protected:
wxString m_filename;
std::string m_filename;
AsyncFileReader* m_reader;
u32 m_current_lsn;
@ -75,13 +75,13 @@ public:
uint GetBlockCount() const { return m_blocks; }
int GetBlockOffset() const { return m_blockofs; }
const wxString& GetFilename() const
const std::string& GetFilename() const
{
return m_filename;
}
bool Test(const wxString& srcfile);
bool Open(const wxString& srcfile, bool testOnly = false);
bool Test(std::string srcfile);
bool Open(std::string srcfile, bool testOnly = false);
void Close();
bool Detect(bool readType = true);
@ -102,7 +102,7 @@ class OutputIsoFile
DeclareNoncopyableObject(OutputIsoFile);
protected:
wxString m_filename;
std::string m_filename;
u32 m_version;
@ -116,7 +116,7 @@ protected:
// dtable is used when reading blockdumps
std::vector<u32> m_dtable;
std::unique_ptr<wxFileOutputStream> m_outstream;
std::FILE* m_outstream = nullptr;
public:
OutputIsoFile();
@ -125,12 +125,12 @@ public:
bool IsOpened() const;
u32 GetBlockSize() const;
const wxString& GetFilename() const
const std::string& GetFilename() const
{
return m_filename;
}
void Create(const wxString& filename, int mode);
void Create(std::string filename, int mode);
void Close();
void WriteHeader(int blockofs, uint blocksize, uint blocks);

View File

@ -17,15 +17,17 @@
#include "PrecompiledHeader.h"
#include "IopCommon.h"
#include "IsoFileFormats.h"
#include "common/FileSystem.h"
#include "common/StringUtil.h"
#include <errno.h>
void pxStream_OpenCheck(const wxStreamBase& stream, const wxString& fname, const wxString& mode)
void pxStream_OpenCheck(std::FILE* stream, const std::string& fname, const wxString& mode)
{
if (stream.IsOk())
if (stream)
return;
ScopedExcept ex(Exception::FromErrno(fname, errno));
ScopedExcept ex(Exception::FromErrno(StringUtil::UTF8StringToWxString(fname), errno));
ex->SetDiagMsg(pxsFmt(L"Unable to open the file for %s: %s", WX_STR(mode), WX_STR(ex->DiagMsg())));
ex->Rethrow();
}
@ -50,20 +52,20 @@ void OutputIsoFile::_init()
m_blocks = 0;
}
void OutputIsoFile::Create(const wxString& filename, int version)
void OutputIsoFile::Create(std::string filename, int version)
{
Close();
m_filename = filename;
m_filename = std::move(filename);
m_version = version;
m_offset = 0;
m_blockofs = 24;
m_blocksize = 2048;
m_outstream = std::make_unique<wxFileOutputStream>(m_filename);
pxStream_OpenCheck(*m_outstream, m_filename, L"writing");
m_outstream = FileSystem::OpenCFile(m_filename.c_str(), "wb");
pxStream_OpenCheck(m_outstream, m_filename, L"writing");
Console.WriteLn("isoFile create ok: %s ", WX_STR(m_filename));
Console.WriteLn("isoFile create ok: %s ", m_filename.c_str());
}
// Generates format header information for blockdumps.
@ -100,9 +102,8 @@ void OutputIsoFile::WriteSector(const u8* src, uint lsn)
}
else
{
wxFileOffset ofs = (wxFileOffset)lsn * m_blocksize + m_offset;
m_outstream->SeekO(ofs);
const s64 ofs = (s64)lsn * m_blocksize + m_offset;
FileSystem::FSeek64(m_outstream, ofs, SEEK_SET);
}
WriteBuffer(src + m_blockofs, m_blocksize);
@ -112,19 +113,27 @@ void OutputIsoFile::Close()
{
m_dtable.clear();
if (m_outstream)
{
std::fclose(m_outstream);
m_outstream = nullptr;
}
_init();
}
void OutputIsoFile::WriteBuffer(const void* src, size_t size)
{
m_outstream->Write(src, size);
if (m_outstream->GetLastError() == wxSTREAM_WRITE_ERROR)
if (std::fwrite(src, size, 1, m_outstream) != 1)
{
int err = errno;
if (!err)
throw Exception::BadStream(m_filename).SetDiagMsg(pxsFmt(L"An error occurred while writing %u bytes to file", size));
{
throw Exception::BadStream(StringUtil::UTF8StringToWxString(m_filename))
.SetDiagMsg(pxsFmt(L"An error occurred while writing %u bytes to file", size));
}
ScopedExcept ex(Exception::FromErrno(m_filename, err));
ScopedExcept ex(Exception::FromErrno(StringUtil::UTF8StringToWxString(m_filename), err));
ex->SetDiagMsg(pxsFmt(L"An error occurred while writing %u bytes to file: %s", size, WX_STR(ex->DiagMsg())));
ex->Rethrow();
}
@ -132,7 +141,7 @@ void OutputIsoFile::WriteBuffer(const void* src, size_t size)
bool OutputIsoFile::IsOpened() const
{
return m_outstream && m_outstream->IsOk();
return m_outstream != nullptr;
}
u32 OutputIsoFile::GetBlockSize() const

View File

@ -239,10 +239,10 @@ bool ThreadedFileReader::TryCachedRead(void*& buffer, u64& offset, u32& size, co
return allDone;
}
bool ThreadedFileReader::Open(const wxString& fileName)
bool ThreadedFileReader::Open(std::string fileName)
{
CancelAndWaitUntilStopped();
return Open2(fileName);
return Open2(std::move(fileName));
}
int ThreadedFileReader::ReadSync(void* pBuffer, uint sector, uint count)

View File

@ -47,7 +47,7 @@ protected:
/// Synchronously read the given block into `dst`
virtual int ReadChunk(void* dst, s64 chunkID) = 0;
/// AsyncFileReader open but ThreadedFileReader needs prep work first
virtual bool Open2(const wxString& fileName) = 0;
virtual bool Open2(std::string fileName) = 0;
/// AsyncFileReader close but ThreadedFileReader needs prep work first
virtual void Close2(void) = 0;
@ -109,7 +109,7 @@ private:
bool TryCachedRead(void*& buffer, u64& offset, u32& size, const std::lock_guard<std::mutex>&);
public:
bool Open(const wxString& fileName) final override;
bool Open(std::string fileName) final override;
int ReadSync(void* pBuffer, uint sector, uint count) final override;
void BeginRead(void* pBuffer, uint sector, uint count) final override;
int FinishRead(void) final override;

View File

@ -107,7 +107,7 @@ Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
#include <zlib/zlib.h>
#endif
#include "CompressedFileReaderUtils.h"
#include "common/FileSystem.h"
#define local static
@ -122,8 +122,8 @@ Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
/* access point entry */
struct point
{
PX_off_t out; /* corresponding offset in uncompressed data */
PX_off_t in; /* offset in input file of first full byte */
s64 out; /* corresponding offset in uncompressed data */
s64 in; /* offset in input file of first full byte */
int bits; /* number of bits (1-7) from byte at in - 1, or 0 */
unsigned char window[WINSIZE]; /* preceding 32K of uncompressed data */
}
@ -142,7 +142,7 @@ struct access
struct point* list; /* allocated list */
s32 span; /* once the index is built, holds the span size used to build it */
PX_off_t uncompressed_size; /* filled by build_index */
s64 uncompressed_size; /* filled by build_index */
}
#ifndef _WIN32
__attribute__((packed))
@ -168,7 +168,7 @@ local void free_index(struct access* index)
/* Add an entry to the access point list. If out of memory, deallocate the
existing list and return NULL. */
local struct access* addpoint(struct access* index, int bits,
PX_off_t in, PX_off_t out, unsigned left, unsigned char* window)
s64 in, s64 out, unsigned left, unsigned char* window)
{
struct point* next;
@ -224,11 +224,11 @@ local struct access* addpoint(struct access* index, int bits,
returns the number of access points on success (>= 1), Z_MEM_ERROR for out
of memory, Z_DATA_ERROR for an error in the input file, or Z_ERRNO for a
file read error. On success, *built points to the resulting index. */
local int build_index(FILE* in, PX_off_t span, struct access** built)
local int build_index(FILE* in, s64 span, struct access** built)
{
int ret;
PX_off_t totin, totout, totPrinted; /* our own total counters to avoid 4GB limit */
PX_off_t last; /* totout value of last access point */
s64 totin, totout, totPrinted; /* our own total counters to avoid 4GB limit */
s64 last; /* totout value of last access point */
struct access* index; /* access points being generated */
z_stream strm;
unsigned char input[CHUNK];
@ -344,13 +344,13 @@ build_index_error:
typedef struct zstate
{
PX_off_t out_offset;
PX_off_t in_offset;
s64 out_offset;
s64 in_offset;
z_stream strm;
int isValid;
} Zstate;
static inline PX_off_t getInOffset(zstate* state)
static inline s64 getInOffset(zstate* state)
{
return state->in_offset;
}
@ -362,7 +362,7 @@ static inline PX_off_t getInOffset(zstate* state)
should not return a data error unless the file was modified since the index
was generated. extract() may also return Z_ERRNO if there is an error on
reading or seeking the input file. */
local int extract(FILE* in, struct access* index, PX_off_t offset,
local int extract(FILE* in, struct access* index, s64 offset,
unsigned char* buf, int len, zstate* state)
{
int ret, skip;
@ -386,7 +386,7 @@ local int extract(FILE* in, struct access* index, PX_off_t offset,
if (state->isValid)
{
state->isValid = 0; // we took control over strm. revalidate when/if we give it back
PX_fseeko(in, state->in_offset, SEEK_SET);
FileSystem::FSeek64(in, state->in_offset, SEEK_SET);
state->strm.avail_in = 0;
offset = 0;
skip = 1;
@ -408,7 +408,7 @@ local int extract(FILE* in, struct access* index, PX_off_t offset,
ret = inflateInit2(&state->strm, -15); /* raw inflate */
if (ret != Z_OK)
return ret;
ret = PX_fseeko(in, here->in - (here->bits ? 1 : 0), SEEK_SET);
ret = FileSystem::FSeek64(in, here->in - (here->bits ? 1 : 0), SEEK_SET);
if (ret == -1)
goto extract_ret;
if (here->bits)
@ -456,7 +456,7 @@ local int extract(FILE* in, struct access* index, PX_off_t offset,
{
if (state->strm.avail_in == 0)
{
state->in_offset = PX_ftello(in);
state->in_offset = FileSystem::FTell64(in);
state->strm.avail_in = fread(input, 1, CHUNK, in);
if (ferror(in))
{

View File

@ -268,7 +268,6 @@ set(pcsx2CDVDHeaders
CDVD/CDVDisoReader.h
CDVD/ChunksCache.h
CDVD/CompressedFileReader.h
CDVD/CompressedFileReaderUtils.h
CDVD/ChdFileReader.h
CDVD/CsoFileReader.h
CDVD/GzippedFileReader.h

View File

@ -15,6 +15,7 @@
#include "PrecompiledHeader.h"
#include "AsyncFileReader.h"
#include "common/FileSystem.h"
// The aio module has been reported to cause issues with FreeBSD 10.3, so let's
// disable it for 10.3 and earlier and hope FreeBSD 11 and onwards is fine.
@ -36,11 +37,11 @@ FlatFileReader::~FlatFileReader(void)
Close();
}
bool FlatFileReader::Open(const wxString& fileName)
bool FlatFileReader::Open(std::string fileName)
{
m_filename = fileName;
m_filename = std::move(fileName);
m_fd = wxOpen(fileName, O_RDONLY, 0);
m_fd = FileSystem::OpenFDFile(m_filename.c_str(), O_RDONLY, 0);
return (m_fd != -1);
}

View File

@ -15,8 +15,10 @@
#include "PrecompiledHeader.h"
#include "AsyncFileReader.h"
#include "common/FileSystem.h"
FlatFileReader::FlatFileReader(bool shareWrite) : shareWrite(shareWrite)
FlatFileReader::FlatFileReader(bool shareWrite)
: shareWrite(shareWrite)
{
m_blocksize = 2048;
m_fd = -1;
@ -28,14 +30,15 @@ FlatFileReader::~FlatFileReader(void)
Close();
}
bool FlatFileReader::Open(const wxString& fileName)
bool FlatFileReader::Open(std::string fileName)
{
m_filename = fileName;
m_filename = std::move(fileName);
int err = io_setup(64, &m_aio_context);
if (err) return false;
if (err)
return false;
m_fd = wxOpen(fileName, O_RDONLY, 0);
m_fd = FileSystem::OpenFDFile(m_filename.c_str(), O_RDONLY, 0);
return (m_fd != -1);
}
@ -67,9 +70,8 @@ int FlatFileReader::FinishRead(void)
struct io_event events[max_nr];
int event = io_getevents(m_aio_context, min_nr, max_nr, events, NULL);
if (event < 1) {
if (event < 1)
return -1;
}
return 1;
}
@ -85,7 +87,8 @@ void FlatFileReader::CancelRead(void)
void FlatFileReader::Close(void)
{
if (m_fd != -1) close(m_fd);
if (m_fd != -1)
close(m_fd);
io_destroy(m_aio_context);
@ -95,5 +98,15 @@ void FlatFileReader::Close(void)
uint FlatFileReader::GetBlockCount(void) const
{
return (int)(Path::GetFileSize(m_filename) / m_blocksize);
#if defined(__HAIKU__) || defined(__APPLE__) || defined(__FreeBSD__)
struct stat sysStatData;
if (fstat(m_fd, &sysStatData) < 0)
return 0;
#else
struct stat64 sysStatData;
if (fstat64(m_fd, &sysStatData) < 0)
return 0;
#endif
return (int)(sysStatData.st_size / m_blocksize);
}

View File

@ -15,6 +15,7 @@
#include "PrecompiledHeader.h"
#include "AsyncFileReader.h"
#include "common/StringUtil.h"
// Tests for a filename extension in both upper and lower case, if the filesystem happens
// to be case-sensitive.
@ -66,7 +67,7 @@ MultipartFileReader::~MultipartFileReader(void)
void MultipartFileReader::FindParts()
{
wxFileName nameparts( m_filename );
wxFileName nameparts( StringUtil::UTF8StringToWxString(m_filename) );
wxString curext( nameparts.GetExt() );
wxChar prefixch = wxTolower(curext[0]);
@ -112,7 +113,7 @@ void MultipartFileReader::FindParts()
wxString name = nameparts.GetFullPath();
thisreader->Open(name);
thisreader->Open(StringUtil::wxStringToUTF8String(name));
thisreader->SetBlockSize(bsize);
thispart->start = blocks;
@ -133,7 +134,7 @@ void MultipartFileReader::FindParts()
//Console.WriteLn( Color_Blue, "isoFile: multi-part ISO loaded (%u parts found)", m_numparts );
}
bool MultipartFileReader::Open(const wxString& fileName)
bool MultipartFileReader::Open(std::string fileName)
{
// Cannot open a MultipartFileReader directly,
// use DetectMultipart to convert a FlatFileReader

View File

@ -18,6 +18,7 @@
#include "Dialogs/ModalPopups.h"
#include "common/StringUtil.h"
#include "CDVD/IsoFileFormats.h"
#include <wx/wfstream.h>
@ -188,7 +189,7 @@ bool IsoDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filen
InputIsoFile iso;
if (iso.Test( filenames[0] ))
if (iso.Test( StringUtil::wxStringToUTF8String(filenames[0]) ))
{
DevCon.WriteLn( L"(Drag&Drop) Found valid ISO file type!" );
wxGetApp().PostEvent( DroppedIso(m_WindowBound, filenames[0]) );

View File

@ -15,6 +15,7 @@
#include "PrecompiledHeader.h"
#include "AsyncFileReader.h"
#include "common/StringUtil.h"
FlatFileReader::FlatFileReader(bool shareWrite) : shareWrite(shareWrite)
{
@ -29,9 +30,9 @@ FlatFileReader::~FlatFileReader(void)
Close();
}
bool FlatFileReader::Open(const wxString& fileName)
bool FlatFileReader::Open(std::string fileName)
{
m_filename = fileName;
m_filename = std::move(fileName);
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
@ -40,7 +41,7 @@ bool FlatFileReader::Open(const wxString& fileName)
shareMode |= FILE_SHARE_WRITE;
hOverlappedFile = CreateFile(
fileName,
StringUtil::UTF8StringToWideString(m_filename).c_str(),
GENERIC_READ,
shareMode,
NULL,