/* unzp.cpp v1.00 -- A simple program to decompress a ZPAQ archive.

  Copyright (C) 2011, Dell Inc. Written by Matt Mahoney.

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so without restriction.
  This Software is provided "as is" without warranty.

Usage: unzp input.zpaq output

unzp decompresses input.zpaq to output. It ignores stored filenames, comments,
and checksums. If input.zpaq contains more than one file, then all of the
compressed contents are concatenated.

To compile for x86-32 or x86-64 processors supporting SSE2 under Windows
or Linux:

  g++ -O3 unzp.cpp libzpaq.cpp -o unzp

For all other targets, use option -DNOJIT (will run slower).
*/

#include "libzpaq.h"
#include <stdio.h>
#include <stdlib.h>

// Required implementation of error handler.
// msg will be an English description of the error. It should not return.
// Any attempt to decompress the rest of the block will likely fail,
// but skipping to the start of the next block would be OK.
void libzpaq::error(const char* msg) {
  fprintf(stderr, "unzp error: %s\n", msg);
  exit(1);
}

// Required implementations of
// int libzpaq::Reader::get() and
// void libzpaq::Writer::put(int c)
// for reading and writing byte strings or files.
struct File: public libzpaq::Reader, public libzpaq::Writer {
  FILE* f;
  int get() {return getc(f);}   // read and return byte 0..255, or -1 at EOF
  void put(int c) {putc(c, f);} // write byte c (0..255)
};

int main(int argc, char** argv) {

  // Check for 2 filename arguments
  if (argc!=3)
    return fprintf(stderr, "To decompress: unzp input.zpaq output\n"), 1;

  // Open files
  File in, out;
  in.f=fopen(argv[1], "rb");
  if (!in.f) return perror(argv[1]), 1;
  out.f=fopen(argv[2], "wb");
  if (!out.f) return perror(argv[2]), 1;

  // Decompress
  libzpaq::decompress(&in, &out);

  return 0;
}  
