1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- /* This program reads a message from stdin, detects its type and decodes it.
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <pb_decode.h>
- #include <pb_common.h>
- #include "unionproto.pb.h"
- /* This function reads manually the first tag from the stream and finds the
- * corresponding message type. It doesn't yet decode the actual message.
- *
- * Returns a pointer to the MsgType_fields array, as an identifier for the
- * message type. Returns null if the tag is of unknown type or an error occurs.
- */
- const pb_msgdesc_t* decode_unionmessage_type(pb_istream_t *stream)
- {
- pb_wire_type_t wire_type;
- uint32_t tag;
- bool eof;
- while (pb_decode_tag(stream, &wire_type, &tag, &eof))
- {
- if (wire_type == PB_WT_STRING)
- {
- pb_field_iter_t iter;
- if (pb_field_iter_begin(&iter, UnionMessage_fields, NULL) &&
- pb_field_iter_find(&iter, tag))
- {
- /* Found our field. */
- return iter.submsg_desc;
- }
- }
-
- /* Wasn't our field.. */
- pb_skip_field(stream, wire_type);
- }
-
- return NULL;
- }
- bool decode_unionmessage_contents(pb_istream_t *stream, const pb_msgdesc_t *messagetype, void *dest_struct)
- {
- pb_istream_t substream;
- bool status;
- if (!pb_make_string_substream(stream, &substream))
- return false;
-
- status = pb_decode(&substream, messagetype, dest_struct);
- pb_close_string_substream(stream, &substream);
- return status;
- }
- int main()
- {
- /* Read the data into buffer */
- uint8_t buffer[512];
- size_t count = fread(buffer, 1, sizeof(buffer), stdin);
- pb_istream_t stream = pb_istream_from_buffer(buffer, count);
-
- const pb_msgdesc_t *type = decode_unionmessage_type(&stream);
- bool status = false;
-
- if (type == MsgType1_fields)
- {
- MsgType1 msg = {};
- status = decode_unionmessage_contents(&stream, MsgType1_fields, &msg);
- printf("Got MsgType1: %d\n", msg.value);
- }
- else if (type == MsgType2_fields)
- {
- MsgType2 msg = {};
- status = decode_unionmessage_contents(&stream, MsgType2_fields, &msg);
- printf("Got MsgType2: %s\n", msg.value ? "true" : "false");
- }
- else if (type == MsgType3_fields)
- {
- MsgType3 msg = {};
- status = decode_unionmessage_contents(&stream, MsgType3_fields, &msg);
- printf("Got MsgType3: %d %d\n", msg.value1, msg.value2);
- }
-
- if (!status)
- {
- printf("Decode failed: %s\n", PB_GET_ERROR(&stream));
- return 1;
- }
-
- return 0;
- }
|