#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(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(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(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(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 }