// ------------------------------- //
// -------- Start of File -------- //
// ------------------------------- //
// ----------------------------------------------------------- // 
// C++ Source Code File Name: testprog.cpp 
// Compiler Used: MSVC40, DJGPP 2.7.2.1, GCC 2.7.2.1, HP CPP 10.24
// Produced By: Doug Gaer 
// File Creation Date: 08/17/1998 
// Date Last Modified: 09/01/1998
// ----------------------------------------------------------- // 
// ------------- Program description and details ------------- // 
// ----------------------------------------------------------- // 
/*
THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
THE ENTIRE RISK OF THE QUALITY AND PERFORMANCE OF THIS SOFTWARE
IS WITH YOU. SHOULD ANY ELEMENT OF THIS SOFTWARE PROVE DEFECTIVE,
YOU WILL ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR
CORRECTION.
  
The CRC32 functions (Cyclic Redundancy Check) are used to
calculate a sophisticated checksum based on the algebra of
polynomials. The Cyclic Redundancy Check, is a way to detect
bit errors that occur during data storage or transmission.
The CRC-32 algorithm operates on a block of data as a single
large numerical value. The algorithm divides this large value
by the CRC-32 polynomial or generator polynomial, leaving the
remainder 32-bit, which is the checksum. 
*/
// ----------------------------------------------------------- // 
#include "crc32.hpp"
#include <iostream.h>
#include <iomanip.h>
#include <string.h>
#include <stdlib.h>

// Define this macro for DOS file opens (the default is UNIX)
// #ifndef __DOS__
// #define __DOS__
// #endif

char in_file[255]; // Input file 

void HelpMessage(const char *program_name)
{
  cout << endl;
  cout << "CRC-32 program." << endl;
  cerr << "Displays 32-bit CRC for a specified file or string." << endl;
  cout << "Usage: " << program_name << " [switches] infile" << endl;
  cout << "Switches:  -?      = Display this help message." << endl;
  cout << "           -sData  = Display 32-bit CRC for a specifed string."
       << endl;
  cout << "           -t      = Write a CRC-32 table to the standard output."
       << endl;
  cout << endl;
  exit(0);
}

void ProcessArgs(int argc, char *argv[])
// Process the program's argument list
{
  char *sbuf;
  int i;
  for(i = 1; i < argc; i++ ) {
    if(*argv[i] == '-') {
      char sw = *(argv[i] +1);
      switch(sw) {
	case '?' :
	  HelpMessage(argv[0]);
	  break;

	case 's': {
	  sbuf = &argv[i][2]; 
	  unsigned long crc;
	  crc = calcCRC32(sbuf, strlen(sbuf));
	  cout << sbuf << endl;
	  cout << "CRC-32 = ";
	  cout.setf(ios::uppercase);
	  cout << "0x" << setfill('0') << setw(8) << hex << crc << endl;
	  cout.unsetf(ios::uppercase);
	  exit(0);
	  break;
	}
	
	case 't':
	  makeCRC32(cout);
	  exit(0);
	  break;

	default:
	  cerr << endl;
	  cerr << "Unknown switch " << argv[i] << endl;
	  cerr << "Exiting..." << endl;
	  cerr << endl;
	  exit(0);
	  break;
      }
    }
    else { 
      strcpy(in_file, argv[i]); 
    }
  }
}

int main(int argc,char *argv[])
{
  // If no argument is given print usage message to the screen 
  if(argc < 2) {
    HelpMessage(argv[0]);
    return 0;
  }

  // Process the programs command line arguments
  ProcessArgs(argc, argv);

  if(in_file[0] == 0 ) {
    cout << endl;
    cout << "You must specify a valid input file name." << endl;
    cout << endl;
    return 0;
  }

#ifndef __DOS__
  // In UNIX there is only one file type
  fstream infile(in_file, ios::in | ios::nocreate);
#else 
  // In MS-DOS/Windows there are two file types, text and binary
  fstream infile(in_file, ios::in | ios::binary | ios::nocreate);
#endif 
  
  if(!infile) {
    cerr << endl;
    cerr << "Cannot open file: " << in_file << endl;
    cerr << "Exiting..." << endl;
    cerr << endl;
    return 1;
  }

  unsigned long crc = calcCRC32(infile);
  cout << in_file << endl;
  cout << "CRC-32 = ";
  cout.setf(ios::uppercase);
  cout << "0x" << setfill('0') << setw(8) << hex << crc << endl;
  cout.unsetf(ios::uppercase);
  infile.close();
  return 0;
}
// ----------------------------------------------------------- // 
// ------------------------------- //
// --------- End of File --------- //
// ------------------------------- //
