home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / uniflex.zip / ufbuff.c < prev    next >
C/C++ Source or Header  |  1993-08-23  |  8KB  |  205 lines

  1. #include "ufk.h"
  2.  
  3. /*
  4.  *  b u f i l l
  5.  *
  6.  *  Get a bufferful of data from the file that's being sent.
  7.  *  Control-quoting, 8-bit & repeat count prefixes are handled.
  8.  */
  9.  
  10. char  *bptr,                              /* Output buffer pointer */
  11.       *ioptr;                             /* In/output buffer pointer */
  12.  
  13. bufill(buffer,first_time,input)
  14. char  buffer[];                           /* Buffer */
  15. char first_time;                          /* Called for the first time */
  16. char  input[];                            /* Input comes from here if not 0 */
  17. {
  18.    int   new_char,                        /* Char read from file */
  19.          rpt_count,
  20.          max_data_size,
  21.          bufsize;
  22.    static int old_char;                   /* Previous character */
  23.    static char *savptr,                   /* Must be saved between calls */
  24.                *savbptr,
  25.                savbuf[6];
  26.  
  27.    bptr = buffer;                         /* Init data buffer pointer */
  28.    ioptr = input;
  29.    max_data_size = spsiz - block_check_type;
  30.    if (spsiz > 94)
  31.       max_data_size -= 7;  /* soh, len, seq, typ, lenx1, lenx2, hcheck */
  32.    else
  33.       max_data_size -= 4;  /* soh, len, seq, typ */
  34.    if (first_time)
  35.    {
  36.       old_char = ioptr ? *ioptr++ : getc(fp);  /* Pre-read char first time */
  37.       savbptr = savbuf;
  38.    }
  39.    if (savbptr != savbuf)                 /* Data left from previous call */
  40.       for (savptr = savbuf; savptr != savbptr;)
  41.          *bptr++ = *savptr++;             /* Copy old data to buffer */
  42.    savbptr = savbuf;                      /* No more data in save buffer */
  43.    while (old_char != EOF)                /* Do until no more data */
  44.    {
  45.       rpt_count = 1;
  46.       while(((new_char = ioptr ? *ioptr++ : getc(fp)) != EOF)
  47.             && (rpt_count < 94)
  48.             && (repeat_quote != 0)
  49.             && (new_char == old_char)
  50.             && ((new_char != '\n')        /* No repeat for newline */
  51.             || binfil))
  52.          rpt_count++;                     /* Count consecutive match */
  53.       if (rpt_count > 1)                  /* We've had more of these */
  54.          if (rpt_count == 2)
  55.             insbuf(old_char);             /* Insert twice if only 2 char's */
  56.          else
  57.          {
  58.             *bptr++ = repeat_quote;       /* Setup repeat quote character */
  59.             *bptr++ = tochar(rpt_count);  /* Send count */
  60.          }
  61.       if (!ioptr)
  62.          transmit_chr_count += rpt_count; /* Counter for total data */
  63.       insbuf(old_char);
  64.       old_char = new_char;                /* Copy next character */
  65.       *bptr = '\0';                       /* So it can be printed */
  66.       bufsize = bptr - buffer;            /* Current number of characters */
  67.       if (bufsize > max_data_size)        /* Check length */
  68.       {
  69.          while (savptr != bptr)
  70.             *savbptr++ = *savptr++;       /* Copy excess data */
  71.          return (bufsize - (savbptr - savbuf));
  72.       }
  73.       else if (bufsize == max_data_size)  /* Exact fit */
  74.          return (bufsize);
  75.       savptr = bptr;
  76.    }
  77.    if (bptr == buffer)                    /* Wind up here only on EOF */
  78.       return(EOF);
  79.    return(bptr - buffer);                 /* Handle partial buffer */
  80. }
  81.  
  82. insbuf(o_char)
  83. int o_char;
  84. {
  85.    char chr7;
  86.  
  87.    chr7 = o_char & 0177;               /* Get low order 7 bits */
  88.    if ((o_char > 127) && (eight_quote != 0))
  89.       *bptr++ = eight_quote;           /* Eight_bit quoting done */
  90.    if (chr7 < SP || chr7 == DEL || chr7 == quote ||
  91.       chr7 == repeat_quote || chr7 == eight_quote)
  92.    {                                   /* Special handling required ? */
  93.       if (o_char == '\r' && !binfil)
  94.       {                                /* Do LF->CRLF mapping if !binfil */
  95.          *bptr++ = quote;
  96.          *bptr++ = ctl('\r');
  97.          o_char = chr7 = '\l';
  98.       }
  99.       *bptr++ = quote;                 /* Quote the character */
  100.       if ((chr7 == 0) || ((chr7 != quote) &&
  101.          (chr7 != repeat_quote) && (chr7 != eight_quote)))
  102.       {
  103.          o_char = ctl(o_char);         /* Uncontrolify it */
  104.          chr7 = ctl(chr7);
  105.       }
  106.    }
  107.    if (binfil && (eight_quote == 0))
  108.       *bptr++ = o_char;                /* Deposit the character itself */
  109.    else
  110.       *bptr++ = chr7;                  /* Only send the low bits */
  111. }
  112.  
  113. /*
  114.  *      b u f e m p
  115.  *
  116.  *  Put data from an incoming packet into a file.
  117.  *  Control-quoting, 8-bit & repeat count prefixes are handled.
  118.  */
  119.  
  120. bufemp(buffer,len,output)
  121. char  buffer[];                           /* Buffer */
  122. int   len;                                /* Length */
  123. char  output[];                           /* Output buffer if not 0 */
  124. {
  125.    int   i, j,                            /* Counters */
  126.          rpt_count;                       /* Repeat counter */
  127.    char  t, t7,                           /* Character holder */
  128.          set_bit_eight;                   /* flag to set bit eight */
  129.  
  130.    ioptr = output;                        /* Init output buffer pointer */
  131.    for (i = 0; i < len; i++)              /* Loop thru the data field */
  132.    {
  133.       t = buffer[i];                      /* Get character */
  134.       if (t == repeat_quote)              /* Repeat quoting ? */
  135.       {
  136.          rpt_count = unchar(buffer[++i]); /* Get repeat count */
  137.          t = buffer[++i];                 /* Get next character */
  138.       }
  139.       else
  140.          rpt_count = 1;                   /* No repeat quoting, count = 1 */
  141.       if (t == eight_quote)               /* Eight-bit quoting ? */
  142.       {
  143.          set_bit_eight = TRUE;            /* Set bit eight */
  144.          t = buffer[++i];                 /* Get next character */
  145.       }
  146.       else
  147.          set_bit_eight = FALSE;           /* Don't set bit eight */
  148.       if (t == quote)                     /* Control quote? */
  149.       {                                   /* Yes */
  150.          t = buffer[++i];                 /* Get the quoted character */
  151.          t7 = t & 0177;                   /* Character without parity bit */
  152.          if ((t7 >= ctl(DEL)) && (t7 <= ctl(DEL) + 32))
  153.             t = ctl(t);                   /* Undo what others did to it */
  154.       }
  155.       if (set_bit_eight)
  156.          t |= 0x80;                       /* Set bit eight on request */
  157.       if (!ioptr)
  158.          transmit_chr_count += rpt_count; /* Counter for total data */
  159.       for (j = 0; j < rpt_count; j++)
  160.          if (binfil)
  161.          {
  162.             if (ioptr)
  163.                *ioptr++ = t;           /* Put in output buffer if specified */
  164. /*
  165.  * Error checking is nonsense here. putc returns it's argument if
  166.  * successful. What if 255 is written ? If putc is declared as
  167.  * char, the return value will be sign extended giving -1 == ERROR !!
  168.  * If declared as unsigned char the return value will be between 0
  169.  * and 255, which can be data. So error checking can't be done here!!
  170. */
  171.             else
  172.                putc(t,fp);                /* send to file if image mode */
  173.          }
  174.          else
  175.          {
  176.             if (t == LF)                  /* strip LF in non-image mode */
  177.             {
  178.                transmit_chr_count--;  /* Adjust count for char not written */
  179.                break;
  180.             }
  181.             if (t == TAB)                 /* expand tabs to spaces */
  182.             {
  183.                while (--tabsleft >= 0)
  184.                   if (ioptr)
  185.                      *ioptr++ = ' ';
  186.                   else if (putc(' ',fp) == ERROR)
  187.                      return(ERROR);
  188.                tabsleft = TABSIZE;        /* reset tabcounter */
  189.             }
  190.             else                          /* pass character */
  191.             {
  192.                if (ioptr)
  193.                   *ioptr++ = t;           /* put in output buf if specified */
  194.                else if (putc(t,fp) == ERROR)
  195.                   return(ERROR);
  196.                if ((--tabsleft <= 0) || (t == CR))
  197.                   tabsleft = TABSIZE;     /* take care of tabcount */
  198.             }
  199.          }
  200.    }
  201.    if (ioptr)
  202.       *ioptr = '\0';                         /* Terminate string */
  203.    return(NULL);
  204. }
  205.