Вот процедура zLib inflate, которая берет буфер в памяти и распаковывает в предоставленный выходной буфер. Это «однократная» функция, в которой она пытается заполнить весь входной буфер за один раз и предполагает, что вы предоставили ему достаточно места, чтобы вместить все это. Также возможно написать функцию многократной записи, которая динамически увеличивает целевой буфер при необходимости.
int inflate(const void *src, int srcLen, void *dst, int dstLen) {
z_stream strm = {0};
strm.total_in = strm.avail_in = srcLen;
strm.total_out = strm.avail_out = dstLen;
strm.next_in = (Bytef *) src;
strm.next_out = (Bytef *) dst;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
int err = -1;
int ret = -1;
err = inflateInit2(&strm, (15 + 32)); //15 window bits, and the +32 tells zlib to to detect if using gzip or zlib
if (err == Z_OK) {
err = inflate(&strm, Z_FINISH);
if (err == Z_STREAM_END) {
ret = strm.total_out;
}
else {
inflateEnd(&strm);
return err;
}
}
else {
inflateEnd(&strm);
return err;
}
inflateEnd(&strm);
return ret;
}
Пояснение:
src : исходный буфер, содержащий сжатые данные (gzip или zlib)
srcLen : длина исходного буфера
dst : целевой буфер, в который будет записан вывод
dstLen : длина буфера назначения
Возвращаемые значения:
Z_BUF_ERROR: если dstLen недостаточно велик, чтобы вместить завышенные данные
Z_MEM_ERROR: если памяти недостаточно для выполнения декомпрессии
Z_DATA_ERROR: если входные данные были повреждены
В противном случае возвращаемое значение - это число байтов, записанных в dst.