// xmillexample.cpp : XMill memory API example
//

#include "stdafx.h"

/* blocksize must be at least as large as the largest element length */
#define BLOCKSIZE	2048

int blockcompdecomp(XMill *xmill, char *xmlfile, int blocksize)
{
	int stat = 0;
	char *xmlbuf = NULL;
	char *xmibuf = NULL;
	char *xmlbuf2 = NULL;
	int xmlbuflen = 0;
	int xmibuflen = 0;
	int xmlbuflen2 = 0;
	int bytesread = 0, endmarker = 0, len = 0;

	/* read XML file */
	if ((stat = readfile(xmlfile, &xmlbuf, &xmlbuflen)) != 0) {
		goto cleanup;
	}

	/* Initialize XMill internal memory */
	xmill->Init();

	/* init block compression */
	xmill->InitCompress(&xmibuf, &xmibuflen, &bytesread);
	do {
		/* must we signal end-of-data ? */
		if ((len = min(blocksize, xmlbuflen-bytesread)) == xmlbuflen-bytesread) {
			/* yes! */
			endmarker = XMILL_END_DATA;
		} else {
			endmarker = XMILL_END_NONE;
		}
		/* compress this block */
		xmill->CompressBlock(
				&xmlbuf[bytesread], 
				len,
				&endmarker);
	} while (bytesread < xmlbuflen);

	/* compression done, check endmarker */
	if (endmarker != XMILL_END_DATA) {
		/* XML file not valid! */
		//throw new XMillException(XMILL_ERR_PARSE, "There are unclosed XML tags!");
		stat = XMILL_ERR_PARSE;
		goto cleanup;
	}

	/* end the block compression */
	xmill->EndCompress();

	/* decompress */
	xmill->Decompress(xmibuf, xmibuflen, &xmlbuf2, &xmlbuflen2, &bytesread);

	/* free some data */
	tryfree (xmlbuf);
	tryfree (xmibuf);
	tryfree (xmlbuf2);

cleanup:
	return stat;
}

int compdecomp(XMill *xmill, char *xmlfile)
{
	char *xmlbuf = NULL;
	char *xmibuf = NULL;
	char *xmlbuf2 = NULL;
	int xmlbuflen = 0;
	int xmibuflen = 0;
	int xmlbuflen2 = 0;
	int bytesread = 0;
	int stat = 0;

	/* read XML file */
	if ((stat = readfile(xmlfile, &xmlbuf, &xmlbuflen)) != 0) {
		goto cleanup;
	}

	/* Initialize XMill internal memory */
	xmill->Init();

	/* compress */
	xmill->Compress(xmlbuf, xmlbuflen, &xmibuf, &xmibuflen, &bytesread);

	/* decompress */
	xmill->Decompress(xmibuf, xmibuflen, &xmlbuf2, &xmlbuflen2, &bytesread);

cleanup:
	/* free some data */
	tryfree (xmlbuf);
	tryfree (xmibuf);
	tryfree (xmlbuf2);

	return stat;
}

#ifdef WIN32
int _tmain(int argc, _TCHAR* argv[])
#else
int main(int argc, char* argv[])
#endif
{
	int stat = 0;
   XMill *xmill = new XMill();

	try {
		for (int i=1; i<argc; i++) {
			/* compress & decompress in one go */
			if ((stat = compdecomp(xmill, argv[i])) != 0) {
				goto cleanup;
			}
			/* compress with blocks, decompress in one go */
			if ((stat = blockcompdecomp(xmill, argv[i], BLOCKSIZE)) != 0) {
				goto cleanup;
			}
		}
	} catch (XMillException *e) {
		e->PrintErrorMsg();
      delete e;
	}

cleanup:
	delete xmill;

	return stat;
}

