]>
Commit | Line | Data |
---|---|---|
a322920d HWN |
1 | /* taken from zlib's uncompr.c |
2 | ||
3 | commit cacf7f1d4e3d44d871b605da3b647f07d718623f | |
4 | Author: Mark Adler <madler@alumni.caltech.edu> | |
5 | Date: Sun Jan 15 09:18:46 2017 -0800 | |
6 | ||
7 | zlib 1.2.11 | |
8 | ||
9 | */ | |
10 | ||
11 | #include "../reftable/system.h" | |
12 | #define z_const | |
13 | ||
14 | /* | |
15 | * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler | |
16 | * For conditions of distribution and use, see copyright notice in zlib.h | |
17 | */ | |
18 | ||
19 | #include <zlib.h> | |
20 | ||
21 | /* clang-format off */ | |
22 | ||
23 | /* =========================================================================== | |
24 | Decompresses the source buffer into the destination buffer. *sourceLen is | |
25 | the byte length of the source buffer. Upon entry, *destLen is the total size | |
26 | of the destination buffer, which must be large enough to hold the entire | |
27 | uncompressed data. (The size of the uncompressed data must have been saved | |
28 | previously by the compressor and transmitted to the decompressor by some | |
29 | mechanism outside the scope of this compression library.) Upon exit, | |
30 | *destLen is the size of the decompressed data and *sourceLen is the number | |
31 | of source bytes consumed. Upon return, source + *sourceLen points to the | |
32 | first unused input byte. | |
33 | ||
34 | uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough | |
35 | memory, Z_BUF_ERROR if there was not enough room in the output buffer, or | |
36 | Z_DATA_ERROR if the input data was corrupted, including if the input data is | |
37 | an incomplete zlib stream. | |
38 | */ | |
39 | int ZEXPORT uncompress2 ( | |
40 | Bytef *dest, | |
41 | uLongf *destLen, | |
42 | const Bytef *source, | |
43 | uLong *sourceLen) { | |
44 | z_stream stream; | |
45 | int err; | |
46 | const uInt max = (uInt)-1; | |
47 | uLong len, left; | |
48 | Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */ | |
49 | ||
50 | len = *sourceLen; | |
51 | if (*destLen) { | |
52 | left = *destLen; | |
53 | *destLen = 0; | |
54 | } | |
55 | else { | |
56 | left = 1; | |
57 | dest = buf; | |
58 | } | |
59 | ||
60 | stream.next_in = (z_const Bytef *)source; | |
61 | stream.avail_in = 0; | |
62 | stream.zalloc = (alloc_func)0; | |
63 | stream.zfree = (free_func)0; | |
64 | stream.opaque = (voidpf)0; | |
65 | ||
66 | err = inflateInit(&stream); | |
67 | if (err != Z_OK) return err; | |
68 | ||
69 | stream.next_out = dest; | |
70 | stream.avail_out = 0; | |
71 | ||
72 | do { | |
73 | if (stream.avail_out == 0) { | |
74 | stream.avail_out = left > (uLong)max ? max : (uInt)left; | |
75 | left -= stream.avail_out; | |
76 | } | |
77 | if (stream.avail_in == 0) { | |
78 | stream.avail_in = len > (uLong)max ? max : (uInt)len; | |
79 | len -= stream.avail_in; | |
80 | } | |
81 | err = inflate(&stream, Z_NO_FLUSH); | |
82 | } while (err == Z_OK); | |
83 | ||
84 | *sourceLen -= len + stream.avail_in; | |
85 | if (dest != buf) | |
86 | *destLen = stream.total_out; | |
87 | else if (stream.total_out && err == Z_BUF_ERROR) | |
88 | left = 1; | |
89 | ||
90 | inflateEnd(&stream); | |
91 | return err == Z_STREAM_END ? Z_OK : | |
92 | err == Z_NEED_DICT ? Z_DATA_ERROR : | |
93 | err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : | |
94 | err; | |
95 | } |