/*
 * pgp-compress.c
 *	  ZIP and ZLIB compression via zlib.
 *
 * Copyright (c) 2005 Marko Kreen
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *	  notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *	  notice, this list of conditions and the following disclaimer in the
 *	  documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * contrib/pgcrypto/pgp-compress.c
 */

#include "postgres.h"

#include "mbuf.h"
#include "px.h"
#include "pgp.h"


/*
 * Compressed pkt writer
 */

#ifdef HAVE_LIBZ

#include <zlib.h>

#define ZIP_OUT_BUF 8192
#define ZIP_IN_BLOCK 8192

struct ZipStat
{
	uint8		type;
	int			buf_len;
	int			hdr_done;
	z_stream	stream;
	uint8		buf[ZIP_OUT_BUF];
};

static void *
z_alloc(void *priv, unsigned n_items, unsigned item_len)
{
	return px_alloc(n_items * item_len);
}

static void
z_free(void *priv, void *addr)
{
	px_free(addr);
}

static int
compress_init(PushFilter *next, void *init_arg, void **priv_p)
{
	int			res;
	struct ZipStat *st;
	PGP_Context *ctx = init_arg;
	uint8		type = ctx->compress_algo;

	if (type != PGP_COMPR_ZLIB && type != PGP_COMPR_ZIP)
		return PXE_PGP_UNSUPPORTED_COMPR;

	/*
	 * init
	 */
	st = px_alloc(sizeof(*st));
	memset(st, 0, sizeof(*st));
	st->buf_len = ZIP_OUT_BUF;
	st->stream.zalloc = z_alloc;
	st->stream.zfree = z_free;

	if (type == PGP_COMPR_ZIP)
		res = deflateInit2(&st->stream, ctx->compress_level,
						   Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
	else
		res = deflateInit(&st->stream, ctx->compress_level);
	if (res != Z_OK)
	{
		px_free(st);
		return PXE_PGP_COMPRESSION_ERROR;
	}
	*priv_p = st;

	return ZIP_IN_BLOCK;
}

/* writes compressed data packet */

/* can handle zero-len incoming data, but shouldn't */
static int
compress_process(PushFilter *next, void *priv, const uint8 *data, int len)
{
	int			res,
				n_out;
	struct ZipStat *st = priv;

	/*
	 * process data
	 */
	while (len > 0)
	{
		st->stream.next_in = (void *) data;
		st->stream.avail_in = len;
		st->stream.next_out = st->buf;
		st->stream.avail_out = st->buf_len;
		res = deflate(&st->stream, 0);
		if (res != Z_OK)
			return PXE_PGP_COMPRESSION_ERROR;

		n_out = st->buf_len - st->stream.avail_out;
		if (n_out > 0)
		{
			res = pushf_write(next, st->buf, n_out);
			if (res < 0)
				return res;
		}
		len = st->stream.avail_in;
	}

	return 0;
}

static int
compress_flush(PushFilter *next, void *priv)
{
	int			res,
				zres,
				n_out;
	struct ZipStat *st = priv;

	st->stream.next_in = NULL;
	st->stream.avail_in = 0;
	while (1)
	{
		st->stream.next_out = st->buf;
		st->stream.avail_out = st->buf_len;
		zres = deflate(&st->stream, Z_FINISH);
		if (zres != Z_STREAM_END && zres != Z_OK)
			return PXE_PGP_COMPRESSION_ERROR;
		n_out = st->buf_len - st->stream.avail_out;
		if (n_out > 0)
		{
			res = pushf_write(next, st->buf, n_out);
			if (res < 0)
				return res;
		}
		if (zres == Z_STREAM_END)
			break;
	}
	return 0;
}

static void
compress_free(void *priv)
{
	struct ZipStat *st = priv;

	deflateEnd(&st->stream);
	memset(st, 0, sizeof(*st));
	px_free(st);
}

static const PushFilterOps
			compress_filter = {
	compress_init, compress_process, compress_flush, compress_free
};

int
pgp_compress_filter(PushFilter **res, PGP_Context *ctx, PushFilter *dst)
{
	return pushf_create(res, &compress_filter, ctx, dst);
}

/*
 * Decompress
 */
struct DecomprData
{
	int			buf_len;		/* = ZIP_OUT_BUF */
	int			buf_data;		/* available data */
	uint8	   *pos;
	z_stream	stream;
	int			eof;
	uint8		buf[ZIP_OUT_BUF];
};

static int
decompress_init(void **priv_p, void *arg, PullFilter *src)
{
	PGP_Context *ctx = arg;
	struct DecomprData *dec;
	int			res;

	if (ctx->compress_algo != PGP_COMPR_ZLIB
		&& ctx->compress_algo != PGP_COMPR_ZIP)
		return PXE_PGP_UNSUPPORTED_COMPR;

	dec = px_alloc(sizeof(*dec));
	memset(dec, 0, sizeof(*dec));
	dec->buf_len = ZIP_OUT_BUF;
	*priv_p = dec;

	dec->stream.zalloc = z_alloc;
	dec->stream.zfree = z_free;

	if (ctx->compress_algo == PGP_COMPR_ZIP)
		res = inflateInit2(&dec->stream, -15);
	else
		res = inflateInit(&dec->stream);
	if (res != Z_OK)
	{
		px_free(dec);
		px_debug("decompress_init: inflateInit error");
		return PXE_PGP_COMPRESSION_ERROR;
	}

	return 0;
}

static int
decompress_read(void *priv, PullFilter *src, int len,
				uint8 **data_p, uint8 *buf, int buflen)
{
	int			res;
	int			flush;
	struct DecomprData *dec = priv;

restart:
	if (dec->buf_data > 0)
	{
		if (len > dec->buf_data)
			len = dec->buf_data;
		*data_p = dec->pos;
		dec->pos += len;
		dec->buf_data -= len;
		return len;
	}

	if (dec->eof)
		return 0;

	if (dec->stream.avail_in == 0)
	{
		uint8	   *tmp;

		res = pullf_read(src, 8192, &tmp);
		if (res < 0)
			return res;
		dec->stream.next_in = tmp;
		dec->stream.avail_in = res;
	}

	dec->stream.next_out = dec->buf;
	dec->stream.avail_out = dec->buf_len;
	dec->pos = dec->buf;

	/*
	 * Z_SYNC_FLUSH is tell zlib to output as much as possible. It should do
	 * it anyway (Z_NO_FLUSH), but seems to reserve the right not to.  So lets
	 * follow the API.
	 */
	flush = dec->stream.avail_in ? Z_SYNC_FLUSH : Z_FINISH;
	res = inflate(&dec->stream, flush);
	if (res != Z_OK && res != Z_STREAM_END)
	{
		px_debug("decompress_read: inflate error: %d", res);
		return PXE_PGP_CORRUPT_DATA;
	}

	dec->buf_data = dec->buf_len - dec->stream.avail_out;
	if (res == Z_STREAM_END)
		dec->eof = 1;
	goto restart;
}

static void
decompress_free(void *priv)
{
	struct DecomprData *dec = priv;

	inflateEnd(&dec->stream);
	memset(dec, 0, sizeof(*dec));
	px_free(dec);
}

static const PullFilterOps
			decompress_filter = {
	decompress_init, decompress_read, decompress_free
};

int
pgp_decompress_filter(PullFilter **res, PGP_Context *ctx, PullFilter *src)
{
	return pullf_create(res, &decompress_filter, ctx, src);
}
#else							/* !HAVE_ZLIB */

int
pgp_compress_filter(PushFilter **res, PGP_Context *ctx, PushFilter *dst)
{
	return PXE_PGP_UNSUPPORTED_COMPR;
}

int
pgp_decompress_filter(PullFilter **res, PGP_Context *ctx, PullFilter *src)
{
	return PXE_PGP_UNSUPPORTED_COMPR;
}

#endif
