/* 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 <proto/exec.h>
#include <proto/dos.h>
#include <proto/xpk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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[])
{
  XFH *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->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);
}
