#pragma once #include #include #include #include // TODO switch to custom when unit tests are ready and bugs are fixed #define CPLT_FILESTREAM_USE_CSTDIO struct IoResult { enum ErrorKind { ERR_None, ERR_PermissionDenied, ERR_UnexpectedEof, ERR_Unsupported, ERR_OutOfSpace, ERR_Other, }; ErrorKind Error; uint32_t SystemError; size_t BytesMoved; }; class InputFileStream { private: #if defined(CPLT_FILESTREAM_USE_CSTDIO) FILE* mFile; #else alignas(void*) char mOsFileHandle[sizeof(void*)]; // mBuffer is always mReadInSize size std::unique_ptr mBuffer; int mReadInSize = 1024; int mFirstByteIdx = 0; int mAvailableBytes = 0; bool mEof = false; #endif public: InputFileStream(const std::filesystem::path& path); ~InputFileStream(); InputFileStream(const InputFileStream&) = delete; InputFileStream& operator=(const InputFileStream&) = delete; InputFileStream(InputFileStream&&); InputFileStream& operator=(InputFileStream&&); int GetReadInSize() const; void SetReadInSize(int size); bool IsEof() const; IoResult ReadBytes(size_t bufferLength, std::byte* buffer); }; class OutputFileStream { public: enum WriteMode { AppendFile, TruncateFile, }; private: #if defined(CPLT_FILESTREAM_USE_CSTDIO) FILE* mFile; #else alignas(void*) char mOsFileHandle[sizeof(void*)]; std::unique_ptr mBuffer; int mMaxBufferSize = 1024; int mCurrentBufferSize = 0; #endif public: OutputFileStream(const std::filesystem::path& path, WriteMode mode); ~OutputFileStream(); OutputFileStream(const OutputFileStream&) = delete; OutputFileStream& operator=(const OutputFileStream&) = delete; OutputFileStream(OutputFileStream&&); OutputFileStream& operator=(OutputFileStream&&); int GetMaxBufferSize() const; void SetMaxBufferSize(int maxSize); IoResult WriteBytes(size_t bufferLength, const std::byte* buffer); void FlushBuffer(); };