MOS Source Code
Loading...
Searching...
No Matches
decode.c
Go to the documentation of this file.
1/* This program reads a message from stdin, detects its type and decodes it.
2 */
3
4#include <stdio.h>
5#include <string.h>
6#include <stdlib.h>
7
8#include <pb_decode.h>
9#include <pb_common.h>
10#include "unionproto.pb.h"
11
12/* This function reads manually the first tag from the stream and finds the
13 * corresponding message type. It doesn't yet decode the actual message.
14 *
15 * Returns a pointer to the MsgType_fields array, as an identifier for the
16 * message type. Returns null if the tag is of unknown type or an error occurs.
17 */
18const pb_msgdesc_t* decode_unionmessage_type(pb_istream_t *stream)
19{
20 pb_wire_type_t wire_type;
21 uint32_t tag;
22 bool eof;
23
24 while (pb_decode_tag(stream, &wire_type, &tag, &eof))
25 {
26 if (wire_type == PB_WT_STRING)
27 {
28 pb_field_iter_t iter;
29 if (pb_field_iter_begin(&iter, UnionMessage_fields, NULL) &&
30 pb_field_iter_find(&iter, tag))
31 {
32 /* Found our field. */
33 return iter.submsg_desc;
34 }
35 }
36
37 /* Wasn't our field.. */
38 pb_skip_field(stream, wire_type);
39 }
40
41 return NULL;
42}
43
44bool decode_unionmessage_contents(pb_istream_t *stream, const pb_msgdesc_t *messagetype, void *dest_struct)
45{
46 pb_istream_t substream;
47 bool status;
48 if (!pb_make_string_substream(stream, &substream))
49 return false;
50
51 status = pb_decode(&substream, messagetype, dest_struct);
52 pb_close_string_substream(stream, &substream);
53 return status;
54}
55
56int main()
57{
58 /* Read the data into buffer */
59 uint8_t buffer[512];
60 size_t count = fread(buffer, 1, sizeof(buffer), stdin);
61 pb_istream_t stream = pb_istream_from_buffer(buffer, count);
62
63 const pb_msgdesc_t *type = decode_unionmessage_type(&stream);
64 bool status = false;
65
66 if (type == MsgType1_fields)
67 {
68 MsgType1 msg = {};
69 status = decode_unionmessage_contents(&stream, MsgType1_fields, &msg);
70 printf("Got MsgType1: %d\n", msg.value);
71 }
72 else if (type == MsgType2_fields)
73 {
74 MsgType2 msg = {};
75 status = decode_unionmessage_contents(&stream, MsgType2_fields, &msg);
76 printf("Got MsgType2: %s\n", msg.value ? "true" : "false");
77 }
78 else if (type == MsgType3_fields)
79 {
80 MsgType3 msg = {};
81 status = decode_unionmessage_contents(&stream, MsgType3_fields, &msg);
82 printf("Got MsgType3: %d %d\n", msg.value1, msg.value2);
83 }
84
85 if (!status)
86 {
87 printf("Decode failed: %s\n", PB_GET_ERROR(&stream));
88 return 1;
89 }
90
91 return 0;
92}
93
94
95
bool decode_unionmessage_contents(pb_istream_t *stream, const pb_msgdesc_t *messagetype, void *dest_struct)
Definition decode.c:44
const pb_msgdesc_t * decode_unionmessage_type(pb_istream_t *stream)
Definition decode.c:18
int main()
Definition decode.c:56
size_t fread(void *__restrict ptr, size_t size, size_t nmemb, FILE *__restrict stream)
#define stdin
Definition mos_stdio.h:30
#define PB_GET_ERROR(stream)
Definition pb.h:891
pb_wire_type_t
Definition pb.h:420
@ PB_WT_STRING
Definition pb.h:423
bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_msgdesc_t *desc, void *message)
Definition pb_common.c:156
bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag)
Definition pb_common.c:195
bool pb_decode(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct)
Definition pb_decode.c:1182
bool pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream)
Definition pb_decode.c:362
pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t msglen)
Definition pb_decode.c:143
bool pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type)
Definition pb_decode.c:308
bool pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream)
Definition pb_decode.c:377
bool pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof)
Definition pb_decode.c:291
#define NULL
Definition pb_syshdr.h:46
unsigned int uint32_t
Definition pb_syshdr.h:24
unsigned char uint8_t
Definition pb_syshdr.h:20
static char buffer[2048]
Definition test_printf.c:7