#pragma once #include "ZipBase.h" #include "fs/Api.h" #include #include #include #include #include namespace fs { ////////////////////////////////////////////////////////////////////////// class IStreamSource; class IStreamSink; class ISink; ////////////////////////////////////////////////////////////////////////// class FS_API ZipWriter : public ZipBase { public: struct DataWriterPayload { CompressionMethod compressionMethod; uint32_t uncompressedCRC32 = 0; //mandatory!!! uint64_t uncompressedSize = 0; //optional, will be set to the written size if == 0 }; using DataWriterError = tl::generic_error; using DataWriterResult = tl::result; using DataWriter = tl::function; ZipWriter(ISink& sink, size_t fileDataAlignment); ~ZipWriter() = default; tl::result addFile(tl::string name, const DataWriter& dataWriter); tl::result addFile(tl::string name, tl::optional lastModificationTime, const DataWriter& dataWriter); tl::result addFile(tl::string name, tl::span comment, tl::span extraField, GeneralBitFlags generalBitFlags, tl::optional lastModificationTime, const DataWriter& dataWriter); void finish(); private: uint64_t computePadding(uint64_t offset, const LocalFileHeader& header) const; ISink& m_sink; size_t m_fileDataAlignment = 0; struct CentralDirectoryRecord { uint64_t compressedSize = 0; uint64_t uncompressedSize = 0; uint64_t localHeaderOffset = 0; CentralDirectoryFileHeader header; tl::string name; tl::memory_buffer comment; tl::memory_buffer extraField; bool zip64 = false; }; tl::vector m_records; tl::memory_buffer m_buffer; }; ////////////////////////////////////////////////////////////////////////// }