home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / varie / binhex / source / binhex.c
Encoding:
C/C++ Source or Header  |  2000-06-22  |  11.3 KB  |  448 lines

  1. #define NAME     "BinHex"
  2. #define REVISION "20"
  3. #define DATE     "22.06.2000"
  4. //#define DEBUG
  5.  
  6. /* Programmheader
  7.  
  8.     Name:        BinHex
  9.     Author:        SDI
  10.     Distribution:    PD
  11.     Description:    converts binary into hexadecimal data and reverse
  12.     Compileropts:    -
  13.     Linkeropts:    -l amiga
  14.  
  15.  1.0   03.10.95 : first version
  16.  1.1   15.10.95 : recompiled
  17.  1.2   05.02.96 : recompiled with better includes
  18.  1.3   06.02.96 : MakeHEX instead of MakeBASE
  19.  1.4   10.02.96 : compiled with my own StartUp
  20.  1.5   12.03.96 : added option ONLYDATA, \ Option, english texts
  21.  1.6   04.05.96 : removed error with ReadArgs
  22.  1.7   11.05.96 : option ROWS added
  23.  1.8   12.05.96 : option ASMDATA added
  24.  1.9   11.06.96 : EndCode like in SDI_defines.h
  25.  1.10  16.06.96 : corrected buffer overworking bug
  26.  1.11  06.10.96 : if last char was an \t program hanged - fixed
  27.  1.12  21.11.96 : added option CDATA, same as ASMDATA but for C
  28.  1.13  04.02.97 : added REVERSED option (now MAKEBIN only)
  29.  1.14  09.02.97 : own functions for ASMDATA and CDATA, SIZE parameter
  30.  1.15  08.93.97 : fixed forgotten address problem, compiler error ?
  31.  1.16  18.03.97 : SDI include names changed
  32.  1.17  26.05.97 : fixed problems with c:Ed
  33.  1.18  31.05.97 : SDI_isprint no longer allows 0x7f
  34.  1.19  27.06.99 : added NOASCII
  35.  1.20  22.06.00 : removed need for SDI_ASM_protos.h
  36. */
  37.  
  38. #include <proto/dos.h>
  39. #include <proto/exec.h>
  40. #include <exec/memory.h>
  41. #include "SDI_version.h"
  42. #include "SDI_structures.h"
  43. #include "SDI_ASM_STD_protos.h"
  44. #include "SDI_protos.h"
  45. #include "SDI_GetLength.c"  /* These files are in SDI_functions.o. Remove */
  46. #include "SDI_FillBuf.c"    /* the lines and build your own makefile.      */
  47. #include "SDI_WriteBuf.c"
  48. #include "SDI_FreeBuf.c"    /* Add also the .lib files to the makefile      */
  49. #include "SDI_GetBuffer.c"  /* to make compilation successful!          */
  50.  
  51. struct SDI_InOut    bin        = {0, 0, 0, 0, 0},
  52.             hex        = {0, 0, 0, 0, 0};
  53. STRPTR            revbuf        = 0;
  54. ULONG            revsize        = 16;
  55. struct RDArgs        *rda        = 0;
  56. ULONG            DosVersion    = 37;        /* forces OS 37!  */
  57.  
  58. #define PARAM "BIN/A,HEX/A,MAKEBIN/S,ONLYDATA/S,ROWS/N,ASMDATA/S,CDATA/S" \
  59.           ",REV=REVERSED/S,SIZE/N,NOTAB/S,NOASCII/S"
  60.  
  61. struct Args {
  62.     STRPTR    bin;
  63.     STRPTR    hex;
  64.     LONG    makebin;
  65.     LONG    onlydata;
  66.     LONG    *rows;
  67.     LONG    asmdata;
  68.     LONG    cdata;
  69.     LONG    reversed;
  70.     LONG    *size;
  71.     LONG    notab;
  72.     LONG    noascii;
  73. };
  74.  
  75. #define NUMPERLINE    (rows<<2)
  76. #define LINESIZE    (rows*(4*(2+1)+1)+8+1+1)
  77. /* rowcount * (4 * (2 numbers + 1 ASCII-character) + 1 space) +
  78.    9 for address + 1 space + 1 return */
  79. #define MAINSIZE    (rows*(4*2+1))
  80. #define ASCIIPOS    (MAINSIZE+8+1)
  81. #define RESTSIZE    (NUMPERLINE+8+1+1)
  82.  
  83. UBYTE GetHEXNum(UBYTE);
  84. STRPTR MakeBin(STRPTR, ULONG, ULONG);
  85. ULONG WriteDataLine(ULONG, ULONG, ULONG);
  86. void MakeHEX(STRPTR p, BYTE num, ULONG val);
  87. void End(UBYTE err);
  88.  
  89. #define MAKECLINE    1
  90. #define MAKEASMLINE    0
  91.  
  92. void main(void)
  93. {
  94.   LONG size = 0;
  95.   struct Args args;
  96.   ULONG h;
  97.   UBYTE rows = 5;
  98.  
  99.   SDI_memset(&args, 0, sizeof(struct Args));
  100.   args.size = &size;
  101.  
  102.   if(!(rda = (struct RDArgs *) AllocDosObject(DOS_RDARGS, 0)))
  103.     End(RETURN_FAIL);
  104.  
  105.   rda->RDA_ExtHelp =
  106. /*
  107.   "Mit dem Programm können binäre Dateien in Hexadezimal dargestellte "
  108.   "Dateien umgewandelt werden. Diese kann man dann mit einem Editor "
  109.   "bearbeitet und wieder in eine Binärdatei umwandeln. "
  110.   "Das Programm liest aus der Hexdatei alle Hex-Zahlen bis zu einem "
  111.   "Tabulator, dann geht es nach dem nächsten Return weiter. Sie müssen "
  112.   "also nicht darauf achten, wieder die genaue Zeilenlänge zu erhalten. "
  113.   "Zwischen Return und Tabulator dürfen jedoch nur die Zeichen 0-9 und A-F "
  114.   "stehen und zwar in einer geraden Anzahl. Das Leerzeichen ist als "
  115.   "Trenner erlaubt. Nach einem \\ wird alles so übernommen, wie gegeben. "
  116.   "Das ist für Texteingaben sehr nützlich.\n";
  117. */
  118.   "Use this program to convert binary data into hexadecimal data. This data "
  119.   "can be edited with a normal text editor. After that it can again become"
  120.   "binary. The program reads in the hexadecimal file all numbers from line "
  121.   "start to next tab stop or return. You do not need to make the linelength "
  122.   "exact as before! Only 0-9 and A-F are allowed in the data part. "
  123.   "Spaces and data after the tab stop are ignored. After a \\ all data is "
  124.   "not converted and taken as given to the binary file (useful for texts).\n";
  125.  
  126.   if(!ReadArgs(PARAM, (LONG *) &args, rda))
  127.     End(RETURN_FAIL);
  128.  
  129.   if(args.rows && *args.rows > 0 && *args.rows < 256)
  130.     rows = (UBYTE) *args.rows;
  131.  
  132.   if((args.makebin && (args.asmdata || args.cdata)) ||
  133.   (args.asmdata && args.cdata))
  134.   {
  135.     PrintFault(ERROR_TOO_MANY_ARGS, 0);
  136.     End(RETURN_FAIL);
  137.   }
  138.  
  139.   if(args.makebin)
  140.   {
  141.     if(
  142.     !(hex.file = Open(args.hex, MODE_OLDFILE)) ||
  143.     !(bin.size = SDI_GetLength(hex.file)))
  144.       End(RETURN_FAIL);
  145.     bin.size = (bin.size >> 2) + 1;
  146.     if(bin.size < NUMPERLINE)
  147.       bin.size = NUMPERLINE;
  148.   }
  149.   else
  150.   {
  151.     if(
  152.     !(bin.file = Open(args.bin, MODE_OLDFILE)) ||
  153.     !(bin.size = SDI_GetLength(bin.file)))
  154.       End(RETURN_FAIL);
  155.   }
  156.  
  157.   if((hex.size = bin.size << 2) > (h = AvailMem(MEMF_LARGEST)))
  158.     hex.size = h;
  159.   if(hex.size < LINESIZE)
  160.     hex.size = LINESIZE;
  161.   if(!SDI_GetBuffer(&hex))
  162.     End(RETURN_FAIL);
  163.   if(args.noascii && args.onlydata)
  164.     args.noascii = 0;
  165.  
  166.   if(args.reversed)
  167.   {
  168.     if(*args.size > 0)
  169.       revsize = *args.size;
  170.  
  171.     if(bin.size < revsize) /* need at least revsize buffer */
  172.       bin.size = revsize;
  173.   }
  174.   else if(*args.size != 2 && *args.size != 4)
  175.     *args.size = 1;                /* set correct size info */
  176.  
  177.   if(bin.size > (h = AvailMem(MEMF_LARGEST)))
  178.     bin.size = (h > revsize ? h : revsize);
  179.  
  180.   if(!SDI_GetBuffer(&bin))
  181.     End(RETURN_FAIL);
  182.  
  183.   if(!(args.makebin ? (bin.file = Open(args.bin, MODE_NEWFILE)) :
  184.   (hex.file = Open(args.hex, MODE_NEWFILE))))
  185.     End(RETURN_FAIL);
  186.  
  187.   if(args.reversed && !(revbuf = (STRPTR) AllocMem(revsize, MEMF_ANY)))
  188.     End(RETURN_FAIL);
  189.  
  190.   if(args.asmdata)
  191.   {
  192.     STRPTR start = "\tDC.B\t";
  193.  
  194.     if(*args.size == 2)
  195.       start[4] = 'W';
  196.     else if(*args.size == 4)
  197.       start[4] = 'L';
  198.  
  199.     SDI_FillBuf(&bin);
  200.     do
  201.     { /* WriteDataLine everytime lets enough space in destination buffer */
  202.       CopyMem(start, hex.pos, 6);
  203.       hex.pos += 6;
  204.     } while(WriteDataLine(*args.size, rows<<2, MAKEASMLINE));
  205.     SDI_WriteBuf(&hex, 0);
  206.   }
  207.   else if(args.cdata)
  208.   {
  209.     SDI_FillBuf(&bin);
  210.     switch(*args.size)
  211.     {
  212.     case 1: CopyMem("UBYTE bin_data[] = {\n", hex.pos, 21); break;
  213.     case 2: CopyMem("UWORD bin_data[] = {\n", hex.pos, 21); break;
  214.     case 4: CopyMem("ULONG bin_data[] = {\n", hex.pos, 21); break;
  215.     };
  216.     hex.pos += 21;
  217.  
  218.     do
  219.     {
  220.       *(hex.pos++) = ' '; *(hex.pos++) = ' ';
  221.     } while(WriteDataLine(*args.size, rows<<2, MAKECLINE));
  222.     *(hex.pos++) = '}';
  223.     *(hex.pos++) = ';';
  224.     *(hex.pos++) = '\n';
  225.     SDI_WriteBuf(&hex, 0);
  226.   }
  227.   else if(args.makebin)
  228.   {
  229.     SDI_FillBuf(&hex);
  230.     if(!args.reversed)
  231.     {
  232.       while(!(bin.pos = MakeBin(bin.pos, bin.size, args.notab)))
  233.       {
  234.         bin.pos = bin.buf + bin.size;
  235.         SDI_WriteBuf(&bin, 0);
  236.       }
  237.     }
  238.     else
  239.     {
  240.       STRPTR bufptr;
  241.       while(!(bufptr = MakeBin(revbuf, revsize, args.notab)))
  242.       {
  243.           bufptr = revbuf + revsize;
  244.         if(bin.buf+bin.size-bin.pos < revsize)
  245.           SDI_WriteBuf(&bin, 0);
  246.     while(bufptr != revbuf)
  247.       *(bin.pos++) = *(--bufptr);
  248.       }
  249.       if(bin.buf+bin.size-bin.pos < bufptr-revbuf)
  250.         SDI_WriteBuf(&bin, 0);
  251.       while(bufptr != revbuf)
  252.     *(bin.pos++) = *(--bufptr);
  253.     }
  254.     SDI_WriteBuf(&bin, 0);
  255.   }
  256.   else
  257.   {
  258.     ULONG address = 0;
  259.  
  260.     SDI_FillBuf(&bin);
  261.     while(bin.count && !(SetSignal(0L,0L) & SIGBREAKF_CTRL_C))
  262.     {
  263.       STRPTR strptr;
  264.  
  265.       strptr = hex.pos + ASCIIPOS;
  266.  
  267.       for(h = 0; h < NUMPERLINE; ++h, ++bin.pos)
  268.       {
  269.         if(bin.pos < bin.buf + bin.count)
  270.         {
  271.       MakeHEX(hex.pos, 2, *bin.pos);
  272.       hex.pos += 2;
  273.           if(!args.onlydata && !args.noascii)
  274.             *(strptr++) = SDI_isprint(*bin.pos) ? *bin.pos : '.';
  275.     /* C:Ed cannot handle 0x7F */
  276.         }
  277.     else if(args.onlydata || args.noascii)
  278.       break;
  279.         else
  280.         {
  281.           *(hex.pos++) = ' '; *(hex.pos++) = ' ';
  282.           *(strptr++) = ' ';
  283.         }
  284.         if(!((h+1 & 3) || args.onlydata))
  285.           *(hex.pos++) = ' ';
  286.       }
  287.       if(!args.onlydata && !args.noascii)
  288.       {
  289.         *hex.pos = '$';
  290.         MakeHEX(hex.pos+1, 7, address);
  291.         *(hex.pos-1) = '\t'; *(hex.pos+8) = ' ';  *strptr = '\n';
  292.         hex.pos += RESTSIZE;
  293.       }
  294.       else if(args.noascii)
  295.     *(hex.pos-1) = '\n';
  296.       else
  297.     *(hex.pos++) = '\n';
  298.       address += NUMPERLINE;
  299.       if(bin.pos >= bin.buf + bin.count - NUMPERLINE)
  300.         SDI_FillBuf(&bin);
  301.       if(hex.pos >= hex.buf + hex.size - LINESIZE)
  302.         SDI_WriteBuf(&hex, 0);
  303.     }
  304.     SDI_WriteBuf(&hex, 0);
  305.   }
  306.  
  307.   End(RETURN_OK);
  308. }
  309.  
  310. UBYTE GetHEXNum(UBYTE h)
  311. {
  312.   if(h > 47 && h < 58)
  313.     return (UBYTE) (h - '0');
  314.   else if(h > 64 && h < 71)
  315.     return (UBYTE) (h - 'A' + 10);
  316.   else if(h > 96 && h < 103)
  317.     return (UBYTE) (h - 'a' + 10);
  318.   return 0;
  319. }
  320.  
  321. STRPTR MakeBin(STRPTR buf, ULONG size, ULONG notab)
  322. {
  323.   static ULONG line = 1, row = 1;
  324.   static UBYTE realmode = 0;
  325.  
  326.   while(hex.count && !(SetSignal(0L,0L) & SIGBREAKF_CTRL_C))
  327.   {
  328.     if(*hex.pos == '\t' || (notab && *hex.pos == '$'))
  329.     {
  330.       while(hex.count && *hex.pos != '\n')
  331.       {
  332.         ++hex.pos;
  333.         if(hex.pos >= hex.buf + hex.count - 2)
  334.           SDI_FillBuf(&hex);
  335.       }
  336.     }
  337.     else if(*hex.pos == '\n')
  338.     {
  339.       ++line; row = 1; ++hex.pos; realmode = 0;
  340.     }
  341.     else if(!realmode && *hex.pos == ' ')
  342.     {
  343.       ++hex.pos; ++row;
  344.     }
  345.     else if(*hex.pos == '\\')
  346.     {
  347.       realmode = 1; ++hex.pos;
  348.     }
  349.     else
  350.     {
  351.       if(realmode)
  352.       {
  353.         *(buf++) = *(hex.pos++); ++row; --size;
  354.       }
  355.       else
  356.       {
  357.         if(!SDI_isxdigit(*hex.pos) || !SDI_isxdigit(*(hex.pos+1)))
  358.         {
  359.       Printf("line %ld, row %ld : ", line, row);
  360.       SetIoErr(ERROR_SEEK_ERROR);
  361.           End(RETURN_FAIL);
  362.         }
  363.         *buf = GetHEXNum(*(hex.pos++)) << 4;
  364.         *(buf++) += GetHEXNum(*(hex.pos++));
  365.         --size;
  366.         row+=2;
  367.       }
  368.     }
  369.     if(hex.pos >= hex.buf + hex.count - 2)
  370.       SDI_FillBuf(&hex);
  371.     if(!size)
  372.       return 0;
  373.   }
  374.   return buf;
  375. }
  376.  
  377. ULONG WriteDataLine(ULONG size, ULONG bytes, ULONG type)
  378. {
  379.   ULONG pos = size;
  380.   while(bin.count && !(SetSignal(0L,0L) & SIGBREAKF_CTRL_C))
  381.   {
  382.     if(hex.pos >= hex.buf + hex.size - 20)
  383.       SDI_WriteBuf(&hex,0);
  384.     if(pos == size)
  385.     {
  386.       pos = 0;
  387.       if(!type)
  388.         *(hex.pos++) = '$';
  389.       else
  390.       {
  391.         *(hex.pos++) = '0'; *(hex.pos++) = 'x';
  392.       }         
  393.     }
  394.     MakeHEX(hex.pos, 2, *(bin.pos++)); hex.pos += 2;
  395.     --bytes;
  396.     if((++pos == size) && (type || bytes))
  397.       *(hex.pos++) = ',';
  398.     if(bin.pos >= bin.buf + bin.count)
  399.       SDI_FillBuf(&bin);
  400.     if(!bytes && bin.count)
  401.     {
  402.       *(hex.pos++) = '\n'; return 1;
  403.     }
  404.   }
  405.  
  406.   while(pos != size)
  407.   {
  408.     ++pos; *(hex.pos++) = '0'; *(hex.pos++) = '0';
  409.   }
  410.  
  411.   *(hex.pos++) = '\n';
  412.  
  413.   return 0;
  414. }
  415.  
  416. void MakeHEX(STRPTR p, BYTE num, ULONG val)
  417. {
  418.   p[num] = 0; /*Ende der Zeichenkette gleich Null setzen --> CSTRING ! */
  419.   while(--num >= 0)
  420.   {
  421.     p[num] += (p[num] = val&15) >= 10 ? 'A'-10 : '0';
  422.     val >>= 4;
  423.   }
  424. }
  425.  
  426. void End(UBYTE err)
  427. {
  428.   if((SetSignal(0L,0L) & SIGBREAKF_CTRL_C))
  429.   {
  430.     err = RETURN_WARN;
  431.     SetIoErr(ERROR_BREAK);
  432.   }
  433.  
  434.   if(bin.file)        Close(bin.file);
  435.   if(hex.file)        Close(hex.file);
  436.   SDI_FreeBuf(&bin);
  437.   SDI_FreeBuf(&hex);
  438.   if(rda)
  439.   {
  440.     FreeArgs(rda);
  441.     FreeDosObject(DOS_RDARGS, rda);
  442.   }
  443.   if(err)
  444.     PrintFault(IoErr(), 0);
  445.   exit(err);
  446. }
  447.  
  448.