home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d8xx / d832 / term.lha / Term / term-3.1-Source.lha / termTranslate.c < prev    next >
C/C++ Source or Header  |  1993-02-18  |  18KB  |  916 lines

  1. /*
  2. **    termTranslate.c
  3. **
  4. **    Character translation support routines
  5. **
  6. **    Copyright © 1990-1993 by Olaf `Olsen' Barthel & MXM
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* Translation chunk header types. */
  13.  
  14. enum    {    TYPE_NONE, TYPE_SEND, TYPE_RECEIVE };
  15.  
  16.     /* Symbolic names for character codes. */
  17.  
  18. STATIC struct { STRPTR Name; UBYTE Value; } CodeTab[44] =
  19. {
  20.     {    "NUL",    0    },
  21.     {    "SOH",    1    },
  22.     {    "STX",    2    },
  23.     {    "ETX",    3    },
  24.     {    "EOT",    4    },
  25.     {    "ENQ",    5    },
  26.     {    "ACK",    6    },
  27.     {    "BEL",    7    },
  28.     {    "BS",    8    },
  29.     {    "HT",    9    },
  30.     {    "LF",    10    },
  31.     {    "VT",    11    },
  32.     {    "FF",    12    },
  33.     {    "CR",    13    },
  34.     {    "SO",    14    },
  35.     {    "SI",    15    },
  36.     {    "DLE",    16    },
  37.     {    "DC1",    17    },
  38.     {    "DC2",    18    },
  39.     {    "DC3",    19    },
  40.     {    "DC4",    20    },
  41.     {    "NAK",    21    },
  42.     {    "SYN",    22    },
  43.     {    "ETB",    23    },
  44.     {    "CAN",    24    },
  45.     {    "EM",    25    },
  46.     {    "SUB",    26    },
  47.     {    "ESC",    27    },
  48.     {    "FS",    28    },
  49.     {    "GS",    29    },
  50.     {    "RS",    30    },
  51.     {    "US",    31    },
  52.     {    "SP",    32    },
  53.     {    "DEL",    127    },
  54.     {    "SS2",    142    },
  55.     {    "SS3",    143    },
  56.     {    "DCS",    144    },
  57.     {    "CSI",    155    },
  58.     {    "ST",    156    },
  59.     {    "OSC",    157    },
  60.     {    "PM",    158    },
  61.     {    "APC",    159    },
  62.     {    "NBS",    160    },
  63.     {    "SHY",    173    }
  64. };
  65.  
  66.     /* TranslateSetup():
  67.      *
  68.      *    Set up for buffer translation.
  69.      */
  70.  
  71. VOID __regargs
  72. TranslateSetup(struct TranslationHandle *Handle,STRPTR SourceBuffer,LONG SourceLen,STRPTR DestinationBuffer,LONG DestinationLen,struct TranslationEntry **Table)
  73. {
  74.     Handle -> LocalBuffer        = NULL;
  75.     Handle -> LocalLen        = 0;
  76.  
  77.     Handle -> SourceBuffer        = SourceBuffer;
  78.     Handle -> SourceLen        = SourceLen;
  79.  
  80.     Handle -> DestinationBuffer    = DestinationBuffer;
  81.     Handle -> DestinationLen    = DestinationLen;
  82.  
  83.     Handle -> Table            = Table;
  84. }
  85.  
  86.     /* TranslateBuffer(struct TranslationHandle *Handle):
  87.      *
  88.      *    Translate buffer contents according to
  89.      *    translation table contents.
  90.      */
  91.  
  92. LONG __regargs
  93. TranslateBuffer(struct TranslationHandle *Handle)
  94. {
  95.     register STRPTR                 Data        = Handle -> DestinationBuffer;
  96.     register LONG                 BytesWritten    = 0;
  97.     register struct TranslationEntry    *Entry;
  98.  
  99.         /* Are we to return any translated data? */
  100.  
  101.     while(Handle -> LocalLen && BytesWritten < Handle -> DestinationLen)
  102.     {
  103.             /* Decrement number of bytes in buffer. */
  104.  
  105.         Handle -> LocalLen--;
  106.  
  107.             /* Return next character. */
  108.  
  109.         *Data++ = *Handle -> LocalBuffer++;
  110.  
  111.             /* Add another byte. */
  112.  
  113.         BytesWritten++;
  114.     }
  115.  
  116.         /* Loop until done. */
  117.  
  118.     while(Handle -> SourceLen && BytesWritten < Handle -> DestinationLen)
  119.     {
  120.             /* Another byte eaten. */
  121.  
  122.         Handle -> SourceLen--;
  123.  
  124.             /* Get table entry. */
  125.  
  126.         if(Entry = Handle -> Table[*Handle -> SourceBuffer++])
  127.         {
  128.                 /* Copy to local data area. */
  129.  
  130.             Handle -> LocalBuffer    = Entry -> String;
  131.             Handle -> LocalLen    = Entry -> Len;
  132.  
  133.                 /* Translate the data. */
  134.  
  135.             while(Handle -> LocalLen && BytesWritten < Handle -> DestinationLen)
  136.             {
  137.                     /* Decrement number of bytes in buffer. */
  138.  
  139.                 Handle -> LocalLen--;
  140.  
  141.                     /* Return next character. */
  142.  
  143.                 *Data++ = *Handle -> LocalBuffer++;
  144.  
  145.                     /* Add another byte. */
  146.  
  147.                 BytesWritten++;
  148.             }
  149.         }
  150.     }
  151.  
  152.     return(BytesWritten);
  153. }
  154.  
  155.     /* NameToCode(STRPTR Name):
  156.      *
  157.      *    Translate a symbolic character code name of numeral.
  158.      */
  159.  
  160. UBYTE __regargs
  161. NameToCode(STRPTR Name)
  162. {
  163.     WORD i;
  164.  
  165.     for(i = 0 ; i < 44 ; i++)
  166.     {
  167.         if(!Stricmp(CodeTab[i] . Name,Name))
  168.             return(CodeTab[i] . Value);
  169.     }
  170.  
  171.     return((UBYTE)atoi(Name));
  172. }
  173.  
  174.     /* CodeToName(UBYTE Code):
  175.      *
  176.      *    Translate a character code into a symbolic
  177.      *    name or numeral.
  178.      */
  179.  
  180. STRPTR __regargs
  181. CodeToName(UBYTE Code)
  182. {
  183.     STATIC UBYTE Name[6];
  184.  
  185.     WORD i;
  186.  
  187.     for(i = 0 ; i < 44 ; i++)
  188.     {
  189.         if(CodeTab[i] . Value == Code)
  190.             return(CodeTab[i] . Name);
  191.     }
  192.  
  193.     SPrintf(Name,"%03ld",Code);
  194.  
  195.     return(Name);
  196. }
  197.  
  198.     /* FreeTranslationTable(struct TranslationEntry **Table):
  199.      *
  200.      *    Free a character translation table.
  201.      */
  202.  
  203. VOID
  204. FreeTranslationTable(struct TranslationEntry **Table)
  205. {
  206.     WORD i;
  207.  
  208.     for(i = 0 ; i < 256 ; i++)
  209.     {
  210.         if(Table[i])
  211.             FreeTranslationEntry(Table[i]);
  212.     }
  213.  
  214.     FreeVec(Table);
  215. }
  216.  
  217.     /* AllocTranslationTable():
  218.      *
  219.      *    Allocate a character translation table.
  220.      */
  221.  
  222. struct TranslationEntry **
  223. AllocTranslationTable()
  224. {
  225.     return((struct TranslationEntry **)AllocVec(sizeof(struct TranslationEntry *) * 256,MEMF_ANY|MEMF_CLEAR));
  226. }
  227.  
  228.     /* FreeTranslationEntry(struct TranslationEntry *Entry):
  229.      *
  230.      *    Free a character translation table entry.
  231.      */
  232.  
  233. VOID
  234. FreeTranslationEntry(struct TranslationEntry *Entry)
  235. {
  236.     FreeVec(Entry);
  237. }
  238.  
  239.     /* AllocTranslationEntry(STRPTR String):
  240.      *
  241.      *    Allocate a character translation table entry.
  242.      */
  243.  
  244. struct TranslationEntry *
  245. AllocTranslationEntry(STRPTR String)
  246. {
  247.     BYTE    GotControl    = FALSE,
  248.         GotEscape    = FALSE;
  249.  
  250.     LONG    Len    = strlen(String),
  251.         Count    = 0,
  252.         i;
  253.  
  254.     UBYTE    Type;
  255.  
  256.     for(i = 0 ; i < Len ; i++)
  257.     {
  258.         if(!GotControl && !GotEscape)
  259.         {
  260.             if(String[i] == '\\')
  261.             {
  262.                 GotControl = TRUE;
  263.  
  264.                 continue;
  265.             }
  266.  
  267.             if(String[i] == '^')
  268.             {
  269.                 GotEscape = TRUE;
  270.  
  271.                 continue;
  272.             }
  273.  
  274.             SharedBuffer[Count++] = String[i];
  275.         }
  276.         else
  277.         {
  278.             if(GotEscape)
  279.             {
  280.                 if(ToUpper(String[i]) >= 'A' && ToUpper(String[i]) <= '_')
  281.                     SharedBuffer[Count++] = ToUpper(String[i]) - '@';
  282.                 else
  283.                     SharedBuffer[Count++] = String[i];
  284.  
  285.                 GotEscape = FALSE;
  286.             }
  287.             else
  288.             {
  289.                 if(GotControl)
  290.                 {
  291.                     switch(ToUpper(String[i]))
  292.                     {
  293.                             /* These are macro commands and
  294.                              * not supported.
  295.                              */
  296.  
  297.                         case 'A':
  298.                         case 'C':
  299.                         case 'D':
  300.                         case 'G':
  301.                         case 'I':
  302.                         case 'P':
  303.                         case 'U':
  304.                         case 'X':
  305.  
  306.                             SharedBuffer[Count++] = '\\';
  307.                             SharedBuffer[Count++] = String[i];
  308.                             break;
  309.  
  310.                             /* Translate code. */
  311.  
  312.                         case '*':
  313.  
  314.                             i++;
  315.  
  316.                             while(i < Len && String[i] == ' ')
  317.                                 i++;
  318.  
  319.                             if(i < Len)
  320.                             {
  321.                                 UBYTE DummyBuffer[5],j = 0,Char;
  322.  
  323.                                 if(String[i] >= '0' && String[i] <= '9')
  324.                                 {
  325.                                     while(j < 3 && i < Len)
  326.                                     {
  327.                                         Char = String[i++];
  328.  
  329.                                         if(Char >= '0' && Char <= '9')
  330.                                             DummyBuffer[j++] = Char;
  331.                                         else
  332.                                         {
  333.                                             i--;
  334.  
  335.                                             break;
  336.                                         }
  337.                                     }
  338.                                 }
  339.                                 else
  340.                                 {
  341.                                     while(j < 4 && i < Len)
  342.                                     {
  343.                                         Char = ToLower(String[i++]);
  344.  
  345.                                         if((Char >= '0' && Char <= '9') || (Char >= 'a' && Char <= 'z'))
  346.                                             DummyBuffer[j++] = Char;
  347.                                         else
  348.                                         {
  349.                                             i--;
  350.  
  351.                                             break;
  352.                                         }
  353.                                     }
  354.                                 }
  355.  
  356.                                 DummyBuffer[j] = 0;
  357.  
  358.                                 SharedBuffer[Count++] = NameToCode(DummyBuffer);
  359.                             }
  360.  
  361.                             i--;
  362.  
  363.                             break;
  364.  
  365.                             /* This is a backspace. */
  366.  
  367.                         case 'B':
  368.  
  369.                             SharedBuffer[Count++] = '\b';
  370.                             break;
  371.  
  372.                             /* This is a form feed. */
  373.  
  374.                         case 'F':
  375.  
  376.                             SharedBuffer[Count++] = '\f';
  377.                             break;
  378.  
  379.                             /* This is a line feed. */
  380.  
  381.                         case 'N':
  382.  
  383.                             SharedBuffer[Count++] = '\n';
  384.                             break;
  385.  
  386.                             /* This is a carriage return. */
  387.  
  388.                         case 'R':
  389.  
  390.                             SharedBuffer[Count++] = '\r';
  391.                             break;
  392.  
  393.                             /* This is a tab. */
  394.  
  395.                         case 'T':
  396.  
  397.                             SharedBuffer[Count++] = '\t';
  398.                             break;
  399.  
  400.                             /* Produce the escape character. */
  401.  
  402.                         case 'E':
  403.  
  404.                             SharedBuffer[Count++] = ESC;
  405.                             break;
  406.  
  407.                             /* Stuff the character into the buffer. */
  408.  
  409.                         default:
  410.  
  411.                             SharedBuffer[Count++] = String[i];
  412.                             break;
  413.                     }
  414.  
  415.                     GotControl = FALSE;
  416.                 }
  417.             }
  418.         }
  419.     }
  420.  
  421.     if(Count > 0)
  422.     {
  423.         struct TranslationEntry *Entry;
  424.  
  425.         if(Count > 1)
  426.         {
  427.             Type = TRANSLATE_STRING;
  428.  
  429.             if(Entry = (struct TranslationEntry *)AllocVec(sizeof(struct TranslationEntry) + Count + 1,MEMF_ANY|MEMF_CLEAR))
  430.             {
  431.                 Entry -> String    = (STRPTR)(Entry + 1);
  432.  
  433.                 memcpy(Entry -> String,SharedBuffer,Count);
  434.             }
  435.         }
  436.         else
  437.         {
  438.             Type = TRANSLATE_SINGLE;
  439.  
  440.             if(Entry = (struct TranslationEntry *)AllocVec(sizeof(struct TranslationEntry),MEMF_ANY|MEMF_CLEAR))
  441.             {
  442.                 Entry -> String    = &Entry -> Extra;
  443.                 Entry -> Extra    = SharedBuffer[0];
  444.             }
  445.         }
  446.  
  447.         if(Entry)
  448.         {
  449.             Entry -> Type    = Type;
  450.             Entry -> Len    = Count;
  451.  
  452.             return(Entry);
  453.         }
  454.     }
  455.  
  456.     return(NULL);
  457. }
  458.  
  459.     /* FillTranslationTable(struct TranslationEntry **Table):
  460.      *
  461.      *    Fill the translation table with defaults.
  462.      */
  463.  
  464. BYTE
  465. FillTranslationTable(struct TranslationEntry **Table)
  466. {
  467.     BYTE Success = TRUE;
  468.     WORD i;
  469.  
  470.     for(i = 0 ; Success && i < 256 ; i++)
  471.     {
  472.         if(Table[i] = (struct TranslationEntry *)AllocVec(sizeof(struct TranslationEntry),MEMF_ANY|MEMF_CLEAR))
  473.         {
  474.             Table[i] -> Type    = TRANSLATE_SINGLE;
  475.             Table[i] -> String    = &Table[i] -> Extra;
  476.             Table[i] -> Extra    = i;
  477.             Table[i] -> Len        = 1;
  478.         }
  479.         else
  480.             Success = FALSE;
  481.     }
  482.  
  483.     if(!Success)
  484.     {
  485.         for(i = 0 ; i < 256 ; i++)
  486.         {
  487.             if(Table[i])
  488.             {
  489.                 FreeVec(Table[i]);
  490.  
  491.                 Table[i] = NULL;
  492.             }
  493.         }
  494.     }
  495.  
  496.     return(Success);
  497. }
  498.  
  499.     /* IsStandardTable(struct TranslationEntry **Table):
  500.      *
  501.      *    Checks a translation table to see if it contains
  502.      *    standard data.
  503.      */
  504.  
  505. BYTE __regargs
  506. IsStandardTable(struct TranslationEntry **Table)
  507. {
  508.     WORD i;
  509.  
  510.     for(i = 0 ; i < 256 ; i++)
  511.     {
  512.         if(Table[i])
  513.         {
  514.             if(Table[i] -> Type != TRANSLATE_SINGLE || Table[i] -> Len != 1 || Table[i] -> String[0] != i)
  515.                 return(FALSE);
  516.         }
  517.         else
  518.             return(FALSE);
  519.     }
  520.  
  521.     return(TRUE);
  522. }
  523.  
  524.     /* TranslateBack(STRPTR From,LONG Len,STRPTR To):
  525.      *
  526.      *    Translate a precompiled translation string
  527.      *    back.
  528.      */
  529.  
  530. VOID
  531. TranslateBack(STRPTR From,LONG Len,STRPTR To)
  532. {
  533.     STATIC char TypeTable[256] =
  534.     {
  535.          1 , 1 , 1 , 1 , 1 , 1 , 1 ,1 ,'b','t','n', 1 ,'f','r', 1 , 1,
  536.          1 , 1 , 1 , 1 , 1 , 1 , 1 ,1 , 1 , 1 , 1 ,'e', 1 , 1 , 1 , 1,
  537.          0 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
  538.          2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
  539.          2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
  540.          2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 ,'\\',2 , 2 , 2,
  541.          2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
  542.          2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 0,
  543.          0 , 0 , 0 , 0 , 0 , 0 , 0 ,0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
  544.          0 , 0 , 0 , 0 , 0 , 0 , 0 ,0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
  545.          0 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 0 , 2 , 2,
  546.          2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
  547.          2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
  548.          2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
  549.          2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
  550.          2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2
  551.     };
  552.  
  553.     STRPTR     Buffer;
  554.     LONG    i,j,BufLen;
  555.  
  556.     for(i = j = 0 ; i < Len ; i++)
  557.     {
  558.         switch(TypeTable[From[i]])
  559.         {
  560.             case 0:    To[j++] = '\\';
  561.                 To[j++] = '*';
  562.  
  563.                 Buffer = CodeToName(From[i]);
  564.  
  565.                 BufLen = strlen(Buffer);
  566.  
  567.                 memcpy(&To[j],Buffer,BufLen);
  568.  
  569.                 j += BufLen;
  570.  
  571.                 break;
  572.  
  573.             case 1:    To[j++] = '^';
  574.                 To[j++] = From[i] + '@';
  575.                 break;
  576.  
  577.             case 2:    To[j++] = From[i];
  578.                 break;
  579.  
  580.             default:To[j++] = '\\';
  581.                 To[j++] = TypeTable[From[i]];
  582.                 break;
  583.         }
  584.     }
  585.  
  586.     To[j] = 0;
  587. }
  588.  
  589.     /* SaveTranslationTables():
  590.      *
  591.      *    Save a character translation table to a file.
  592.      */
  593.  
  594. BYTE
  595. SaveTranslationTables(STRPTR Name,struct TranslationEntry **SendTable,struct TranslationEntry **ReceiveTable)
  596. {
  597.     BYTE    Success = FALSE,
  598.         DoIt = FALSE;
  599.     WORD    i;
  600.  
  601.     for(i = 0 ; !DoIt && i < 256 ; i++)
  602.     {
  603.         if(SendTable[i] || ReceiveTable[i])
  604.             DoIt = TRUE;
  605.     }
  606.  
  607.     if(DoIt)
  608.     {
  609.         struct IFFHandle *Handle;
  610.  
  611.         if(Handle = AllocIFF())
  612.         {
  613.             if(Handle -> iff_Stream = Open(Name,MODE_NEWFILE))
  614.             {
  615.                 InitIFFasDOS(Handle);
  616.  
  617.                 if(!OpenIFF(Handle,IFFF_WRITE))
  618.                 {
  619.                     if(!PushChunk(Handle,ID_TERM,ID_CAT,IFFSIZE_UNKNOWN))
  620.                     {
  621.                         if(!PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN))
  622.                         {
  623.                             if(!PushChunk(Handle,0,ID_VERS,IFFSIZE_UNKNOWN))
  624.                             {
  625.                                 struct TermInfo TermInfo;
  626.  
  627.                                 TermInfo . Version    = TermVersion;
  628.                                 TermInfo . Revision    = TermRevision;
  629.  
  630.                                 if(WriteChunkRecords(Handle,&TermInfo,sizeof(struct TermInfo),1))
  631.                                 {
  632.                                     if(!PopChunk(Handle))
  633.                                     {
  634.                                         if(!PopChunk(Handle))
  635.                                         {
  636.                                             struct TranslationHeader Header;
  637.  
  638.                                             Success = TRUE;
  639.  
  640.                                             for(i = 0 ; Success && i < 256 ; i++)
  641.                                             {
  642.                                                 if(SendTable[i])
  643.                                                 {
  644.                                                     Header . Type    = SendTable[i] -> Type;
  645.                                                     Header . Len    = SendTable[i] -> Len;
  646.                                                     Header . Code    = i;
  647.                                                     Header . Pad    = 0;
  648.  
  649.                                                     if(!PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN))
  650.                                                     {
  651.                                                         if(!PushChunk(Handle,0,ID_SEND,sizeof(struct TranslationHeader)))
  652.                                                         {
  653.                                                             if(WriteChunkRecords(Handle,&Header,sizeof(struct TranslationHeader),1))
  654.                                                             {
  655.                                                                 if(!PopChunk(Handle))
  656.                                                                 {
  657.                                                                     if(!PushChunk(Handle,0,ID_CHRS,SendTable[i] -> Len))
  658.                                                                     {
  659.                                                                         if(WriteChunkRecords(Handle,SendTable[i] -> String,SendTable[i] -> Len,1))
  660.                                                                         {
  661.                                                                             if(PopChunk(Handle))
  662.                                                                                 Success = FALSE;
  663.                                                                         }
  664.                                                                         else
  665.                                                                             Success = FALSE;
  666.                                                                     }
  667.                                                                 }
  668.                                                                 else
  669.                                                                     Success = FALSE;
  670.                                                             }
  671.                                                             else
  672.                                                                 Success = FALSE;
  673.                                                         }
  674.  
  675.                                                         if(PopChunk(Handle))
  676.                                                             Success = FALSE;
  677.                                                     }
  678.                                                     else
  679.                                                         Success = FALSE;
  680.                                                 }
  681.  
  682.                                                 if(ReceiveTable[i])
  683.                                                 {
  684.                                                     Header . Type    = ReceiveTable[i] -> Type;
  685.                                                     Header . Len    = ReceiveTable[i] -> Len;
  686.                                                     Header . Code    = i;
  687.                                                     Header . Pad    = 0;
  688.  
  689.                                                     if(!PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN))
  690.                                                     {
  691.                                                         if(!PushChunk(Handle,0,ID_RECV,sizeof(struct TranslationHeader)))
  692.                                                         {
  693.                                                             if(WriteChunkRecords(Handle,&Header,sizeof(struct TranslationHeader),1))
  694.                                                             {
  695.                                                                 if(!PopChunk(Handle))
  696.                                                                 {
  697.                                                                     if(!PushChunk(Handle,0,ID_CHRS,ReceiveTable[i] -> Len))
  698.                                                                     {
  699.                                                                         if(WriteChunkRecords(Handle,ReceiveTable[i] -> String,ReceiveTable[i] -> Len,1))
  700.                                                                         {
  701.                                                                             if(PopChunk(Handle))
  702.                                                                                 Success = FALSE;
  703.                                                                         }
  704.                                                                         else
  705.                                                                             Success = FALSE;
  706.                                                                     }
  707.                                                                 }
  708.                                                                 else
  709.                                                                     Success = FALSE;
  710.                                                             }
  711.                                                             else
  712.                                                                 Success = FALSE;
  713.                                                         }
  714.  
  715.                                                         if(PopChunk(Handle))
  716.                                                             Success = FALSE;
  717.                                                     }
  718.                                                     else
  719.                                                         Success = FALSE;
  720.                                                 }
  721.                                             }
  722.                                         }
  723.                                     }
  724.                                 }
  725.                             }
  726.                         }
  727.  
  728.                         if(PopChunk(Handle))
  729.                             Success = FALSE;
  730.                     }
  731.  
  732.                     CloseIFF(Handle);
  733.                 }
  734.  
  735.                 Close(Handle -> iff_Stream);
  736.  
  737.                 if(Success)
  738.                     SetProtection(Name,FIBF_EXECUTE);
  739.                 else
  740.                     DeleteFile(Name);
  741.             }
  742.  
  743.             FreeIFF(Handle);
  744.         }
  745.     }
  746.  
  747.     return(Success);
  748. }
  749.  
  750.     /* LoadTranslationTable()s:
  751.      *
  752.      *    Load a translation table from a file.
  753.      */
  754.  
  755. BYTE
  756. LoadTranslationTables(STRPTR Name,struct TranslationEntry **SendTable,struct TranslationEntry **ReceiveTable)
  757. {
  758.     STATIC ULONG Stops[4 * 2] =
  759.     {
  760.         ID_TERM,    ID_VERS,
  761.         ID_TERM,    ID_SEND,
  762.         ID_TERM,    ID_RECV,
  763.         ID_TERM,    ID_CHRS
  764.     };
  765.  
  766.     struct IFFHandle    *Handle;
  767.     BYTE             Success = FALSE;
  768.     WORD             i;
  769.  
  770.     if(Handle = AllocIFF())
  771.     {
  772.         if(Handle -> iff_Stream = Open(Name,MODE_OLDFILE))
  773.         {
  774.             InitIFFasDOS(Handle);
  775.  
  776.             if(!OpenIFF(Handle,IFFF_READ))
  777.             {
  778.                 if(!StopChunks(Handle,Stops,4))
  779.                 {
  780.                     struct ContextNode        *Chunk;
  781.                     struct TermInfo             TermInfo;
  782.                     struct TranslationHeader     Header;
  783.                     BYTE                 LastType = TYPE_NONE;
  784.  
  785.                     Success = TRUE;
  786.  
  787.                     while(Success && !ParseIFF(Handle,IFFPARSE_SCAN))
  788.                     {
  789.                         Chunk = CurrentChunk(Handle);
  790.  
  791.                         switch(Chunk -> cn_ID)
  792.                         {
  793.                             case ID_VERS:
  794.  
  795.                                 if(ReadChunkBytes(Handle,&TermInfo,sizeof(struct TermInfo)) == sizeof(struct TermInfo))
  796.                                 {
  797.                                     if(TermInfo . Version > TermVersion || (TermInfo . Version == TermVersion && TermInfo . Revision > TermRevision))
  798.                                         Success = FALSE;
  799.                                 }
  800.                                 else
  801.                                     Success = FALSE;
  802.  
  803.                                 break;
  804.  
  805.                             case ID_SEND:
  806.  
  807.                                 if(LastType != TYPE_NONE)
  808.                                     Success = FALSE;
  809.                                 else
  810.                                 {
  811.                                     if(!ReadChunkRecords(Handle,&Header,MIN(sizeof(struct TranslationHeader),Chunk -> cn_Size),1))
  812.                                         Success = FALSE;
  813.                                     else
  814.                                         LastType = TYPE_SEND;
  815.                                 }
  816.  
  817.                                 break;
  818.  
  819.                             case ID_RECV:
  820.  
  821.                                 if(LastType != TYPE_NONE)
  822.                                     Success = FALSE;
  823.                                 else
  824.                                 {
  825.                                     if(!ReadChunkRecords(Handle,&Header,MIN(sizeof(struct TranslationHeader),Chunk -> cn_Size),1))
  826.                                         Success = FALSE;
  827.                                     else
  828.                                         LastType = TYPE_RECEIVE;
  829.                                 }
  830.  
  831.                                 break;
  832.  
  833.                             case ID_CHRS:
  834.  
  835.                                 if(LastType == TYPE_NONE)
  836.                                     Success = FALSE;
  837.                                 else
  838.                                 {
  839.                                     if(ReadChunkRecords(Handle,SharedBuffer,Header . Len,1))
  840.                                     {
  841.                                         struct TranslationEntry *Entry;
  842.  
  843.                                         if(Header . Type == TRANSLATE_SINGLE)
  844.                                         {
  845.                                             if(Entry = (struct TranslationEntry *)AllocVec(sizeof(struct TranslationEntry),MEMF_ANY|MEMF_CLEAR))
  846.                                             {
  847.                                                 Entry -> String    = &Entry -> Extra;
  848.                                                 Entry -> Extra    = SharedBuffer[0];
  849.                                             }
  850.                                         }
  851.                                         else
  852.                                         {
  853.                                             if(Entry = (struct TranslationEntry *)AllocVec(sizeof(struct TranslationEntry) + Header . Len + 1,MEMF_ANY|MEMF_CLEAR))
  854.                                             {
  855.                                                 Entry -> String    = (STRPTR)(Entry + 1);
  856.  
  857.                                                 memcpy(Entry -> String,SharedBuffer,Header . Len);
  858.                                             }
  859.                                         }
  860.  
  861.                                         if(Entry)
  862.                                         {
  863.                                             Entry -> Type        = Header . Type;
  864.                                             Entry -> Len        = Header . Len;
  865.  
  866.                                             if(LastType == TYPE_SEND)
  867.                                                 SendTable[Header . Code]    = Entry;
  868.                                             else
  869.                                                 ReceiveTable[Header . Code]    = Entry;
  870.  
  871.                                             LastType = TYPE_NONE;
  872.                                         }
  873.                                         else
  874.                                             Success = FALSE;
  875.                                     }
  876.                                     else
  877.                                         Success = FALSE;
  878.                                 }
  879.  
  880.                                 break;
  881.                         }
  882.                     }
  883.                 }
  884.  
  885.                 CloseIFF(Handle);
  886.             }
  887.  
  888.             Close(Handle -> iff_Stream);
  889.         }
  890.  
  891.         FreeIFF(Handle);
  892.     }
  893.  
  894.     if(!Success)
  895.     {
  896.         for(i = 0 ; i < 256 ; i++)
  897.         {
  898.             if(SendTable[i])
  899.             {
  900.                 FreeTranslationEntry(SendTable[i]);
  901.  
  902.                 SendTable[i] = NULL;
  903.             }
  904.  
  905.             if(ReceiveTable[i])
  906.             {
  907.                 FreeTranslationEntry(ReceiveTable[i]);
  908.  
  909.                 ReceiveTable[i] = NULL;
  910.             }
  911.         }
  912.     }
  913.  
  914.     return(Success);
  915. }
  916.