// ------------------------------- //
// -------- Start of File -------- //
// ------------------------------- //
// ----------------------------------------------------------- // 
// C++ Source Code File Name: testprog.cpp 
// Compiler Used: MSVC, BCC32, GCC, HPUX aCC, SOLARIS CC
// Produced By: glNET Software
// File Creation Date: 08/17/1998 
// Date Last Modified: 05/25/2001
// Copyright (c) 2001 glNET Software
// ----------------------------------------------------------- // 
// ------------- Program description and details ------------- // 
// ----------------------------------------------------------- // 
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
 
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  
USA
  
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 "gxcrc32.h"
#include <iostream.h>
#include <iomanip.h>
#include <string.h>
#include <stdlib.h>

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;
  }

#if defined (__UNIX__)
  // In UNIX there is only one file type
  fstream infile(in_file, ios::in | ios::nocreate);

#elif defined (__DOS__) || defined (__WIN32__)
  // In MS-DOS/Windows there are two file types, text and binary
#ifdef __BCC32__
  // The BCC 32 ios class does not have an enumeration for "nocreate"
  fstream infile(in_file, ios::in | ios::binary);
#else 
  fstream infile(in_file, ios::in | ios::binary | ios::nocreate);
#endif // __BCC32__

#else
#error You must define a file system: __DOS__ __WIN32__ or __UNIX__
#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 --------- //
// ------------------------------- //