tinfzlib: Refactor to support stream interface.

This commit is contained in:
Paul Sokolovsky 2016-08-06 00:18:52 +03:00
parent e200028869
commit 61d9cd644f
2 changed files with 38 additions and 46 deletions

View file

@ -59,6 +59,9 @@ typedef struct TINF_DATA {
/* Remaining bytes in buffer */
unsigned int destRemaining;
/* Accumulating checksum */
unsigned int checksum;
int btype;
int bfinal;
unsigned int curlen;
@ -89,7 +92,9 @@ typedef struct TINF_DATA {
void tinf_uncompress_dyn_init(TINF_DATA *d, void *dict, unsigned int dictLen);
int TINFCC tinf_uncompress_dyn(TINF_DATA *d);
int TINFCC tinf_zlib_uncompress_dyn(TINF_DATA *d, unsigned int sourceLen);
int TINFCC tinf_zlib_parse_header(TINF_DATA *d);
int TINFCC tinf_zlib_uncompress_dyn(TINF_DATA *d);
/* high-level API */
@ -103,8 +108,7 @@ typedef struct TINF_GZIP_INFO {
int tinf_gzip_parse_header(TINF_GZIP_INFO *gz, const unsigned char **source, unsigned int sourceLen);
int tinf_gzip_parse_trailer(TINF_GZIP_INFO *gz, const unsigned char **source, unsigned int sourceLen);
int TINFCC tinf_zlib_uncompress(void *dest, unsigned int *destLen,
const void *source, unsigned int sourceLen);
unsigned char TINFCC tinf_read_src_byte(TINF_DATA *d);
unsigned int TINFCC tinf_adler32(const void *data, unsigned int length, unsigned int prev_sum /* 1 */);

View file

@ -33,35 +33,14 @@
#include "tinf.h"
int tinf_zlib_uncompress(void *dest, unsigned int *destLen,
const void *source, unsigned int sourceLen)
int tinf_zlib_parse_header(TINF_DATA *d)
{
TINF_DATA d;
int res;
/* initialise data */
d.source = (const unsigned char *)source;
d.destStart = (unsigned char *)dest;
d.destSize = *destLen;
res = tinf_zlib_uncompress_dyn(&d, sourceLen);
*destLen = d.dest - d.destStart;
return res;
}
int tinf_zlib_uncompress_dyn(TINF_DATA *d, unsigned int sourceLen)
{
unsigned int a32;
int res;
unsigned char cmf, flg;
/* -- get header bytes -- */
cmf = d->source[0];
flg = d->source[1];
cmf = tinf_read_src_byte(d);
flg = tinf_read_src_byte(d);
/* -- check format -- */
@ -77,25 +56,34 @@ int tinf_zlib_uncompress_dyn(TINF_DATA *d, unsigned int sourceLen)
/* check there is no preset dictionary */
if (flg & 0x20) return TINF_DATA_ERROR;
/* -- get adler32 checksum -- */
/* initialize for adler32 checksum */
d->checksum = 1;
a32 = d->source[sourceLen - 4];
a32 = 256*a32 + d->source[sourceLen - 3];
a32 = 256*a32 + d->source[sourceLen - 2];
a32 = 256*a32 + d->source[sourceLen - 1];
d->source += 2;
/* -- inflate -- */
res = tinf_uncompress_dyn(d);
if (res != TINF_OK) return res;
/* -- check adler32 checksum -- */
if (a32 != tinf_adler32(d->destStart, d->dest - d->destStart)) return TINF_DATA_ERROR;
return TINF_OK;
return cmf >> 4;
}
int tinf_zlib_uncompress_dyn(TINF_DATA *d)
{
int res;
unsigned char *data = d->dest;
res = tinf_uncompress_dyn(d);
if (res < 0) return res;
d->checksum = tinf_adler32(data, d->dest - data, d->checksum);
if (res == TINF_DONE) {
/* -- get adler32 checksum -- */
unsigned int a32 = 0;
int i;
for (i = 4; i--;) {
a32 = a32 << 8 | tinf_read_src_byte(d);
}
if (d->checksum != a32) {
return TINF_DATA_ERROR;
}
}
return res;
}