Files
aurora/lib/card/FileIO.cpp
T
CraftyBoss a801671643 Card gci folder update (#135)
* add ability to set path of card image before CARDInit

* begin work on updating card class to support gci folders

a lot of work will just be directly reading from whatever folder is supplied, instead of relying on an always open FileIO handle

* swap to interface system for easier code seperation, begin actually planning out logic for gci loading

* fix wrong name for func, add modified time to new gci file entry

* get gci folder working

tp seems to be happy with everything ive done, the only funcs im worried about are getSerial and getChecksum as those dont do anything atm.

* fix createFile not assigning file index to output FileHandle, CARDSetLoadType now takes an enum

* make probeCardFile a virtual func so GciFolder and RawFile can both implement their own, bit of cleanup
2026-04-23 22:39:42 -07:00

122 lines
2.4 KiB
C++

#include "FileIO.hpp"
#include <SDL3/SDL_iostream.h>
#include <SDL3/SDL_filesystem.h>
#include <cstdint>
#include <utility>
namespace aurora::card {
FileIO::FileIO(std::string_view filename, bool truncate) {
m_path = filename;
SDL_IOStream* stream = nullptr;
stream = fileOpen(m_path.c_str(), truncate ? "w+b" : "r+b");
if (stream != nullptr) {
SDL_FlushIO(stream);
SDL_CloseIO(stream);
m_ready = true;
}
}
FileIO::FileIO(FileIO&& other) noexcept {
m_path = std::move(other.m_path);
m_ready = std::exchange(other.m_ready, false);
}
FileIO& FileIO::operator=(FileIO&& other) noexcept {
if (this != &other) {
m_path = std::move(other.m_path);
m_ready = std::exchange(other.m_ready, false);
}
return *this;
}
bool FileIO::fileRead(void* buf, size_t length, off_t offset) {
if (!isReady()) {
return false;
}
SDL_IOStream* stream = fileOpen(m_path, "rb");
if (stream == nullptr) {
return false;
}
if (SDL_SeekIO(stream, offset, SDL_IO_SEEK_SET) < 0) {
SDL_CloseIO(stream);
return false;
}
size_t total = 0;
auto* dst = static_cast<uint8_t*>(buf);
while (total < length) {
const size_t read = SDL_ReadIO(stream, dst + total, length - total);
if (read == 0) {
SDL_CloseIO(stream);
return false;
}
total += read;
}
SDL_CloseIO(stream);
return true;
}
bool FileIO::fileWrite(const void* buf, size_t length, off_t offset) {
if (!isReady()) {
return false;
}
SDL_IOStream* stream = fileOpen(m_path, "r+b");
if (stream == nullptr) {
stream = fileOpen(m_path, "w+b");
}
if (stream == nullptr) {
return false;
}
if (SDL_SeekIO(stream, offset, SDL_IO_SEEK_SET) < 0) {
SDL_FlushIO(stream);
SDL_CloseIO(stream);
return false;
}
size_t total = 0;
auto* src = static_cast<const uint8_t*>(buf);
while (total < length) {
const size_t written = SDL_WriteIO(stream, src + total, length - total);
if (written == 0) {
SDL_CloseIO(stream);
return false;
}
total += written;
}
SDL_FlushIO(stream);
SDL_CloseIO(stream);
return true;
}
size_t FileIO::fileSize() const {
SDL_PathInfo info;
if (SDL_GetPathInfo(m_path.c_str(), &info)) {
return info.size;
}
return 0;
}
bool FileIO::deleteFile() {
if (SDL_RemovePath(m_path.c_str())) {
m_ready = false;
m_path.clear();
return true;
}
return false;
}
FileIO::operator bool() const { return isReady(); }
} // namespace aurora::card