8 void test_basic_unstuff(unstuff_func_t* unstuff)
10 uint8_t bytes[] = { 1, 2, 3, 4, 5, 6, 0xff, 0x00, 7, 8, 9, 0xff, 0x00, 10, 11, 12, 13, 14 };
11 uint8_t ref[] = { 1, 2, 3, 4, 5, 6, 0xff, 7, 8, 9, 0xff, 10, 11, 12, 13, 14 };
12 uint8_t dst[sizeof(bytes)];
13 int ret = (*unstuff)(dst, bytes, sizeof(bytes));
15 assert(ret == sizeof(ref));
16 assert(memcmp(dst, ref, ret) == 0);
19 // Stuff byte crossing the 16-byte boundaries the SSE4.1 function uses.
20 void test_edge_unstuff(unstuff_func_t* unstuff)
22 uint8_t bytes[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0x00, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 };
23 uint8_t ref[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 };
24 uint8_t dst[sizeof(bytes)];
25 int ret = (*unstuff)(dst, bytes, sizeof(bytes));
27 assert(ret == sizeof(ref));
28 assert(memcmp(dst, ref, ret) == 0);
31 void test_marker(unstuff_func_t* unstuff)
33 uint8_t bytes[] = { 1, 2, 3, 4, 5, 6, 0xff, 0x01, 7, 8, 9, 0xff, 0x00, 10, 11, 12, 13, 14 };
34 uint8_t dst[sizeof(bytes)];
35 int ret = (*unstuff)(dst, bytes, sizeof(bytes));
40 void test_marker_end(unstuff_func_t* unstuff)
42 uint8_t bytes[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xff };
43 uint8_t dst[sizeof(bytes)];
44 int ret = (*unstuff)(dst, bytes, sizeof(bytes));
49 void gen_random_stuffed_data(uint8_t* dst, size_t len)
51 // Standard NR LCG (we avoid rand() to get consistent behavior across platforms).
53 for (unsigned i = 0; i < len; ++i) {
54 seed = seed * 1664525 + 1013904223;
55 uint8_t byte = (uint8_t)(seed & 0xff);
59 } else if (i == len - 1) {
60 // Don't make a partial marker.
69 void test_performance(unstuff_func_t* unstuff)
71 const size_t len = 4096;
72 const unsigned num_runs = 400000;
74 uint8_t src[len], dst[len];
75 gen_random_stuffed_data(src, len);
77 start_benchmark_timer();
79 for (unsigned i = 0; i < num_runs; ++i) {
80 int ret = unstuff(dst, src, len);
84 double diff = stop_benchmark_timer();
85 double mb_sec = (len * num_runs) / (1048576.0 * diff);
86 printf("%u runs with %zu bytes in %.2f CPU seconds = %.2f MB/sec\n",
87 num_runs, len, diff, mb_sec);
90 void test_all_unstuff(unstuff_func_t* unstuff)
92 printf(" test_basic_unstuff()\n");
93 test_basic_unstuff(unstuff);
95 printf(" test_edge_unstuff()\n");
96 test_edge_unstuff(unstuff);
98 printf(" test_marker()\n");
101 printf(" test_marker_end()\n");
102 test_marker_end(unstuff);
104 printf(" performance test: ");
105 test_performance(unstuff);
110 printf("unstuff_reference:\n");
111 test_all_unstuff(unstuff_reference);
113 printf("unstuff_fast:\n");
114 test_all_unstuff(unstuff_fast);
116 printf("unstuff_sse41:\n");
117 test_all_unstuff(unstuff_sse41);
119 printf("All tests pass.\n");