1*c8d645caSAndroid Build Coastguard Worker /* This program reads a message from stdin, detects its type and decodes it.
2*c8d645caSAndroid Build Coastguard Worker */
3*c8d645caSAndroid Build Coastguard Worker
4*c8d645caSAndroid Build Coastguard Worker #include <stdio.h>
5*c8d645caSAndroid Build Coastguard Worker #include <string.h>
6*c8d645caSAndroid Build Coastguard Worker #include <stdlib.h>
7*c8d645caSAndroid Build Coastguard Worker
8*c8d645caSAndroid Build Coastguard Worker #include <pb_decode.h>
9*c8d645caSAndroid Build Coastguard Worker #include "unionproto.pb.h"
10*c8d645caSAndroid Build Coastguard Worker
11*c8d645caSAndroid Build Coastguard Worker /* This function reads manually the first tag from the stream and finds the
12*c8d645caSAndroid Build Coastguard Worker * corresponding message type. It doesn't yet decode the actual message.
13*c8d645caSAndroid Build Coastguard Worker *
14*c8d645caSAndroid Build Coastguard Worker * Returns a pointer to the MsgType_fields array, as an identifier for the
15*c8d645caSAndroid Build Coastguard Worker * message type. Returns null if the tag is of unknown type or an error occurs.
16*c8d645caSAndroid Build Coastguard Worker */
decode_unionmessage_type(pb_istream_t * stream)17*c8d645caSAndroid Build Coastguard Worker const pb_field_t* decode_unionmessage_type(pb_istream_t *stream)
18*c8d645caSAndroid Build Coastguard Worker {
19*c8d645caSAndroid Build Coastguard Worker pb_wire_type_t wire_type;
20*c8d645caSAndroid Build Coastguard Worker uint32_t tag;
21*c8d645caSAndroid Build Coastguard Worker bool eof;
22*c8d645caSAndroid Build Coastguard Worker
23*c8d645caSAndroid Build Coastguard Worker while (pb_decode_tag(stream, &wire_type, &tag, &eof))
24*c8d645caSAndroid Build Coastguard Worker {
25*c8d645caSAndroid Build Coastguard Worker if (wire_type == PB_WT_STRING)
26*c8d645caSAndroid Build Coastguard Worker {
27*c8d645caSAndroid Build Coastguard Worker const pb_field_t *field;
28*c8d645caSAndroid Build Coastguard Worker for (field = UnionMessage_fields; field->tag != 0; field++)
29*c8d645caSAndroid Build Coastguard Worker {
30*c8d645caSAndroid Build Coastguard Worker if (field->tag == tag && (field->type & PB_LTYPE_SUBMESSAGE))
31*c8d645caSAndroid Build Coastguard Worker {
32*c8d645caSAndroid Build Coastguard Worker /* Found our field. */
33*c8d645caSAndroid Build Coastguard Worker return field->ptr;
34*c8d645caSAndroid Build Coastguard Worker }
35*c8d645caSAndroid Build Coastguard Worker }
36*c8d645caSAndroid Build Coastguard Worker }
37*c8d645caSAndroid Build Coastguard Worker
38*c8d645caSAndroid Build Coastguard Worker /* Wasn't our field.. */
39*c8d645caSAndroid Build Coastguard Worker pb_skip_field(stream, wire_type);
40*c8d645caSAndroid Build Coastguard Worker }
41*c8d645caSAndroid Build Coastguard Worker
42*c8d645caSAndroid Build Coastguard Worker return NULL;
43*c8d645caSAndroid Build Coastguard Worker }
44*c8d645caSAndroid Build Coastguard Worker
decode_unionmessage_contents(pb_istream_t * stream,const pb_field_t fields[],void * dest_struct)45*c8d645caSAndroid Build Coastguard Worker bool decode_unionmessage_contents(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)
46*c8d645caSAndroid Build Coastguard Worker {
47*c8d645caSAndroid Build Coastguard Worker pb_istream_t substream;
48*c8d645caSAndroid Build Coastguard Worker bool status;
49*c8d645caSAndroid Build Coastguard Worker if (!pb_make_string_substream(stream, &substream))
50*c8d645caSAndroid Build Coastguard Worker return false;
51*c8d645caSAndroid Build Coastguard Worker
52*c8d645caSAndroid Build Coastguard Worker status = pb_decode(&substream, fields, dest_struct);
53*c8d645caSAndroid Build Coastguard Worker pb_close_string_substream(stream, &substream);
54*c8d645caSAndroid Build Coastguard Worker return status;
55*c8d645caSAndroid Build Coastguard Worker }
56*c8d645caSAndroid Build Coastguard Worker
main()57*c8d645caSAndroid Build Coastguard Worker int main()
58*c8d645caSAndroid Build Coastguard Worker {
59*c8d645caSAndroid Build Coastguard Worker /* Read the data into buffer */
60*c8d645caSAndroid Build Coastguard Worker uint8_t buffer[512];
61*c8d645caSAndroid Build Coastguard Worker size_t count = fread(buffer, 1, sizeof(buffer), stdin);
62*c8d645caSAndroid Build Coastguard Worker pb_istream_t stream = pb_istream_from_buffer(buffer, count);
63*c8d645caSAndroid Build Coastguard Worker
64*c8d645caSAndroid Build Coastguard Worker const pb_field_t *type = decode_unionmessage_type(&stream);
65*c8d645caSAndroid Build Coastguard Worker bool status = false;
66*c8d645caSAndroid Build Coastguard Worker
67*c8d645caSAndroid Build Coastguard Worker if (type == MsgType1_fields)
68*c8d645caSAndroid Build Coastguard Worker {
69*c8d645caSAndroid Build Coastguard Worker MsgType1 msg = {};
70*c8d645caSAndroid Build Coastguard Worker status = decode_unionmessage_contents(&stream, MsgType1_fields, &msg);
71*c8d645caSAndroid Build Coastguard Worker printf("Got MsgType1: %d\n", msg.value);
72*c8d645caSAndroid Build Coastguard Worker }
73*c8d645caSAndroid Build Coastguard Worker else if (type == MsgType2_fields)
74*c8d645caSAndroid Build Coastguard Worker {
75*c8d645caSAndroid Build Coastguard Worker MsgType2 msg = {};
76*c8d645caSAndroid Build Coastguard Worker status = decode_unionmessage_contents(&stream, MsgType2_fields, &msg);
77*c8d645caSAndroid Build Coastguard Worker printf("Got MsgType2: %s\n", msg.value ? "true" : "false");
78*c8d645caSAndroid Build Coastguard Worker }
79*c8d645caSAndroid Build Coastguard Worker else if (type == MsgType3_fields)
80*c8d645caSAndroid Build Coastguard Worker {
81*c8d645caSAndroid Build Coastguard Worker MsgType3 msg = {};
82*c8d645caSAndroid Build Coastguard Worker status = decode_unionmessage_contents(&stream, MsgType3_fields, &msg);
83*c8d645caSAndroid Build Coastguard Worker printf("Got MsgType3: %d %d\n", msg.value1, msg.value2);
84*c8d645caSAndroid Build Coastguard Worker }
85*c8d645caSAndroid Build Coastguard Worker
86*c8d645caSAndroid Build Coastguard Worker if (!status)
87*c8d645caSAndroid Build Coastguard Worker {
88*c8d645caSAndroid Build Coastguard Worker printf("Decode failed: %s\n", PB_GET_ERROR(&stream));
89*c8d645caSAndroid Build Coastguard Worker return 1;
90*c8d645caSAndroid Build Coastguard Worker }
91*c8d645caSAndroid Build Coastguard Worker
92*c8d645caSAndroid Build Coastguard Worker return 0;
93*c8d645caSAndroid Build Coastguard Worker }
94*c8d645caSAndroid Build Coastguard Worker
95*c8d645caSAndroid Build Coastguard Worker
96*c8d645caSAndroid Build Coastguard Worker
97