1 /* This program reads a message from stdin, detects its type and decodes it.
9 #include "unionproto.pb.h"
11 /* This function reads manually the first tag from the stream and finds the
12 * corresponding message type. It doesn't yet decode the actual message.
14 * Returns a pointer to the MsgType_fields array, as an identifier for the
15 * message type. Returns null if the tag is of unknown type or an error occurs.
17 const pb_field_t* decode_unionmessage_type(pb_istream_t *stream)
19 pb_wire_type_t wire_type;
23 while (pb_decode_tag(stream, &wire_type, &tag, &eof))
25 if (wire_type == PB_WT_STRING)
27 const pb_field_t *field;
28 for (field = UnionMessage_fields; field->tag != 0; field++)
30 if (field->tag == tag && (field->type & PB_LTYPE_SUBMESSAGE))
32 /* Found our field. */
38 /* Wasn't our field.. */
39 pb_skip_field(stream, wire_type);
45 bool decode_unionmessage_contents(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)
47 pb_field_t field = {}; /* NB: Could get rid of this wrapper by fixing issue #2. */
50 return pb_dec_submessage(stream, &field, dest_struct);
55 /* Read the data into buffer */
57 size_t count = fread(buffer, 1, sizeof(buffer), stdin);
58 pb_istream_t stream = pb_istream_from_buffer(buffer, count);
60 const pb_field_t *type = decode_unionmessage_type(&stream);
63 if (type == MsgType1_fields)
66 status = decode_unionmessage_contents(&stream, MsgType1_fields, &msg);
67 printf("Got MsgType1: %d\n", msg.value);
69 else if (type == MsgType2_fields)
72 status = decode_unionmessage_contents(&stream, MsgType2_fields, &msg);
73 printf("Got MsgType2: %s\n", msg.value ? "true" : "false");
75 else if (type == MsgType3_fields)
78 status = decode_unionmessage_contents(&stream, MsgType3_fields, &msg);
79 printf("Got MsgType3: %d %d\n", msg.value1, msg.value2);
84 printf("Decoding failed.\n");