165 lines
3.6 KiB
C
165 lines
3.6 KiB
C
/* $NetBSD: inflate.c,v 1.5 2003/03/25 22:48:44 mycroft Exp $ */
|
|
|
|
/* inflate.c -- zlib interface to inflate modules
|
|
* Copyright (C) 1995-2002 Mark Adler
|
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
|
*/
|
|
|
|
#include "zutil.h"
|
|
#include "infblock.h"
|
|
|
|
struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
|
|
|
|
typedef enum {
|
|
BLOCKS, /* decompressing blocks */
|
|
DONE, /* finished check, done */
|
|
BAD} /* got an error--stay here */
|
|
inflate_mode;
|
|
|
|
/* inflate private state */
|
|
struct internal_state {
|
|
|
|
/* mode */
|
|
inflate_mode mode; /* current inflate mode */
|
|
|
|
/* mode independent information */
|
|
uInt wbits; /* log2(window size) (8..15, defaults to 15) */
|
|
inflate_blocks_statef
|
|
*blocks; /* current inflate_blocks state */
|
|
|
|
};
|
|
|
|
|
|
int ZEXPORT inflateReset(z)
|
|
z_streamp z;
|
|
{
|
|
if (z == Z_NULL || z->state == Z_NULL)
|
|
return Z_STREAM_ERROR;
|
|
z->total_in = z->total_out = 0;
|
|
z->msg = Z_NULL;
|
|
z->state->mode = BLOCKS;
|
|
inflate_blocks_reset(z->state->blocks, z, Z_NULL);
|
|
Tracev((stderr, "inflate: reset\n"));
|
|
return Z_OK;
|
|
}
|
|
|
|
|
|
int ZEXPORT inflateEnd(z)
|
|
z_streamp z;
|
|
{
|
|
if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
|
|
return Z_STREAM_ERROR;
|
|
if (z->state->blocks != Z_NULL)
|
|
inflate_blocks_free(z->state->blocks, z);
|
|
ZFREE(z, z->state);
|
|
z->state = Z_NULL;
|
|
Tracev((stderr, "inflate: end\n"));
|
|
return Z_OK;
|
|
}
|
|
|
|
|
|
int ZEXPORT inflateInit2_(z, w, version, stream_size)
|
|
z_streamp z;
|
|
int w;
|
|
const char *version;
|
|
int stream_size;
|
|
{
|
|
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
|
|
stream_size != sizeof(z_stream))
|
|
return Z_VERSION_ERROR;
|
|
|
|
/* initialize state */
|
|
if (z == Z_NULL)
|
|
return Z_STREAM_ERROR;
|
|
z->msg = Z_NULL;
|
|
if (z->zalloc == Z_NULL)
|
|
{
|
|
z->zalloc = zcalloc;
|
|
z->opaque = (voidpf)0;
|
|
}
|
|
if (z->zfree == Z_NULL) z->zfree = zcfree;
|
|
if ((z->state = (struct internal_state FAR *)
|
|
ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
|
|
return Z_MEM_ERROR;
|
|
z->state->blocks = Z_NULL;
|
|
|
|
/* handle undocumented nowrap option (no zlib header or check) */
|
|
if (w < 0)
|
|
w = - w;
|
|
else
|
|
return Z_STREAM_ERROR;
|
|
|
|
/* set window size */
|
|
if (w < 8 || w > 15)
|
|
{
|
|
inflateEnd(z);
|
|
return Z_STREAM_ERROR;
|
|
}
|
|
z->state->wbits = (uInt)w;
|
|
|
|
/* create inflate_blocks state */
|
|
if ((z->state->blocks =
|
|
inflate_blocks_new(z, Z_NULL, (uInt)1 << w))
|
|
== Z_NULL)
|
|
{
|
|
inflateEnd(z);
|
|
return Z_MEM_ERROR;
|
|
}
|
|
Tracev((stderr, "inflate: allocated\n"));
|
|
|
|
/* reset state */
|
|
inflateReset(z);
|
|
return Z_OK;
|
|
}
|
|
|
|
|
|
int ZEXPORT inflateInit_(z, version, stream_size)
|
|
z_streamp z;
|
|
const char *version;
|
|
int stream_size;
|
|
{
|
|
return inflateInit2_(z, -DEF_WBITS, version, stream_size);
|
|
}
|
|
|
|
|
|
#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
|
|
#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
|
|
|
|
int ZEXPORT inflate(z, f)
|
|
z_streamp z;
|
|
int f;
|
|
{
|
|
int r;
|
|
|
|
if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
|
|
return Z_STREAM_ERROR;
|
|
f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
|
|
r = Z_BUF_ERROR;
|
|
while (1) switch (z->state->mode)
|
|
{
|
|
case BLOCKS:
|
|
r = inflate_blocks(z->state->blocks, z, r);
|
|
if (r == Z_DATA_ERROR)
|
|
{
|
|
z->state->mode = BAD;
|
|
break;
|
|
}
|
|
if (r == Z_OK)
|
|
r = f;
|
|
if (r != Z_STREAM_END)
|
|
return r;
|
|
r = f;
|
|
inflate_blocks_reset(z->state->blocks, z, Z_NULL);
|
|
z->state->mode = DONE;
|
|
case DONE:
|
|
return Z_STREAM_END;
|
|
case BAD:
|
|
return Z_DATA_ERROR;
|
|
default:
|
|
return Z_STREAM_ERROR;
|
|
}
|
|
#ifdef NEED_DUMMY_RETURN
|
|
return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
|
|
#endif
|
|
}
|