mirror of
https://github.com/google/pebble.git
synced 2025-03-20 19:01:21 +00:00
96 lines
2.6 KiB
C
96 lines
2.6 KiB
C
|
/* 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;
|
||
|
}
|
||
|
|
||
|
|
||
|
|