3f003d2bbc040fa3a435400350a37aadc55b602c
[fjl] / input_test.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <assert.h>
4 #include <time.h>
5 #include <sys/time.h>
6
7 #include "input.h"
8
9 struct custom_read_userdata {
10         uint8_t* bytes;
11         unsigned bytes_left;
12 };
13
14 ssize_t custom_read(void* userdata, uint8_t* buf, size_t count)
15 {
16         struct custom_read_userdata* ud = (struct custom_read_userdata*)userdata;
17         size_t num_to_read = (ud->bytes_left > count ? count : ud->bytes_left);
18         memcpy(buf, ud->bytes, num_to_read);
19         ud->bytes += num_to_read;
20         ud->bytes_left -= num_to_read;
21         return num_to_read;     
22 }
23
24 ssize_t custom_read_slow(void* userdata, uint8_t* buf, size_t count)
25 {
26         struct custom_read_userdata* ud = (struct custom_read_userdata*)userdata;
27         size_t num_to_read = (count > 0 ? 1 : 0);
28         memcpy(buf, ud->bytes, num_to_read);
29         ud->bytes += num_to_read;
30         ud->bytes_left -= num_to_read;
31         return num_to_read;
32 }
33
34 // Read 6 bits at a time. We should get 0b101010 every time.
35 void test_basic_reading()
36 {
37         uint8_t bytes[] = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
38         struct custom_read_userdata ud;
39         ud.bytes = bytes;
40         ud.bytes_left = sizeof(bytes);
41
42         struct data_source source;
43         init_data_source(&source, custom_read, &ud);
44
45         for (int i = 0; i < sizeof(bytes) * 8 / 6; ++i) {
46                 possibly_refill(&source, 6);
47                 unsigned ret = read_bits(&source, 6);
48                 assert(ret == 0x2a);
49         }
50
51         assert(ud.bytes_left == 0);
52 }
53
54 // Same, but with an input source that gives back only one byte at a time.
55 void test_slow_source()
56 {
57         uint8_t bytes[] = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
58         struct custom_read_userdata ud;
59         ud.bytes = bytes;
60         ud.bytes_left = sizeof(bytes);
61
62         struct data_source source;
63         init_data_source(&source, custom_read_slow, &ud);
64
65         for (int i = 0; i < sizeof(bytes) * 8 / 6; ++i) {
66                 possibly_refill(&source, 6);
67                 unsigned ret = read_bits(&source, 6);
68                 assert(ret == 0x2a);
69         }
70
71         assert(ud.bytes_left == 0);
72 }
73
74 // Read a few different bit sizes.
75 void test_variable_size()
76 {
77         uint8_t bytes[] = { 0x12, 0x34, 0x56, 0x78, 0xff };
78         struct custom_read_userdata ud;
79         ud.bytes = bytes;
80         ud.bytes_left = sizeof(bytes);
81
82         struct data_source source;
83         init_data_source(&source, custom_read, &ud);
84
85         {
86                 possibly_refill(&source, 4);
87                 unsigned ret = read_bits(&source, 1);
88                 assert(ret == 0x0);
89                 ret = read_bits(&source, 1);
90                 assert(ret == 0x0);
91                 ret = read_bits(&source, 1);
92                 assert(ret == 0x0);
93                 ret = read_bits(&source, 1);
94                 assert(ret == 0x1);
95         }
96         {
97                 possibly_refill(&source, 4);
98                 unsigned ret = read_bits(&source, 4);
99                 assert(ret == 0x2);
100         }
101         {
102                 possibly_refill(&source, 12);
103                 unsigned ret = read_bits(&source, 12);
104                 assert(ret == 0x345);
105         }
106         {
107                 possibly_refill(&source, 20);
108                 unsigned ret = read_bits(&source, 16);
109                 assert(ret == 0x678f);
110                 ret = read_bits(&source, 4);
111                 assert(ret == 0xf);
112         }
113
114         assert(ud.bytes_left == 0);
115 }
116
117 int main(void)
118 {
119         printf("test_basic_reading()\n");
120         test_basic_reading();
121         
122         printf("test_slow_source()\n");
123         test_slow_source();
124         
125         printf("test_variable_size()\n");
126         test_variable_size();
127         
128         printf("All tests pass.\n");
129         return 0;
130 }