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