/*
This product contains certain software code or other information
("AT&T Software") proprietary to AT&T Corp. ("AT&T").  The AT&T
Software is provided to you "AS IS".  YOU ASSUME TOTAL RESPONSIBILITY
AND RISK FOR USE OF THE AT&T SOFTWARE.  AT&T DOES NOT MAKE, AND
EXPRESSLY DISCLAIMS, ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND
WHATSOEVER, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, WARRANTIES OF
TITLE OR NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS, ANY
WARRANTIES ARISING BY USAGE OF TRADE, COURSE OF DEALING OR COURSE OF
PERFORMANCE, OR ANY WARRANTY THAT THE AT&T SOFTWARE IS "ERROR FREE" OR
WILL MEET YOUR REQUIREMENTS.

Unless you accept a license to use the AT&T Software, you shall not
reverse compile, disassemble or otherwise reverse engineer this
product to ascertain the source code for any AT&T Software.

(c) AT&T Corp. All rights reserved.  AT&T is a registered trademark of AT&T Corp.

***********************************************************************

History:

      24/11/99  - initial release by Hartmut Liefke, liefke@seas.upenn.edu
                                     Dan Suciu,      suciu@research.att.com
*/

//**************************************************************************
//**************************************************************************

// This module implements 'Compressor' and 'Uncompressor' -
// the interfaces to the ZLIB (either gzip or bzip) libary

#include "stdafx.h"

GZip::GZip(int idx, bool iscomp): Zipper(idx, iscomp)
{
	zstate.zalloc=zalloc;
	zstate.zfree=zfree;
}

GZip::~GZip() 
{}
	
void GZip::initCompress() 
{
	if(deflateInit(&zstate, idx) != Z_OK) {
		throw new XMillException (XMILL_ERR_ZLIB, "Error while compressing container!");
	}
}

void GZip::setCompPtrs(char *nextout, char* nextin, int availin)
{
	zstate.next_out = (Bytef*)nextout;
	zstate.next_in = (Bytef*)nextin;
	zstate.avail_in = availin;
}

int GZip::doCompress(int flag)
{
	if (flag == -1)
		flag = Z_FINISH;
	else if (flag = BZ_RUN)
		flag = Z_NO_FLUSH;
	switch (deflate(&zstate,flag)) {
		case Z_STREAM_END:
			return BZ_STREAM_END;
		case Z_OK:
			if (flag == Z_NO_FLUSH)
				return BZ_RUN_OK;
			else
				return BZ_OK;
	}
	/* invent error code */
	return BZ_SEQUENCE_ERROR;
}

void GZip::endCompress() 
{
	deflateEnd(&zstate);
}

void GZip::resetCompress()
{
	if(deflateReset(&zstate) != Z_OK) {
		throw new XMillException (XMILL_ERR_ZLIB, "Error while compressing container!");
	}
}

void GZip::initUncompress() 
{
	if(inflateInit(&zstate) != Z_OK) {
		throw new XMillException (XMILL_ERR_ZLIB, "Error while uncompressing container!");
	}
}

void GZip::setUncompPtrs(char *nextout, int availout, int availin)
{
	zstate.next_out = (Bytef*)nextout;
	zstate.avail_out = availout;
	zstate.avail_in = availin;
}

void GZip::setNextOut(char* nextout)
{
	zstate.next_out = (Bytef*)nextout;
}

void GZip::setNextIn(char* nextin)
{
	zstate.next_in = (Bytef*)nextin;
}

void GZip::setAvailIn(int availin)
{
	zstate.avail_in = availin;
}

char **GZip::getNextInPtr() 
{
	return (char **)&(zstate.next_in);
}

void GZip::endUncompress()
{
	if(inflateReset(&zstate) != Z_OK) {
		throw new XMillException (XMILL_ERR_ZLIB, "Error while uncompressing container!");
	}
}

int GZip::getAvailIn()
{
	return zstate.avail_in;
}

int* GZip::getAvailInPtr()
{
	return (int*)&zstate.avail_in;
}

int GZip::getAvailOut()
{
	return zstate.avail_out;
}

int* GZip::getAvailOutPtr()
{
	return (int*)&zstate.avail_out;
}

int GZip::getTotalOut()
{
	return zstate.total_out;
}

int GZip::getTotalIn()
{
	return zstate.total_in;
}

void GZip::resetTotals()
{
	zstate.total_in = 0;
	zstate.total_out = 0;
}

int GZip::doUncompress()
{
	int retcode;
	switch (inflate(&zstate,Z_NO_FLUSH)) {
		case Z_STREAM_END:
			retcode = BZ_STREAM_END;
			break;
		case Z_OK:
			retcode = BZ_OK;
			break;
		default:
			if (zstate.next_in != NULL)
				/* 'invent' error code */
				retcode = BZ_SEQUENCE_ERROR;
			else {
				/* continue anyway, next_in will be filled next time */
				retcode = BZ_OK;
			}
			break;
	}
	return retcode;
}
