2024-03-14 10:41:53 +00:00
|
|
|
#include "StarZSTDCompression.hpp"
|
|
|
|
#include <zstd.h>
|
|
|
|
|
|
|
|
namespace Star {
|
|
|
|
|
|
|
|
CompressionStream::CompressionStream() : m_cStream(ZSTD_createCStream()) {
|
|
|
|
ZSTD_CCtx_setParameter(m_cStream, ZSTD_c_enableLongDistanceMatching, 1);
|
|
|
|
ZSTD_CCtx_setParameter(m_cStream, ZSTD_c_windowLog, 24);
|
|
|
|
ZSTD_initCStream(m_cStream, 2);
|
2024-03-15 04:26:38 +00:00
|
|
|
m_output.resize(ZSTD_CStreamOutSize());
|
2024-03-14 10:41:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CompressionStream::~CompressionStream() { ZSTD_freeCStream(m_cStream); }
|
|
|
|
|
|
|
|
ByteArray CompressionStream::compress(const char* in, size_t inLen) {
|
|
|
|
size_t const cOutSize = ZSTD_CStreamOutSize();
|
2024-03-15 04:26:38 +00:00
|
|
|
ZSTD_inBuffer inBuffer = {in, inLen, 0};
|
|
|
|
size_t written = 0;
|
|
|
|
bool finished = false;
|
|
|
|
do {
|
|
|
|
ZSTD_outBuffer outBuffer = {m_output.ptr() + written, min(cOutSize, m_output.size() - written), 0};
|
|
|
|
size_t ret = ZSTD_compressStream2(m_cStream, &outBuffer, &inBuffer, ZSTD_e_flush);
|
|
|
|
if (ZSTD_isError(ret)) {
|
|
|
|
throw IOException(strf("ZSTD compression error {}", ZSTD_getErrorName(ret)));
|
|
|
|
break;
|
|
|
|
}
|
2024-03-14 10:41:53 +00:00
|
|
|
|
|
|
|
written += outBuffer.pos;
|
2024-03-15 04:26:38 +00:00
|
|
|
if (outBuffer.pos == outBuffer.size) {
|
|
|
|
if (written >= m_output.size())
|
|
|
|
m_output.resize(m_output.size() * 2);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
finished = ret == 0 && inBuffer.pos == inBuffer.size;
|
|
|
|
} while (!finished);
|
|
|
|
return ByteArray(m_output.ptr(), written);
|
2024-03-14 10:41:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DecompressionStream::DecompressionStream() : m_dStream(ZSTD_createDStream()) {
|
|
|
|
ZSTD_DCtx_setParameter(m_dStream, ZSTD_d_windowLogMax, 25);
|
|
|
|
ZSTD_initDStream(m_dStream);
|
2024-03-15 04:26:38 +00:00
|
|
|
m_output.resize(ZSTD_DStreamOutSize());
|
2024-03-14 10:41:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DecompressionStream::~DecompressionStream() { ZSTD_freeDStream(m_dStream); }
|
|
|
|
|
|
|
|
ByteArray DecompressionStream::decompress(const char* in, size_t inLen) {
|
|
|
|
size_t const dOutSize = ZSTD_DStreamOutSize();
|
2024-03-15 04:26:38 +00:00
|
|
|
ZSTD_inBuffer inBuffer = {in, inLen, 0};
|
|
|
|
size_t written = 0;
|
|
|
|
bool finished = false;
|
|
|
|
do {
|
|
|
|
ZSTD_outBuffer outBuffer = {m_output.ptr() + written, min(dOutSize, m_output.size() - written), 0};
|
|
|
|
size_t ret = ZSTD_decompressStream(m_dStream, &outBuffer, &inBuffer);
|
|
|
|
if (ZSTD_isError(ret)) {
|
|
|
|
throw IOException(strf("ZSTD decompression error {}", ZSTD_getErrorName(ret)));
|
|
|
|
break;
|
|
|
|
}
|
2024-03-14 10:41:53 +00:00
|
|
|
|
|
|
|
written += outBuffer.pos;
|
2024-03-15 04:26:38 +00:00
|
|
|
if (outBuffer.pos == outBuffer.size) {
|
|
|
|
if (written >= m_output.size())
|
|
|
|
m_output.resize(m_output.size() * 2);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
finished = inBuffer.pos == inBuffer.size;
|
|
|
|
} while (!finished);
|
|
|
|
return ByteArray(m_output.ptr(), written);
|
2024-03-14 10:41:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|