1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-24 07:14:31 +01:00

Stream changes from NSF (#15446)

* Bring over NSF changes to stream classes

* Add orca stream to project files

* Bring over util changes as well.

* Add const to util and fix util ungzip

* Add const and apply review comments

* Apply review comments
This commit is contained in:
Duncan
2021-09-30 13:02:54 +01:00
committed by GitHub
parent bfe7caacd7
commit e01c9a3afa
11 changed files with 810 additions and 1 deletions

View File

@@ -693,6 +693,102 @@ bool util_gzip_compress(FILE* source, FILE* dest)
return true;
}
std::vector<uint8_t> Gzip(const void* data, const size_t dataLen)
{
assert(data != nullptr);
std::vector<uint8_t> output;
z_stream strm{};
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
{
const auto ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 | 16, 8, Z_DEFAULT_STRATEGY);
if (ret != Z_OK)
{
throw std::runtime_error("deflateInit2 failed with error " + std::to_string(ret));
}
}
int flush = 0;
const auto* src = static_cast<const Bytef*>(data);
size_t srcRemaining = dataLen;
do
{
const auto nextBlockSize = std::min(srcRemaining, CHUNK);
srcRemaining -= nextBlockSize;
flush = srcRemaining == 0 ? Z_FINISH : Z_NO_FLUSH;
strm.avail_in = static_cast<uInt>(nextBlockSize);
strm.next_in = const_cast<Bytef*>(src);
do
{
output.resize(output.size() + nextBlockSize);
strm.avail_out = static_cast<uInt>(nextBlockSize);
strm.next_out = &output[output.size() - nextBlockSize];
const auto ret = deflate(&strm, flush);
if (ret == Z_STREAM_ERROR)
{
throw std::runtime_error("deflate failed with error " + std::to_string(ret));
}
output.resize(output.size() - strm.avail_out);
} while (strm.avail_out == 0);
src += nextBlockSize;
} while (flush != Z_FINISH);
deflateEnd(&strm);
return output;
}
std::vector<uint8_t> Ungzip(const void* data, const size_t dataLen)
{
assert(data != nullptr);
std::vector<uint8_t> output;
z_stream strm{};
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
{
const auto ret = inflateInit2(&strm, 15 | 16);
if (ret != Z_OK)
{
throw std::runtime_error("inflateInit2 failed with error " + std::to_string(ret));
}
}
int flush = 0;
const auto* src = static_cast<const Bytef*>(data);
size_t srcRemaining = dataLen;
do
{
const auto nextBlockSize = std::min(srcRemaining, CHUNK);
srcRemaining -= nextBlockSize;
flush = srcRemaining == 0 ? Z_FINISH : Z_NO_FLUSH;
strm.avail_in = static_cast<uInt>(nextBlockSize);
strm.next_in = const_cast<Bytef*>(src);
do
{
output.resize(output.size() + nextBlockSize);
strm.avail_out = static_cast<uInt>(nextBlockSize);
strm.next_out = &output[output.size() - nextBlockSize];
const auto ret = inflate(&strm, flush);
if (ret == Z_STREAM_ERROR)
{
throw std::runtime_error("deflate failed with error " + std::to_string(ret));
}
output.resize(output.size() - strm.avail_out);
} while (strm.avail_out == 0);
src += nextBlockSize;
} while (flush != Z_FINISH);
inflateEnd(&strm);
return output;
}
// Type-independent code left as macro to reduce duplicate code.
#define add_clamp_body(value, value_to_add, min_cap, max_cap) \
if ((value_to_add > 0) && (value > (max_cap - (value_to_add)))) \