MeterLogger
test_heatshrink_static.c
Go to the documentation of this file.
1 #include <ctype.h>
2 
3 #include "heatshrink_encoder.h"
4 #include "heatshrink_decoder.h"
5 #include "greatest.h"
6 
7 #if HEATSHRINK_DYNAMIC_ALLOC
8 #error HEATSHRINK_DYNAMIC_ALLOC must be false for static allocation test suite.
9 #endif
10 
11 SUITE(integration);
12 
13 /* The majority of the tests are in test_heatshrink_dynamic, because that allows
14  * instantiating encoders/decoders with different settings at run-time. */
15 
18 
19 static void fill_with_pseudorandom_letters(uint8_t *buf, uint16_t size, uint32_t seed) {
20  uint64_t rn = 9223372036854775783; /* prime under 2^64 */
21  for (int i=0; i<size; i++) {
22  rn = rn*seed + seed;
23  buf[i] = (rn % 26) + 'a';
24  }
25 }
26 
27 static void dump_buf(char *name, uint8_t *buf, uint16_t count) {
28  for (int i=0; i<count; i++) {
29  uint8_t c = (uint8_t)buf[i];
30  printf("%s %d: 0x%02x ('%c')\n", name, i, c, isprint(c) ? c : '.');
31  }
32 }
33 
34 static int compress_and_expand_and_check(uint8_t *input, uint32_t input_size, int log_lvl) {
37  size_t comp_sz = input_size + (input_size/2) + 4;
38  size_t decomp_sz = input_size + (input_size/2) + 4;
39  uint8_t *comp = malloc(comp_sz);
40  uint8_t *decomp = malloc(decomp_sz);
41  if (comp == NULL) FAILm("malloc fail");
42  if (decomp == NULL) FAILm("malloc fail");
43  memset(comp, 0, comp_sz);
44  memset(decomp, 0, decomp_sz);
45 
46  size_t count = 0;
47 
48  if (log_lvl > 1) {
49  printf("\n^^ COMPRESSING\n");
50  dump_buf("input", input, input_size);
51  }
52 
53  uint32_t sunk = 0;
54  uint32_t polled = 0;
55  while (sunk < input_size) {
56  ASSERT(heatshrink_encoder_sink(&hse, &input[sunk], input_size - sunk, &count) >= 0);
57  sunk += count;
58  if (log_lvl > 1) printf("^^ sunk %zd\n", count);
59  if (sunk == input_size) {
61  }
62 
63  HSE_poll_res pres;
64  do { /* "turn the crank" */
65  pres = heatshrink_encoder_poll(&hse, &comp[polled], comp_sz - polled, &count);
66  ASSERT(pres >= 0);
67  polled += count;
68  if (log_lvl > 1) printf("^^ polled %zd\n", count);
69  } while (pres == HSER_POLL_MORE);
71  if (polled >= comp_sz) FAILm("compression should never expand that much");
72  if (sunk == input_size) {
74  }
75  }
76  if (log_lvl > 0) printf("in: %u compressed: %u ", input_size, polled);
77  uint32_t compressed_size = polled;
78  sunk = 0;
79  polled = 0;
80 
81  if (log_lvl > 1) {
82  printf("\n^^ DECOMPRESSING\n");
83  dump_buf("comp", comp, compressed_size);
84  }
85  while (sunk < compressed_size) {
86  ASSERT(heatshrink_decoder_sink(&hsd, &comp[sunk], compressed_size - sunk, &count) >= 0);
87  sunk += count;
88  if (log_lvl > 1) printf("^^ sunk %zd\n", count);
89  if (sunk == compressed_size) {
91  }
92 
93  HSD_poll_res pres;
94  do {
95  pres = heatshrink_decoder_poll(&hsd, &decomp[polled],
96  decomp_sz - polled, &count);
97  ASSERT(pres >= 0);
98  polled += count;
99  if (log_lvl > 1) printf("^^ polled %zd\n", count);
100  } while (pres == HSDR_POLL_MORE);
101  ASSERT_EQ(HSDR_POLL_EMPTY, pres);
102  if (sunk == compressed_size) {
105  }
106 
107  if (polled > input_size) {
108  FAILm("Decompressed data is larger than original input");
109  }
110  }
111  if (log_lvl > 0) printf("decompressed: %u\n", polled);
112  if (polled != input_size) {
113  FAILm("Decompressed length does not match original input length");
114  }
115 
116  if (log_lvl > 1) dump_buf("decomp", decomp, polled);
117  for (size_t i=0; i<input_size; i++) {
118  if (input[i] != decomp[i]) {
119  printf("*** mismatch at %zd\n", i);
120  if (0) {
121  for (size_t j=0; j<=/*i*/ input_size; j++) {
122  printf("in[%zd] == 0x%02x ('%c') => out[%zd] == 0x%02x ('%c')\n",
123  j, input[j], isprint(input[j]) ? input[j] : '.',
124  j, decomp[j], isprint(decomp[j]) ? decomp[j] : '.');
125  }
126  }
127  }
128  ASSERT_EQ(input[i], decomp[i]);
129  }
130  free(comp);
131  free(decomp);
132  PASS();
133 }
134 
135 TEST pseudorandom_data_should_match(uint32_t size, uint32_t seed) {
136  uint8_t input[size];
137  fill_with_pseudorandom_letters(input, size, seed);
138  return compress_and_expand_and_check(input, size, 0);
139 }
140 
141 SUITE(integration) {
142 #if __STDC_VERSION__ >= 19901L
143  for (uint32_t size=1; size < 64*1024; size <<= 1) {
144  if (GREATEST_IS_VERBOSE()) printf(" -- size %u\n", size);
145  for (uint32_t seed=1; seed<=100; seed++) {
146  if (GREATEST_IS_VERBOSE()) printf(" -- seed %u\n", seed);
148  }
149  }
150 #endif
151 }
152 
153 /* Add all the definitions that need to be in the test runner's main file. */
155 
156 int main(int argc, char **argv) {
157  GREATEST_MAIN_BEGIN(); /* command-line arguments, initialization. */
158  printf("INPUT_BUFFER_SIZE: %u\n", HEATSHRINK_STATIC_INPUT_BUFFER_SIZE);
159  printf("WINDOW_BITS: %u\n", HEATSHRINK_STATIC_WINDOW_BITS);
160  printf("LOOKAHEAD_BITS: %u\n", HEATSHRINK_STATIC_LOOKAHEAD_BITS);
161 
162  printf("sizeof(heatshrink_encoder): %zd\n", sizeof(heatshrink_encoder));
163  printf("sizeof(heatshrink_decoder): %zd\n", sizeof(heatshrink_decoder));
164  RUN_SUITE(integration);
165  GREATEST_MAIN_END(); /* display results */
166 }
#define free(x)
Definition: platform.h:20
static int compress_and_expand_and_check(uint8_t *input, uint32_t input_size, int log_lvl)
HSD_poll_res heatshrink_decoder_poll(heatshrink_decoder *hsd, uint8_t *out_buf, size_t out_buf_size, size_t *output_size)
#define memset(x, a, b)
Definition: platform.h:21
#define RUN_SUITE
Definition: greatest.h:568
#define NULL
Definition: def.h:47
#define PASS
Definition: greatest.h:577
#define TEST
Definition: greatest.h:564
#define malloc(x)
Definition: platform.h:19
#define ASSERT
Definition: greatest.h:569
HSD_poll_res
#define isprint(c)
Definition: ip_addr.c:115
GREATEST_MAIN_DEFS()
HSD_finish_res heatshrink_decoder_finish(heatshrink_decoder *hsd)
#define GREATEST_IS_VERBOSE()
Definition: greatest.h:237
SUITE(integration)
static void dump_buf(char *name, uint8_t *buf, uint16_t count)
static heatshrink_decoder hsd
void heatshrink_decoder_reset(heatshrink_decoder *hsd)
HSE_finish_res heatshrink_encoder_finish(heatshrink_encoder *hse)
HSD_sink_res heatshrink_decoder_sink(heatshrink_decoder *hsd, uint8_t *in_buf, size_t size, size_t *input_size)
int main(int argc, char **argv)
#define ASSERT_EQ
Definition: greatest.h:572
HSE_poll_res heatshrink_encoder_poll(heatshrink_encoder *hse, uint8_t *out_buf, size_t out_buf_size, size_t *output_size)
HSE_sink_res heatshrink_encoder_sink(heatshrink_encoder *hse, uint8_t *in_buf, size_t size, size_t *input_size)
#define RUN_TESTp
Definition: greatest.h:588
void heatshrink_encoder_reset(heatshrink_encoder *hse)
HSD_finish_res
#define printf(...)
Definition: platform.h:13
TEST pseudorandom_data_should_match(uint32_t size, uint32_t seed)
#define GREATEST_MAIN_BEGIN()
Definition: greatest.h:502
#define GREATEST_MAIN_END()
Definition: greatest.h:543
static void fill_with_pseudorandom_letters(uint8_t *buf, uint16_t size, uint32_t seed)
#define FAILm
Definition: greatest.h:581
static heatshrink_encoder hse
HSE_poll_res