1 /* Decode a message using oneof fields */ 2 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <string.h> 6 #include <pb_decode.h> 7 #include "oneof.pb.h" 8 #include "test_helpers.h" 9 #include "unittests.h" 10 11 /* Test the 'OneOfMessage' */ 12 int test_oneof_1(pb_istream_t *stream, int option) 13 { 14 OneOfMessage msg; 15 int status = 0; 16 17 /* To better catch initialization errors */ 18 memset(&msg, 0xAA, sizeof(msg)); 19 20 if (!pb_decode(stream, OneOfMessage_fields, &msg)) 21 { 22 printf("Decoding failed: %s\n", PB_GET_ERROR(stream)); 23 return 1; 24 } 25 26 /* Check that the basic fields work normally */ 27 TEST(msg.prefix == 123); 28 TEST(msg.suffix == 321); 29 30 /* Check that we got the right oneof according to command line */ 31 if (option == 1) 32 { 33 TEST(msg.which_values == OneOfMessage_first_tag); 34 TEST(msg.values.first == 999); 35 } 36 else if (option == 2) 37 { 38 TEST(msg.which_values == OneOfMessage_second_tag); 39 TEST(strcmp(msg.values.second, "abcd") == 0); 40 } 41 else if (option == 3) 42 { 43 TEST(msg.which_values == OneOfMessage_third_tag); 44 TEST(msg.values.third.array[0] == 1); 45 TEST(msg.values.third.array[1] == 2); 46 TEST(msg.values.third.array[2] == 3); 47 TEST(msg.values.third.array[3] == 4); 48 TEST(msg.values.third.array[4] == 5); 49 } 50 51 return status; 52 } 53 54 55 /* Test the 'PlainOneOfMessage' */ 56 int test_oneof_2(pb_istream_t *stream, int option) 57 { 58 PlainOneOfMessage msg = PlainOneOfMessage_init_zero; 59 int status = 0; 60 61 if (!pb_decode(stream, PlainOneOfMessage_fields, &msg)) 62 { 63 printf("Decoding failed: %s\n", PB_GET_ERROR(stream)); 64 return 1; 65 } 66 67 /* Check that we got the right oneof according to command line */ 68 if (option == 1) 69 { 70 TEST(msg.which_values == OneOfMessage_first_tag); 71 TEST(msg.values.first == 999); 72 } 73 else if (option == 2) 74 { 75 TEST(msg.which_values == OneOfMessage_second_tag); 76 TEST(strcmp(msg.values.second, "abcd") == 0); 77 } 78 else if (option == 3) 79 { 80 TEST(msg.which_values == OneOfMessage_third_tag); 81 TEST(msg.values.third.array[0] == 1); 82 TEST(msg.values.third.array[1] == 2); 83 TEST(msg.values.third.array[2] == 3); 84 TEST(msg.values.third.array[3] == 4); 85 TEST(msg.values.third.array[4] == 5); 86 } 87 88 return status; 89 } 90 91 int main(int argc, char **argv) 92 { 93 uint8_t buffer[OneOfMessage_size]; 94 size_t count; 95 int option; 96 97 if (argc != 2) 98 { 99 fprintf(stderr, "Usage: decode_oneof [number]\n"); 100 return 1; 101 } 102 option = atoi(argv[1]); 103 104 SET_BINARY_MODE(stdin); 105 count = fread(buffer, 1, sizeof(buffer), stdin); 106 107 if (!feof(stdin)) 108 { 109 printf("Message does not fit in buffer\n"); 110 return 1; 111 } 112 113 { 114 int status = 0; 115 pb_istream_t stream; 116 117 stream = pb_istream_from_buffer(buffer, count); 118 status = test_oneof_1(&stream, option); 119 120 if (status != 0) 121 return status; 122 123 stream = pb_istream_from_buffer(buffer, count); 124 status = test_oneof_2(&stream, option); 125 126 if (status != 0) 127 return status; 128 } 129 130 return 0; 131 } 132