home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / comm / jmodem.zip / JMODEM_D.C < prev    next >
Text File  |  1990-06-20  |  8KB  |  138 lines

  1. /****************************************************************************/
  2. /*   FILE JMODEM_D.C                                                        */
  3. /*   Created 11-JAN-1990                  Richard B. Johnson                */
  4. /*                                        405 Broughton Drive               */
  5. /*                                        Beverly, Massachusetts 01915      */
  6. /*                                        BBS (508) 922-3166                */
  7. /*                                                                          */
  8. /*   encode();      (Data compression routine  )                            */
  9. /*   decode();      (Data expansion routine    )                            */
  10. /*   calc_crc();    (CRC checking and setting  )                            */
  11. /*                                                                          */
  12. /****************************************************************************/
  13. #include <stdlib.h>                             /* For _rotl()              */
  14. #include "jmodem.h"                             /* JMODEM primatives        */
  15. /****************************************************************************/
  16. /*                   Encode (compress) the input string.                    */
  17. /*   The routine looks for groups of identical characters and replaces them */
  18. /*   with the character  0xBB, a word denoting the number of characters to  */
  19. /*   duplicate, followed by the character to duplicate.                     */
  20. /*                                                                          */
  21. /****************************************************************************/
  22.  
  23. unsigned short encode(len, in_buffer, out_buffer)
  24. unsigned short len;                             /* Length of input string   */
  25. register unsigned char *in_buffer;              /* Pointer to input buffer  */
  26. register unsigned char *out_buffer;             /* Pointer to output buffer */
  27. {
  28.     unsigned short *word;                       /* Used to address string   */
  29.     unsigned short how_many=0;                  /* Character count          */
  30.     unsigned short count=0;                     /* Output byte count        */
  31.     unsigned short start;                       /* Starting count           */
  32.     unsigned char dupl;                         /* Character to replace     */
  33.  
  34.     start = len;                                /* Save starting length     */
  35.     while (len)                                 /* While bytes in buffer    */
  36.     {
  37.         if ( (*in_buffer == 0xBB)               /* If the sentinel byte     */
  38.           || (*in_buffer == *(in_buffer+1)) )   /* If two adjacent the same */
  39.         {
  40.             *out_buffer++ = 0xBB;               /* Insert , bump pointer    */
  41.             dupl = *in_buffer;                  /* Save duplicate character */
  42.             how_many = 0;                       /* Duplicate char count     */
  43.             while ( (*in_buffer++ == dupl)      /* Count duplicates         */
  44.                               && (len) )        /* While bytes still left.  */
  45.             {
  46.                 how_many++;                     /* Identical characters     */
  47.                 len --;                         /* Don't move to (while)    */
  48.             }
  49.             word = (unsigned short *)out_buffer;/* Address string pointer   */
  50.             *word = how_many;                   /* Insert character count   */
  51.             out_buffer++;                       /* Adjust pointer           */
  52.             out_buffer++;                       /* (get past count)         */
  53.             *out_buffer++ = dupl;               /* The duplicate character  */
  54.             count += 4;                         /* Adjust byte count        */
  55.             in_buffer--;                        /* Non-duplicate character  */
  56.         }
  57.         else
  58.         {
  59.             *out_buffer++ = *in_buffer++;      /* Copy byte                 */
  60.             count++;                           /* Character count           */
  61.             len--;
  62.         }
  63.         if ( count > start )                   /* Check unwarranted growth  */
  64.             return JM_MAX;
  65.     }
  66.     return count;                              /* New length                */
  67. }
  68. /****************************************************************************/
  69. /*                     Decode (expand) the encoded string.                  */
  70. /*    Routine checks for a sentinel byte, 0xBB, and if found, takes the     */
  71. /*    following word as the number of identical bytes to add. The actual    */
  72. /*    byte to add is located following the length-word.                     */
  73. /*                                                                          */
  74. /****************************************************************************/
  75. unsigned short decode(len, in_buffer, out_buffer)
  76. unsigned short len;                             /* Length to input string   */
  77. register unsigned char *in_buffer;              /* Pointer to input buffer  */
  78. register unsigned char *out_buffer;             /* Pointer to output buffer */
  79. {
  80.     unsigned char *start;                       /* To save buffer start     */
  81.     unsigned short *word;                       /* Address string as word   */
  82.  
  83.     if (len > DAT_MAX)                          /* Check for valid data     */
  84.         return 0;
  85.     start = out_buffer;                         /* Save starting address    */
  86.     while (len--)
  87.     {
  88.         if (*in_buffer == 0xBB )                  /* If the sentinel byte   */
  89.         {
  90.             word =(unsigned short *) ++in_buffer; /* Next character         */
  91.             in_buffer++;                          /* Adjust buffer pointer  */
  92.             in_buffer++;                          /* (get past the count)   */
  93.             do                                    /* Expand the byte        */
  94.             {
  95.                 *out_buffer++ = *in_buffer;       /* Expand byte            */
  96.             }   while (--(*word) );
  97.             in_buffer++;                          /* Adjust pointer         */
  98.             len -=3;                              /* Adjust input count     */
  99.         }
  100.         else                                      /* Else, just copy        */
  101.             *out_buffer++ = *in_buffer++;
  102.     }
  103.     return (unsigned short) (out_buffer - start); /* New string length      */
  104. }
  105. /****************************************************************************/
  106. /*                  Calculate the simple JMODEM CRC                         */
  107. /*    Routine obtains a pointer to the buffer of characters to be checked.  */
  108. /*    The first passed parameter is the length of the buffer. The CRC is    */
  109. /*    returned.                                                             */
  110. /*                                                                          */
  111. /****************************************************************************/
  112. unsigned short calc_crc(command, length, buffer)
  113. unsigned short command;                     /* Set or Check CRC             */
  114. unsigned short length;                      /* Buffer length                */
  115. register unsigned char *buffer;             /* Pointer to the buffer        */
  116. {
  117.     register unsigned short *word;          /* Address string as word       */
  118.     unsigned short crc=0;                   /* Start at zero                */
  119.  
  120.     if (length <3)                          /* Check for a valid string     */
  121.         return JM_MAX;                      /* Nothing to CRC               */
  122.  
  123.     length -=2;                             /* Don't CRC the CRC            */
  124.     do
  125.     {
  126.     crc += (unsigned short) *buffer++;      /* Sum first                    */
  127.     crc  = _rotl(crc, (length & 0x07) );    /* Rotate  max 7 bits left      */
  128.     } while (--length);
  129.     word = (unsigned short *) buffer;       /* Set up to point to CRC       */
  130.     if (command == GET_CRC)
  131.         return (crc - *word);               /* Return AX = 0 if CRC okay    */
  132.     else                                    /* Else command = SET_CRC       */
  133.         *word = crc;                        /* Set the CRC in output string */
  134.         return crc;                         /* Return the CRC also          */
  135. }
  136. /****************************************************************************/
  137. /************************ E N D  O F   M O D U L E **************************/
  138.