mirror of
https://github.com/encounter/aurora.git
synced 2026-07-09 18:19:33 -07:00
Refactor CARD FileIO with on-demand handles (#77)
* Refactor CARD FileIO with on-demand handles * Guarantee stream is flushed before closing handle
This commit is contained in:
+34
-22
@@ -7,37 +7,28 @@
|
||||
|
||||
namespace aurora::card {
|
||||
|
||||
bool FileIO::isReady() const { return m_stream != nullptr; }
|
||||
|
||||
FileIO::FileIO(std::string_view filename, bool truncate) {
|
||||
m_path = filename;
|
||||
if (!truncate) {
|
||||
m_stream = SDL_IOFromFile(m_path.c_str(), "r+b");
|
||||
}
|
||||
if (m_stream == nullptr) {
|
||||
m_stream = SDL_IOFromFile(m_path.c_str(), "w+b");
|
||||
}
|
||||
}
|
||||
SDL_IOStream* stream = nullptr;
|
||||
|
||||
FileIO::~FileIO() {
|
||||
if (m_stream != nullptr) {
|
||||
SDL_CloseIO(m_stream);
|
||||
m_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_stream = std::exchange(other.m_stream, nullptr);
|
||||
m_path = std::move(other.m_path);
|
||||
m_ready = std::exchange(other.m_ready, false);
|
||||
}
|
||||
|
||||
FileIO& FileIO::operator=(FileIO&& other) noexcept {
|
||||
if (this != &other) {
|
||||
if (m_stream != nullptr) {
|
||||
SDL_CloseIO(m_stream);
|
||||
}
|
||||
m_stream = std::exchange(other.m_stream, nullptr);
|
||||
m_path = std::move(other.m_path);
|
||||
m_ready = std::exchange(other.m_ready, false);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -47,20 +38,28 @@ bool FileIO::fileRead(void* buf, size_t length, off_t offset) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SDL_SeekIO(m_stream, offset, SDL_IO_SEEK_SET) < 0) {
|
||||
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(m_stream, dst + total, length - total);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -69,20 +68,33 @@ bool FileIO::fileWrite(const void* buf, size_t length, off_t offset) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SDL_SeekIO(m_stream, offset, SDL_IO_SEEK_SET) < 0) {
|
||||
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(m_stream, src + total, length - total);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -9,20 +9,21 @@ namespace aurora::card {
|
||||
|
||||
class FileIO {
|
||||
std::string m_path;
|
||||
SDL_IOStream* m_stream = nullptr;
|
||||
bool m_ready = false;
|
||||
|
||||
bool isReady() const;
|
||||
bool isReady() const { return m_ready && !m_path.empty(); };
|
||||
|
||||
public:
|
||||
FileIO() = default;
|
||||
explicit FileIO(std::string_view filename, bool truncate = false);
|
||||
~FileIO();
|
||||
~FileIO() = default;
|
||||
|
||||
FileIO(FileIO&& other) noexcept;
|
||||
FileIO& operator=(FileIO&& other) noexcept;
|
||||
FileIO(const FileIO& other) = delete;
|
||||
FileIO& operator=(const FileIO& other) = delete;
|
||||
|
||||
static SDL_IOStream* fileOpen(const std::string& path, const char* mode) {return path.empty() ? nullptr : SDL_IOFromFile(path.c_str(), mode);}
|
||||
bool fileRead(void* buf, size_t length, off_t offset);
|
||||
bool fileWrite(const void* buf, size_t length, off_t offset);
|
||||
explicit operator bool() const;
|
||||
|
||||
Reference in New Issue
Block a user