Common: Error/FileSystem backports

This commit is contained in:
Stenzek
2023-08-19 23:40:36 +10:00
parent 7890051165
commit 39f64a03ee
18 changed files with 311 additions and 555 deletions

View File

@ -21,7 +21,7 @@ u32 CDImage::GetBytesPerSector(TrackMode mode)
return sizes[static_cast<u32>(mode)];
}
std::unique_ptr<CDImage> CDImage::Open(const char* filename, bool allow_patches, Common::Error* error)
std::unique_ptr<CDImage> CDImage::Open(const char* filename, bool allow_patches, Error* error)
{
const char* extension;
@ -94,10 +94,7 @@ std::unique_ptr<CDImage> CDImage::Open(const char* filename, bool allow_patches,
{
image = CDImage::OverlayPPFPatch(ppf_filename.c_str(), std::move(image));
if (!image)
{
if (error)
error->SetFormattedMessage("Failed to apply ppf patch from '%s'.", ppf_filename.c_str());
}
Error::SetString(error, fmt::format("Failed to apply ppf patch from '{}'.", ppf_filename));
}
}
@ -343,7 +340,7 @@ u32 CDImage::GetCurrentSubImage() const
return 0;
}
bool CDImage::SwitchSubImage(u32 index, Common::Error* error)
bool CDImage::SwitchSubImage(u32 index, Error* error)
{
return false;
}

View File

@ -11,9 +11,7 @@
#include <tuple>
#include <vector>
namespace Common {
class Error;
}
class CDImage
{
@ -220,15 +218,15 @@ public:
static bool IsDeviceName(const char* filename);
// Opening disc image.
static std::unique_ptr<CDImage> Open(const char* filename, bool allow_patches, Common::Error* error);
static std::unique_ptr<CDImage> OpenBinImage(const char* filename, Common::Error* error);
static std::unique_ptr<CDImage> OpenCueSheetImage(const char* filename, Common::Error* error);
static std::unique_ptr<CDImage> OpenCHDImage(const char* filename, Common::Error* error);
static std::unique_ptr<CDImage> OpenEcmImage(const char* filename, Common::Error* error);
static std::unique_ptr<CDImage> OpenMdsImage(const char* filename, Common::Error* error);
static std::unique_ptr<CDImage> OpenPBPImage(const char* filename, Common::Error* error);
static std::unique_ptr<CDImage> OpenM3uImage(const char* filename, bool apply_patches, Common::Error* error);
static std::unique_ptr<CDImage> OpenDeviceImage(const char* filename, Common::Error* error);
static std::unique_ptr<CDImage> Open(const char* filename, bool allow_patches, Error* error);
static std::unique_ptr<CDImage> OpenBinImage(const char* filename, Error* error);
static std::unique_ptr<CDImage> OpenCueSheetImage(const char* filename, Error* error);
static std::unique_ptr<CDImage> OpenCHDImage(const char* filename, Error* error);
static std::unique_ptr<CDImage> OpenEcmImage(const char* filename, Error* error);
static std::unique_ptr<CDImage> OpenMdsImage(const char* filename, Error* error);
static std::unique_ptr<CDImage> OpenPBPImage(const char* filename, Error* error);
static std::unique_ptr<CDImage> OpenM3uImage(const char* filename, bool apply_patches, Error* error);
static std::unique_ptr<CDImage> OpenDeviceImage(const char* filename, Error* error);
static std::unique_ptr<CDImage>
CreateMemoryImage(CDImage* image, ProgressCallback* progress = ProgressCallback::NullProgressCallback);
static std::unique_ptr<CDImage> OverlayPPFPatch(const char* filename, std::unique_ptr<CDImage> parent_image,
@ -341,7 +339,7 @@ public:
virtual u32 GetCurrentSubImage() const;
// Changes the current sub-image. If this fails, the image state is unchanged.
virtual bool SwitchSubImage(u32 index, Common::Error* error);
virtual bool SwitchSubImage(u32 index, Error* error);
// Retrieve sub-image metadata.
virtual std::string GetSubImageMetadata(u32 index, const std::string_view& type) const;

View File

@ -15,7 +15,7 @@ public:
CDImageBin();
~CDImageBin() override;
bool Open(const char* filename, Common::Error* error);
bool Open(const char* filename, Error* error);
bool ReadSubChannelQ(SubChannelQ* subq, const Index& index, LBA lba_in_index) override;
bool HasNonStandardSubchannel() const override;
@ -38,7 +38,7 @@ CDImageBin::~CDImageBin()
std::fclose(m_fp);
}
bool CDImageBin::Open(const char* filename, Common::Error* error)
bool CDImageBin::Open(const char* filename, Error* error)
{
m_filename = filename;
m_fp = FileSystem::OpenCFile(filename, "rb");
@ -136,7 +136,7 @@ bool CDImageBin::ReadSectorFromIndex(void* buffer, const Index& index, LBA lba_i
return true;
}
std::unique_ptr<CDImage> CDImage::OpenBinImage(const char* filename, Common::Error* error)
std::unique_ptr<CDImage> CDImage::OpenBinImage(const char* filename, Error* error)
{
std::unique_ptr<CDImageBin> image = std::make_unique<CDImageBin>();
if (!image->Open(filename, error))

View File

@ -59,7 +59,7 @@ public:
CDImageCHD();
~CDImageCHD() override;
bool Open(const char* filename, Common::Error* error);
bool Open(const char* filename, Error* error);
bool ReadSubChannelQ(SubChannelQ* subq, const Index& index, LBA lba_in_index) override;
bool HasNonStandardSubchannel() const override;
@ -77,7 +77,7 @@ private:
MAX_PARENTS = 32 // Surely someone wouldn't be insane enough to go beyond this...
};
chd_file* OpenCHD(const char* filename, FileSystem::ManagedCFilePtr fp, Common::Error* error, u32 recursion_level);
chd_file* OpenCHD(const char* filename, FileSystem::ManagedCFilePtr fp, Error* error, u32 recursion_level);
bool ReadHunk(u32 hunk_index);
chd_file* m_chd = nullptr;
@ -100,8 +100,7 @@ CDImageCHD::~CDImageCHD()
chd_close(m_chd);
}
chd_file* CDImageCHD::OpenCHD(const char* filename, FileSystem::ManagedCFilePtr fp, Common::Error* error,
u32 recursion_level)
chd_file* CDImageCHD::OpenCHD(const char* filename, FileSystem::ManagedCFilePtr fp, Error* error, u32 recursion_level)
{
chd_file* chd;
chd_error err = chd_open_file(fp.get(), CHD_OPEN_READ | CHD_OPEN_TRANSFER_FILE, nullptr, &chd);
@ -114,16 +113,14 @@ chd_file* CDImageCHD::OpenCHD(const char* filename, FileSystem::ManagedCFilePtr
else if (err != CHDERR_REQUIRES_PARENT)
{
Log_ErrorPrintf("Failed to open CHD '%s': %s", filename, chd_error_string(err));
if (error)
error->SetMessage(chd_error_string(err));
Error::SetString(error, chd_error_string(err));
return nullptr;
}
if (recursion_level >= MAX_PARENTS)
{
Log_ErrorPrintf("Failed to open CHD '%s': Too many parent files", filename);
if (error)
error->SetMessage("Too many parent files");
Error::SetString(error, "Too many parent files");
return nullptr;
}
@ -133,8 +130,7 @@ chd_file* CDImageCHD::OpenCHD(const char* filename, FileSystem::ManagedCFilePtr
if (err != CHDERR_NONE)
{
Log_ErrorPrintf("Failed to read CHD header '%s': %s", filename, chd_error_string(err));
if (error)
error->SetMessage(chd_error_string(err));
Error::SetString(error, chd_error_string(err));
return nullptr;
}
@ -163,15 +159,16 @@ chd_file* CDImageCHD::OpenCHD(const char* filename, FileSystem::ManagedCFilePtr
// Match! Open this one.
if ((parent_chd = OpenCHD(fd.FileName.c_str(), std::move(parent_fp), error, recursion_level + 1)) != nullptr)
{
Log_DevPrintf(fmt::format("Found parent CHD '{}' for '{}'.", Path::GetFileName(fd.FileName), Path::GetFileName(filename)).c_str());
Log_DevPrintf(
fmt::format("Found parent CHD '{}' for '{}'.", Path::GetFileName(fd.FileName), Path::GetFileName(filename))
.c_str());
break;
}
}
if (!parent_chd)
{
Log_ErrorPrintf("Failed to open CHD '%s': Failed to find parent CHD, it must be in the same directory.", filename);
if (error)
error->SetMessage("Failed to find parent CHD, it must be in the same directory.");
Error::SetString(error, "Failed to find parent CHD, it must be in the same directory.");
return nullptr;
}
@ -180,8 +177,7 @@ chd_file* CDImageCHD::OpenCHD(const char* filename, FileSystem::ManagedCFilePtr
if (err != CHDERR_NONE)
{
Log_ErrorPrintf("Failed to open CHD '%s': %s", filename, chd_error_string(err));
if (error)
error->SetMessage(chd_error_string(err));
Error::SetString(error, chd_error_string(err));
return nullptr;
}
@ -190,7 +186,7 @@ chd_file* CDImageCHD::OpenCHD(const char* filename, FileSystem::ManagedCFilePtr
return chd;
}
bool CDImageCHD::Open(const char* filename, Common::Error* error)
bool CDImageCHD::Open(const char* filename, Error* error)
{
auto fp = FileSystem::OpenManagedSharedCFile(filename, "rb", FileSystem::FileShareMode::DenyWrite);
if (!fp)
@ -211,9 +207,8 @@ bool CDImageCHD::Open(const char* filename, Common::Error* error)
if ((m_hunk_size % CHD_CD_SECTOR_DATA_SIZE) != 0)
{
Log_ErrorPrintf("Hunk size (%u) is not a multiple of %u", m_hunk_size, CHD_CD_SECTOR_DATA_SIZE);
if (error)
error->SetFormattedMessage("Hunk size (%u) is not a multiple of %u", m_hunk_size, CHD_CD_SECTOR_DATA_SIZE);
Error::SetString(error, fmt::format("Hunk size ({}) is not a multiple of {}", m_hunk_size,
static_cast<u32>(CHD_CD_SECTOR_DATA_SIZE)));
return false;
}
@ -244,9 +239,7 @@ bool CDImageCHD::Open(const char* filename, Common::Error* error)
&pregap_frames, pgtype_str, pgsub_str, &postgap_frames) != 8)
{
Log_ErrorPrintf("Invalid track v2 metadata: '%s'", metadata_str);
if (error)
error->SetFormattedMessage("Invalid track v2 metadata: '%s'", metadata_str);
Error::SetString(error, fmt::format("Invalid track v2 metadata: '{}'", metadata_str));
return false;
}
}
@ -264,9 +257,7 @@ bool CDImageCHD::Open(const char* filename, Common::Error* error)
if (std::sscanf(metadata_str, CDROM_TRACK_METADATA_FORMAT, &track_num, type_str, subtype_str, &frames) != 4)
{
Log_ErrorPrintf("Invalid track metadata: '%s'", metadata_str);
if (error)
error->SetFormattedMessage("Invalid track v2 metadata: '%s'", metadata_str);
Error::SetString(error, fmt::format("Invalid track v2 metadata: '{}'", metadata_str));
return false;
}
}
@ -275,12 +266,8 @@ bool CDImageCHD::Open(const char* filename, Common::Error* error)
{
Log_ErrorPrintf("Incorrect track number at index %d, expected %d got %d", num_tracks, (num_tracks + 1),
track_num);
if (error)
{
error->SetFormattedMessage("Incorrect track number at index %d, expected %d got %d", num_tracks,
(num_tracks + 1), track_num);
}
Error::SetString(error, fmt::format("Incorrect track number at index {}, expected {} got {}", num_tracks,
(num_tracks + 1), track_num));
return false;
}
@ -288,9 +275,7 @@ bool CDImageCHD::Open(const char* filename, Common::Error* error)
if (!mode.has_value())
{
Log_ErrorPrintf("Invalid track mode: '%s'", type_str);
if (error)
error->SetFormattedMessage("Invalid track mode: '%s'", type_str);
Error::SetString(error, fmt::format("Invalid track mode: '{}'", type_str));
return false;
}
@ -321,9 +306,7 @@ bool CDImageCHD::Open(const char* filename, Common::Error* error)
if (pregap_frames > frames)
{
Log_ErrorPrintf("Pregap length %u exceeds track length %u", pregap_frames, frames);
if (error)
error->SetFormattedMessage("Pregap length %u exceeds track length %u", pregap_frames, frames);
Error::SetString(error, fmt::format("Pregap length {} exceeds track length {}", pregap_frames, frames));
return false;
}
@ -368,9 +351,7 @@ bool CDImageCHD::Open(const char* filename, Common::Error* error)
if (m_tracks.empty())
{
Log_ErrorPrintf("File '%s' contains no tracks", filename);
if (error)
error->SetFormattedMessage("File '%s' contains no tracks", filename);
Error::SetString(error, fmt::format("File '{}' contains no tracks", filename));
return false;
}
@ -497,7 +478,7 @@ bool CDImageCHD::ReadHunk(u32 hunk_index)
return true;
}
std::unique_ptr<CDImage> CDImage::OpenCHDImage(const char* filename, Common::Error* error)
std::unique_ptr<CDImage> CDImage::OpenCHDImage(const char* filename, Error* error)
{
std::unique_ptr<CDImageCHD> image = std::make_unique<CDImageCHD>();
if (!image->Open(filename, error))

View File

@ -3,16 +3,21 @@
#include "cd_image.h"
#include "cd_subchannel_replacement.h"
#include "cue_parser.h"
#include "common/assert.h"
#include "common/error.h"
#include "common/file_system.h"
#include "common/log.h"
#include "common/path.h"
#include "cue_parser.h"
#include "fmt/format.h"
#include <algorithm>
#include <cerrno>
#include <cinttypes>
#include <map>
Log_SetChannel(CDImageCueSheet);
class CDImageCueSheet : public CDImage
@ -21,7 +26,7 @@ public:
CDImageCueSheet();
~CDImageCueSheet() override;
bool OpenAndParse(const char* filename, Common::Error* error);
bool OpenAndParse(const char* filename, Error* error);
bool ReadSubChannelQ(SubChannelQ* subq, const Index& index, LBA lba_in_index) override;
bool HasNonStandardSubchannel() const override;
@ -48,7 +53,7 @@ CDImageCueSheet::~CDImageCueSheet()
std::for_each(m_files.begin(), m_files.end(), [](TrackFile& t) { std::fclose(t.file); });
}
bool CDImageCueSheet::OpenAndParse(const char* filename, Common::Error* error)
bool CDImageCueSheet::OpenAndParse(const char* filename, Error* error)
{
std::FILE* fp = FileSystem::OpenCFile(filename, "rb");
if (!fp)
@ -94,7 +99,8 @@ bool CDImageCueSheet::OpenAndParse(const char* filename, Common::Error* error)
{
const std::string track_full_filename(
!Path::IsAbsolute(track_filename) ? Path::BuildRelativePath(m_filename, track_filename) : track_filename);
std::FILE* track_fp = FileSystem::OpenCFile(track_full_filename.c_str(), "rb");
Error track_error;
std::FILE* track_fp = FileSystem::OpenCFile(track_full_filename.c_str(), "rb", &track_error);
if (!track_fp && track_file_index == 0)
{
// many users have bad cuesheets, or they're renamed the files without updating the cuesheet.
@ -110,14 +116,11 @@ bool CDImageCueSheet::OpenAndParse(const char* filename, Common::Error* error)
if (!track_fp)
{
Log_ErrorPrintf("Failed to open track filename '%s' (from '%s' and '%s'): errno %d",
track_full_filename.c_str(), track_filename.c_str(), filename, errno);
if (error)
{
error->SetFormattedMessage("Failed to open track filename '%s' (from '%s' and '%s'): errno %d",
track_full_filename.c_str(), track_filename.c_str(), filename, errno);
}
Log_ErrorPrintf("Failed to open track filename '%s' (from '%s' and '%s'): %s", track_full_filename.c_str(),
track_filename.c_str(), filename, track_error.GetDescription().c_str());
Error::SetString(error,
fmt::format("Failed to open track filename '{}' (from '{}' and '{}'): {}", track_full_filename,
track_filename, filename, track_error.GetDescription()));
return false;
}
@ -148,11 +151,8 @@ bool CDImageCueSheet::OpenAndParse(const char* filename, Common::Error* error)
{
Log_ErrorPrintf("Failed to open track %u in '%s': track start is out of range (%u vs %" PRIu64 ")", track_num,
filename, track_start, file_size);
if (error)
{
error->SetFormattedMessage("Failed to open track %u in '%s': track start is out of range (%u vs %" PRIu64 ")",
track_num, filename, track_start, file_size);
}
Error::SetString(error, fmt::format("Failed to open track {} in '{}': track start is out of range ({} vs {}))",
track_num, filename, track_start, file_size));
return false;
}
@ -283,8 +283,7 @@ bool CDImageCueSheet::OpenAndParse(const char* filename, Common::Error* error)
if (m_tracks.empty())
{
Log_ErrorPrintf("File '%s' contains no tracks", filename);
if (error)
error->SetFormattedMessage("File '%s' contains no tracks", filename);
Error::SetString(error, fmt::format("File '{}' contains no tracks", filename));
return false;
}
@ -333,7 +332,7 @@ bool CDImageCueSheet::ReadSectorFromIndex(void* buffer, const Index& index, LBA
return true;
}
std::unique_ptr<CDImage> CDImage::OpenCueSheetImage(const char* filename, Common::Error* error)
std::unique_ptr<CDImage> CDImage::OpenCueSheetImage(const char* filename, Error* error)
{
std::unique_ptr<CDImageCueSheet> image = std::make_unique<CDImageCueSheet>();
if (!image->OpenAndParse(filename, error))

View File

@ -72,7 +72,7 @@ public:
CDImageDeviceWin32();
~CDImageDeviceWin32() override;
bool Open(const char* filename, Common::Error* error);
bool Open(const char* filename, Error* error);
bool ReadSubChannelQ(SubChannelQ* subq, const Index& index, LBA lba_in_index) override;
bool HasNonStandardSubchannel() const override;
@ -112,7 +112,7 @@ CDImageDeviceWin32::~CDImageDeviceWin32()
CloseHandle(m_hDevice);
}
bool CDImageDeviceWin32::Open(const char* filename, Common::Error* error)
bool CDImageDeviceWin32::Open(const char* filename, Error* error)
{
m_filename = filename;
m_hDevice = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
@ -244,8 +244,7 @@ bool CDImageDeviceWin32::Open(const char* filename, Common::Error* error)
if (m_tracks.empty())
{
Log_ErrorPrintf("File '%s' contains no tracks", filename);
if (error)
error->SetFormattedMessage("File '%s' contains no tracks", filename);
Error::SetString(error, fmt::format("File '{}' contains no tracks", filename));
return false;
}
@ -270,9 +269,7 @@ bool CDImageDeviceWin32::Open(const char* filename, Common::Error* error)
if (!DetermineReadMode())
{
Log_ErrorPrintf("Could not determine read mode");
if (error)
error->SetMessage("Could not determine read mode");
Error::SetString(error, "Could not determine read mode");
return false;
}
@ -476,7 +473,7 @@ bool CDImageDeviceWin32::DetermineReadMode()
return false;
}
std::unique_ptr<CDImage> CDImage::OpenDeviceImage(const char* filename, Common::Error* error)
std::unique_ptr<CDImage> CDImage::OpenDeviceImage(const char* filename, Error* error)
{
std::unique_ptr<CDImageDeviceWin32> image = std::make_unique<CDImageDeviceWin32>();
if (!image->Open(filename, error))
@ -528,7 +525,7 @@ bool CDImage::IsDeviceName(const char* filename)
#else
std::unique_ptr<CDImage> CDImage::OpenDeviceImage(const char* filename, Common::Error* error)
std::unique_ptr<CDImage> CDImage::OpenDeviceImage(const char* filename, Error* error)
{
return {};
}

View File

@ -164,7 +164,7 @@ public:
CDImageEcm();
~CDImageEcm() override;
bool Open(const char* filename, Common::Error* error);
bool Open(const char* filename, Error* error);
bool ReadSubChannelQ(SubChannelQ* subq, const Index& index, LBA lba_in_index) override;
bool HasNonStandardSubchannel() const override;
@ -224,7 +224,7 @@ CDImageEcm::~CDImageEcm()
std::fclose(m_fp);
}
bool CDImageEcm::Open(const char* filename, Common::Error* error)
bool CDImageEcm::Open(const char* filename, Error* error)
{
m_filename = filename;
m_fp = FileSystem::OpenCFile(filename, "rb");
@ -253,9 +253,7 @@ bool CDImageEcm::Open(const char* filename, Common::Error* error)
header[3] != 0)
{
Log_ErrorPrintf("Failed to read/invalid header");
if (error)
error->SetMessage("Failed to read/invalid header");
Error::SetString(error, "Failed to read/invalid header");
return false;
}
@ -269,9 +267,7 @@ bool CDImageEcm::Open(const char* filename, Common::Error* error)
if (bits == EOF)
{
Log_ErrorPrintf("Unexpected EOF after %zu chunks", m_data_map.size());
if (error)
error->SetFormattedMessage("Unexpected EOF after %zu chunks", m_data_map.size());
Error::SetString(error, fmt::format("Unexpected EOF after {} chunks", m_data_map.size()));
return false;
}
@ -285,9 +281,7 @@ bool CDImageEcm::Open(const char* filename, Common::Error* error)
if (bits == EOF)
{
Log_ErrorPrintf("Unexpected EOF after %zu chunks", m_data_map.size());
if (error)
error->SetFormattedMessage("Unexpected EOF after %zu chunks", m_data_map.size());
Error::SetString(error, fmt::format("Unexpected EOF after {} chunks", m_data_map.size()));
return false;
}
@ -305,9 +299,7 @@ bool CDImageEcm::Open(const char* filename, Common::Error* error)
if (count >= 0x80000000u)
{
Log_ErrorPrintf("Corrupted header after %zu chunks", m_data_map.size());
if (error)
error->SetFormattedMessage("Corrupted header after %zu chunks", m_data_map.size());
Error::SetString(error, fmt::format("Corrupted header after {} chunks", m_data_map.size()));
return false;
}
@ -324,8 +316,7 @@ bool CDImageEcm::Open(const char* filename, Common::Error* error)
if (static_cast<s64>(file_offset) > file_size)
{
Log_ErrorPrintf("Out of file bounds after %zu chunks", m_data_map.size());
if (error)
error->SetFormattedMessage("Out of file bounds after %zu chunks", m_data_map.size());
Error::SetString(error, fmt::format("Out of file bounds after {} chunks", m_data_map.size()));
}
}
}
@ -342,8 +333,7 @@ bool CDImageEcm::Open(const char* filename, Common::Error* error)
if (static_cast<s64>(file_offset) > file_size)
{
Log_ErrorPrintf("Out of file bounds after %zu chunks", m_data_map.size());
if (error)
error->SetFormattedMessage("Out of file bounds after %zu chunks", m_data_map.size());
Error::SetString(error, fmt::format("Out of file bounds after {} chunks", m_data_map.size()));
}
}
}
@ -351,9 +341,7 @@ bool CDImageEcm::Open(const char* filename, Common::Error* error)
if (std::fseek(m_fp, file_offset, SEEK_SET) != 0)
{
Log_ErrorPrintf("Failed to seek to offset %u after %zu chunks", file_offset, m_data_map.size());
if (error)
error->SetFormattedMessage("Failed to seek to offset %u after %zu chunks", file_offset, m_data_map.size());
Error::SetString(error, fmt::format("Failed to seek to offset {} after {} chunks", file_offset, m_data_map.size()));
return false;
}
}
@ -361,9 +349,7 @@ bool CDImageEcm::Open(const char* filename, Common::Error* error)
if (m_data_map.empty())
{
Log_ErrorPrintf("No data in image '%s'", filename);
if (error)
error->SetFormattedMessage("No data in image '%s'", filename);
Error::SetString(error, fmt::format("No data in image '{}'", filename));
return false;
}
@ -549,7 +535,7 @@ bool CDImageEcm::ReadSectorFromIndex(void* buffer, const Index& index, LBA lba_i
return true;
}
std::unique_ptr<CDImage> CDImage::OpenEcmImage(const char* filename, Common::Error* error)
std::unique_ptr<CDImage> CDImage::OpenEcmImage(const char* filename, Error* error)
{
std::unique_ptr<CDImageEcm> image = std::make_unique<CDImageEcm>();
if (!image->Open(filename, error))

View File

@ -20,7 +20,7 @@ public:
CDImageM3u();
~CDImageM3u() override;
bool Open(const char* path, bool apply_patches, Common::Error* Error);
bool Open(const char* path, bool apply_patches, Error* Error);
bool ReadSubChannelQ(SubChannelQ* subq, const Index& index, LBA lba_in_index) override;
bool HasNonStandardSubchannel() const override;
@ -29,7 +29,7 @@ public:
u32 GetSubImageCount() const override;
u32 GetCurrentSubImage() const override;
std::string GetSubImageMetadata(u32 index, const std::string_view& type) const override;
bool SwitchSubImage(u32 index, Common::Error* error) override;
bool SwitchSubImage(u32 index, Error* error) override;
protected:
bool ReadSectorFromIndex(void* buffer, const Index& index, LBA lba_in_index) override;
@ -52,7 +52,7 @@ CDImageM3u::CDImageM3u() = default;
CDImageM3u::~CDImageM3u() = default;
bool CDImageM3u::Open(const char* path, bool apply_patches, Common::Error* error)
bool CDImageM3u::Open(const char* path, bool apply_patches, Error* error)
{
std::FILE* fp = FileSystem::OpenCFile(path, "rb");
if (!fp)
@ -62,8 +62,7 @@ bool CDImageM3u::Open(const char* path, bool apply_patches, Common::Error* error
std::fclose(fp);
if (!m3u_file.has_value() || m3u_file->empty())
{
if (error)
error->SetMessage("Failed to read M3u file");
Error::SetString(error, "Failed to read M3u file");
return false;
}
@ -128,7 +127,7 @@ u32 CDImageM3u::GetCurrentSubImage() const
return m_current_image_index;
}
bool CDImageM3u::SwitchSubImage(u32 index, Common::Error* error)
bool CDImageM3u::SwitchSubImage(u32 index, Error* error)
{
if (index >= m_entries.size())
return false;
@ -175,7 +174,7 @@ bool CDImageM3u::ReadSubChannelQ(SubChannelQ* subq, const Index& index, LBA lba_
return m_current_image->ReadSubChannelQ(subq, index, lba_in_index);
}
std::unique_ptr<CDImage> CDImage::OpenM3uImage(const char* filename, bool apply_patches, Common::Error* error)
std::unique_ptr<CDImage> CDImage::OpenM3uImage(const char* filename, bool apply_patches, Error* error)
{
std::unique_ptr<CDImageM3u> image = std::make_unique<CDImageM3u>();
if (!image->Open(filename, apply_patches, error))

View File

@ -39,7 +39,7 @@ public:
CDImageMds();
~CDImageMds() override;
bool OpenAndParse(const char* filename, Common::Error* error);
bool OpenAndParse(const char* filename, Error* error);
bool ReadSubChannelQ(SubChannelQ* subq, const Index& index, LBA lba_in_index) override;
bool HasNonStandardSubchannel() const override;
@ -61,15 +61,12 @@ CDImageMds::~CDImageMds()
std::fclose(m_mdf_file);
}
bool CDImageMds::OpenAndParse(const char* filename, Common::Error* error)
bool CDImageMds::OpenAndParse(const char* filename, Error* error)
{
std::FILE* mds_fp = FileSystem::OpenCFile(filename, "rb");
std::FILE* mds_fp = FileSystem::OpenCFile(filename, "rb", error);
if (!mds_fp)
{
Log_ErrorPrintf("Failed to open mds '%s': errno %d", filename, errno);
if (error)
error->SetErrno(errno);
return false;
}
@ -78,20 +75,15 @@ bool CDImageMds::OpenAndParse(const char* filename, Common::Error* error)
if (!mds_data_opt.has_value() || mds_data_opt->size() < 0x54)
{
Log_ErrorPrintf("Failed to read mds file '%s'", filename);
if (error)
error->SetFormattedMessage("Failed to read mds file '%s'", filename);
Error::SetString(error, fmt::format("Failed to read mds file '{}'", filename));
return false;
}
std::string mdf_filename(Path::ReplaceExtension(filename, "mdf"));
m_mdf_file = FileSystem::OpenCFile(mdf_filename.c_str(), "rb");
m_mdf_file = FileSystem::OpenCFile(mdf_filename.c_str(), "rb", error);
if (!m_mdf_file)
{
Log_ErrorPrintf("Failed to open mdf file '%s': errno %d", mdf_filename.c_str(), errno);
if (error)
error->SetFormattedMessage("Failed to open mdf file '%s': errno %d", mdf_filename.c_str(), errno);
return false;
}
@ -100,9 +92,7 @@ bool CDImageMds::OpenAndParse(const char* filename, Common::Error* error)
if (std::memcmp(&mds[0], expected_signature, sizeof(expected_signature) - 1) != 0)
{
Log_ErrorPrintf("Incorrect signature in '%s'", filename);
if (error)
error->SetFormattedMessage("Incorrect signature in '%s'", filename);
Error::SetString(error, fmt::format("Incorrect signature in '{}'", filename));
return false;
}
@ -111,9 +101,7 @@ bool CDImageMds::OpenAndParse(const char* filename, Common::Error* error)
if ((session_offset + 24) > mds.size())
{
Log_ErrorPrintf("Invalid session offset in '%s'", filename);
if (error)
error->SetFormattedMessage("Invalid session offset in '%s'", filename);
Error::SetString(error, fmt::format("Invalid session offset in '{}'", filename));
return false;
}
@ -124,9 +112,7 @@ bool CDImageMds::OpenAndParse(const char* filename, Common::Error* error)
if (track_count > 99 || track_offset >= mds.size())
{
Log_ErrorPrintf("Invalid track count/block offset %u/%u in '%s'", track_count, track_offset, filename);
if (error)
error->SetFormattedMessage("Invalid track count/block offset %u/%u in '%s'", track_count, track_offset, filename);
Error::SetString(error, fmt::format("Invalid track count/block offset {}/{} in '{}'", track_count, track_offset, filename));
return false;
}
@ -145,9 +131,7 @@ bool CDImageMds::OpenAndParse(const char* filename, Common::Error* error)
if ((track_offset + sizeof(TrackEntry)) > mds.size())
{
Log_ErrorPrintf("End of file in '%s' at track %u", filename, track_number);
if (error)
error->SetFormattedMessage("End of file in '%s' at track %u", filename, track_number);
Error::SetString(error, fmt::format("End of file in '{}' at track {}", filename, track_number));
return false;
}
@ -158,9 +142,7 @@ bool CDImageMds::OpenAndParse(const char* filename, Common::Error* error)
if (PackedBCDToBinary(track.track_number) != track_number)
{
Log_ErrorPrintf("Unexpected track number 0x%02X in track %u", track.track_number, track_number);
if (error)
error->SetFormattedMessage("Unexpected track number 0x%02X in track %u", track.track_number, track_number);
Error::SetString(error, fmt::format("Unexpected track number 0x{:02X} in track {}", track.track_number, track_number));
return false;
}
@ -171,9 +153,7 @@ bool CDImageMds::OpenAndParse(const char* filename, Common::Error* error)
if ((track.extra_offset + sizeof(u32) + sizeof(u32)) > mds.size())
{
Log_ErrorPrintf("Invalid extra offset %u in track %u", track.extra_offset, track_number);
if (error)
error->SetFormattedMessage("Invalid extra offset %u in track %u", track.extra_offset, track_number);
Error::SetString(error, fmt::format("Invalid extra offset {} in track {}", track.extra_offset, track_number));
return false;
}
@ -196,9 +176,7 @@ bool CDImageMds::OpenAndParse(const char* filename, Common::Error* error)
if (track_pregap > track_start_lba)
{
Log_ErrorPrintf("Track pregap %u is too large for start lba %u", track_pregap, track_start_lba);
if (error)
error->SetFormattedMessage("Track pregap %u is too large for start lba %u", track_pregap, track_start_lba);
Error::SetString(error, fmt::format("Track pregap {} is too large for start lba {}", track_pregap, track_start_lba));
return false;
}
@ -247,9 +225,7 @@ bool CDImageMds::OpenAndParse(const char* filename, Common::Error* error)
if (m_tracks.empty())
{
Log_ErrorPrintf("File '%s' contains no tracks", filename);
if (error)
error->SetFormattedMessage("File '%s' contains no tracks", filename);
Error::SetString(error, fmt::format("File '{}' contains no tracks", filename));
return false;
}
@ -297,7 +273,7 @@ bool CDImageMds::ReadSectorFromIndex(void* buffer, const Index& index, LBA lba_i
return true;
}
std::unique_ptr<CDImage> CDImage::OpenMdsImage(const char* filename, Common::Error* error)
std::unique_ptr<CDImage> CDImage::OpenMdsImage(const char* filename, Error* error)
{
std::unique_ptr<CDImageMds> image = std::make_unique<CDImageMds>();
if (!image->OpenAndParse(filename, error))

View File

@ -27,7 +27,7 @@ public:
CDImagePBP() = default;
~CDImagePBP() override;
bool Open(const char* filename, Common::Error* error);
bool Open(const char* filename, Error* error);
bool ReadSubChannelQ(SubChannelQ* subq, const Index& index, LBA lba_in_index) override;
bool HasNonStandardSubchannel() const override;
@ -35,7 +35,7 @@ public:
bool HasSubImages() const override;
u32 GetSubImageCount() const override;
u32 GetCurrentSubImage() const override;
bool SwitchSubImage(u32 index, Common::Error* error) override;
bool SwitchSubImage(u32 index, Error* error) override;
std::string GetMetadata(const std::string_view& type) const override;
std::string GetSubImageMetadata(u32 index, const std::string_view& type) const override;
@ -61,12 +61,12 @@ private:
bool LoadSFOIndexTable();
bool LoadSFOTable();
bool IsValidEboot(Common::Error* error);
bool IsValidEboot(Error* error);
bool InitDecompressionStream();
bool DecompressBlock(const BlockInfo& block_info);
bool OpenDisc(u32 index, Common::Error* error);
bool OpenDisc(u32 index, Error* error);
static const std::string* LookupStringSFOTableEntry(const char* key, const SFOTable& table);
@ -277,7 +277,7 @@ bool CDImagePBP::LoadSFOTable()
return true;
}
bool CDImagePBP::IsValidEboot(Common::Error* error)
bool CDImagePBP::IsValidEboot(Error* error)
{
// Check some fields to make sure this is a valid PS1 EBOOT.PBP
@ -288,16 +288,14 @@ bool CDImagePBP::IsValidEboot(Common::Error* error)
if (!std::holds_alternative<u32>(data_value) || std::get<u32>(data_value) != 1)
{
Log_ErrorPrint("Invalid BOOTABLE value");
if (error)
error->SetMessage("Invalid BOOTABLE value");
Error::SetString(error, "Invalid BOOTABLE value");
return false;
}
}
else
{
Log_ErrorPrint("No BOOTABLE value found");
if (error)
error->SetMessage("No BOOTABLE value found");
Error::SetString(error, "No BOOTABLE value found");
return false;
}
@ -308,23 +306,21 @@ bool CDImagePBP::IsValidEboot(Common::Error* error)
if (!std::holds_alternative<std::string>(data_value) || std::get<std::string>(data_value) != "ME")
{
Log_ErrorPrint("Invalid CATEGORY value");
if (error)
error->SetMessage("Invalid CATEGORY value");
Error::SetString(error, "Invalid CATEGORY value");
return false;
}
}
else
{
Log_ErrorPrint("No CATEGORY value found");
if (error)
error->SetMessage("No CATEGORY value found");
Error::SetString(error, "No CATEGORY value found");
return false;
}
return true;
}
bool CDImagePBP::Open(const char* filename, Common::Error* error)
bool CDImagePBP::Open(const char* filename, Error* error)
{
if (!EndianHelper::HostIsLittleEndian())
{
@ -347,8 +343,7 @@ bool CDImagePBP::Open(const char* filename, Common::Error* error)
if (!LoadPBPHeader())
{
Log_ErrorPrint("Failed to load PBP header");
if (error)
error->SetMessage("Failed to load PBP header");
Error::SetString(error, "Failed to load PBP header");
return false;
}
@ -356,8 +351,7 @@ bool CDImagePBP::Open(const char* filename, Common::Error* error)
if (!LoadSFOHeader())
{
Log_ErrorPrint("Failed to load SFO header");
if (error)
error->SetMessage("Failed to load SFO header");
Error::SetString(error, "Failed to load SFO header");
return false;
}
@ -365,8 +359,7 @@ bool CDImagePBP::Open(const char* filename, Common::Error* error)
if (!LoadSFOIndexTable())
{
Log_ErrorPrint("Failed to load SFO index table");
if (error)
error->SetMessage("Failed to load SFO index table");
Error::SetString(error, "Failed to load SFO index table");
return false;
}
@ -374,8 +367,7 @@ bool CDImagePBP::Open(const char* filename, Common::Error* error)
if (!LoadSFOTable())
{
Log_ErrorPrint("Failed to load SFO table");
if (error)
error->SetMessage("Failed to load SFO table");
Error::SetString(error, "Failed to load SFO table");
return false;
}
@ -412,9 +404,7 @@ bool CDImagePBP::Open(const char* filename, Common::Error* error)
if (disc_table[0] == 0x44475000) // "\0PGD"
{
Log_ErrorPrintf("Encrypted PBP images are not supported, skipping %s", m_filename.c_str());
if (error)
error->SetMessage("Encrypted PBP images are not supported");
Error::SetString(error, "Encrypted PBP images are not supported");
return false;
}
@ -442,13 +432,12 @@ bool CDImagePBP::Open(const char* filename, Common::Error* error)
return OpenDisc(0, error);
}
bool CDImagePBP::OpenDisc(u32 index, Common::Error* error)
bool CDImagePBP::OpenDisc(u32 index, Error* error)
{
if (index >= m_disc_offsets.size())
{
Log_ErrorPrintf("File does not contain disc %u", index + 1);
if (error)
error->SetMessage(TinyString::FromFormat("File does not contain disc %u", index + 1));
Error::SetString(error, fmt::format("File does not contain disc {}", index + 1));
return false;
}
@ -484,9 +473,7 @@ bool CDImagePBP::OpenDisc(u32 index, Common::Error* error)
if (pgd_magic == 0x44475000) // "\0PGD"
{
Log_ErrorPrintf("Encrypted PBP images are not supported, skipping %s", m_filename.c_str());
if (error)
error->SetMessage("Encrypted PBP images are not supported");
Error::SetString(error, "Encrypted PBP images are not supported");
return false;
}
@ -867,7 +854,7 @@ u32 CDImagePBP::GetCurrentSubImage() const
return m_current_disc;
}
bool CDImagePBP::SwitchSubImage(u32 index, Common::Error* error)
bool CDImagePBP::SwitchSubImage(u32 index, Error* error)
{
if (index >= m_disc_offsets.size())
return false;
@ -895,7 +882,7 @@ std::string CDImagePBP::GetSubImageMetadata(u32 index, const std::string_view& t
return CDImage::GetSubImageMetadata(index, type);
}
std::unique_ptr<CDImage> CDImage::OpenPBPImage(const char* filename, Common::Error* error)
std::unique_ptr<CDImage> CDImage::OpenPBPImage(const char* filename, Error* error)
{
std::unique_ptr<CDImagePBP> image = std::make_unique<CDImagePBP>();
if (!image->Open(filename, error))

View File

@ -45,7 +45,7 @@ Track* File::GetMutableTrack(u32 n)
return nullptr;
}
bool File::Parse(std::FILE* fp, Common::Error* error)
bool File::Parse(std::FILE* fp, Error* error)
{
char line[1024];
u32 line_number = 1;
@ -66,7 +66,7 @@ bool File::Parse(std::FILE* fp, Common::Error* error)
return true;
}
void File::SetError(u32 line_number, Common::Error* error, const char* format, ...)
void File::SetError(u32 line_number, Error* error, const char* format, ...)
{
std::va_list ap;
SmallString str;
@ -75,9 +75,7 @@ void File::SetError(u32 line_number, Common::Error* error, const char* format, .
va_end(ap);
Log_ErrorPrintf("Cue parse error at line %u: %s", line_number, str.GetCharArray());
if (error)
error->SetFormattedMessage("Cue parse error at line %u: %s", line_number, str.GetCharArray());
Error::SetString(error, fmt::format("Cue parse error at line {}: {}", line_number, str));
}
std::string_view File::GetToken(const char*& line)
@ -166,7 +164,7 @@ std::optional<MSF> File::GetMSF(const std::string_view& token)
return ret;
}
bool File::ParseLine(const char* line, u32 line_number, Common::Error* error)
bool File::ParseLine(const char* line, u32 line_number, Error* error)
{
const std::string_view command(GetToken(line));
if (command.empty())
@ -210,7 +208,7 @@ bool File::ParseLine(const char* line, u32 line_number, Common::Error* error)
return false;
}
bool File::HandleFileCommand(const char* line, u32 line_number, Common::Error* error)
bool File::HandleFileCommand(const char* line, u32 line_number, Error* error)
{
const std::string_view filename(GetToken(line));
const std::string_view mode(GetToken(line));
@ -232,7 +230,7 @@ bool File::HandleFileCommand(const char* line, u32 line_number, Common::Error* e
return true;
}
bool File::HandleTrackCommand(const char* line, u32 line_number, Common::Error* error)
bool File::HandleTrackCommand(const char* line, u32 line_number, Error* error)
{
if (!CompleteLastTrack(line_number, error))
return false;
@ -288,7 +286,7 @@ bool File::HandleTrackCommand(const char* line, u32 line_number, Common::Error*
return true;
}
bool File::HandleIndexCommand(const char* line, u32 line_number, Common::Error* error)
bool File::HandleIndexCommand(const char* line, u32 line_number, Error* error)
{
if (!m_current_track.has_value())
{
@ -334,7 +332,7 @@ bool File::HandleIndexCommand(const char* line, u32 line_number, Common::Error*
return true;
}
bool File::HandlePregapCommand(const char* line, u32 line_number, Common::Error* error)
bool File::HandlePregapCommand(const char* line, u32 line_number, Error* error)
{
if (!m_current_track.has_value())
{
@ -366,7 +364,7 @@ bool File::HandlePregapCommand(const char* line, u32 line_number, Common::Error*
return true;
}
bool File::HandleFlagCommand(const char* line, u32 line_number, Common::Error* error)
bool File::HandleFlagCommand(const char* line, u32 line_number, Error* error)
{
if (!m_current_track.has_value())
{
@ -395,7 +393,7 @@ bool File::HandleFlagCommand(const char* line, u32 line_number, Common::Error* e
return true;
}
bool File::CompleteLastTrack(u32 line_number, Common::Error* error)
bool File::CompleteLastTrack(u32 line_number, Error* error)
{
if (!m_current_track.has_value())
return true;
@ -436,7 +434,7 @@ bool File::CompleteLastTrack(u32 line_number, Common::Error* error)
return true;
}
bool File::SetTrackLengths(u32 line_number, Common::Error* error)
bool File::SetTrackLengths(u32 line_number, Error* error)
{
for (const Track& track : m_tracks)
{

View File

@ -60,26 +60,26 @@ public:
const Track* GetTrack(u32 n) const;
bool Parse(std::FILE* fp, Common::Error* error);
bool Parse(std::FILE* fp, Error* error);
private:
Track* GetMutableTrack(u32 n);
void SetError(u32 line_number, Common::Error* error, const char* format, ...);
void SetError(u32 line_number, Error* error, const char* format, ...);
static std::string_view GetToken(const char*& line);
static std::optional<MSF> GetMSF(const std::string_view& token);
bool ParseLine(const char* line, u32 line_number, Common::Error* error);
bool ParseLine(const char* line, u32 line_number, Error* error);
bool HandleFileCommand(const char* line, u32 line_number, Common::Error* error);
bool HandleTrackCommand(const char* line, u32 line_number, Common::Error* error);
bool HandleIndexCommand(const char* line, u32 line_number, Common::Error* error);
bool HandlePregapCommand(const char* line, u32 line_number, Common::Error* error);
bool HandleFlagCommand(const char* line, u32 line_number, Common::Error* error);
bool HandleFileCommand(const char* line, u32 line_number, Error* error);
bool HandleTrackCommand(const char* line, u32 line_number, Error* error);
bool HandleIndexCommand(const char* line, u32 line_number, Error* error);
bool HandlePregapCommand(const char* line, u32 line_number, Error* error);
bool HandleFlagCommand(const char* line, u32 line_number, Error* error);
bool CompleteLastTrack(u32 line_number, Common::Error* error);
bool SetTrackLengths(u32 line_number, Common::Error* error);
bool CompleteLastTrack(u32 line_number, Error* error);
bool SetTrackLengths(u32 line_number, Error* error);
std::vector<Track> m_tracks;
std::optional<std::string> m_current_file;