/*
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:

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

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

#pragma once

#include "XMill.h"

class XMLOutput;

/* C functions */
inline void IntToStr(long val, char *tmpstr, int tmplen, char **retptr);
inline void PrintZeros(XMLOutput *output,unsigned long zeronum);
void PrintInteger(unsigned long val,char isneg,unsigned mindigits,XMLOutput *output);
char ParseUnsignedInt(char *str,int len,unsigned long *val);
char ParseSignedInt(char *str,int len,unsigned long *val,unsigned char *neg);
char ParseSignedInt(char *str,int len,long *val);

// The simple text compressor 't'
class PlainTextCompressor : public UserCompressor
{
public:
   PlainTextCompressor(Session *s);
   void CompressString(char *str,unsigned len,CompressContainer *cont,char *dataptr);
};

class PlainTextUncompressor : public UserUncompressor
{
public:
	PlainTextUncompressor();
   PlainTextUncompressor(Session *s);
	void Init();
   void UncompressItem(UncompressContainer *cont,char *dataptr,XMLOutput *xoutput);
};

class PlainTextCompressorFactory : public UserCompressorFactory
{
   PlainTextUncompressor   uncompressor;
public:
   char *GetName();
   char *GetDescription();

	PlainTextCompressorFactory(Session *s): UserCompressorFactory(s) 
	{
		uncompressor.SetSession(s);
	}

   UserCompressor *InstantiateCompressor(char *paramstr,int len);
	UserUncompressor *InstantiateUncompressor(char *paramstr,int len);
};

// The simple print compressor 'p'
class PrintCompressor : public UserCompressor
{
public:
	PrintCompressor();
   PrintCompressor(Session *s);
	void Init();
   char ParseString(char *str,unsigned len,char *dataptr);
   void CompressString(char *str,unsigned len,CompressContainer *cont,char *dataptr);
};

class PrintUncompressor : public UserUncompressor
{
public:
	PrintUncompressor();
   PrintUncompressor(Session *s);
	void Init();
   void UncompressItem(UncompressContainer *cont,char *dataptr,XMLOutput *xoutput);
};

class PrintCompressorFactory : public UserCompressorFactory
{
   PrintCompressor   compressor;
   PrintUncompressor uncompressor;
public:
   char *GetName();
   char *GetDescription();

	PrintCompressorFactory(Session *s): UserCompressorFactory(s) 
	{
		compressor.SetSession(s);
		uncompressor.SetSession(s);
	}

   UserCompressor *InstantiateCompressor(char *paramstr,int len);
	UserUncompressor *InstantiateUncompressor(char *paramstr,int len);
};

// The standard integer user compressor 'u'
class UnsignedIntCompressor : public UserCompressor
{
   unsigned long val;
   unsigned long mindigits;
public:
   UnsignedIntCompressor(Session *s, unsigned long mymindigits);
   char ParseString(char *str,unsigned len,char *dataptr);
   void CompressString(char *str,unsigned len,CompressContainer *cont,char *dataptr);
};

class UnsignedIntUncompressor : public UserUncompressor
{
   unsigned long mindigits;

public:
   UnsignedIntUncompressor(unsigned long mymindigits=0);
   UnsignedIntUncompressor(Session *s, unsigned long mymindigits=0);
	void Init(unsigned long mymindigits);
   void UncompressItem(UncompressContainer *cont,char *dataptr,XMLOutput *xoutput);
};

class UnsignedIntCompressorFactory : public UserCompressorFactory
{
   UnsignedIntUncompressor uncompressor;
public:
   char *GetName();
   char *GetDescription();

	UnsignedIntCompressorFactory(Session *s): UserCompressorFactory(s) 
	{
		uncompressor.SetSession(s);
	}

   UserCompressor *InstantiateCompressor(char *paramstr,int len);
	UserUncompressor *InstantiateUncompressor(char *paramstr,int len);
};

// The standard byte integer compressor 'u8'
class UnsignedInt8Compressor : public UserCompressor
{
   unsigned long val;
   unsigned long mindigits;
public:
   UnsignedInt8Compressor(Session *s, unsigned long mymindigits);
   char ParseString(char *str,unsigned len,char *dataptr);
   void CompressString(char *str,unsigned len,CompressContainer *cont,char *dataptr);
};

class UnsignedInt8Uncompressor : public UserUncompressor
{
   unsigned long mindigits;
public:
   UnsignedInt8Uncompressor(unsigned long mymindigits=0);
   UnsignedInt8Uncompressor(Session *s, unsigned long mymindigits=0);
   void Init(unsigned long mymindigits);
   void UncompressItem(UncompressContainer *cont,char *dataptr,XMLOutput *xoutput);
};

class UnsignedInt8CompressorFactory : public UserCompressorFactory
{
   UnsignedInt8Uncompressor   uncompressor;

public:
   char *GetName();
   char *GetDescription();

	UnsignedInt8CompressorFactory(Session *s): UserCompressorFactory(s) 
	{
		uncompressor.SetSession(s);
	}

	UserCompressor *InstantiateCompressor(char *paramstr,int len);
	UserUncompressor *InstantiateUncompressor(char *paramstr,int len);
};

// The standard signed integer compressor 'i'
class SignedIntCompressor : public UserCompressor
{
   unsigned long  val;
   unsigned char  isneg;
   unsigned long  mindigits;
public:
   SignedIntCompressor(Session *s, unsigned long mymindigits);
   char ParseString(char *str,unsigned len,char *dataptr);
   void CompressString(char *str,unsigned len,CompressContainer *cont,char *dataptr);
};

class SignedIntUncompressor : public UserUncompressor
{
   unsigned long mindigits;
public:
   SignedIntUncompressor(unsigned long mymindigits=0);
   SignedIntUncompressor(Session *s, unsigned long mymindigits=0);
   void Init(unsigned long mymindigits);
   void UncompressItem(UncompressContainer *cont,char *dataptr,XMLOutput *xoutput);
};

class SignedIntCompressorFactory : public UserCompressorFactory
{
   SignedIntUncompressor   uncompressor;
public:
	SignedIntCompressorFactory(Session *s): UserCompressorFactory(s) 
	{
		uncompressor.SetSession(s);
	}

	char *GetName();
   char *GetDescription();

   UserCompressor *InstantiateCompressor(char *paramstr,int len);
	UserUncompressor *InstantiateUncompressor(char *paramstr,int len);
};

// The delta compressor 'di'
struct DeltaCompressorState
   // The state of the delta compressor
{
   long  prevvalue;
};

class DeltaCompressor : public UserCompressor
{
   long  val;                 // The temporarily parsed value
   unsigned long mindigits;

public:
   DeltaCompressor(Session *s, unsigned long mymindigits);
   void InitCompress(CompressContainer *cont,char *dataptr);
   char ParseString(char *str,unsigned len,char *dataptr);
   void CompressString(char *str,unsigned len,CompressContainer *cont,char *dataptr);
};

class DeltaUncompressor : public UserUncompressor
{
   unsigned long mindigits;
public:
   DeltaUncompressor(unsigned long mymindigits=0);
   DeltaUncompressor(Session *s, unsigned long mymindigits=0);
   void Init(unsigned long mymindigits);
   void InitUncompress(UncompressContainer *cont,char *dataptr);
   void UncompressItem(UncompressContainer *cont,char *dataptr,XMLOutput *xoutput);
};

class DeltaCompressorFactory : public UserCompressorFactory
{
   DeltaUncompressor uncompressor;

public:
	char *GetName();
   char *GetDescription();

	DeltaCompressorFactory(Session *s);
   UserCompressor *InstantiateCompressor(char *paramstr,int len);
	UserUncompressor *InstantiateUncompressor(char *paramstr,int len);};

// The constant compressor
class ConstantCompressor : public UserCompressor
{
   char     *constantstr;     // The constant string that the parsed string must match
   unsigned constantstrlen;

public:
   ConstantCompressor(Session *s, char *str,unsigned len);
   ~ConstantCompressor();

   char IsRejecting();
   char CanOverlap();
   unsigned short GetContainerNum();
   char ParseString(char *str,unsigned len,char *dataptr);
   void CompressString(char *str,unsigned len,CompressContainer *cont,char *dataptr);
};

class ConstantUncompressor : public UserUncompressor
{
   char     *constantstr;
   unsigned constantstrlen;

public:
   ConstantUncompressor(Session *s, char *str,unsigned len);
   ~ConstantUncompressor();

	void UncompressItem(UncompressContainer *cont,char *dataptr,XMLOutput *xoutput);
};

class ConstantCompressorFactory : public UserCompressorFactory
{
public:
	char *GetName();
   char *GetDescription();

	ConstantCompressorFactory(Session *s,int comp);
   UserCompressor *InstantiateCompressor(char *paramstr,int len);
	UserUncompressor *InstantiateUncompressor(char *paramstr,int len);
};
