1 /* This program takes a command line argument and encodes a message in
2  * one of MsgType1, MsgType2 or MsgType3.
3  */
4 
5 #include <stdio.h>
6 #include <string.h>
7 #include <stdlib.h>
8 
9 #include <pb_encode.h>
10 #include "unionproto.pb.h"
11 
12 /* This function is the core of the union encoding process. It handles
13  * the top-level pb_field_t array manually, in order to encode a correct
14  * field tag before the message. The pointer to MsgType_fields array is
15  * used as an unique identifier for the message type.
16  */
17 bool encode_unionmessage(pb_ostream_t *stream, const pb_field_t messagetype[], const void *message)
18 {
19     const pb_field_t *field;
20     for (field = UnionMessage_fields; field->tag != 0; field++)
21     {
22         if (field->ptr == messagetype)
23         {
24             /* This is our field, encode the message using it. */
25             if (!pb_encode_tag_for_field(stream, field))
26                 return false;
27 
28             return pb_encode_submessage(stream, messagetype, message);
29         }
30     }
31 
32     /* Didn't find the field for messagetype */
33     return false;
34 }
35 
36 int main(int argc, char **argv)
37 {
38     if (argc != 2)
39     {
40         fprintf(stderr, "Usage: %s (1|2|3)\n", argv[0]);
41         return 1;
42     }
43 
44     uint8_t buffer[512];
45     pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
46 
47     bool status = false;
48     int msgtype = atoi(argv[1]);
49     if (msgtype == 1)
50     {
51         /* Send message of type 1 */
52         MsgType1 msg = {42};
53         status = encode_unionmessage(&stream, MsgType1_fields, &msg);
54     }
55     else if (msgtype == 2)
56     {
57         /* Send message of type 2 */
58         MsgType2 msg = {true};
59         status = encode_unionmessage(&stream, MsgType2_fields, &msg);
60     }
61     else if (msgtype == 3)
62     {
63         /* Send message of type 3 */
64         MsgType3 msg = {3, 1415};
65         status = encode_unionmessage(&stream, MsgType3_fields, &msg);
66     }
67     else
68     {
69         fprintf(stderr, "Unknown message type: %d\n", msgtype);
70         return 2;
71     }
72 
73     if (!status)
74     {
75         fprintf(stderr, "Encoding failed!\n");
76         return 3;
77     }
78     else
79     {
80         fwrite(buffer, 1, stream.bytes_written, stdout);
81         return 0; /* Success */
82     }
83 }
84 
85 
86