mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-13 17:49:47 +12:00
Migrate IOFile
implementation to io_file.cpp
Makes the implementation of `IOFile` private, allowing inclusions and defines such as `#define fseeko` and `#include <io.h>` to not poison client-code or the global namespace.
This commit is contained in:
parent
c042dbc293
commit
1b9f270b19
3 changed files with 138 additions and 114 deletions
|
@ -67,7 +67,7 @@ else()
|
||||||
message(FATAL_ERROR "Currently unsupported CPU architecture")
|
message(FATAL_ERROR "Currently unsupported CPU architecture")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(SOURCE_FILES src/main.cpp src/emulator.cpp src/core/CPU/cpu_dynarmic.cpp src/core/CPU/dynarmic_cycles.cpp
|
set(SOURCE_FILES src/main.cpp src/emulator.cpp src/io_file.cpp src/core/CPU/cpu_dynarmic.cpp src/core/CPU/dynarmic_cycles.cpp
|
||||||
src/core/memory.cpp
|
src/core/memory.cpp
|
||||||
)
|
)
|
||||||
set(KERNEL_SOURCE_FILES src/core/kernel/kernel.cpp src/core/kernel/resource_limits.cpp
|
set(KERNEL_SOURCE_FILES src/core/kernel/kernel.cpp src/core/kernel/resource_limits.cpp
|
||||||
|
|
|
@ -1,136 +1,45 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdio>
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
// 64 bit offsets for MSVC
|
|
||||||
#define fseeko _fseeki64
|
|
||||||
#define ftello _ftelli64
|
|
||||||
#define fileno _fileno
|
|
||||||
|
|
||||||
#pragma warning(disable : 4996)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#include <io.h> // For _chsize_s
|
|
||||||
#else
|
|
||||||
#include <unistd.h> // For ftruncate
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class IOFile {
|
class IOFile {
|
||||||
FILE* handle = nullptr;
|
FILE* handle = nullptr;
|
||||||
static inline std::filesystem::path appData = ""; // Directory for holding app data. AppData on Windows
|
static inline std::filesystem::path appData = ""; // Directory for holding app data. AppData on Windows
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IOFile() {}
|
IOFile();
|
||||||
IOFile(FILE* handle) : handle(handle) {}
|
IOFile(FILE* handle);
|
||||||
IOFile(const std::filesystem::path& path, const char* permissions = "rb") {
|
IOFile(const std::filesystem::path& path, const char* permissions = "rb");
|
||||||
open(path, permissions);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isOpen() {
|
bool isOpen();
|
||||||
return handle != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool open(const std::filesystem::path& path, const char* permissions = "rb") {
|
bool open(const std::filesystem::path& path, const char* permissions = "rb");
|
||||||
const auto str = path.string(); // For some reason converting paths directly with c_str() doesn't work
|
|
||||||
return open(str.c_str(), permissions);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool open(const char* filename, const char* permissions = "rb") {
|
bool open(const char* filename, const char* permissions = "rb");
|
||||||
handle = std::fopen(filename, permissions);
|
|
||||||
return isOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
void close() {
|
void close();
|
||||||
if (isOpen()) {
|
|
||||||
fclose(handle);
|
|
||||||
handle = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<bool, std::size_t> read(void* data, std::size_t length, std::size_t dataSize) {
|
std::pair<bool, std::size_t> read(void* data, std::size_t length, std::size_t dataSize);
|
||||||
if (!isOpen()) {
|
|
||||||
return { false, std::numeric_limits<std::size_t>::max() };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length == 0) return { true, 0 };
|
std::pair<bool, std::size_t> readBytes(void* data, std::size_t count);
|
||||||
return { true, std::fread(data, dataSize, length, handle) };
|
|
||||||
}
|
|
||||||
|
|
||||||
auto readBytes(void* data, std::size_t count) {
|
std::pair<bool, std::size_t> write(const void* data, std::size_t length, std::size_t dataSize);
|
||||||
return read(data, count, sizeof(std::uint8_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<bool, std::size_t> write(const void* data, std::size_t length, std::size_t dataSize) {
|
std::pair<bool, std::size_t> writeBytes(const void* data, std::size_t count);
|
||||||
if (!isOpen()) {
|
|
||||||
return { false, std::numeric_limits<std::size_t>::max() };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length == 0) return { true, 0 };
|
std::optional<std::uint64_t> size();
|
||||||
return { true, std::fwrite(data, dataSize, length, handle) };
|
|
||||||
}
|
|
||||||
|
|
||||||
auto writeBytes(const void* data, std::size_t count) {
|
bool seek(std::int64_t offset, int origin = SEEK_SET);
|
||||||
return write(data, count, sizeof(std::uint8_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<std::uint64_t> size() {
|
bool rewind();
|
||||||
if (!isOpen()) return {};
|
|
||||||
|
|
||||||
std::uint64_t pos = ftello(handle);
|
FILE* getHandle();
|
||||||
if (fseeko(handle, 0, SEEK_END) != 0) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::uint64_t size = ftello(handle);
|
static void setAppDataDir(const std::filesystem::path& dir);
|
||||||
if ((size != pos) && (fseeko(handle, pos, SEEK_SET) != 0)) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
// Sets the size of the file to "size" and returns whether it succeeded or not
|
||||||
}
|
bool setSize(std::uint64_t size);
|
||||||
|
|
||||||
bool seek(std::int64_t offset, int origin = SEEK_SET) {
|
static std::filesystem::path getAppData();
|
||||||
if (!isOpen() || fseeko(handle, offset, origin) != 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool rewind() {
|
|
||||||
return seek(0, SEEK_SET);
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE* getHandle() {
|
|
||||||
return handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setAppDataDir(const std::filesystem::path& dir) {
|
|
||||||
if (dir == "") Helpers::panic("Failed to set app data directory");
|
|
||||||
appData = dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets the size of the file to "size" and returns whether it succeeded or not
|
|
||||||
bool setSize(std::uint64_t size) {
|
|
||||||
if (!isOpen()) return false;
|
|
||||||
bool success;
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
success = _chsize_s(_fileno(handle), size) == 0;
|
|
||||||
#else
|
|
||||||
success = ftruncate(fileno(handle), size) == 0;
|
|
||||||
#endif
|
|
||||||
fflush(handle);
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::filesystem::path getAppData() { return IOFile::appData; }
|
|
||||||
};
|
};
|
115
src/io_file.cpp
Normal file
115
src/io_file.cpp
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
#include "io_file.hpp"
|
||||||
|
|
||||||
|
#include "helpers.hpp"
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
// 64 bit offsets for MSVC
|
||||||
|
#define fseeko _fseeki64
|
||||||
|
#define ftello _ftelli64
|
||||||
|
#define fileno _fileno
|
||||||
|
|
||||||
|
#pragma warning(disable : 4996)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||||
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <io.h> // For _chsize_s
|
||||||
|
#else
|
||||||
|
#include <unistd.h> // For ftruncate
|
||||||
|
#endif
|
||||||
|
|
||||||
|
IOFile::IOFile() {}
|
||||||
|
|
||||||
|
IOFile::IOFile(FILE* handle) : handle(handle) {}
|
||||||
|
|
||||||
|
IOFile::IOFile(const std::filesystem::path& path, const char* permissions) { open(path, permissions); }
|
||||||
|
|
||||||
|
bool IOFile::isOpen() { return handle != nullptr; }
|
||||||
|
|
||||||
|
bool IOFile::open(const std::filesystem::path& path, const char* permissions) {
|
||||||
|
const auto str = path.string(); // For some reason converting paths directly with c_str() doesn't work
|
||||||
|
return open(str.c_str(), permissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOFile::open(const char* filename, const char* permissions) {
|
||||||
|
handle = std::fopen(filename, permissions);
|
||||||
|
return isOpen();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOFile::close() {
|
||||||
|
if (isOpen()) {
|
||||||
|
fclose(handle);
|
||||||
|
handle = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<bool, std::size_t> IOFile::read(void* data, std::size_t length, std::size_t dataSize) {
|
||||||
|
if (!isOpen()) {
|
||||||
|
return {false, std::numeric_limits<std::size_t>::max()};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length == 0) return {true, 0};
|
||||||
|
return {true, std::fread(data, dataSize, length, handle)};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<bool, std::size_t> IOFile::readBytes(void* data, std::size_t count) { return read(data, count, sizeof(std::uint8_t)); }
|
||||||
|
|
||||||
|
std::pair<bool, std::size_t> IOFile::write(const void* data, std::size_t length, std::size_t dataSize) {
|
||||||
|
if (!isOpen()) {
|
||||||
|
return {false, std::numeric_limits<std::size_t>::max()};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length == 0) return {true, 0};
|
||||||
|
return {true, std::fwrite(data, dataSize, length, handle)};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<bool, std::size_t> IOFile::writeBytes(const void* data, std::size_t count) { return write(data, count, sizeof(std::uint8_t)); }
|
||||||
|
|
||||||
|
std::optional<std::uint64_t> IOFile::size() {
|
||||||
|
if (!isOpen()) return {};
|
||||||
|
|
||||||
|
std::uint64_t pos = ftello(handle);
|
||||||
|
if (fseeko(handle, 0, SEEK_END) != 0) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint64_t size = ftello(handle);
|
||||||
|
if ((size != pos) && (fseeko(handle, pos, SEEK_SET) != 0)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOFile::seek(std::int64_t offset, int origin) {
|
||||||
|
if (!isOpen() || fseeko(handle, offset, origin) != 0) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOFile::rewind() { return seek(0, SEEK_SET); }
|
||||||
|
|
||||||
|
FILE* IOFile::getHandle() { return handle; }
|
||||||
|
|
||||||
|
void IOFile::setAppDataDir(const std::filesystem::path& dir) {
|
||||||
|
if (dir == "") Helpers::panic("Failed to set app data directory");
|
||||||
|
appData = dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOFile::setSize(std::uint64_t size) {
|
||||||
|
if (!isOpen()) return false;
|
||||||
|
bool success;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
success = _chsize_s(_fileno(handle), size) == 0;
|
||||||
|
#else
|
||||||
|
success = ftruncate(fileno(handle), size) == 0;
|
||||||
|
#endif
|
||||||
|
fflush(handle);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::filesystem::path IOFile::getAppData() { return IOFile::appData; }
|
Loading…
Add table
Reference in a new issue