aboutsummaryrefslogtreecommitdiff
path: root/src/zenutil/basicfile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/zenutil/basicfile.cpp')
-rw-r--r--src/zenutil/basicfile.cpp94
1 files changed, 84 insertions, 10 deletions
diff --git a/src/zenutil/basicfile.cpp b/src/zenutil/basicfile.cpp
index 1dce71e60..7d0edaa5d 100644
--- a/src/zenutil/basicfile.cpp
+++ b/src/zenutil/basicfile.cpp
@@ -76,16 +76,15 @@ BasicFile::Open(const std::filesystem::path& FileName, Mode InMode, std::error_c
const DWORD dwShareMode = FILE_SHARE_READ | (EnumHasAllFlags(InMode, Mode::kPreventWrite) ? 0 : FILE_SHARE_WRITE) |
(EnumHasAllFlags(InMode, Mode::kPreventDelete) ? 0 : FILE_SHARE_DELETE);
- const DWORD dwFlagsAndAttributes =
- FILE_ATTRIBUTE_NORMAL | (EnumHasAllFlags(InMode, Mode::kDeleteOnClose) ? FILE_FLAG_DELETE_ON_CLOSE : 0);
- const HANDLE hTemplateFile = nullptr;
- const HANDLE FileHandle = CreateFile(FileName.c_str(),
- dwDesiredAccess,
- dwShareMode,
- /* lpSecurityAttributes */ nullptr,
- dwCreationDisposition,
- dwFlagsAndAttributes,
- hTemplateFile);
+ const DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
+ const HANDLE hTemplateFile = nullptr;
+ const HANDLE FileHandle = CreateFile(FileName.c_str(),
+ dwDesiredAccess,
+ dwShareMode,
+ /* lpSecurityAttributes */ nullptr,
+ dwCreationDisposition,
+ dwFlagsAndAttributes,
+ hTemplateFile);
if (FileHandle == INVALID_HANDLE_VALUE)
{
@@ -588,6 +587,8 @@ LockFile::Update(CbObject Payload, std::error_code& Ec)
BasicFile::Write(Payload.GetBuffer(), 0, Ec);
}
+//////////////////////////////////////////////////////////////////////////
+
BasicFileBuffer::BasicFileBuffer(BasicFile& Base, uint64_t BufferSize)
: m_Base(Base)
, m_Buffer(nullptr)
@@ -662,6 +663,79 @@ BasicFileBuffer::MakeView(uint64_t Size, uint64_t FileOffset)
return MemoryView(m_Buffer + (FileOffset - m_BufferStart), Size);
}
+//////////////////////////////////////////////////////////////////////////
+
+BasicFileWriter::BasicFileWriter(BasicFile& Base, uint64_t BufferSize)
+: m_Base(Base)
+, m_Buffer(nullptr)
+, m_BufferSize(BufferSize)
+, m_BufferStart(0)
+, m_BufferEnd(0)
+{
+ m_Buffer = (uint8_t*)Memory::Alloc(m_BufferSize);
+}
+
+BasicFileWriter::~BasicFileWriter()
+{
+ Flush();
+ Memory::Free(m_Buffer);
+}
+
+void
+BasicFileWriter::Write(void* Data, uint64_t Size, uint64_t FileOffset)
+{
+ if (m_Buffer == nullptr || (Size >= m_BufferSize))
+ {
+ m_Base.Write(Data, Size, FileOffset);
+ return;
+ }
+
+ // Note that this only supports buffering of sequential writes!
+
+ if (FileOffset != m_BufferEnd)
+ {
+ Flush();
+ m_BufferStart = m_BufferEnd = FileOffset;
+ }
+
+ while (Size)
+ {
+ const uint64_t RemainingBufferCapacity = m_BufferStart + m_BufferSize - m_BufferEnd;
+ const uint64_t BlockWriteBytes = Min(RemainingBufferCapacity, Size);
+ const uint64_t BufferWriteOffset = FileOffset - m_BufferStart;
+
+ ZEN_ASSERT_SLOW(BufferWriteOffset < m_BufferSize);
+ ZEN_ASSERT_SLOW((BufferWriteOffset + BlockWriteBytes) <= m_BufferSize);
+
+ memcpy(m_Buffer + BufferWriteOffset, Data, BlockWriteBytes);
+
+ Size -= BlockWriteBytes;
+ m_BufferEnd += BlockWriteBytes;
+ FileOffset += BlockWriteBytes;
+
+ if ((m_BufferEnd - m_BufferStart) == m_BufferSize)
+ {
+ Flush();
+ }
+ }
+}
+
+void
+BasicFileWriter::Flush()
+{
+ const uint64_t BufferedBytes = m_BufferEnd - m_BufferStart;
+
+ if (BufferedBytes == 0)
+ return;
+
+ const uint64_t WriteOffset = m_BufferStart;
+ m_BufferStart = m_BufferEnd;
+
+ m_Base.Write(m_Buffer, BufferedBytes, WriteOffset);
+}
+
+//////////////////////////////////////////////////////////////////////////
+
/*
___________ __
\__ ___/___ _______/ |_ ______