1 /* Decode a message using oneof fields */
2 
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <pb_decode.h>
7 #include "oneof.pb.h"
8 #include "test_helpers.h"
9 #include "unittests.h"
10 
11 /* Test the 'OneOfMessage' */
test_oneof_1(pb_istream_t * stream,int option)12 int test_oneof_1(pb_istream_t *stream, int option)
13 {
14     OneOfMessage msg;
15     int status = 0;
16 
17     /* To better catch initialization errors */
18     memset(&msg, 0xAA, sizeof(msg));
19 
20     if (!pb_decode(stream, OneOfMessage_fields, &msg))
21     {
22         printf("Decoding failed: %s\n", PB_GET_ERROR(stream));
23         return 1;
24     }
25 
26     /* Check that the basic fields work normally */
27     TEST(msg.prefix == 123);
28     TEST(msg.suffix == 321);
29 
30     /* Check that we got the right oneof according to command line */
31     if (option == 1)
32     {
33         TEST(msg.which_values == OneOfMessage_first_tag);
34         TEST(msg.values.first == 999);
35     }
36     else if (option == 2)
37     {
38         TEST(msg.which_values == OneOfMessage_second_tag);
39         TEST(strcmp(msg.values.second, "abcd") == 0);
40     }
41     else if (option == 3)
42     {
43         TEST(msg.which_values == OneOfMessage_third_tag);
44         TEST(msg.values.third.array[0] == 1);
45         TEST(msg.values.third.array[1] == 2);
46         TEST(msg.values.third.array[2] == 3);
47         TEST(msg.values.third.array[3] == 4);
48         TEST(msg.values.third.array[4] == 5);
49     }
50 
51     return status;
52 }
53 
54 
55 /* Test the 'PlainOneOfMessage' */
test_oneof_2(pb_istream_t * stream,int option)56 int test_oneof_2(pb_istream_t *stream, int option)
57 {
58     PlainOneOfMessage msg = PlainOneOfMessage_init_zero;
59     int status = 0;
60 
61     if (!pb_decode(stream, PlainOneOfMessage_fields, &msg))
62     {
63         printf("Decoding failed: %s\n", PB_GET_ERROR(stream));
64         return 1;
65     }
66 
67     /* Check that we got the right oneof according to command line */
68     if (option == 1)
69     {
70         TEST(msg.which_values == OneOfMessage_first_tag);
71         TEST(msg.values.first == 999);
72     }
73     else if (option == 2)
74     {
75         TEST(msg.which_values == OneOfMessage_second_tag);
76         TEST(strcmp(msg.values.second, "abcd") == 0);
77     }
78     else if (option == 3)
79     {
80         TEST(msg.which_values == OneOfMessage_third_tag);
81         TEST(msg.values.third.array[0] == 1);
82         TEST(msg.values.third.array[1] == 2);
83         TEST(msg.values.third.array[2] == 3);
84         TEST(msg.values.third.array[3] == 4);
85         TEST(msg.values.third.array[4] == 5);
86     }
87 
88     return status;
89 }
90 
main(int argc,char ** argv)91 int main(int argc, char **argv)
92 {
93     uint8_t buffer[OneOfMessage_size];
94     size_t count;
95     int option;
96 
97     if (argc != 2)
98     {
99         fprintf(stderr, "Usage: decode_oneof [number]\n");
100         return 1;
101     }
102     option = atoi(argv[1]);
103 
104     SET_BINARY_MODE(stdin);
105     count = fread(buffer, 1, sizeof(buffer), stdin);
106 
107     if (!feof(stdin))
108     {
109         printf("Message does not fit in buffer\n");
110         return 1;
111     }
112 
113     {
114         int status = 0;
115         pb_istream_t stream;
116 
117         stream = pb_istream_from_buffer(buffer, count);
118         status = test_oneof_1(&stream, option);
119 
120         if (status != 0)
121             return status;
122 
123         stream = pb_istream_from_buffer(buffer, count);
124         status = test_oneof_2(&stream, option);
125 
126         if (status != 0)
127             return status;
128     }
129 
130     return 0;
131 }
132