| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 | 
							- /* Decode a message using callbacks inside oneof fields */
 
- #include <stdio.h>
 
- #include <stdlib.h>
 
- #include <string.h>
 
- #include <pb_decode.h>
 
- #include <assert.h>
 
- #include "oneof.pb.h"
 
- #include "test_helpers.h"
 
- #include "unittests.h"
 
- /* This is a nanopb-0.4 style global callback, that is referred by function name
 
-  * and does not have to be bound separately to the message. It also allows defining
 
-  * a custom data type for the field in the structure.
 
-  */
 
- bool SubMsg3_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_t *field)
 
- {
 
-     if (istream && field->tag == SubMsg3_strvalue_tag)
 
-     {
 
-         /* We could e.g. malloc some memory and assign it to our custom datatype
 
-          * in the message structure here, accessible by field->pData. But in
 
-          * this example we just print the string directly.
 
-          */
 
-         uint8_t buffer[64];
 
-         int strlen = istream->bytes_left;
 
-         if (strlen > sizeof(buffer) - 1)
 
-             return false;
 
-         buffer[strlen] = '\0';
 
-         if (!pb_read(istream, buffer, strlen))
 
-             return false;
 
-         printf("  strvalue: \"%s\"\n", buffer);
 
-     }
 
-     return true;
 
- }
 
- /* The two callbacks below are traditional callbacks that use function pointers
 
-  * defined in pb_callback_t.
 
-  */
 
- bool print_int32(pb_istream_t *stream, const pb_field_t *field, void **arg)
 
- {
 
-     uint64_t value;
 
-     if (!pb_decode_varint(stream, &value))
 
-         return false;
 
-     printf((char*)*arg, (int)value);
 
-     return true;
 
- }
 
- bool print_string(pb_istream_t *stream, const pb_field_t *field, void **arg)
 
- {
 
-     uint8_t buffer[64];
 
-     int strlen = stream->bytes_left;
 
-     if (strlen > sizeof(buffer) - 1)
 
-         return false;
 
-     buffer[strlen] = '\0';
 
-     if (!pb_read(stream, buffer, strlen))
 
-         return false;
 
-     /* Print the string, in format comparable with protoc --decode.
 
-      * Format comes from the arg defined in main().
 
-      */
 
-     printf((char*)*arg, buffer);
 
-     return true;
 
- }
 
- /* The callback below is a message-level callback which is called before each
 
-  * submessage is encoded. It is used to set the pb_callback_t callbacks inside
 
-  * the submessage. The reason we need this is that different submessages share
 
-  * storage inside oneof union, and before we know the message type we can't set
 
-  * the callbacks without overwriting each other.
 
-  */
 
- bool msg_callback(pb_istream_t *stream, const pb_field_t *field, void **arg)
 
- {
 
-     /* Print the prefix field before the submessages.
 
-      * This also demonstrates how to access the top level message fields
 
-      * from callbacks.
 
-      */
 
-     OneOfMessage *topmsg = field->message;
 
-     printf("prefix: %d\n", (int)topmsg->prefix);
 
-     if (field->tag == OneOfMessage_submsg1_tag)
 
-     {
 
-         SubMsg1 *msg = field->pData;
 
-         printf("submsg1 {\n");
 
-         msg->array.funcs.decode = print_int32;
 
-         msg->array.arg = "  array: %d\n";
 
-     }
 
-     else if (field->tag == OneOfMessage_submsg2_tag)
 
-     {
 
-         SubMsg2 *msg = field->pData;
 
-         printf("submsg2 {\n");
 
-         msg->strvalue.funcs.decode = print_string;
 
-         msg->strvalue.arg = "  strvalue: \"%s\"\n";
 
-     }
 
-     else if (field->tag == OneOfMessage_submsg3_tag)
 
-     {
 
-         /* Because SubMsg3 callback is bound by function name, we do not
 
-          * need to initialize anything here. But we just print a string
 
-          * to get protoc-equivalent formatted output from the testcase.
 
-          */
 
-         printf("submsg3 {\n");
 
-     }
 
-     /* Once we return true, pb_dec_submessage() will go on to decode the
 
-      * submessage contents. But if we want, we can also decode it ourselves
 
-      * above and leave stream->bytes_left at 0 value, inhibiting automatic
 
-      * decoding.
 
-      */
 
-     return true;
 
- }
 
- int main(int argc, char **argv)
 
- {
 
-     uint8_t buffer[256];
 
-     OneOfMessage msg = OneOfMessage_init_zero;
 
-     pb_istream_t stream;
 
-     size_t count;
 
-     SET_BINARY_MODE(stdin);
 
-     count = fread(buffer, 1, sizeof(buffer), stdin);
 
-     if (!feof(stdin))
 
-     {
 
-         fprintf(stderr, "Message does not fit in buffer\n");
 
-         return 1;
 
-     }
 
-     /* Set up the cb_values callback, which will in turn set up the callbacks
 
-      * for each oneof field once the field tag is known. */
 
-     msg.cb_values.funcs.decode = msg_callback;
 
-     stream = pb_istream_from_buffer(buffer, count);
 
-     if (!pb_decode(&stream, OneOfMessage_fields, &msg))
 
-     {
 
-         fprintf(stderr, "Decoding failed: %s\n", PB_GET_ERROR(&stream));
 
-         return 1;
 
-     }
 
-     /* This is just printing for the test case logic */
 
-     if (msg.which_values == OneOfMessage_intvalue_tag)
 
-     {
 
-         printf("prefix: %d\n", (int)msg.prefix);
 
-         printf("intvalue: %d\n", (int)msg.values.intvalue);
 
-     }
 
-     else if (msg.which_values == OneOfMessage_strvalue_tag)
 
-     {
 
-         printf("prefix: %d\n", (int)msg.prefix);
 
-         printf("strvalue: \"%s\"\n", msg.values.strvalue);
 
-     }
 
-     else if (msg.which_values == OneOfMessage_submsg3_tag &&
 
-              msg.values.submsg3.which_values == SubMsg3_intvalue_tag)
 
-     {
 
-         printf("  intvalue: %d\n", (int)msg.values.submsg3.values.intvalue);
 
-         printf("}\n");
 
-     }
 
-     else
 
-     {
 
-         printf("}\n");
 
-     }
 
-     printf("suffix: %d\n", (int)msg.suffix);
 
-     assert(msg.prefix == 123);
 
-     assert(msg.suffix == 321);
 
-     return 0;
 
- }
 
 
  |