home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_10_10 / 1010118a < prev    next >
Text File  |  1992-08-13  |  4KB  |  192 lines

  1. /*
  2.  * Listing 3
  3.  *
  4.  * TESTRDC.C - Ross Data Compression (RDC)
  5.  *             test driver program
  6.  *
  7.  * Written by Ed Ross, 1/92
  8.  *
  9.  * This program will compress or decompress a file
  10.  * using RDC data compression.
  11.  *
  12. */
  13.  
  14. #include <stdlib.h>
  15. #include <stdio.h>
  16. #include <stdarg.h>
  17. #include <string.h>
  18.  
  19. #define HASH_LEN   4096    /* # hash table entries */
  20. #define BUFF_LEN  16384    /* size of disk io buffer */
  21.  
  22. typedef unsigned char uchar;    /*  8 bits, unsigned */
  23. typedef unsigned int  uint;     /* 16 bits, unsigned */
  24.  
  25. uchar   *hash_tbl[HASH_LEN];        /* hash table */
  26.  
  27. uchar   inbuff[BUFF_LEN];           /* io buffers */
  28. uchar   outbuff[BUFF_LEN];
  29.  
  30. FILE    *infile, *outfile;          /* FILE access */
  31.  
  32. char    usage[] =
  33.         "\nUsage: TESTRDC <c | d> <infile> <outfile>\n"
  34.           "       c = compress infile to outfile\n"
  35.           "       d = decompress infile to outfile\n";
  36.  
  37. /* compression function prototypes */
  38.  
  39. int rdc_compress(uchar *inbuff, uint inbuff_len,
  40.                  uchar *outbuff,
  41.                  uchar *hash_tbl[], uint hash_len);
  42.  
  43. int rdc_decompress(uchar *inbuff, uint inbuff_len,
  44.                    uchar *outbuff);
  45.  
  46. /*--- post error message and exit ---*/
  47.  
  48. void err_exit(char *fmt, ...)
  49. {
  50. va_list v;
  51.  
  52.   va_start(v, fmt);
  53.   vfprintf(stderr, fmt, v);
  54.   va_end(v);
  55.  
  56.   exit(1);
  57. }
  58.  
  59. /*--- compress infile to outfile ---*/
  60.  
  61. void do_compress(void)
  62. {
  63. int     bytes_read;
  64. int     compress_len;
  65.  
  66.   /* read infile BUFF_LEN bytes at a time */
  67.  
  68.   while ((bytes_read =
  69.           fread(inbuff, 1, BUFF_LEN, infile)) > 0)
  70.   {
  71.     /* compress this load of bytes */
  72.  
  73.     compress_len = rdc_compress(inbuff, bytes_read,
  74.                    outbuff, hash_tbl, HASH_LEN);
  75.  
  76.     /* write length of compressed buffer */
  77.  
  78.     if (fwrite(&compress_len, sizeof(int),
  79.                1, outfile) != 1)
  80.       err_exit("Error writing block length.\n");
  81.  
  82.     /* check for negative length indicating the
  83.        buffer could not be compressed */
  84.  
  85.     if (compress_len < 0)
  86.       compress_len = 0 - compress_len;
  87.  
  88.     /* write the buffer */
  89.  
  90.     if (fwrite(outbuff, compress_len, 1, outfile) != 1)
  91.       err_exit("Error writing compressed data.\n");
  92.  
  93.     /* we're done if less than full buffer was read */
  94.  
  95.     if (bytes_read != BUFF_LEN)
  96.       break;
  97.   }
  98.  
  99.   /* add trailer to indicate end of file */
  100.  
  101.   compress_len = 0;
  102.  
  103.   if (fwrite(&compress_len, sizeof(int),
  104.              1, outfile) != 1)
  105.       err_exit("Error writing trailer.\n");
  106. }
  107.  
  108. /*--- decompress infile to outfile ---*/
  109.  
  110. void do_decompress(void)
  111. {
  112. int     block_len;
  113. int     decomp_len;
  114.  
  115.   /* read infile BUFF_LEN bytes at a time */
  116.  
  117.   for (;;)
  118.   {
  119.     if (fread(&block_len, sizeof(int), 1, infile) != 1)
  120.         err_exit("Can't read block length.\n");
  121.  
  122.     /* check for end-of-file flag */
  123.  
  124.     if (block_len == 0)
  125.       return;
  126.  
  127.     if (block_len < 0)  /* copy uncompressed chars */
  128.     {
  129.       decomp_len = 0 - block_len;
  130.       if (fread(outbuff, decomp_len, 1, infile) != 1)
  131.         err_exit("Can't read uncompressed block.\n");
  132.     }
  133.     else                /* decompress this buffer */
  134.     {
  135.       if (fread(inbuff, block_len, 1, infile) != 1)
  136.         err_exit("Can't read compressed block.\n");
  137.  
  138.       decomp_len = rdc_decompress(inbuff, block_len,
  139.                                   outbuff);
  140.     }
  141.  
  142.     /* and write this buffer outfile */
  143.  
  144.     if (fwrite(outbuff, decomp_len, 1, outfile) != 1)
  145.       err_exit("Error writing uncompressed data.\n");
  146.   }
  147. }
  148.  
  149. /*--- main ---*/
  150.  
  151. void main(int argc, char *argv[])
  152. {
  153.   /* check command line */
  154.  
  155.   if (argc != 4)
  156.     err_exit(usage);
  157.  
  158.   /* open the files */
  159.  
  160.   if ((infile = fopen(argv[2], "rb")) == NULL)
  161.     err_exit("Can't open %s for input.\n", argv[2]);
  162.  
  163.   if ((outfile = fopen(argv[3], "wb")) == NULL)
  164.     err_exit("Can't open %s for output.\n", argv[3]);
  165.  
  166.   /* dispatch to requested function */
  167.  
  168.   switch (argv[1][0])
  169.   {
  170.   case    'c':
  171.   case    'C':
  172.           do_compress();
  173.           break;
  174.  
  175.   case    'd':
  176.   case    'D':
  177.           do_decompress();
  178.           break;
  179.  
  180.   default:
  181.           err_exit(usage);
  182.   }
  183.  
  184.   /* and close the files */
  185.  
  186.   if (fclose(infile))
  187.     err_exit("Error closing input file.\n");
  188.  
  189.   if (fclose(outfile))
  190.     err_exit("Error closing output file.\n");
  191. }
  192.