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