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' */
12int 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' */
56int 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
91int 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