xref: /netbsd-src/external/gpl3/gdb/dist/zlib/uncompr.c (revision 924795e69c8bb3f17afd8fcbb799710cc1719dc4)
1212397c6Schristos /* uncompr.c -- decompress a memory buffer
2796c32c9Schristos  * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler
3212397c6Schristos  * For conditions of distribution and use, see copyright notice in zlib.h
4212397c6Schristos  */
5212397c6Schristos 
6*924795e6Schristos /* @(#) Id */
7212397c6Schristos 
8212397c6Schristos #define ZLIB_INTERNAL
9212397c6Schristos #include "zlib.h"
10212397c6Schristos 
11212397c6Schristos /* ===========================================================================
12796c32c9Schristos      Decompresses the source buffer into the destination buffer.  *sourceLen is
13796c32c9Schristos    the byte length of the source buffer. Upon entry, *destLen is the total size
14796c32c9Schristos    of the destination buffer, which must be large enough to hold the entire
15796c32c9Schristos    uncompressed data. (The size of the uncompressed data must have been saved
16796c32c9Schristos    previously by the compressor and transmitted to the decompressor by some
17796c32c9Schristos    mechanism outside the scope of this compression library.) Upon exit,
18796c32c9Schristos    *destLen is the size of the decompressed data and *sourceLen is the number
19796c32c9Schristos    of source bytes consumed. Upon return, source + *sourceLen points to the
20796c32c9Schristos    first unused input byte.
21212397c6Schristos 
22796c32c9Schristos      uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough
23796c32c9Schristos    memory, Z_BUF_ERROR if there was not enough room in the output buffer, or
24796c32c9Schristos    Z_DATA_ERROR if the input data was corrupted, including if the input data is
25796c32c9Schristos    an incomplete zlib stream.
26212397c6Schristos */
uncompress2(dest,destLen,source,sourceLen)27796c32c9Schristos int ZEXPORT uncompress2 (dest, destLen, source, sourceLen)
28796c32c9Schristos     Bytef *dest;
29796c32c9Schristos     uLongf *destLen;
30796c32c9Schristos     const Bytef *source;
31796c32c9Schristos     uLong *sourceLen;
32796c32c9Schristos {
33796c32c9Schristos     z_stream stream;
34796c32c9Schristos     int err;
35796c32c9Schristos     const uInt max = (uInt)-1;
36796c32c9Schristos     uLong len, left;
37796c32c9Schristos     Byte buf[1];    /* for detection of incomplete stream when *destLen == 0 */
38796c32c9Schristos 
39796c32c9Schristos     len = *sourceLen;
40796c32c9Schristos     if (*destLen) {
41796c32c9Schristos         left = *destLen;
42796c32c9Schristos         *destLen = 0;
43796c32c9Schristos     }
44796c32c9Schristos     else {
45796c32c9Schristos         left = 1;
46796c32c9Schristos         dest = buf;
47796c32c9Schristos     }
48796c32c9Schristos 
49796c32c9Schristos     stream.next_in = (z_const Bytef *)source;
50796c32c9Schristos     stream.avail_in = 0;
51796c32c9Schristos     stream.zalloc = (alloc_func)0;
52796c32c9Schristos     stream.zfree = (free_func)0;
53796c32c9Schristos     stream.opaque = (voidpf)0;
54796c32c9Schristos 
55796c32c9Schristos     err = inflateInit(&stream);
56796c32c9Schristos     if (err != Z_OK) return err;
57796c32c9Schristos 
58796c32c9Schristos     stream.next_out = dest;
59796c32c9Schristos     stream.avail_out = 0;
60796c32c9Schristos 
61796c32c9Schristos     do {
62796c32c9Schristos         if (stream.avail_out == 0) {
63796c32c9Schristos             stream.avail_out = left > (uLong)max ? max : (uInt)left;
64796c32c9Schristos             left -= stream.avail_out;
65796c32c9Schristos         }
66796c32c9Schristos         if (stream.avail_in == 0) {
67796c32c9Schristos             stream.avail_in = len > (uLong)max ? max : (uInt)len;
68796c32c9Schristos             len -= stream.avail_in;
69796c32c9Schristos         }
70796c32c9Schristos         err = inflate(&stream, Z_NO_FLUSH);
71796c32c9Schristos     } while (err == Z_OK);
72796c32c9Schristos 
73796c32c9Schristos     *sourceLen -= len + stream.avail_in;
74796c32c9Schristos     if (dest != buf)
75796c32c9Schristos         *destLen = stream.total_out;
76796c32c9Schristos     else if (stream.total_out && err == Z_BUF_ERROR)
77796c32c9Schristos         left = 1;
78796c32c9Schristos 
79796c32c9Schristos     inflateEnd(&stream);
80796c32c9Schristos     return err == Z_STREAM_END ? Z_OK :
81796c32c9Schristos            err == Z_NEED_DICT ? Z_DATA_ERROR  :
82796c32c9Schristos            err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR :
83796c32c9Schristos            err;
84796c32c9Schristos }
85796c32c9Schristos 
uncompress(dest,destLen,source,sourceLen)86212397c6Schristos int ZEXPORT uncompress (dest, destLen, source, sourceLen)
87212397c6Schristos     Bytef *dest;
88212397c6Schristos     uLongf *destLen;
89212397c6Schristos     const Bytef *source;
90212397c6Schristos     uLong sourceLen;
91212397c6Schristos {
92796c32c9Schristos     return uncompress2(dest, destLen, source, &sourceLen);
93212397c6Schristos }
94