Files
SweepStore/cpp/src/Private/sweepstore/utils/file_handle.cpp

128 lines
3.2 KiB
C++

#include "sweepstore/utils/file_handle.h"
// Constructor
SweepstoreFileHandle::SweepstoreFileHandle(const std::string& p, std::ios::openmode mode)
: path(p)
#ifdef WITH_UNREAL
{
IPlatformFile& platformFile = FPlatformFileManager::Get().GetPlatformFile();
// Map std::ios flags to Unreal flags
bool read = (mode & std::ios::in) != 0;
bool write = (mode & std::ios::out) != 0;
if (read && write) {
unrealHandle = platformFile.OpenReadWrite(*FString(path.c_str()), true);
} else if (write) {
unrealHandle = platformFile.OpenWrite(*FString(path.c_str()), false, false);
} else {
unrealHandle = platformFile.OpenRead(*FString(path.c_str()), false);
}
if (!unrealHandle) {
throw std::runtime_error("Failed to open file: " + path);
}
}
#else
, stream(std::make_unique<std::fstream>(p, mode))
{
if (!stream->is_open()) {
throw std::runtime_error("Failed to open file: " + path);
}
}
#endif
// isOpen
bool SweepstoreFileHandle::isOpen() const {
#ifdef WITH_UNREAL
return unrealHandle != nullptr;
#else
return stream && stream->is_open();
#endif
}
// close
void SweepstoreFileHandle::close() {
#ifdef WITH_UNREAL
if (unrealHandle) {
delete unrealHandle;
unrealHandle = nullptr;
}
#else
if (stream) {
stream->close();
}
#endif
}
// readSeek
void SweepstoreFileHandle::readSeek(std::streampos pos, std::ios::seekdir dir) {
#ifdef WITH_UNREAL
// Unreal doesn't have separate read/write pointers, so just seek
int64 unrealPos = static_cast<int64>(pos);
if (dir == std::ios::beg) {
unrealHandle->Seek(unrealPos);
} else if (dir == std::ios::cur) {
unrealHandle->Seek(unrealHandle->Tell() + unrealPos);
} else if (dir == std::ios::end) {
unrealHandle->SeekFromEnd(unrealPos);
}
#else
#ifdef _WIN32
// On Windows, flush and sync to disk, then invalidate buffers
stream->flush();
stream->sync();
stream->clear();
// Sync both pointers to same position
stream->seekp(pos, dir);
stream->seekg(pos, dir);
#else
stream->seekg(pos, dir);
#endif
#endif
}
// writeSeek
void SweepstoreFileHandle::writeSeek(std::streampos pos, std::ios::seekdir dir) {
#ifdef WITH_UNREAL
// Same as readSeek for Unreal
readSeek(pos, dir);
#else
#ifdef _WIN32
stream->flush();
stream->sync();
#endif
stream->seekp(pos, dir);
#endif
}
// readBytes
void SweepstoreFileHandle::readBytes(char* buffer, std::streamsize size) {
#ifdef WITH_UNREAL
unrealHandle->Read(reinterpret_cast<uint8*>(buffer), size);
#else
stream->read(buffer, size);
#ifdef _WIN32
// Check for read errors on Windows
if (stream->fail() && !stream->eof()) {
stream->clear();
}
#endif
#endif
}
// writeBytes
void SweepstoreFileHandle::writeBytes(const char* buffer, std::streamsize size) {
#ifdef WITH_UNREAL
unrealHandle->Write(reinterpret_cast<const uint8*>(buffer), size);
unrealHandle->Flush(); // Unreal requires explicit flush
#else
stream->write(buffer, size);
#ifdef _WIN32
// Check for write errors on Windows
if (stream->fail()) {
stream->clear();
}
#endif
#endif
}