1 /** 2 * @file test_huff_code.c Test Huffman coding 3 * @author David Huggins-Daines <dhuggins@cs.cmu.edu> 4 */ 5 6 #include "huff_code.h" 7 #include "test_macros.h" 8 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 13 int32 const ivalues[10] = { 14 1, 2, 3, 5, 7, 11, 13, 17, 19, 23 15 }; 16 int32 const frequencies[10] = { 17 42, 4, 5, 6, 225, 15001, 3, 2, 87, 1003 18 }; 19 char * const svalues[10] = { 20 "foo", "bar", "baz", "quux", "argh", 21 "hurf", "burf", "blatz", "unf", "woof" 22 }; 23 char * const svalues2[10] = { 24 "1","2","3","4","5","6","7","8","9","10" 25 }; 26 char const cdata[7] = { 0x08, 0x30, 0x40, 0x4c, 0x00, 0x04, 0x50 }; 27 28 void 29 test_intcode(huff_code_t *hc) 30 { 31 FILE *fh; 32 char const *dptr; 33 int i, offset; 34 size_t dlen; 35 int32 val; 36 37 fh = fopen("hufftest.out", "wb"); 38 huff_code_attach(hc, fh, "wb"); 39 for (i = 0; i < 10; ++i) { 40 huff_code_encode_int(hc, ivalues[i], NULL); 41 } 42 huff_code_detach(hc); 43 fclose(fh); 44 fh = fopen("hufftest.out", "rb"); 45 huff_code_attach(hc, fh, "rb"); 46 for (i = 0; i < 10; ++i) { 47 int32 val; 48 huff_code_decode_int(hc, &val, NULL, NULL, 0); 49 printf("%d ", val); 50 TEST_EQUAL(val, ivalues[i]); 51 } 52 printf("\n"); 53 huff_code_detach(hc); 54 fclose(fh); 55 56 dptr = cdata; 57 dlen = 7; 58 offset = 0; 59 for (i = 0; i < 10; ++i) { 60 huff_code_decode_int(hc, &val, &dptr, &dlen, &offset); 61 printf("%d ", val); 62 TEST_EQUAL(val, ivalues[i]); 63 } 64 TEST_EQUAL(dlen, 1); 65 TEST_EQUAL(offset, 4); 66 printf("\n"); 67 68 dptr = cdata; 69 dlen = 7; 70 offset = 0; 71 i = 0; 72 while (huff_code_decode_int(hc, &val, &dptr, &dlen, &offset) != -1) { 73 printf("%d ", val); 74 TEST_EQUAL(val, ivalues[i++]); 75 } 76 TEST_EQUAL(dlen, 1); 77 TEST_EQUAL(offset, 4); 78 printf("\n"); 79 } 80 81 void 82 test_strcode(huff_code_t *hc, char * const *svalues) 83 { 84 FILE *fh; 85 char const *dptr; 86 int i, offset; 87 size_t dlen; 88 89 fh = fopen("hufftest.out", "wb"); 90 huff_code_attach(hc, fh, "wb"); 91 for (i = 9; i >= 0; --i) { 92 huff_code_encode_str(hc, svalues[i], NULL); 93 } 94 huff_code_detach(hc); 95 fclose(fh); 96 fh = fopen("hufftest.out", "rb"); 97 huff_code_attach(hc, fh, "rb"); 98 for (i = 9; i >= 0; --i) { 99 char const *val = huff_code_decode_str(hc, NULL, NULL, 0); 100 printf("%s ", val); 101 TEST_EQUAL(0, strcmp(val, svalues[i])); 102 } 103 printf("\n"); 104 huff_code_detach(hc); 105 fclose(fh); 106 107 dptr = cdata; 108 dlen = 7; 109 offset = 0; 110 for (i = 0; i < 10; ++i) { 111 char const *val = huff_code_decode_str(hc, &dptr, &dlen, &offset); 112 printf("%s ", val); 113 TEST_EQUAL(0, strcmp(val, svalues[i])); 114 } 115 TEST_EQUAL(dlen, 1); 116 TEST_EQUAL(offset, 4); 117 printf("\n"); 118 } 119 120 int 121 main(int argc, char *argv[]) 122 { 123 huff_code_t *hc; 124 FILE *fh; 125 126 hc = huff_code_build_int(ivalues, frequencies, 10); 127 huff_code_dump(hc, stdout); 128 test_intcode(hc); 129 fh = fopen("huffcode.out", "wb"); 130 huff_code_write(hc, fh); 131 fclose(fh); 132 huff_code_free(hc); 133 134 fh = fopen("huffcode.out", "rb"); 135 hc = huff_code_read(fh); 136 fclose(fh); 137 test_intcode(hc); 138 huff_code_free(hc); 139 140 hc = huff_code_build_str(svalues, frequencies, 10); 141 huff_code_dump(hc, stdout); 142 test_strcode(hc, svalues); 143 fh = fopen("huffcode.out", "wb"); 144 huff_code_write(hc, fh); 145 fclose(fh); 146 huff_code_free(hc); 147 148 fh = fopen("huffcode.out", "rb"); 149 hc = huff_code_read(fh); 150 fclose(fh); 151 test_strcode(hc, svalues); 152 huff_code_free(hc); 153 154 hc = huff_code_build_str(svalues2, frequencies, 10); 155 huff_code_dump(hc, stdout); 156 test_strcode(hc, svalues2); 157 huff_code_free(hc); 158 159 return 0; 160 } 161 162