if(d->header->compression() &&
!d->header->encryption())
{
- ByteVector data(frameDataLength);
- uLongf uLongTmp = frameDataLength;
- ::uncompress((Bytef *) data.data(),
- (uLongf *) &uLongTmp,
- (Bytef *) frameData.data() + frameDataOffset,
- size());
+ z_stream stream;
+ memset(&stream, 0, sizeof(z_stream));
+
+ if(inflateInit(&stream) != Z_OK)
+ return ByteVector();
+
+ stream.avail_in = (uLongf) frameDataLength;
+ stream.next_in = (Bytef *) frameData.data() + frameDataOffset;
+
+ static const uint chunkSize = 1024;
+
+ ByteVector data;
+ ByteVector chunk(chunkSize);
+
+ do {
+ stream.avail_out = (uLongf) chunk.size();
+ stream.next_out = (Bytef *) chunk.data();
+
+ int result = inflate(&stream, Z_NO_FLUSH);
+
+ if(result == Z_STREAM_ERROR)
+ return ByteVector();
+ else if(result == Z_NEED_DICT ||
+ result == Z_DATA_ERROR ||
+ result == Z_MEM_ERROR)
+ {
+ inflateEnd(&stream);
+ return ByteVector();
+ }
+
+ data.append(stream.avail_out == 0 ? chunk : chunk.mid(0, chunk.size() - stream.avail_out));
+ } while(stream.avail_out == 0);
+
+ inflateEnd(&stream);
+
+ if(frameDataLength != data.size())
+ debug("frameDataLength does not match the data length returned by zlib");
+
return data;
}
else