1 /* Decode a message using msgid prefix to identify message type */
2 
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <pb_decode.h>
6 #include "msgid_example.pb.h"
7 #include "test_helpers.h"
8 
9 /* This function reads the prefix written by sending side. */
read_prefix(pb_istream_t * stream,int * msgid)10 bool read_prefix(pb_istream_t *stream, int *msgid)
11 {
12     uint8_t prefix = 0;
13 
14     if (!pb_read(stream, &prefix, 1))
15         return false;
16 
17     *msgid = prefix;
18     return true;
19 }
20 
21 /* Main function will call one of these functions based on the prefix */
22 
handle_MyMessage1(pb_istream_t * stream)23 bool handle_MyMessage1(pb_istream_t *stream)
24 {
25     MyMessage1 msg = MyMessage1_init_default;
26 
27     if (!pb_decode(stream, MyMessage1_fields, &msg))
28         return false;
29 
30     printf("Got MyMessage1: intvalue = %d\n", (int)msg.intvalue);
31     return true;
32 }
33 
handle_MyMessage2(pb_istream_t * stream)34 bool handle_MyMessage2(pb_istream_t *stream)
35 {
36     MyMessage2 msg = MyMessage2_init_default;
37 
38     if (!pb_decode(stream, MyMessage2_fields, &msg))
39         return false;
40 
41     printf("Got MyMessage2: intvalue = %d, strvalue = %s\n",
42            (int)msg.intvalue, msg.strvalue);
43     return true;
44 }
45 
handle_MyMessage3(pb_istream_t * stream)46 bool handle_MyMessage3(pb_istream_t *stream)
47 {
48     MyMessage3 msg = MyMessage3_init_default;
49 
50     if (!pb_decode(stream, MyMessage3_fields, &msg))
51         return false;
52 
53     printf("Got MyMessage3: boolvalue = %d\n", (int)msg.boolvalue);
54     return true;
55 }
56 
main(int argc,char ** argv)57 int main(int argc, char **argv)
58 {
59     uint8_t buffer[128];
60     pb_istream_t stream;
61     size_t count;
62     bool status = false;
63     int prefix;
64 
65     /* Read the data into buffer */
66     SET_BINARY_MODE(stdin);
67     count = fread(buffer, 1, sizeof(buffer), stdin);
68 
69     if (!feof(stdin))
70     {
71         printf("Message does not fit in buffer\n");
72         return 1;
73     }
74 
75     stream = pb_istream_from_buffer(buffer, count);
76 
77     if (!read_prefix(&stream, &prefix))
78     {
79         printf("Failed to read prefix: %s\n", PB_GET_ERROR(&stream));
80         return 1;
81     }
82 
83     /* Call message handler based on prefix.
84      * We could write the switch cases manually, comparing against
85      * the MyMessageX_msgid defines. However, this uses the automatically
86      * generated X-macro construct to make the switch case.
87      */
88 
89     switch (prefix)
90     {
91         #define PB_MSG(id,len,name) case id: status = handle_ ## name(&stream); break;
92         MSGID_EXAMPLE_MESSAGES
93         #undef PB_MSG
94 
95         default: printf("Unknown prefix: %d\n", prefix); return 1;
96     }
97 
98     if (!status)
99     {
100         printf("Parsing failed: %s\n", PB_GET_ERROR(&stream));
101         return 1;
102     } else {
103         return 0;
104     }
105 }
106