Documenting and improving stream behaviour
[apps/agl-service-can-low-level.git] / tests / decode_unittests.c
1 #include <stdio.h>
2 #include <string.h>
3 #include "pb_decode.h"
4 #include "unittests.h"
5
6 #define S(x) pb_istream_from_buffer((uint8_t*)x, sizeof(x))
7
8 bool stream_callback(pb_istream_t *stream, uint8_t *buf, size_t count)
9 {
10     if (stream->state != NULL)
11         return false; /* Simulate error */
12     
13     if (buf != NULL)
14         memset(buf, 'x', count);
15     return true;
16 }
17
18 int main()
19 {
20     int status = 0;
21     
22     {
23         uint8_t buffer1[] = "foobartest1234";
24         uint8_t buffer2[sizeof(buffer1)];
25         pb_istream_t stream = pb_istream_from_buffer(buffer1, sizeof(buffer1));
26         
27         COMMENT("Test pb_read and pb_istream_t");
28         TEST(pb_read(&stream, buffer2, 6))
29         TEST(memcmp(buffer2, "foobar", 6) == 0)
30         TEST(stream.bytes_left == sizeof(buffer1) - 6)
31         TEST(pb_read(&stream, buffer2 + 6, stream.bytes_left))
32         TEST(memcmp(buffer1, buffer2, sizeof(buffer1)) == 0)
33         TEST(stream.bytes_left == 0)
34         TEST(!pb_read(&stream, buffer2, 1))
35     }
36     
37     {
38         uint8_t buffer[20];
39         pb_istream_t stream = {&stream_callback, NULL, 20};
40         
41         COMMENT("Test pb_read with custom callback");
42         TEST(pb_read(&stream, buffer, 5))
43         TEST(memcmp(buffer, "xxxxx", 5) == 0)
44         TEST(!pb_read(&stream, buffer, 50))
45         stream.state = (void*)1; /* Simulated error return from callback */
46         TEST(!pb_read(&stream, buffer, 5))
47         stream.state = NULL;
48         TEST(pb_read(&stream, buffer, 15))
49     }
50     
51     {
52         pb_istream_t s;
53         uint32_t u;
54         int32_t i;
55         
56         COMMENT("Test pb_decode_varint32");
57         TEST((s = S("\x00"), pb_decode_varint32(&s, &u) && u == 0));
58         TEST((s = S("\x01"), pb_decode_varint32(&s, &u) && u == 1));
59         TEST((s = S("\xAC\x02"), pb_decode_varint32(&s, &u) && u == 300));
60         TEST((s = S("\xFF\xFF\xFF\xFF\x0F"), pb_decode_varint32(&s, &u) && u == UINT32_MAX));
61         TEST((s = S("\xFF\xFF\xFF\xFF\x0F"), pb_decode_varint32(&s, (uint32_t*)&i) && i == -1));
62     }
63     
64     {
65         pb_istream_t s;
66         uint64_t u;
67         int64_t i;
68         
69         COMMENT("Test pb_decode_varint64");
70         TEST((s = S("\x00"), pb_decode_varint64(&s, &u) && u == 0));
71         TEST((s = S("\x01"), pb_decode_varint64(&s, &u) && u == 1));
72         TEST((s = S("\xAC\x02"), pb_decode_varint64(&s, &u) && u == 300));
73         TEST((s = S("\xFF\xFF\xFF\xFF\x0F"), pb_decode_varint64(&s, &u) && u == UINT32_MAX));
74         TEST((s = S("\xFF\xFF\xFF\xFF\x0F"), pb_decode_varint64(&s, (uint64_t*)&i) && i == UINT32_MAX));
75         TEST((s = S("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"),
76               pb_decode_varint64(&s, (uint64_t*)&i) && i == -1));
77         TEST((s = S("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"),
78               pb_decode_varint64(&s, &u) && u == UINT64_MAX));
79     }
80     
81     {
82         pb_istream_t s;
83         COMMENT("Test pb_skip_varint");
84         TEST((s = S("\x00""foobar"), pb_skip_varint(&s) && s.bytes_left == 7))
85         TEST((s = S("\xAC\x02""foobar"), pb_skip_varint(&s) && s.bytes_left == 7))
86         TEST((s = S("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01""foobar"),
87               pb_skip_varint(&s) && s.bytes_left == 7))
88     }
89     
90     {
91         pb_istream_t s;
92         COMMENT("Test pb_skip_string")
93         TEST((s = S("\x00""foobar"), pb_skip_string(&s) && s.bytes_left == 7))
94         TEST((s = S("\x04""testfoobar"), pb_skip_string(&s) && s.bytes_left == 7))
95     }
96     
97     {
98         pb_istream_t s = S("\x01\xFF\xFF\x03");
99         pb_field_t f = {1, PB_LTYPE_VARINT, 0, 0, 4, 0, 0};
100         uint32_t d;
101         COMMENT("Test pb_dec_varint using uint32_t")
102         TEST(pb_dec_varint(&s, &f, &d) && d == 1)
103         
104         /* Verify that no more than data_size is written. */
105         d = 0;
106         f.data_size = 1;
107         TEST(pb_dec_varint(&s, &f, &d) && (d == 0xFF || d == 0xFF000000))
108     }
109     
110     {
111         pb_istream_t s;
112         pb_field_t f = {1, PB_LTYPE_SVARINT, 0, 0, 4, 0, 0};
113         int32_t d;
114         
115         COMMENT("Test pb_dec_svarint using int32_t")
116         TEST((s = S("\x01"), pb_dec_svarint(&s, &f, &d) && d == -1))
117         TEST((s = S("\x02"), pb_dec_svarint(&s, &f, &d) && d == 1))
118         TEST((s = S("\xfe\xff\xff\xff\x0f"), pb_dec_svarint(&s, &f, &d) && d == INT32_MAX))
119         TEST((s = S("\xff\xff\xff\xff\x0f"), pb_dec_svarint(&s, &f, &d) && d == INT32_MIN))
120     }
121     
122     {
123         pb_istream_t s;
124         pb_field_t f = {1, PB_LTYPE_SVARINT, 0, 0, 8, 0, 0};
125         uint64_t d;
126         
127         COMMENT("Test pb_dec_svarint using uint64_t")
128         TEST((s = S("\x01"), pb_dec_svarint(&s, &f, &d) && d == -1))
129         TEST((s = S("\x02"), pb_dec_svarint(&s, &f, &d) && d == 1))
130         TEST((s = S("\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"), pb_dec_svarint(&s, &f, &d) && d == INT64_MAX))
131         TEST((s = S("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"), pb_dec_svarint(&s, &f, &d) && d == INT64_MIN))
132     }
133     
134     if (status != 0)
135         fprintf(stdout, "\n\nSome tests FAILED!\n");
136     
137     return status;
138 }