#define NAME	 "testMemUnpack"
#define REVISION "2"
#define ENDCODE_NOCTRLC

/* Programmheader

	Name:		testMemUnpack
	Author:		SDI
	Distribution:	PD
	Description:	tests Xpk Pack function
	Compileropts:	-
	Linkeropts:	-l xpkmaster amiga

 1.1   06.12.96 : fixed for new includes, added new WriteXpkFib
 1.2   15.04.97 : removed WriteXpkFib.c
*/

#include <pragma/exec_lib.h>
#include <pragma/dos_lib.h>
#include <pragma/xpkmaster_lib.h>
#include <exec/memory.h>
#include "SDI_defines.h"

#ifdef __MAXON__
  #define __asm
  #define __saveds
#endif

struct Library		*XpkBase		= 0;
ULONG			DosVersion		= 37;
STRPTR			ibuf			= 0,
			obuf			= 0;
ULONG			ibuflen			= 0,
			obuflen			= 0;
BPTR			fh			= 0;
struct RDArgs		*rda			= 0;
struct FileInfoBlock	*fib			= 0;
struct XpkFib		*xfib			= 0;

#define PARAM "FROM/A,TO"

LONG __asm __saveds chunkfunc(register __a1 struct XpkProgress *prog)
{
  switch(prog->xp_Type)
  {
  case XPKPROG_START: PutStr("Start: "); break;
  case XPKPROG_MID: PutStr("\rMid  : "); break;
  case XPKPROG_END: PutStr("\rEnd  : "); break;
  }

  if(prog->xp_Type != XPKPROG_END)
    Printf("%4s: %-8s (%3ld%% done, %2ld%% CF, %6ld cps) %s",
      prog->xp_PackerName, prog->xp_Activity, prog->xp_Done,
      prog->xp_CF, prog->xp_Speed, prog->xp_FileName);
  else
    Printf("%4s: %-8s (%3ldK, %2ld%% CF, %6ld cps) %s\033[K\n",
      prog->xp_PackerName, prog->xp_Activity, prog->xp_ULen >> 10,
      prog->xp_CF, prog->xp_Speed, prog->xp_FileName);

  Flush(Output());
  return (LONG) SetSignal(0, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C;
}

struct Hook chunkhook = { {0}, (ULONG (*)()) chunkfunc};

void main(void)
{
  UBYTE errbuf[XPKERRMSGSIZE+1];
  ULONG olen;
  struct {
    STRPTR from;
    STRPTR to;
  } args = {0,0};

  if(!(rda = ReadArgs(PARAM, (LONG *) &args, 0)) ||
  !(xfib = (struct XpkFib *) AllocMem(sizeof(struct XpkFib), MEMF_ANY|MEMF_CLEAR)) ||
  !(XpkBase = OpenLibrary(XPKNAME, 0)) ||
  !(fh = Open(args.from, MODE_OLDFILE)) ||
  !(fib = (struct FileInfoBlock *) AllocDosObject(DOS_FIB, 0)) ||
  !(ExamineFH(fh, fib)) ||
  !(ibuf = (STRPTR) AllocMem(fib->fib_Size, MEMF_ANY)) ||
  Read(fh, ibuf, fib->fib_Size) != fib->fib_Size)
    End(RETURN_FAIL);

  ibuflen = fib->fib_Size;
  Close(fh); fh = 0;

  if(XpkExamineTags(xfib, XPK_InBuf, ibuf, XPK_InLen, ibuflen,
    XPK_GetError, errbuf, TAG_DONE))
  {
    STRPTR a = errbuf;
    VPrintf("Can't XpkExamine: %s\n", &a);
    End(RETURN_FAIL);
  }

  if(XpkUnpackTags(XPK_InBuf, ibuf, XPK_InLen, ibuflen,
    XPK_GetOutBuf, &obuf, XPK_GetOutBufLen, &obuflen,
    XPK_GetOutLen, &olen, XPK_GetError, errbuf,
    XPK_PassThru, 1, XPK_ChunkHook, &chunkhook, TAG_DONE))
  {
    STRPTR a = errbuf;
    VPrintf("Can't XpkUnpack: %s\n", &a);
    End(RETURN_FAIL);
  }

  if(args.to)
    if(!(fh = Open(args.to, MODE_NEWFILE)) ||
    Write(fh, obuf, olen) != olen)
      End(RETURN_FAIL);

  End(RETURN_OK);
}

void end(void)
{
  if(fh)	Close(fh);
  if(xfib)	FreeMem(xfib, sizeof(struct XpkFib));
  if(XpkBase)	CloseLibrary(XpkBase);
  if(fib)	FreeDosObject(DOS_FIB, fib);
  if(rda)	FreeArgs(rda);
  if(ibuf)	FreeMem(ibuf, ibuflen);
  if(obuf)	FreeMem(obuf, obuflen);
}

