static zip_int64_t deflate_decompress(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { struct deflate *ctx; zip_int64_t n; int ret; ctx = (struct deflate *)ud; switch (cmd) { case ZIP_SOURCE_OPEN: if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) { _zip_error_set_from_source(&ctx->error, src); return -1; } ctx->zstr.zalloc = Z_NULL; ctx->zstr.zfree = Z_NULL; ctx->zstr.opaque = NULL; ctx->zstr.next_in = (Bytef *)ctx->buffer; ctx->zstr.avail_in = (uInt)n; /* negative value to tell zlib that there is no header */ if ((ret=inflateInit2(&ctx->zstr, -MAX_WBITS)) != Z_OK) { zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret); return -1; } return 0; case ZIP_SOURCE_READ: return decompress_read(src, ctx, data, len); case ZIP_SOURCE_CLOSE: inflateEnd(&ctx->zstr); return 0; case ZIP_SOURCE_STAT: { zip_stat_t *st; st = (zip_stat_t *)data; st->comp_method = ZIP_CM_STORE; if (st->comp_size > 0 && st->size > 0) st->comp_size = st->size; return 0; } case ZIP_SOURCE_ERROR: return zip_error_to_data(&ctx->error, data, len); case ZIP_SOURCE_FREE: free(ctx); return 0; case ZIP_SOURCE_SUPPORTS: return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, -1); default: zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); return -1; } }
static zip_int64_t deflate_decompress(struct zip_source *src, void *ud, void *data, zip_uint64_t len, enum zip_source_cmd cmd) { struct deflate *ctx; zip_int64_t n; int ret; ctx = (struct deflate *)ud; switch (cmd) { case ZIP_SOURCE_OPEN: if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) return ZIP_SOURCE_ERR_LOWER; ctx->zstr.zalloc = Z_NULL; ctx->zstr.zfree = Z_NULL; ctx->zstr.opaque = NULL; ctx->zstr.next_in = (Bytef *)ctx->buffer; ctx->zstr.avail_in = (uInt)n /* TODO: check for overflow */; /* negative value to tell zlib that there is no header */ if ((ret=inflateInit2(&ctx->zstr, -MAX_WBITS)) != Z_OK) { ctx->e[0] = ZIP_ER_ZLIB; ctx->e[1] = ret; return -1; } return 0; case ZIP_SOURCE_READ: return decompress_read(src, ctx, data, len); case ZIP_SOURCE_CLOSE: inflateEnd(&ctx->zstr); return 0; case ZIP_SOURCE_STAT: { struct zip_stat *st; st = (struct zip_stat *)data; st->comp_method = ZIP_CM_STORE; if (st->comp_size > 0 && st->size > 0) st->comp_size = st->size; } return 0; case ZIP_SOURCE_ERROR: if (len < sizeof(int)*2) return -1; memcpy(data, ctx->e, sizeof(int)*2); return sizeof(int)*2; case ZIP_SOURCE_FREE: /* TODO: inflateEnd if close was not called */ free(ctx); return 0; default: ctx->e[0] = ZIP_ER_INVAL; ctx->e[1] = 0; return -1; } }