blob: 9124ad6aca7aa63161c7ebedcbc3ee5dc2f1b2b0 [file] [log] [blame]
#include "zip.h"
#include "zipint.h"
int
zip_fread(struct zip_file *zff, char *outbuf, int toread)
{
int len, out_before, ret;
if (!zff)
return -1;
if (zff->flags != 0)
return -1;
if (toread == 0)
return 0;
if (zff->bytes_left == 0) {
zff->flags = -1;
if (zff->crc != zff->crc_orig) {
zff->flags = ZERR_CRC;
return -1;
}
return 0;
}
if (zff->method == 0) {
ret = _zip_file_fillbuf(outbuf, toread, zff);
if (ret > 0) {
zff->crc = crc32(zff->crc, outbuf, ret);
zff->bytes_left -= ret;
}
return ret;
}
zff->zstr->next_out = outbuf;
zff->zstr->avail_out = toread;
out_before = zff->zstr->total_out;
/* endless loop until something has been accomplished */
for (;;) {
ret = inflate(zff->zstr, Z_SYNC_FLUSH);
switch (ret) {
case Z_OK:
case Z_STREAM_END:
/* all ok */
/* XXX: STREAM_END probably won't happen, since we didn't
have a header */
len = zff->zstr->total_out - out_before;
if (len >= zff->bytes_left || len >= toread) {
zff->crc = crc32(zff->crc, outbuf, len);
zff->bytes_left -= len;
return(len);
}
break;
case Z_BUF_ERROR:
if (zff->zstr->avail_in == 0) {
/* read some more bytes */
len = _zip_file_fillbuf(zff->buffer, BUFSIZE, zff);
if (len <= 0) {
/* XXX: error
myerror (ERRSTR, "read error");
*/
return -1;
}
zff->zstr->next_in = zff->buffer;
zff->zstr->avail_in = len;
continue;
}
/* XXX: set error */
zip_err = ZERR_ZLIB;
return -1;
case Z_NEED_DICT:
case Z_DATA_ERROR:
case Z_STREAM_ERROR:
case Z_MEM_ERROR:
/* XXX: set error */
zip_err = ZERR_ZLIB;
return -1;
}
}
}