shared_data xcc_z::gunzip(data_ref s) { if (s.size() < 18) return shared_data(); shared_data d(read_int_le(4, s.end() - 4)); z_stream stream; stream.zalloc = NULL; stream.zfree = NULL; stream.opaque = NULL; stream.next_in = const_cast<unsigned char*>(s.begin()) + 10; stream.avail_in = s.size() - 18; stream.next_out = d.data(); stream.avail_out = d.size(); return stream.next_out && Z_OK == inflateInit2(&stream, -MAX_WBITS) && Z_STREAM_END == inflate(&stream, Z_FINISH) && Z_OK == inflateEnd(&stream) ? d : shared_data(); }
static int read_int(const byte*& r) { r += 4; return read_int_le(4, r - 4); }