17ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen/* Decoding testcase for callback fields. 27ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen * Run e.g. ./test_encode_callbacks | ./test_decode_callbacks 37ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen */ 47ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen 57ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen#include <stdio.h> 67ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen#include <pb_decode.h> 77ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen#include "callbacks.pb.h" 87ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen#include "test_helpers.h" 97ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen 107ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohenbool print_string(pb_istream_t *stream, const pb_field_t *field, void **arg) 117ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen{ 127ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen uint8_t buffer[1024] = {0}; 137ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen 147ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen /* We could read block-by-block to avoid the large buffer... */ 157ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen if (stream->bytes_left > sizeof(buffer) - 1) 167ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen return false; 177ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen 187ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen if (!pb_read(stream, buffer, stream->bytes_left)) 197ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen return false; 207ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen 217ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen /* Print the string, in format comparable with protoc --decode. 227ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen * Format comes from the arg defined in main(). 237ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen */ 247ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen printf((char*)*arg, buffer); 257ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen return true; 267ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen} 277ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen 287ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohenbool print_int32(pb_istream_t *stream, const pb_field_t *field, void **arg) 297ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen{ 307ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen uint64_t value; 317ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen if (!pb_decode_varint(stream, &value)) 327ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen return false; 337ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen 347ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen printf((char*)*arg, (long)value); 357ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen return true; 367ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen} 377ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen 387ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohenbool print_fixed32(pb_istream_t *stream, const pb_field_t *field, void **arg) 397ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen{ 407ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen uint32_t value; 417ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen if (!pb_decode_fixed32(stream, &value)) 427ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen return false; 437ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen 447ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen printf((char*)*arg, (long)value); 457ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen return true; 467ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen} 477ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen 487ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohenbool print_fixed64(pb_istream_t *stream, const pb_field_t *field, void **arg) 497ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen{ 507ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen uint64_t value; 517ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen if (!pb_decode_fixed64(stream, &value)) 527ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen return false; 537ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen 547ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen printf((char*)*arg, (long)value); 557ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen return true; 567ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen} 577ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen 587ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohenint main() 597ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen{ 607ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen uint8_t buffer[1024]; 617ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen size_t length; 627ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen pb_istream_t stream; 637ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen /* Note: empty initializer list initializes the struct with all-0. 647ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen * This is recommended so that unused callbacks are set to NULL instead 657ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen * of crashing at runtime. 667ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen */ 677ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen TestMessage testmessage = {{{NULL}}}; 687ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen 697ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen SET_BINARY_MODE(stdin); 707ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen length = fread(buffer, 1, 1024, stdin); 717ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen stream = pb_istream_from_buffer(buffer, length); 727ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen 737ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen testmessage.submsg.stringvalue.funcs.decode = &print_string; 747ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen testmessage.submsg.stringvalue.arg = "submsg {\n stringvalue: \"%s\"\n"; 757ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen testmessage.submsg.int32value.funcs.decode = &print_int32; 767ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen testmessage.submsg.int32value.arg = " int32value: %ld\n"; 777ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen testmessage.submsg.fixed32value.funcs.decode = &print_fixed32; 787ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen testmessage.submsg.fixed32value.arg = " fixed32value: %ld\n"; 797ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen testmessage.submsg.fixed64value.funcs.decode = &print_fixed64; 807ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen testmessage.submsg.fixed64value.arg = " fixed64value: %ld\n}\n"; 817ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen 827ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen testmessage.stringvalue.funcs.decode = &print_string; 837ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen testmessage.stringvalue.arg = "stringvalue: \"%s\"\n"; 847ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen testmessage.int32value.funcs.decode = &print_int32; 857ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen testmessage.int32value.arg = "int32value: %ld\n"; 867ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen testmessage.fixed32value.funcs.decode = &print_fixed32; 877ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen testmessage.fixed32value.arg = "fixed32value: %ld\n"; 887ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen testmessage.fixed64value.funcs.decode = &print_fixed64; 897ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen testmessage.fixed64value.arg = "fixed64value: %ld\n"; 907ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen testmessage.repeatedstring.funcs.decode = &print_string; 917ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen testmessage.repeatedstring.arg = "repeatedstring: \"%s\"\n"; 927ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen 937ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen if (!pb_decode(&stream, TestMessage_fields, &testmessage)) 947ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen return 1; 957ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen 967ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen return 0; 977ef855e462b9a18b7d330e4b40f350164a6ad9daEtan Cohen} 98