Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/core/StarZSTDCompression.cpp
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2024-03-14 21:41:53 +1100
committerKae <80987908+Novaenia@users.noreply.github.com>2024-03-14 21:41:53 +1100
commit662b83ff92cc2316fb962ff1608359f6d705a5f0 (patch)
treed0e7d15887ed14bd252e6e61888710c8bac2200a /source/core/StarZSTDCompression.cpp
parent8164e5ae6fa33c9ec2a14f107585a7cbe7fbf813 (diff)
Initial commit of experimental zstd network compression
currently a bit buggy
Diffstat (limited to 'source/core/StarZSTDCompression.cpp')
-rw-r--r--source/core/StarZSTDCompression.cpp84
1 files changed, 84 insertions, 0 deletions
diff --git a/source/core/StarZSTDCompression.cpp b/source/core/StarZSTDCompression.cpp
new file mode 100644
index 0000000..733b182
--- /dev/null
+++ b/source/core/StarZSTDCompression.cpp
@@ -0,0 +1,84 @@
+#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);
+}
+
+CompressionStream::~CompressionStream() { ZSTD_freeCStream(m_cStream); }
+
+ByteArray CompressionStream::compress(const char* in, size_t inLen) {
+ size_t const cInSize = ZSTD_CStreamInSize ();
+ size_t const cOutSize = ZSTD_CStreamOutSize();
+ ByteArray output(cOutSize, 0);
+ size_t written = 0, read = 0;
+ while (read < inLen) {
+ ZSTD_inBuffer inBuffer = {in + read, min(cInSize, inLen - read), 0};
+ ZSTD_outBuffer outBuffer = {output.ptr() + written, output.size() - written, 0};
+ bool finished = false;
+ do {
+ 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;
+ }
+
+ if (outBuffer.pos == outBuffer.size) {
+ output.resize(output.size() * 2);
+ outBuffer.dst = output.ptr();
+ outBuffer.size = output.size();
+ continue;
+ }
+
+ finished = ret == 0 && inBuffer.pos == inBuffer.size;
+ } while (!finished);
+
+ read += inBuffer.pos;
+ written += outBuffer.pos;
+ }
+ output.resize(written);
+ return output;
+}
+
+DecompressionStream::DecompressionStream() : m_dStream(ZSTD_createDStream()) {
+ ZSTD_DCtx_setParameter(m_dStream, ZSTD_d_windowLogMax, 25);
+ ZSTD_initDStream(m_dStream);
+}
+
+DecompressionStream::~DecompressionStream() { ZSTD_freeDStream(m_dStream); }
+
+ByteArray DecompressionStream::decompress(const char* in, size_t inLen) {
+ size_t const dInSize = ZSTD_DStreamInSize ();
+ size_t const dOutSize = ZSTD_DStreamOutSize();
+ ByteArray output(dOutSize, 0);
+ size_t written = 0, read = 0;
+ while (read < inLen) {
+ ZSTD_inBuffer inBuffer = {in + read, min(dInSize, inLen - read), 0};
+ ZSTD_outBuffer outBuffer = {output.ptr() + written, output.size() - written, 0};
+ do {
+ size_t ret = ZSTD_decompressStream(m_dStream, &outBuffer, &inBuffer);
+ if (ZSTD_isError(ret)) {
+ throw IOException(strf("ZSTD decompression error {}", ZSTD_getErrorName(ret)));
+ break;
+ }
+
+ if (outBuffer.pos == outBuffer.size) {
+ output.resize(output.size() * 2);
+ outBuffer.dst = output.ptr();
+ outBuffer.size = output.size();
+ continue;
+ }
+ } while (inBuffer.pos < inBuffer.size);
+
+ read += inBuffer.pos;
+ written += outBuffer.pos;
+ }
+ output.resize(written);
+ return output;
+}
+
+} \ No newline at end of file