#include "GpFileStream_Win32.h" GpFileStream_Win32::GpFileStream_Win32(HANDLE handle, bool readable, bool writeable, bool seekable) : m_handle(handle) , m_readable(readable) , m_writeable(writeable) , m_seekable(seekable) { } size_t GpFileStream_Win32::Read(void *bytesOut, size_t size) { if (!m_readable) return 0; size_t totalRead = 0; while (size) { const DWORD chunkSizeToRead = (size > MAXDWORD) ? MAXDWORD : size; DWORD numRead = 0; BOOL readSucceeded = ReadFile(m_handle, bytesOut, chunkSizeToRead, &numRead, nullptr); if (!readSucceeded) return totalRead; totalRead += static_cast(numRead); size -= static_cast(numRead); bytesOut = static_cast(static_cast(bytesOut) + numRead); if (numRead != chunkSizeToRead) return totalRead; } return totalRead; } size_t GpFileStream_Win32::Write(const void *bytes, size_t size) { if (!m_writeable) return 0; size_t totalWritten = 0; while (size) { const DWORD chunkSizeToWrite = (size > MAXDWORD) ? MAXDWORD : size; DWORD numWritten = 0; BOOL writeSucceeded = WriteFile(m_handle, bytes, chunkSizeToWrite, &numWritten, nullptr); if (!writeSucceeded) return totalWritten; totalWritten += static_cast(numWritten); size -= static_cast(numWritten); bytes = static_cast(static_cast(bytes) + numWritten); if (numWritten != chunkSizeToWrite) return totalWritten; } return totalWritten; } bool GpFileStream_Win32::IsSeekable() const { return m_seekable; } bool GpFileStream_Win32::IsReadOnly() const { return !m_writeable; } bool GpFileStream_Win32::IsWriteOnly() const { return !m_readable; } bool GpFileStream_Win32::SeekStart(PortabilityLayer::UFilePos_t loc) { LARGE_INTEGER li; li.QuadPart = static_cast(loc); return SetFilePointerEx(m_handle, li, nullptr, FILE_BEGIN) != 0; } bool GpFileStream_Win32::SeekCurrent(PortabilityLayer::FilePos_t loc) { LARGE_INTEGER li; li.QuadPart = static_cast(loc); return SetFilePointerEx(m_handle, li, nullptr, FILE_CURRENT) != 0; } bool GpFileStream_Win32::SeekEnd(PortabilityLayer::UFilePos_t loc) { LARGE_INTEGER li; li.QuadPart = static_cast(loc); return SetFilePointerEx(m_handle, li, nullptr, FILE_END) != 0; } bool GpFileStream_Win32::Truncate(PortabilityLayer::UFilePos_t loc) { if (!m_writeable) return false; PortabilityLayer::UFilePos_t oldPos = Tell(); if (!SeekStart(loc)) return false; if (!SetEndOfFile(m_handle)) return false; if (!SeekStart(oldPos)) return false; return true; } PortabilityLayer::UFilePos_t GpFileStream_Win32::Size() const { LARGE_INTEGER fsize; if (!GetFileSizeEx(m_handle, &fsize)) return 0; return static_cast(fsize.QuadPart); } PortabilityLayer::UFilePos_t GpFileStream_Win32::Tell() const { LARGE_INTEGER zero; zero.QuadPart = 0; LARGE_INTEGER fpos; if (!SetFilePointerEx(m_handle, zero, &fpos, FILE_CURRENT)) return 0; return static_cast(fpos.QuadPart); } void GpFileStream_Win32::Close() { CloseHandle(m_handle); }