78 lines
2.0 KiB
C++
78 lines
2.0 KiB
C++
#pragma once
|
|
|
|
#include "ZipBase.h"
|
|
#include "fs/Api.h"
|
|
#include <tl/memory_buffer.h>
|
|
#include <tl/span.h>
|
|
#include <tl/vector.h>
|
|
#include <tl/result.h>
|
|
#include <tl/optional.h>
|
|
|
|
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<DataWriterPayload, DataWriterError>;
|
|
|
|
using DataWriter = tl::function<DataWriterResult(IStreamSink& sink)>;
|
|
|
|
ZipWriter(ISink& sink, size_t fileDataAlignment);
|
|
~ZipWriter() = default;
|
|
|
|
tl::result<void> addFile(tl::string name, const DataWriter& dataWriter);
|
|
|
|
tl::result<void> addFile(tl::string name, tl::optional<time_t> lastModificationTime, const DataWriter& dataWriter);
|
|
|
|
tl::result<void> addFile(tl::string name,
|
|
tl::span<const uint8_t> comment,
|
|
tl::span<const uint8_t> extraField,
|
|
GeneralBitFlags generalBitFlags,
|
|
tl::optional<time_t> 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<CentralDirectoryRecord> m_records;
|
|
|
|
tl::memory_buffer m_buffer;
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
}
|