Я пытаюсь распаковать 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);
}
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
со структурой нулей. Последующие задания — это все, что вам нужно.