home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / lib / dial / d_coding.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-02-01  |  7.7 KB  |  392 lines

  1. # include  "util.h"
  2. # include  "d_proto.h"
  3. # include  "d_returns.h"
  4.  
  5. # define  TAB         '\11'     /*  tab  */
  6. # define  LINEFEED    '\12'     /*  line feed  */
  7. # define  FORMFEED    '\14'     /*  form feed  */
  8. # define  CR          '\15'     /*  carriage return  */
  9.  
  10. /* speed optimization */
  11.  
  12. #define    D_TESTBIT(b,v)    ((!isascii(b))||((v)[(b)>>4]&(1<<((b)&017))))
  13.  
  14. /*
  15.  *     D_BLDCVEC
  16.  *
  17.  *     this routine builds a code vector from a hex digit string which
  18.  *     specifies 'illegal' characters for transmission to a host.  each
  19.  *     of the digits in the input vector to be sure that it is a legal
  20.  *     hex digit.
  21.  *
  22.  *     hexvec -- pointer to a 32 character string of hex digits.
  23.  *
  24.  *     codevec -- pointer to an 8 word bit map table for the output.
  25.  */
  26.  
  27. d_bldcvec(hexvec, codevec)
  28.   register char  *hexvec;
  29.   unsigned  short codevec[];
  30.     {
  31.     extern int  d_errno;
  32.     register int  word, digit;
  33.     unsigned short bits;
  34.     int  value;
  35.  
  36. /*  each word of the code vector is constructed from 4 hex digits  */
  37.  
  38.     for (word = 0; word <= 7; word++)
  39.       {
  40.       bits = 0;
  41.  
  42.       for (digit = 0; digit <= 3; digit++)
  43.         {
  44.         if ((value = d_fromhex(*hexvec++)) < 0)
  45.           {
  46. #ifdef D_LOG
  47.           d_log("d_bldcvec", "bad hex digit in path illegal character field");
  48. #endif D_LOG
  49.           d_errno = D_PACKERR;
  50.           return(D_FATAL);
  51.           }
  52.  
  53.         bits |= (value & 017) << (4 * digit);
  54.         }
  55.  
  56.       codevec[word] = bits;
  57.       }
  58.  
  59.     return(D_OK);
  60.     }
  61.  
  62. /*
  63.  *     D_BLDHVEC
  64.  *
  65.  *     this routine takes a code vector and builds a string of 32 hex
  66.  *     digits for transmission in a RESET packet.
  67.  *
  68.  *     codevec -- pointer to the code vector to be converted
  69.  *
  70.  *     hexvec -- pointer to place to load the 32 hex digits
  71.  */
  72.  
  73. d_bldhvec(codevec, hexvec)
  74.   unsigned  short codevec[];
  75.   register char  *hexvec;
  76.     {
  77.     register unsigned  bits, digit;
  78.     int  word;
  79.  
  80.     for (word = 0; word <= 7; word++)
  81.       {
  82.       bits = codevec[word];
  83.  
  84.       for (digit = 0; digit <= 3; digit++)
  85.         {
  86.         *hexvec++ = d_tohex(bits & 017);
  87.         bits >>= 4;
  88.         }
  89.       }
  90.  
  91.     *hexvec = '\0';
  92.     return(D_OK);
  93.     }
  94.  
  95. /*
  96.  *     D_DECODE
  97.  *
  98.  *     this routine takes encoded strings and forms the plaintext
  99.  *     output.
  100.  *
  101.  *     input -- input string to be decoded
  102.  *
  103.  *     ninput -- the number of characters in the input string
  104.  *
  105.  *     output -- pointer to place for the decoded output
  106.  *
  107.  *     the routine returns the number of output characters.
  108.  */
  109.  
  110. d_decode(input, ninput, output)
  111.   register char  *input, *output;
  112.   register int  ninput;
  113.     {
  114.     extern char  d_rcvesc;
  115.     extern int  d_errno;
  116.     int  chigh, clow, noutput;
  117.  
  118.     noutput = 0;
  119.  
  120. /*  cycle through the input string.  if a character isn't the escape, just  */
  121. /*  copy it to the output.                                                  */
  122.  
  123.     while (ninput)
  124.       {
  125.       if (*input != d_rcvesc)
  126.         {
  127.         *output++ = *input++;
  128.         ninput--;
  129.         noutput++;
  130.         continue;
  131.         }
  132.  
  133. /*  must be the escape character.  if the next one is the escape also  */
  134. /*  then load one of them into the output.  otherwise switch for the   */
  135. /*  special cases.                                                     */
  136.  
  137.       input++;
  138.  
  139.       if (*input == d_rcvesc)
  140.         {
  141.         *output++ = *input++;
  142.         ninput -= 2;
  143.         noutput++;
  144.         continue;
  145.         }
  146.  
  147.       switch (*input)
  148.         {
  149.         case  'I':
  150.  
  151.             *output++ = TAB;
  152.             break;
  153.  
  154.         case  'J':
  155.  
  156.             *output++ = LINEFEED;
  157.             break;
  158.  
  159.         case  'L':
  160.  
  161.             *output++ = FORMFEED;
  162.             break;
  163.  
  164.         case  'M':
  165.  
  166.             *output++ = CR;
  167.             break;
  168.  
  169.         default:
  170.  
  171.             chigh = d_fromhex(*input++);
  172.             clow = d_fromhex(*input++);
  173.  
  174.             if ((chigh < 0) || (clow < 0))
  175.               {
  176. #ifdef D_LOG
  177.               d_log("d_decode", "illegal character encoding");
  178. #endif D_LOG
  179.               d_errno = D_PACKERR;
  180.               return(D_FATAL);
  181.               }
  182.  
  183.             *output++ = (chigh << 4) | (clow & 017);
  184.             noutput++;
  185.             ninput -= 3;;
  186.             continue;
  187.         }
  188.  
  189.       input++;
  190.       ninput -= 2;
  191.       noutput++;
  192.       }
  193.  
  194.     return(noutput);
  195.     }
  196.  
  197. /*
  198.  *     D_CCODE
  199.  *
  200.  *     this routine computes the encoding for a single character, if any,
  201.  *     based on the bit vector which specifies whether the target host
  202.  *     can receive the character without undesired side effects.
  203.  *
  204.  *     c -- the character to be encoded
  205.  *
  206.  *     string -- place to put the encoding
  207.  */
  208.  
  209. d_ccode(c, string)
  210.   register unsigned c;
  211.   register char  *string;
  212.     {
  213.     extern unsigned  short d_lcvec[];
  214.     extern char  d_snesc;
  215.  
  216. /*  if we're encoding the escape character itself, just double it.  */
  217.  
  218.     if (c == d_snesc)
  219.       {
  220.       *string++ = d_snesc;
  221.       *string = d_snesc;
  222.       return(2);
  223.       }
  224.  
  225. /*  if the bit corresponding to the character is on in the vector, then we  */
  226. /*  have to encode it.  switch for special cases, otherwise use hex digits  */
  227.  
  228.     if (D_TESTBIT(c, d_lcvec) == 0)
  229.       {
  230.       *string = c;
  231.       return(1);
  232.       }
  233.  
  234.     *string++ = d_snesc;
  235.  
  236.     switch (c)
  237.       {
  238.       case  TAB:
  239.  
  240.           *string = 'I';
  241.           return(2);
  242.  
  243.       case  LINEFEED:
  244.  
  245.           *string = 'J';
  246.           return(2);
  247.  
  248.       case  FORMFEED:
  249.  
  250.           *string = 'L';
  251.           return(2);
  252.  
  253.       case  CR:
  254.  
  255.           *string = 'M';
  256.           return(2);
  257.  
  258.       default:
  259.  
  260.           *string++ = d_tohex(c >> 4);
  261.           *string++ = d_tohex(c & 017);
  262.           return(3);
  263.       }
  264.     }
  265.  
  266. /*
  267.  *     D_TESTBIT
  268.  *
  269.  *     this routine is called to test if a given bit is on in a bit vector
  270.  *     the routine returns 1 if it is, 0 otherwise.
  271.  *
  272.  *     bit -- the bit to test
  273.  *
  274.  *     bitvector -- the bit vector
  275.  */
  276.  
  277. d_testbit(bit, bitvector)
  278.   register int  bit;
  279.   register unsigned  short bitvector[];
  280.     {
  281.     return(D_TESTBIT(bit,bitvector));
  282.     }
  283.  
  284. /*
  285.  *     D_SETBIT
  286.  *
  287.  *     this routine is called to set a bit in a bit vector.
  288.  *
  289.  *     bit -- the bit to set
  290.  *
  291.  *     bitvector -- the bit vector to set it in
  292.  */
  293.  
  294. d_setbit(bit, bitvector)
  295.   register int  bit;
  296.   register unsigned  short bitvector[];
  297.     {
  298.  
  299.     bit &= 0177;
  300.  
  301.     bitvector[bit >> 4] |= (1 << (bit & 017));
  302.  
  303.     return(D_OK);
  304.     }
  305.  
  306. /*
  307.  *     D_ORBITVEC
  308.  *
  309.  *     this routine computes a word by word logical or of the input bit
  310.  *     vectors
  311.  *
  312.  *     a, b -- the input bit vector
  313.  *
  314.  *     out -- the bit vector which becomes the bit-wise 'or' of a and b
  315.  */
  316.  
  317. d_orbitvec(a, b, out)
  318.   register unsigned  short a[], b[], out[];
  319.     {
  320.     int  word;
  321.  
  322.     for (word = 0; word < 8; word++)
  323.       out[word] = a[word] | b[word];
  324.  
  325.     return(D_OK);
  326.     }
  327.  
  328. /*
  329.  *     D_TOHEX
  330.  *
  331.  *     routine which returns the value of its argument as a single hex
  332.  *     character
  333.  *
  334.  *     value -- the value to be converted
  335.  */
  336.  
  337. d_tohex(value)
  338.   register int  value;
  339.     {
  340.  
  341.     if ((value >= 0) && (value <= 9))
  342.       return(value + '0');
  343.  
  344.     if ((value >= 10) && (value <= 15))
  345.       return(value - 10 + 'A');
  346.  
  347.     return(-1);
  348.     }
  349.  
  350. /*
  351.  *     D_FROMHEX
  352.  *
  353.  *     routine which returns the value of the hex character given as the
  354.  *     argument.
  355.  *
  356.  *     c -- the character whose value is desired
  357.  */
  358.  
  359. d_fromhex(c)
  360.   register int  c;
  361.     {
  362.  
  363.     if ((c >= '0') && (c <= '9'))
  364.       return(c - '0');
  365.  
  366.     if ((c >= 'A') && (c <= 'F'))
  367.       return(c - 'A' + 10);
  368.  
  369.     return(-1);
  370.     }
  371.  
  372. /*
  373.  *     D_SETILL
  374.  *
  375.  *     this routine is used to copy the illegal character bit vectors
  376.  *
  377.  *     in -- pointer to the source bit vector
  378.  *
  379.  *     out -- pointer to the destination bit vector
  380.  */
  381.  
  382. d_setill(in, out)
  383.   register unsigned  short in[], out[];
  384.     {
  385.     register int  word;
  386.  
  387.     for (word = 0; word < 8; word++)
  388.       out[word] = in[word];
  389.  
  390.     return(D_OK);
  391.     }
  392.