home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************/
- /* FILE JMODEM_D.C */
- /* Created 11-JAN-1990 Richard B. Johnson */
- /* 405 Broughton Drive */
- /* Beverly, Massachusetts 01915 */
- /* BBS (508) 922-3166 */
- /* */
- /* encode(); (Data compression routine ) */
- /* decode(); (Data expansion routine ) */
- /* calc_crc(); (CRC checking and setting ) */
- /* */
- /****************************************************************************/
- #include <stdlib.h> /* For _rotl() */
- #include "jmodem.h" /* JMODEM primatives */
- /****************************************************************************/
- /* Encode (compress) the input string. */
- /* The routine looks for groups of identical characters and replaces them */
- /* with the character 0xBB, a word denoting the number of characters to */
- /* duplicate, followed by the character to duplicate. */
- /* */
- /****************************************************************************/
-
- word encode(word len, /* Length of input string */
- register byte *in_buffer, /* Pointer to input buffer */
- register byte *out_buffer) /* Pointer to output buffer */
- {
- word *wrds; /* Used to address string */
- word how_many=0; /* Character count */
- word count=0; /* Output byte count */
- word start; /* Starting count */
- byte dupl; /* Character to replace */
-
- start = len; /* Save starting length */
- while (len) /* While bytes in buffer */
- {
- if ( (*in_buffer == 0xBB) /* If the sentinel byte */
- || (*in_buffer == *(in_buffer+1)) ) /* If two adjacent the same */
- {
- *out_buffer++ = 0xBB; /* Insert , bump pointer */
- dupl = *in_buffer; /* Save duplicate character */
- how_many = 0; /* Duplicate char count */
- while ( (*in_buffer++ == dupl) /* Count duplicates */
- && (len) ) /* While bytes still left. */
- {
- how_many++; /* Identical characters */
- len --; /* Don't move to (while) */
- }
- wrds = (word *)out_buffer; /* Address string pointer */
- *wrds = how_many; /* Insert character count */
- out_buffer++; /* Adjust pointer */
- out_buffer++; /* (get past count) */
- *out_buffer++ = dupl; /* The duplicate character */
- count += 4; /* Adjust byte count */
- in_buffer--; /* Non-duplicate character */
- }
- else
- {
- *out_buffer++ = *in_buffer++; /* Copy byte */
- count++; /* Character count */
- len--;
- }
- if ( count > start ) /* Check unwarranted growth */
- return JM_MAX;
- }
- return count; /* New length */
- }
- /****************************************************************************/
- /* Decode (expand) the encoded string. */
- /* Routine checks for a sentinel byte, 0xBB, and if found, takes the */
- /* following word as the number of identical bytes to add. The actual */
- /* byte to add is located following the length-word. */
- /* */
- /****************************************************************************/
- word decode(word len, /* Length to input string */
- register byte *in_buffer, /* Pointer to input buffer */
- register byte *out_buffer) /* Pointer to output buffer */
- {
- byte *start; /* To save buffer start */
- word *wrds; /* Address string as word */
-
- if (len > DAT_MAX) /* Check for valid data */
- return 0;
- start = out_buffer; /* Save starting address */
- while (len--)
- {
- if (*in_buffer == 0xBB ) /* If the sentinel byte */
- {
- wrds =(word *) ++in_buffer; /* Next character */
- in_buffer++; /* Adjust buffer pointer */
- in_buffer++; /* (get past the count) */
- do /* Expand the byte */
- {
- *out_buffer++ = *in_buffer; /* Expand byte */
- } while (--(*wrds) );
- in_buffer++; /* Adjust pointer */
- len -=3; /* Adjust input count */
- }
- else /* Else, just copy */
- *out_buffer++ = *in_buffer++;
- }
- return (word) (out_buffer - start); /* New string length */
- }
- /****************************************************************************/
- /* Calculate the simple JMODEM CRC */
- /* Routine obtains a pointer to the buffer of characters to be checked. */
- /* The first passed parameter is the length of the buffer. The CRC is */
- /* returned. */
- /* */
- /****************************************************************************/
- word calc_crc(word command, /* Set or Check CRC */
- word length, /* Buffer length */
- register byte *buffer) /* Pointer to the buffer */
- {
- register word *wrds; /* Address string as word */
- word crc=0; /* Start at zero */
-
- if (length <3) /* Check forvalid string */
- return JM_MAX; /* Nothing to CRC */
-
- length -=2; /* Don't CRC the CRC */
- do
- {
- crc += (word) *buffer++; /* Sum first */
- crc = _rotl(crc, (length & 0x07) ); /* Rotate max 7 bits left */
- } while (--length);
- wrds = (word *) buffer; /* Set up to point to CRC */
- if (command == GET_CRC)
- return (crc - *wrds); /* Return 0 if CRC okay */
- else /* Else command = SET_CRC */
- *wrds = crc; /* Set the CRC in string */
- return crc; /* Return the CRC also */
- }
- /****************************************************************************/
- /************************ E N D O F M O D U L E **************************/