/* XSum2.c - sums up all bytes in a compressed or uncompressed file
 *           without reading the whole file at once into mem
 *
 * This is a typical read-and-process xpk application. Try it out... XSum a
 * file, then compress it and XSum it again. The result should be the same.
 */

#include <pragma/exec_lib.h>
#include <pragma/dos_lib.h>
#include <pragma/xpkmaster_lib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

extern struct Library *DOSBase;
struct Library *XpkBase = NULL;

char errbuf[XPKERRMSGSIZE + 1];
UBYTE *outbuf = NULL;
long outbuflen;

void end (char *text)
{
  if (outbuf)
    FreeMem (outbuf, outbuflen);
  if (text)
    Write (Output (), text, strlen (text));
  if (XpkBase)
    CloseLibrary (XpkBase);
  exit (text ? 10 : 0);
}

void 
main (int argc, char *argv[])
{
  struct XpkFib *xfh;
  LONG len, sum = 0;
  UBYTE *ptr, *last;

  if(argc != 2)
    end("Usage: xSum <filename>\n");

  if(!(XpkBase = OpenLibrary (XPKNAME, 0)))
    end("Cannot open " XPKNAME "\n");

  if(XpkOpenTags (&xfh, XPK_InName, argv[1], XPK_PassThru, TRUE, TAG_DONE))
    end(strcat (errbuf, "\n"));

  if(!(outbuf = (UBYTE *) AllocMem (outbuflen = xfh->xf_NLen + XPK_MARGIN, 0)))
    end("Out of memory\n");

  while((len = XpkRead (xfh, outbuf, XPKLEN_ONECHUNK)) > 0)
  {
    ptr = (UBYTE *) outbuf;
    last = ptr + len;
    while (ptr < last)
      sum += *ptr++;
  }

  if(XpkClose (xfh) || len)
    end (strcat (errbuf, "\n"));

  printf("%d\n", sum);

  end (NULL);
}
