/*
 * This library is mainly intended to demonstrate how to program an
 * encryption sub library/
 */

#define NO_SUB_PRAGMAS

#include <libraries/xpksub.h>

#define A3000 XPKMF_A3000SPEED

XMINFO EncoMode = {
	NULL,    // next
	100,     // upto
	A3000,   // flags
	0,       // packmem
	0,       // unpackmem
	140,     // packspeed,   K/sec
	1043,    // unpackspeed, K/sec
	45,      // ratio,      *0.1%
	0,       // reserved
	"normal" // description
};

static struct XpkInfo EncoInfo = {
		1,               /* info version */
		0,               /* lib  version */
		0,               /* master vers  */
		0,               /* pad          */
		"ENCO",          /* short name   */
		"Encoder 0.1",   /* long name    */
		"Totally unsafe encryption", /* description*/
		'ENCO',          /* 4 letter ID  */
		XPKIF_PK_CHUNK  |/* flags        */
		XPKIF_UP_CHUNK  |
		XPKIF_ENCRYPTION|
		XPKIF_NEEDPASSWD,
		500000,          /* max in chunk */
		0,               /* min in chunk */
		50000,           /* def in chunk */
		"Encoding",      /* pk message   */
		"Decoding",      /* up message   */
		"Encoded",       /* pk past msg  */
		"Decoded",       /* up past msg  */
		50,              /* def mode     */
		0,               /* pad          */
		&EncoMode        /* modes        */
};

/*
 * Returns an info structure about our packer
 */
struct XpkInfo * __saveds __asm
XpksPackerInfo( void )
{
	return &EncoInfo;
}


void __saveds __asm
XpksPackFree( REG __a0 XPARAMS* xpar )
{
}

/*
 * This forces the next chunk to be uncompressable independent from the
 * previous one. This is always the case in RLEN.
 */
long __saveds __asm
XpksPackReset( REG __a0 XPARAMS* xpar )
{
	return 0;
}


void __saveds __asm
XpksUnpackFree( REG __a0 XPARAMS* xpar )
{
}

/*
 * Pack a chunk
 */

UBYTE
password( APTR word )
{
	UBYTE *p=(UBYTE *)word;
	UBYTE r=0;

	while( *p )
		r ^= *p++;
	return r;
}

long __saveds __asm
XpksPackChunk( REG __a0 XPARAMS *xpar )
{
	UBYTE  pw = password(xpar->Password), *r, *w, byte, sum=0;
	LONG   len;

	for(  r=xpar->InBuf,w=xpar->OutBuf,len=xpar->InLen; len; len-- ) {
		byte=*r++;
		sum+=byte;
		byte^=pw;
		*w++=byte;
	}
	*w= sum;

	xpar->OutLen= xpar->InLen+1;
	return 0;
}


long __saveds __asm
XpksUnpackChunk( REG __a0 XPARAMS* xpar )
{
	UBYTE  pw = password(xpar->Password), *r, *w, byte, sum=0;
	LONG   len;

	for(  r=xpar->InBuf,w=xpar->OutBuf,len=xpar->InLen-1; len; len-- ) {
		byte=*r++;
		byte^=pw;
		sum+=byte;
		*w++=byte;
	}
	if( *r!=sum )
		return XPKERR_WRONGPW;

	xpar->OutLen= xpar->InLen-1;
	return 0;
}
