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

summaryrefslogtreecommitdiff
path: root/source/core/StarCompression.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/StarCompression.cpp
parent8164e5ae6fa33c9ec2a14f107585a7cbe7fbf813 (diff)
Initial commit of experimental zstd network compression
currently a bit buggy
Diffstat (limited to 'source/core/StarCompression.cpp')
-rw-r--r--source/core/StarCompression.cpp51
1 files changed, 32 insertions, 19 deletions
diff --git a/source/core/StarCompression.cpp b/source/core/StarCompression.cpp
index 2aa59b2..58b43ef 100644
--- a/source/core/StarCompression.cpp
+++ b/source/core/StarCompression.cpp
@@ -15,9 +15,9 @@ void compressData(ByteArray const& in, ByteArray& out, CompressionLevel compress
return;
const size_t BUFSIZE = 32 * 1024;
- unsigned char temp_buffer[BUFSIZE];
+ auto tempBuffer = std::make_unique<unsigned char[]>(BUFSIZE);
- z_stream strm;
+ z_stream strm{};
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
@@ -27,13 +27,13 @@ void compressData(ByteArray const& in, ByteArray& out, CompressionLevel compress
strm.next_in = (unsigned char*)in.ptr();
strm.avail_in = in.size();
- strm.next_out = temp_buffer;
+ strm.next_out = tempBuffer.get();
strm.avail_out = BUFSIZE;
while (deflate_res == Z_OK) {
deflate_res = deflate(&strm, Z_FINISH);
if (strm.avail_out == 0) {
- out.append((char const*)temp_buffer, BUFSIZE);
- strm.next_out = temp_buffer;
+ out.append((char const*)tempBuffer.get(), BUFSIZE);
+ strm.next_out = tempBuffer.get();
strm.avail_out = BUFSIZE;
}
}
@@ -42,7 +42,7 @@ void compressData(ByteArray const& in, ByteArray& out, CompressionLevel compress
if (deflate_res != Z_STREAM_END)
throw IOException(strf("Internal error in uncompressData, deflate_res is {}", deflate_res));
- out.append((char const*)temp_buffer, BUFSIZE - strm.avail_out);
+ out.append((char const*)tempBuffer.get(), BUFSIZE - strm.avail_out);
}
ByteArray compressData(ByteArray const& in, CompressionLevel compression) {
@@ -51,16 +51,16 @@ ByteArray compressData(ByteArray const& in, CompressionLevel compression) {
return out;
}
-void uncompressData(ByteArray const& in, ByteArray& out) {
+void uncompressData(const char* in, size_t inLen, ByteArray& out, size_t limit) {
out.clear();
- if (in.empty())
+ if (!inLen)
return;
const size_t BUFSIZE = 32 * 1024;
- unsigned char temp_buffer[BUFSIZE];
+ auto tempBuffer = std::make_unique<unsigned char[]>(BUFSIZE);
- z_stream strm;
+ z_stream strm{};
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
@@ -68,17 +68,22 @@ void uncompressData(ByteArray const& in, ByteArray& out) {
if (inflate_res != Z_OK)
throw IOException(strf("Failed to initialise inflate ({})", inflate_res));
- strm.next_in = (unsigned char*)in.ptr();
- strm.avail_in = in.size();
- strm.next_out = temp_buffer;
+ strm.next_in = (unsigned char*)in;
+ strm.avail_in = inLen;
+ strm.next_out = tempBuffer.get();
strm.avail_out = BUFSIZE;
while (inflate_res == Z_OK || inflate_res == Z_BUF_ERROR) {
inflate_res = inflate(&strm, Z_FINISH);
if (strm.avail_out == 0) {
- out.append((char const*)temp_buffer, BUFSIZE);
- strm.next_out = temp_buffer;
+ out.append((char const*)tempBuffer.get(), BUFSIZE);
+ strm.next_out = tempBuffer.get();
strm.avail_out = BUFSIZE;
+ if (limit && out.size() >= limit) {
+ inflateEnd(&strm);
+ throw IOException(strf("hit uncompressData limit of {} bytes", limit));
+ break;
+ }
} else if (inflate_res == Z_BUF_ERROR) {
break;
}
@@ -88,15 +93,23 @@ void uncompressData(ByteArray const& in, ByteArray& out) {
if (inflate_res != Z_STREAM_END)
throw IOException(strf("Internal error in uncompressData, inflate_res is {}", inflate_res));
- out.append((char const*)temp_buffer, BUFSIZE - strm.avail_out);
+ out.append((char const*)tempBuffer.get(), BUFSIZE - strm.avail_out);
}
-ByteArray uncompressData(ByteArray const& in) {
- ByteArray out = ByteArray::withReserve(in.size());
- uncompressData(in, out);
+ByteArray uncompressData(const char* in, size_t inLen, size_t limit) {
+ ByteArray out = ByteArray::withReserve(inLen);
+ uncompressData(in, inLen, out, limit);
return out;
}
+void uncompressData(ByteArray const& in, ByteArray& out, size_t limit) {
+ uncompressData(in.ptr(), in.size(), out, limit);
+}
+
+ByteArray uncompressData(ByteArray const& in, size_t limit) {
+ return uncompressData(in.ptr(), in.size(), limit);
+}
+
CompressedFilePtr CompressedFile::open(String const& filename, IOMode mode, CompressionLevel comp) {
CompressedFilePtr f = make_shared<CompressedFile>(filename);
f->open(mode, comp);