52 lines
1.5 KiB
C++

#pragma once
#include <solanaceae/file/file2.hpp>
#include <memory>
#include <zstd.h>
// zstd compression wrapper over another file
// WARNING: only supports sequential writes
struct File2ZSTDW : public File2I {
File2I& _real_file;
// TODO: hide this detail?
std::unique_ptr<ZSTD_CCtx, decltype(&ZSTD_freeCCtx)> _cctx{ZSTD_createCCtx(), &ZSTD_freeCCtx};
File2ZSTDW(File2I& real);
virtual ~File2ZSTDW(void);
bool isGood(void) override;
// for simplicity and potential future seekability each write is its own frame
bool write(const ByteSpan data, int64_t pos = -1) override;
std::variant<ByteSpan, std::vector<uint8_t>> read(uint64_t size, int64_t pos = -1) override;
};
// zstd decompression wrapper over another file
// WARNING: only supports sequential reads
// TODO: add seeking support (use frames)
struct File2ZSTDR : public File2I {
File2I& _real_file;
// TODO: hide this detail?
std::unique_ptr<ZSTD_DCtx, decltype(&ZSTD_freeDCtx)> _dctx{ZSTD_createDCtx(), &ZSTD_freeDCtx};
std::vector<uint8_t> _in_buffer;
std::vector<uint8_t> _out_buffer;
std::vector<uint8_t> _decompressed_buffer; // retains decompressed unread data between read() calls
ZSTD_inBuffer _z_input{nullptr, 0, 0};
File2ZSTDR(File2I& real);
virtual ~File2ZSTDR(void) {}
bool isGood(void) override;
bool write(const ByteSpan data, int64_t pos = -1) override;
std::variant<ByteSpan, std::vector<uint8_t>> read(uint64_t size, int64_t pos = -1) override;
private:
bool feedInput(std::variant<ByteSpan, std::vector<uint8_t>>&& read_buff);
};