/*
 * 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 "pgp.h"
#include "px.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 palloc(n_items * item_len);
}

static void
z_free(void *priv, void *addr)
{
	pfree(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 = palloc0(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)
	{
		pfree(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
	 */
	st->stream.next_in = unconstify(uint8 *, data);
	st->stream.avail_in = len;
	while (st->stream.avail_in > 0)
	{
		st->stream.next_out = st->buf;
		st->stream.avail_out = st->buf_len;
		res = deflate(&st->stream, Z_NO_FLUSH);
		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;
		}
	}

	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);
	px_memset(st, 0, sizeof(*st));
	pfree(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 = palloc0(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)
	{
		pfree(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)
	{
		uint8	   *tmp;

		/*
		 * A stream must be terminated by a normal packet.  If the last stream
		 * packet in the source stream is a full packet, a normal empty packet
		 * must follow.  Since the underlying packet reader doesn't know that
		 * the compressed stream has been ended, we need to consume the
		 * terminating packet here.  This read does not harm even if the
		 * stream has already ended.
		 */
		res = pullf_read(src, 1, &tmp);

		if (res < 0)
			return res;
		else if (res > 0)
		{
			px_debug("decompress_read: extra bytes after end of stream");
			return PXE_PGP_CORRUPT_DATA;
		}
		dec->eof = 1;
	}
	goto restart;
}

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

	inflateEnd(&dec->stream);
	px_memset(dec, 0, sizeof(*dec));
	pfree(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_LIBZ */

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
