zlib inflate возвращает ошибку буфера

Я пытаюсь распаковать zip-файл с помощью zlib (без использования каких-либо расширений или сторонних).
Первоначально src_len это 48756255, а dest_len это 49209890.
С первым проходом в цикле while все в порядке: err равен Z_OK, и начинается второй проход. На втором проходе, независимо от того, что я делаю, я получаю Z_BUF_ERROR от inflate. stream.total_out на данный момент равен 49034460, поэтому бит остался, но stream.avail_in на втором проходе равен 0. В любом случае, я ожидаю, что inflate выдаст мне Z_STREAM_END. Я действительно не знаю, что происходит, кто-нибудь может помочь?

void compression::uncompress2(char* dest, unsigned dest_len, char* src, unsigned src_len) {
TempAllocator ta;

z_stream_s stream = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
stream.next_in = (Bytef*)src;
stream.avail_in = (uInt)src_len;
stream.next_out = (Bytef*)dest;
stream.avail_out = (uInt)dest_len;
stream.zalloc = zalloc;
stream.zfree = zfree;
stream.opaque = &ta;

// no header
int err = inflateInit2(&stream, -MAX_WBITS);
XENSURE(err == Z_OK);

bool done = false;
while (!done) {
stream.next_out = (Bytef*)(dest + stream.total_out);
stream.avail_out = dest_len - stream.total_out;

err = inflate(&stream, Z_SYNC_FLUSH);
if (err == Z_STREAM_END)
done = true;
else if (err != Z_OK) {
break;
}
}

err = inflateEnd(&stream);
XENSURE(err == Z_OK);
}

0

Решение

inflate() обработает как можно больше входных данных, используя доступные выходные данные. Как только он не сможет ни обработать ввод, ни произвести вывод, он вернет Z_BUF_ERROR,

В этом случае все входные данные обрабатываются, и есть место для резервирования, но конец потока не обнаружен. Вы не получаете Z_STREAM_END потому что по какой-то причине вы не предоставляете полный поток дефлята.

Вот некоторые другие комментарии к вашему коду. Ваш цикл ничего не делает, и настройка next_out а также avail_out в цикле, как вы делаете, ничего не делает. Вы не предоставляете ни нового ввода, ни нового выходного пространства в вашем цикле, поэтому нет смысла иметь цикл. Единственная цель иметь петлю вокруг inflate() либо предоставить больше входных данных, обеспечить больше выходного пространства, либо и то, и другое. Кроме того, когда inflate() возвращается, next_out а также avail_out обновляются до следующего доступного местоположения в выходном буфере и объема доступного пространства там. Ваши заявления, которые устанавливают next_out а также avail_out в цикле установите те значения, которые у них уже есть.

В код с правильными циклами вокруг inflate(), Z_BUF_ERROR это не проблема, и обработка может продолжаться. Хотя, если вы ожидаете другого результата при следующем вызове inflate()должно быть предоставлено больше входного и / или большего выходного пространства.

Нет необходимости инициализировать stream со структурой нулей. Последующие задания — это все, что вам нужно.

5

Другие решения