mirror of
https://github.com/whoahq/whoa.git
synced 2026-02-01 08:12:44 +03:00
feat(util): add ZlibDecompress
This commit is contained in:
parent
f183ee172c
commit
424b2c5227
@ -28,6 +28,8 @@ target_link_libraries(util
|
|||||||
common
|
common
|
||||||
storm
|
storm
|
||||||
tempest
|
tempest
|
||||||
|
PRIVATE
|
||||||
|
zlib-1.2
|
||||||
)
|
)
|
||||||
|
|
||||||
if(WHOA_SYSTEM_LINUX OR WHOA_SYSTEM_MAC)
|
if(WHOA_SYSTEM_LINUX OR WHOA_SYSTEM_MAC)
|
||||||
|
|||||||
76
src/util/Zlib.cpp
Normal file
76
src/util/Zlib.cpp
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#include "util/Zlib.hpp"
|
||||||
|
#include <storm/Error.hpp>
|
||||||
|
#include <storm/Memory.hpp>
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
int zlib_uncompress(Bytef* dest, uInt* destLen, const Bytef* source, uInt sourceLen) {
|
||||||
|
char buffer[47000];
|
||||||
|
ZlibAllocBufferHeader header = { buffer, sizeof(buffer), buffer };
|
||||||
|
|
||||||
|
z_stream strm;
|
||||||
|
strm.next_in = const_cast<Bytef*>(source);
|
||||||
|
strm.avail_in = sourceLen;
|
||||||
|
strm.next_out = dest;
|
||||||
|
strm.avail_out = *destLen;
|
||||||
|
strm.zalloc = &ZlibAlloc;
|
||||||
|
strm.zfree = &ZlibFree;
|
||||||
|
strm.opaque = &header;
|
||||||
|
|
||||||
|
auto err = inflateInit(&strm);
|
||||||
|
if (err != Z_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = inflate(&strm, Z_FINISH);
|
||||||
|
if (err == Z_STREAM_END) {
|
||||||
|
*destLen = strm.total_out;
|
||||||
|
return inflateEnd(&strm);
|
||||||
|
}
|
||||||
|
|
||||||
|
inflateEnd(&strm);
|
||||||
|
return err ? err : Z_BUF_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* ZlibAlloc(void* opaque, uint32_t items, uint32_t size) {
|
||||||
|
auto buffer = static_cast<ZlibAllocBufferHeader*>(opaque);
|
||||||
|
STORM_ASSERT(buffer);
|
||||||
|
|
||||||
|
uint32_t total = items * size;
|
||||||
|
|
||||||
|
// Align to 4 bytes
|
||||||
|
if ((total & 3) != 0) {
|
||||||
|
total = (total & ~3) + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ptr = buffer->nextPtr;
|
||||||
|
size_t used = buffer->nextPtr - buffer->bufStart;
|
||||||
|
size_t remaining = buffer->bufSize - used;
|
||||||
|
|
||||||
|
// Fall back to heap if stack allocated buffer is exhausted
|
||||||
|
if (total >= remaining) {
|
||||||
|
return STORM_ALLOC(total);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer->nextPtr = ptr + total;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZlibFree(void* opaque, void* ptr) {
|
||||||
|
auto* buffer = static_cast<ZlibAllocBufferHeader*>(opaque);
|
||||||
|
auto bufferStart = buffer->bufStart;
|
||||||
|
auto bufferEnd = buffer->bufStart + buffer->bufSize;
|
||||||
|
|
||||||
|
// Only free if pointer is outside of stack allocated buffer
|
||||||
|
if (ptr < bufferStart || ptr >= bufferEnd) {
|
||||||
|
STORM_FREE(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t ZlibDecompress(void* dest, uint32_t* destLen, const void* source, uint32_t sourceLen) {
|
||||||
|
return zlib_uncompress(
|
||||||
|
static_cast<Bytef*>(dest),
|
||||||
|
destLen,
|
||||||
|
static_cast<const Bytef*>(source),
|
||||||
|
sourceLen
|
||||||
|
);
|
||||||
|
}
|
||||||
18
src/util/Zlib.hpp
Normal file
18
src/util/Zlib.hpp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef UTIL_ZLIB_HPP
|
||||||
|
#define UTIL_ZLIB_HPP
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
struct ZlibAllocBufferHeader {
|
||||||
|
char* nextPtr;
|
||||||
|
uint32_t bufSize;
|
||||||
|
char* bufStart;
|
||||||
|
};
|
||||||
|
|
||||||
|
void* ZlibAlloc(void* opaque, uint32_t items, uint32_t size);
|
||||||
|
|
||||||
|
int32_t ZlibDecompress(void* dest, uint32_t* destLen, const void* source, uint32_t sourceLen);
|
||||||
|
|
||||||
|
void ZlibFree(void* opaque, void* ptr);
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Reference in New Issue
Block a user