home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / games / tinymud2.zip / COMPRESS.C < prev    next >
C/C++ Source or Header  |  1990-09-02  |  3KB  |  114 lines

  1. /* Compression routines */
  2.  
  3. /* These use a pathetically simple encoding that takes advantage of the */
  4. /* eighth bit on a char; if you are using an international character set, */
  5. /* they may need substantial patching. */
  6.  
  7. #ifdef COMPRESS
  8.  
  9. #define BUFFER_LEN 16384    /* nice big buffer */
  10.  
  11. #define TOKEN_BIT 0x80        /* if on, it's a token */
  12. #define TOKEN_MASK 0x7f        /* for stripping out token value */
  13. #define NUM_TOKENS (128)
  14. #define MAX_CHAR (128)
  15.  
  16. /* Top 128 bigrams in the CMU TinyMUD database as of 2/13/90 */ 
  17. static const char *tokens[NUM_TOKENS] = {
  18.     "e ", " t", "th", "he", "s ", " a", "ou", "in",
  19.     "t ", " s", "er", "d ", "re", "an", "n ", " i",
  20.     " o", "es", "st", "to", "or", "nd", "o ", "ar",
  21.     "r ", ", ", "on", " b", "ea", "it", "u ", " w",
  22.     "ng", "le", "is", "te", "en", "at", " c", "y ",
  23.     "ro", " f", "oo", "al", ". ", "a ", " d", "ut",
  24.     " h", "se", "nt", "ll", "g ", "yo", " l", " y",
  25.     " p", "ve", "f ", "as", "om", "of", "ha", "ed",
  26.     "h ", "hi", " r", "lo", "Yo", " m", "ne", "l ",
  27.     "li", "de", "el", "ta", "wa", "ri", "ee", "ti",
  28.     "no", "do", "Th", " e", "ck", "ur", "ow", "la",
  29.     "ac", "et", "me", "il", " g", "ra", "co", "ch",
  30.     "ma", "un", "so", "rt", "ai", "ce", "ic", "be",
  31.     " n", "k ", "ge", "ot", "si", "pe", "tr", "wi",
  32.     "e.", "ca", "rs", "ly", "ad", "we", "bo", "ho",
  33.     "ir", "fo", "ke", "us", "m ", " T", "di", ".." };
  34.  
  35. static char token_table[MAX_CHAR][MAX_CHAR];
  36. static int table_initialized = 0;
  37.  
  38. static void init_compress(void)
  39. {
  40.     int i;
  41.     int j;
  42.  
  43.     for(i = 0; i < MAX_CHAR; i++) {
  44.     for(j = 0; j < MAX_CHAR; j++) {
  45.         token_table[i][j] = 0;
  46.     }
  47.     }
  48.  
  49.     for(i = 0; i < NUM_TOKENS; i++) {
  50.     token_table[tokens[i][0]][tokens[i][1]] = i | TOKEN_BIT;
  51.     }
  52.  
  53.     table_initialized = 1;
  54. }
  55.  
  56. static int compressed(const char *s)
  57. {
  58.     while(*s) {
  59.     if(*s++ & TOKEN_BIT) return 1;
  60.     }
  61.     return 0;
  62. }
  63.  
  64. const char *compress(const char *s)
  65. {
  66.     static char buf[BUFFER_LEN];
  67.     char *to;
  68.     char token;
  69.  
  70.     if(!table_initialized) init_compress();
  71.  
  72.     if(compressed(s)) return s;    /* already compressed */
  73.  
  74.     /* tokenize the first characters */
  75.     for(to = buf; s[0] && s[1]; to++) {
  76.     if(token = token_table[s[0]][s[1]]) {
  77.         *to = token;
  78.         s += 2;
  79.     } else {
  80.         *to = s[0];
  81.         s++;
  82.     }
  83.     }
  84.  
  85.     /* copy the last character (if any) and null */
  86.     while(*to++ = *s++);
  87.  
  88.     return buf;
  89. }
  90.     
  91. const char *uncompress(const char *s)
  92. {
  93.     static char buf[BUFFER_LEN];
  94.     char *to;
  95.     const char *token;
  96.  
  97.     for(to = buf; *s; s++) {
  98.     if(*s & TOKEN_BIT) {
  99.         token = tokens[*s & TOKEN_MASK];
  100.         *to++ = *token++;
  101.         *to++ = *token;
  102.     } else {
  103.         *to++ = *s;
  104.     }
  105.     }
  106.  
  107.     *to++ = *s;
  108.  
  109.     return buf;
  110. }
  111.  
  112. #endif /* COMPRESS */
  113.         
  114.