//B.J. Guillot
//April 10, 2000
//e-mail: bguillot@acm.org

//To compile, use Borland Delphi 5.0, "dcc32 asc2bin.pas"

program
  asc2bin;

{$APPTYPE CONSOLE}

procedure badUser;
begin
  writeln('     Syntax:   asc2bin f|i inputfilename outputfilename');
  writeln('This program takes an ASCII input file of floats or integers');
  writeln('and converts it to a binary representation');
  writeln('The first parameter is either "f" or "i" which indicates we');
  writeln('will use either floating point (32-bit) or integer (32-bit)');
  writeln('data types.');
  halt(1);
end;

procedure convertFloat;
var
  ascInput : text;
  binFile : file of single;
  data : single;
  count : longint;
  io : integer;
  scratch, temp : array[1..sizeof(single)] of byte;
begin
  writeln('Converting ASCII data to IEEE-764 single precision BIG endian');
  writeln('(Please note that the PC is little endian)');
  writeln('sizeof(single)=', sizeof(single));
  writeln('Range is 1.5x10E-45 to 3.4x10E+38');

  assign(ascInput, paramstr(2));
  {$i-}
    reset(ascInput);
    io := ioresult;
    if io > 0 then begin
      writeln('Trouble opening input file ', paramstr(2));
      halt(1);
    end;
  {$i+}
  assign(binFile, paramstr(3));
  rewrite(binFile);
  count := 0;
  repeat
    {$i-}
      read(ascInput, data);
      io := ioresult;
      if io > 0 then begin
        writeln('Error #', io, ' occured parsing in data element# ', count+1);
        halt(1);
      end;
    {$i+}
    if not eof(ascInput) then begin //don't write last dummy eof data
      inc(count);
      move(data, scratch, sizeof(data));  //reverse order of float bytes
      temp[1] := scratch[4];
      temp[2] := scratch[3];
      temp[3] := scratch[2];
      temp[4] := scratch[1];
      move(temp, data, sizeof(data));
      write(binFile, data);
    end;
  until(eof(ascInput));
  close(ascInput);
  close(binFile);
  writeln('Converted ', count, ' elements.');
end;

procedure convertInteger;
var
  ascInput : text;
  binFile : file of integer;
  data : integer;
  count : longint;
  io : integer;
begin
  writeln('Converting ASCII data to Pascal "integer" binary data type');
  writeln('The "integer" data type should be equivilant to a C "int"');
  writeln('sizeof(integer)=', sizeof(integer));
  writeln('Range: -2147483648 to 2147483647');

  assign(ascInput, paramstr(2));
  {$i-}
    reset(ascInput);
    io := ioresult;
    if io > 0 then begin
      writeln('Trouble opening input file ', paramstr(2));
      halt(1);
    end;
  {$i+}
  assign(binFile, paramstr(3));
  rewrite(binFile);
  count := 0;
  repeat
    {$i-}
      read(ascInput, data);
      io := ioresult;
      if io > 0 then begin
        writeln('Error #', io, ' occured parsing in data element #', count+1);
        halt(1);
      end;
    {$i+}
    if not eof(ascInput) then begin //don't write last dummy eof data
      inc(count);
      write(binFile, data);
    end;
  until(eof(ascInput));
  close(ascInput);
  close(binFile);
  writeln('Converted ', count, ' elements.');
end;


begin       // the main routine
  writeln('[asc2bin 0.1]       Build Date 04/12/2000');
  writeln('Program by B.J. Guillot, bguillot@acm.org');
  if (paramcount <> 3) then
    badUser;
  if paramstr(1) = 'f' then
    convertFloat
  else if paramstr(1) = 'i' then
    convertInteger
  else
    badUser;
end.