diff --git a/cmake/headerlist.cmake b/cmake/headerlist.cmake index 0bc9ea9..bf21c40 100644 --- a/cmake/headerlist.cmake +++ b/cmake/headerlist.cmake @@ -1,5 +1,6 @@ set(headers common/IArchive.h + common/IBufferedFileStream.h common/IBufferStream.h common/IConsole.h common/ICriticalSection.h diff --git a/cmake/sourcelist.cmake b/cmake/sourcelist.cmake index 558e814..f77e7be 100644 --- a/cmake/sourcelist.cmake +++ b/cmake/sourcelist.cmake @@ -1,5 +1,6 @@ set(sources common/IArchive.cpp + common/IBufferedFileStream.cpp common/IBufferStream.cpp common/IConsole.cpp common/IDataStream.cpp diff --git a/common/IBufferedFileStream.cpp b/common/IBufferedFileStream.cpp new file mode 100644 index 0000000..ef5f60b --- /dev/null +++ b/common/IBufferedFileStream.cpp @@ -0,0 +1,84 @@ +#include "IBufferedFileStream.h" + +IBufferedFileStream::IBufferedFileStream() { } + +IBufferedFileStream::~IBufferedFileStream() +{ + Close(); +} + +bool IBufferedFileStream::Open(const char* name) +{ + bool success = streamFile.Open(name); + + if (success) + { + SetLength(streamFile.GetLength()); + SetOffset(0); + + streamFile.ReadBuf(streamBuffer.data(), streamLength); + + streamFile.SetOffset(0); + } + + return success; +} + +bool IBufferedFileStream::Create(const char* name) +{ + bool success = streamFile.Create(name); + + if (success) + { + SetLength(0); + SetOffset(0); + } + + return success; +} + +void IBufferedFileStream::Close(void) +{ + if (streamBufferHasWrite) + { + streamFile.SetLength(streamLength); + + streamFile.SetOffset(0); + + streamFile.WriteBuf(streamBuffer.data(), streamLength); + + streamBufferHasWrite = false; + } + + SetLength(0); + SetOffset(0); + + streamFile.Close(); +} + +void IBufferedFileStream::ReadBuf(void* buf, UInt32 inLength) +{ + ASSERT_STR(inLength <= GetRemain(), "IBufferedFileStream::ReadBuf: hit eof"); + ASSERT_STR(streamBuffer.size() >= streamOffset + inLength, "IBufferedFileStream::ReadBuf: hit buffer eof"); + + memcpy(buf, &streamBuffer[streamOffset], inLength); + streamOffset += inLength; +} + +void IBufferedFileStream::WriteBuf(const void* buf, UInt32 inLength) +{ + streamBufferHasWrite = true; + + if (streamBuffer.size() < streamOffset + inLength) + SetLength(streamOffset + inLength); + + memcpy(&streamBuffer[streamOffset], buf, inLength); + streamOffset += inLength; +} + +void IBufferedFileStream::SetLength(UInt64 length) +{ + streamBuffer.resize(length); + + streamLength = length; +} diff --git a/common/IBufferedFileStream.h b/common/IBufferedFileStream.h new file mode 100644 index 0000000..6e453d3 --- /dev/null +++ b/common/IBufferedFileStream.h @@ -0,0 +1,31 @@ +#pragma once + +#include "common/IDataStream.h" +#include "common/IFileStream.h" +#include + +/** + * An input/output file stream with buffering, write file on close + */ +class IBufferedFileStream : public IDataStream +{ +public: + IBufferedFileStream(); + virtual ~IBufferedFileStream(); + + bool Open(const char* name); + bool Create(const char* name); + + void Close(void); + + virtual void ReadBuf(void* buf, UInt32 inLength); + virtual void WriteBuf(const void* buf, UInt32 inLength); + + void SetLength(UInt64 length); + +private: + std::vector streamBuffer; + IFileStream streamFile; + + bool streamBufferHasWrite = false; +}; diff --git a/common/IFileStream.h b/common/IFileStream.h index 01aa955..2e0208a 100644 --- a/common/IFileStream.h +++ b/common/IFileStream.h @@ -3,7 +3,7 @@ #include "common/IDataStream.h" /** - * An input file stream + * An input/output file stream */ class IFileStream : public IDataStream {