mirror of https://github.com/PCSX2/pcsx2.git
CDVD: Remove wx from file access
This commit is contained in:
parent
16af078b3b
commit
8d44e1af0e
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -52,7 +52,7 @@ s32 CALLBACK ISOopen(const char* pTitle)
|
|||
|
||||
try
|
||||
{
|
||||
iso.Open(fromUTF8(pTitle));
|
||||
iso.Open(pTitle);
|
||||
}
|
||||
catch (BaseException& ex)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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++)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 //////////
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]) );
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue