Guest User

Untitled

a guest
Jan 17th, 2019
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.59 KB | None | 0 0
  1. /* Program to decode "compressed" text that has been rendered down
  2.    to a sequence of number pairs, as per the project specification.
  3.  
  4.    Written by Alistair Moffat, October 2012.
  5.  */
  6.  
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <ctype.h>
  11. #include <string.h>
  12. #include <strings.h>
  13. #include <assert.h>
  14.  
  15. /* constants and fixed strings */
  16.  
  17.     /* Maximum output size (1MB) */
  18. #define MAXBYTES 1000000
  19.     /* Assumed radix for nibble encoding */
  20. #define RADIX 15
  21.     /* Flag for single byte insertion */
  22. #define LITERAL  0
  23.  
  24. /* function prototypes */
  25.  
  26. void copybytes(unsigned char *S, int dest, int src, int len);
  27. int nibble_length(int d);
  28.  
  29. /* where it all happens */
  30.  
  31. int
  32. main(int argc, char **argv) {
  33.     unsigned char S[MAXBYTES];
  34.     int copyoffset, copylength;
  35.     int current=0;
  36.     int inputnibbles=0, inputphrases=0;
  37.     /* main loop, slightly longer than ideal without breaking up into
  38.        a series of functions, but it is the sole action of the program,
  39.        so ok... */
  40.     while (scanf("%d,%d", &copyoffset, &copylength)==2) {
  41.         if ((copyoffset<0) || (copyoffset>current) ||
  42.                 (copylength<0)) {
  43.             fprintf(stderr, "Invalid input\n");
  44.             exit(EXIT_FAILURE);
  45.         }
  46.         if (copyoffset == LITERAL) {
  47.             /* in this case, the "copylength" is actually
  48.                a single character */
  49.             S[current++] = copylength;
  50.             /* and this combination always takes
  51.                three nibbles */
  52.             inputnibbles += 3;
  53.         } else {
  54.             /* in this case, a sequence of prior bytes
  55.                is copied, as indicated by the offset */
  56.             copybytes(S, current,
  57.                 current-copyoffset, copylength);
  58.             current += copylength;
  59.             /* count nibbles in the radix-15 encoding */
  60.             inputnibbles += nibble_length(copyoffset);
  61.             inputnibbles += nibble_length(copylength);
  62.             /* and allow for the two sentinel nibbles */
  63.             inputnibbles += 2;
  64.         }
  65.         inputphrases += 1;
  66.     }
  67.     fwrite(S, sizeof(*S), current, stdout);
  68.     fprintf(stderr, "# %d phrases extracted\n", inputphrases);
  69.     fprintf(stderr, "# %d input nibbles, %d bytes\n",
  70.             inputnibbles, (inputnibbles+1)/2);
  71.     fprintf(stderr, "# %d bytes written to stdout\n", current);
  72.     fprintf(stderr, "# %.2f bits per byte compression rate\n",
  73.         inputnibbles*4.0/current);
  74.     return 0;
  75. }
  76.  
  77. /* copy a sequence of bytes from one part of the buffer to another */
  78. void
  79. copybytes(unsigned char *S, int dest, int src, int len) {
  80.     int i=0;
  81.     assert(len>0 && src<dest);
  82.     for (i=0; i<len; i++) {
  83.         S[dest+i] = S[src+i];
  84.     }
  85. }
  86.  
  87. /* count the number of base-RADIX digits in the integer d >= 0 */
  88. int
  89. nibble_length(int d) {
  90.     int len=0;
  91.     assert(d>=0);
  92.     while (d>=1) {
  93.         d /= RADIX;
  94.         len++;
  95.     }
  96.     return len;
  97. }
Add Comment
Please, Sign In to add comment