1
0
mirror of https://github.com/Amulet-Team/leveldb-mcpe.git synced 2024-11-14 10:27:04 +00:00
leveldb-amulet/db/zlib_compressor.cc

122 lines
2.7 KiB
C++

#ifndef NO_ZLIB
#include "leveldb/zlib_compressor.h"
#include <zlib.h>
#include <algorithm>
namespace leveldb {
void ZlibCompressorBase::compressImpl(const char* input, size_t length, ::std::string& buffer) const
{
const size_t BUFSIZE = 128 * 1024;
unsigned char temp_buffer[BUFSIZE];
//reserve enough memory to not reallocate on the fly
buffer.reserve(buffer.size() + compressBound(length));
z_stream strm;
strm.zalloc = 0;
strm.zfree = 0;
strm.next_in = (unsigned char *)(input);
strm.avail_in = (uint32_t)length;
strm.next_out = temp_buffer;
strm.avail_out = BUFSIZE;
auto res = deflateInit2(&strm, compressionLevel, Z_DEFLATED, _window(), 8, Z_DEFAULT_STRATEGY);
assert(res == Z_OK);
int deflate_res = Z_OK;
while (strm.avail_in != 0)
{
int res = deflate(&strm, Z_NO_FLUSH);
assert(res == Z_OK);
if (strm.avail_out == 0)
{
buffer.append(temp_buffer, temp_buffer + BUFSIZE);
strm.next_out = temp_buffer;
strm.avail_out = BUFSIZE;
}
}
while (deflate_res == Z_OK)
{
if (strm.avail_out == 0)
{
buffer.append(temp_buffer, temp_buffer + BUFSIZE);
strm.next_out = temp_buffer;
strm.avail_out = BUFSIZE;
}
deflate_res = deflate(&strm, Z_FINISH);
}
assert(deflate_res == Z_STREAM_END);
buffer.append(temp_buffer, temp_buffer + BUFSIZE - strm.avail_out);
deflateEnd(&strm);
}
int ZlibCompressorBase::inflate(const char* input, size_t length, ::std::string &output) const {
const int CHUNK = 64 * 1024;
int ret;
size_t have;
z_stream strm;
unsigned char out[CHUNK];
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = (uint32_t)length;
strm.next_in = (Bytef*)input;
ret = inflateInit2(&strm, _window());
if (ret != Z_OK)
{
return ret;
}
/* decompress until deflate stream ends or end of file */
do {
/* run inflate() on input until output buffer not full */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = ::inflate(&strm, Z_NO_FLUSH);
if (ret == Z_NEED_DICT) {
ret = Z_DATA_ERROR;
}
if (ret < 0) {
(void)inflateEnd(&strm);
return ret;
}
have = CHUNK - strm.avail_out;
output.append((char*)out, have);
} while (strm.avail_out == 0);
/* done when inflate() says it's done */
} while (ret != Z_STREAM_END);
/* clean up and return */
(void)inflateEnd(&strm);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
bool ZlibCompressorBase::decompress(const char* input, size_t length, ::std::string &output) const {
return inflate(input, length, output) == Z_OK;
}
int ZlibCompressorBase::_window() const {
return raw ? -15 : 15;
}
}
#endif