1 #include <stdio.h>
2 #include <string.h>
3 #include <pb_decode.h>
4 #include <pb_encode.h>
5 #include "unittests.h"
6 #include "intsizes.pb.h"
7 
8 #define S(x) pb_istream_from_buffer((uint8_t*)x, sizeof(x) - 1)
9 
10 /* This is a macro instead of function in order to get the actual values
11  * into the TEST() lines in output */
12 #define TEST_ROUNDTRIP(int8, uint8, sint8, \
13                        int16, uint16, sint16, \
14                        int32, uint32, sint32, \
15                        int64, uint64, sint64, expected_result) \
16 {                                                                           \
17     uint8_t buffer1[128], buffer2[128];                                     \
18     size_t msgsize;                                                         \
19     DefaultSizes msg1 = DefaultSizes_init_zero;                             \
20     IntSizes msg2 = IntSizes_init_zero;                                     \
21                                                                             \
22     msg1.req_int8   = int8;                                                 \
23     msg1.req_uint8  = uint8;                                                \
24     msg1.req_sint8  = sint8;                                                \
25     msg1.req_int16  = int16;                                                \
26     msg1.req_uint16 = uint16;                                               \
27     msg1.req_sint16 = sint16;                                               \
28     msg1.req_int32  = int32;                                                \
29     msg1.req_uint32 = uint32;                                               \
30     msg1.req_sint32 = sint32;                                               \
31     msg1.req_int64  = int64;                                                \
32     msg1.req_uint64 = uint64;                                               \
33     msg1.req_sint64 = sint64;                                               \
34                                                                             \
35     {                                                                       \
36         pb_ostream_t s = pb_ostream_from_buffer(buffer1, sizeof(buffer1));  \
37         TEST(pb_encode(&s, DefaultSizes_fields, &msg1));                    \
38         msgsize = s.bytes_written;                                          \
39     }                                                                       \
40                                                                             \
41     {                                                                       \
42         pb_istream_t s = pb_istream_from_buffer(buffer1, msgsize);          \
43         TEST(pb_decode(&s, IntSizes_fields, &msg2) == expected_result);     \
44         if (expected_result)                                                \
45         {                                                                   \
46             TEST( (int64_t)msg2.req_int8   == int8);                        \
47             TEST((uint64_t)msg2.req_uint8  == uint8);                       \
48             TEST( (int64_t)msg2.req_sint8  == sint8);                       \
49             TEST( (int64_t)msg2.req_int16  == int16);                       \
50             TEST((uint64_t)msg2.req_uint16 == uint16);                      \
51             TEST( (int64_t)msg2.req_sint16 == sint16);                      \
52             TEST( (int64_t)msg2.req_int32  == int32);                       \
53             TEST((uint64_t)msg2.req_uint32 == uint32);                      \
54             TEST( (int64_t)msg2.req_sint32 == sint32);                      \
55             TEST( (int64_t)msg2.req_int64  == int64);                       \
56             TEST((uint64_t)msg2.req_uint64 == uint64);                      \
57             TEST( (int64_t)msg2.req_sint64 == sint64);                      \
58         }                                                                   \
59     }                                                                       \
60                                                                             \
61     if (expected_result)                                                    \
62     {                                                                       \
63         pb_ostream_t s = pb_ostream_from_buffer(buffer2, sizeof(buffer2));  \
64         TEST(pb_encode(&s, IntSizes_fields, &msg2));                        \
65         TEST(s.bytes_written == msgsize);                                   \
66         TEST(memcmp(buffer1, buffer2, msgsize) == 0);                       \
67     }                                                                       \
68 }
69 
70 int main()
71 {
72     int status = 0;
73 
74     {
75         IntSizes msg = IntSizes_init_zero;
76 
77         COMMENT("Test field sizes");
78         TEST(sizeof(msg.req_int8) == 1);
79         TEST(sizeof(msg.req_uint8) == 1);
80         TEST(sizeof(msg.req_sint8) == 1);
81         TEST(sizeof(msg.req_int16) == 2);
82         TEST(sizeof(msg.req_uint16) == 2);
83         TEST(sizeof(msg.req_sint16) == 2);
84         TEST(sizeof(msg.req_int32) == 4);
85         TEST(sizeof(msg.req_uint32) == 4);
86         TEST(sizeof(msg.req_sint32) == 4);
87         TEST(sizeof(msg.req_int64) == 8);
88         TEST(sizeof(msg.req_uint64) == 8);
89         TEST(sizeof(msg.req_sint64) == 8);
90     }
91 
92     COMMENT("Test roundtrip at maximum value");
93     TEST_ROUNDTRIP(127,     255,    127,
94                    32767, 65535,  32767,
95                    INT32_MAX, UINT32_MAX, INT32_MAX,
96                    INT64_MAX, UINT64_MAX, INT64_MAX, true);
97 
98     COMMENT("Test roundtrip at minimum value");
99     TEST_ROUNDTRIP(-128,      0,   -128,
100                    -32768,    0, -32768,
101                    INT32_MIN, 0, INT32_MIN,
102                    INT64_MIN, 0, INT64_MIN, true);
103 
104     COMMENT("Test overflow detection");
105     TEST_ROUNDTRIP(-129,      0,   -128,
106                    -32768,    0, -32768,
107                    INT32_MIN, 0, INT32_MIN,
108                    INT64_MIN, 0, INT64_MIN, false);
109     TEST_ROUNDTRIP(127,     256,    127,
110                    32767, 65535,  32767,
111                    INT32_MAX, UINT32_MAX, INT32_MAX,
112                    INT64_MAX, UINT64_MAX, INT64_MAX, false);
113     TEST_ROUNDTRIP(-128,      0,   -128,
114                    -32768,    0, -32769,
115                    INT32_MIN, 0, INT32_MIN,
116                    INT64_MIN, 0, INT64_MIN, false);
117 
118     if (status != 0)
119         fprintf(stdout, "\n\nSome tests FAILED!\n");
120 
121     return status;
122 }