/* Binary to C/C++ header file converter v1.0
** by Basty/Seasons (c) 1999. */

#include <stdio.h>
#include <stdlib.h>

int StrCmpNC(char *string1, char *string2);
int ConvertBinary( void );
int ConvertASCII( void );

#define ASCII 1
#define BINARY 0

#define LINESIZE 16

#define CONV_OKAY 0
#define CONV_ERROR_READ 1
#define CONV_ERROR_WRITE 2

#define VERSION_MAJOR 1
#define VERSION_MINOR 0

FILE *infile;
FILE *outfile;
unsigned long len;

int StrCmpNC(char *string1, char *string2)
{
  unsigned char c1,c2;

  do
  {
    c1 = (((c1 = *string1++) >= 'a' && c1 <= 'z') ? c1 - ' ' : c1);
    c2 = (((c2 = *string2++) >= 'a' && c2 <= 'z') ? c2 - ' ' : c2);

    if (c1 != c2)
      return(-1);
  } while (c1 != 0 && c2 != 0);

  return(0);
}

int ConvertBinary()
{
  unsigned char Buffer[LINESIZE];
  unsigned int rlen;
  unsigned long rpos = 0;
  int i;

  while (rlen = fread(Buffer,1,LINESIZE,infile))
  {
    if (ferror(infile)) return CONV_ERROR_READ;
    fputs("\n\t",outfile);
    for (i = 0; i<rlen; i++)
    {
      rpos++;
      fprintf(outfile,"0x%02x",*(Buffer+i));
      if ((rpos != len) || i != rlen-1)
        fputs(",",outfile);
      if (i != rlen-1) fputs(" ",outfile);
    }
    if (ferror(outfile)) return CONV_ERROR_WRITE;
  }
  return(0);
}

int ConvertASCII()
{
  unsigned char Buffer[LINESIZE],cbyte;
  unsigned int rlen;
  unsigned long rpos = 0;
  int i;

  while (rlen = fread(Buffer,1,LINESIZE,infile))
  {
    if (ferror(infile)) return CONV_ERROR_READ;
    fputs("\n\t",outfile);
    for (i = 0; i<rlen; i++)
    {
      rpos++;
      cbyte = Buffer[i];
      if ((cbyte > 31) && (cbyte < 128))
        fprintf(outfile,"'%c'",cbyte);
      else
        fprintf(outfile,"0x%02x",cbyte);
      if ((rpos != len) || i != rlen-1)
        fputs(",",outfile);
      if (i != rlen-1) fputs(" ",outfile);
    }
    if (ferror(outfile)) return CONV_ERROR_WRITE;
  }
  return(0);
}

int main(int argc,char **argv)
{
  char Mode = BINARY;
  int conv = 0;

  printf("Bin2H v%d.%02d (c) 1999 by Basty/Seasons (%s, %s).\n\n", VERSION_MAJOR, VERSION_MINOR, __DATE__, __TIME__);

  if (argc != 3 && argc != 4) goto usage;
  if (argc == 4)
  {
    if (StrCmpNC(argv[3],"ASCII")) goto usage;
    Mode = ASCII;
  }
  if (!(infile = fopen(argv[1],"rb"))) goto openerr;

  fseek(infile,0,SEEK_END);
  len = ftell(infile);
  fseek(infile,0,SEEK_SET);

  if (ferror(infile)) goto openerr;

  if (!(outfile = fopen(argv[2],"w"))) goto createrr;

    fprintf(outfile,"/* Converted with binary to C-include.  (c) 1999 by Basty/Seasons. */\n\nunsigned char %s[%ld] =\n{",argv[1],len);

  switch (Mode)
  {
    case BINARY:
    {
      conv = ConvertBinary();

      break;
    }
    case ASCII:
    {
      conv = ConvertASCII();

      break;
    }
  }

  if (conv == CONV_OKAY) fputs("\n};\n",outfile);

  fclose(outfile);
  fclose(infile);

  switch (conv)
  {
  case CONV_ERROR_READ:
    goto readerr;
  case CONV_ERROR_WRITE:
    goto writerr;
  }

  exit(0);

  usage:
  printf("Invalid parameters !\n\nUsage is: %s <infile> <outfile> [ASCII]\n",argv[0]);

  exit(20);

  openerr:
  printf("%s: Couldn't open %s.\nProgram terminated !\n",argv[0],argv[1]);

  exit(10);

  createrr:
  fclose(infile);
  printf("%s: Couldn't create %s.\nProgram terminated !\n",argv[0],argv[2]);

  exit(10);

  readerr:
  printf("%s: Couldn't read in %s.\nProgram terminated !\n",argv[0],argv[1]);

  exit(10);

  writerr:
  printf("%s: Couldn't write to %s.\nProgram terminated !\n",argv[0],argv[2]);

  exit(10);
}
