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;
    }
}
Exemple #2
0
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;
    }
    
}