Implement file handling improvements with Unreal compatibility and enhanced read/write methods
This commit is contained in:
110
cpp/src/Private/sweepstore/utils/file_handle.cpp
Normal file
110
cpp/src/Private/sweepstore/utils/file_handle.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
#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 output and sync to invalidate input buffer
|
||||
stream->flush();
|
||||
stream->seekp(pos, dir); // Sync put pointer
|
||||
#endif
|
||||
stream->seekg(pos, dir);
|
||||
#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(); // Flush any pending writes
|
||||
#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);
|
||||
#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);
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user