decode_callbacks.c 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /* Decoding testcase for callback fields.
  2. * Run e.g. ./test_encode_callbacks | ./test_decode_callbacks
  3. */
  4. #include <stdio.h>
  5. #include <pb_decode.h>
  6. #include "callbacks.pb.h"
  7. #include "test_helpers.h"
  8. bool print_string(pb_istream_t *stream, const pb_field_t *field, void **arg)
  9. {
  10. uint8_t buffer[1024] = {0};
  11. /* We could read block-by-block to avoid the large buffer... */
  12. if (stream->bytes_left > sizeof(buffer) - 1)
  13. return false;
  14. if (!pb_read(stream, buffer, stream->bytes_left))
  15. return false;
  16. /* Print the string, in format comparable with protoc --decode.
  17. * Format comes from the arg defined in main().
  18. */
  19. printf((char*)*arg, buffer);
  20. return true;
  21. }
  22. bool print_int32(pb_istream_t *stream, const pb_field_t *field, void **arg)
  23. {
  24. uint64_t value;
  25. if (!pb_decode_varint(stream, &value))
  26. return false;
  27. printf((char*)*arg, (long)value);
  28. return true;
  29. }
  30. bool print_fixed32(pb_istream_t *stream, const pb_field_t *field, void **arg)
  31. {
  32. uint32_t value;
  33. if (!pb_decode_fixed32(stream, &value))
  34. return false;
  35. printf((char*)*arg, (long)value);
  36. return true;
  37. }
  38. bool print_fixed64(pb_istream_t *stream, const pb_field_t *field, void **arg)
  39. {
  40. uint64_t value;
  41. if (!pb_decode_fixed64(stream, &value))
  42. return false;
  43. printf((char*)*arg, (long)value);
  44. return true;
  45. }
  46. int main()
  47. {
  48. uint8_t buffer[1024];
  49. size_t length;
  50. pb_istream_t stream;
  51. /* Note: empty initializer list initializes the struct with all-0.
  52. * This is recommended so that unused callbacks are set to NULL instead
  53. * of crashing at runtime.
  54. */
  55. TestMessage testmessage = {{{NULL}}};
  56. SET_BINARY_MODE(stdin);
  57. length = fread(buffer, 1, 1024, stdin);
  58. stream = pb_istream_from_buffer(buffer, length);
  59. testmessage.submsg.stringvalue.funcs.decode = &print_string;
  60. testmessage.submsg.stringvalue.arg = "submsg {\n stringvalue: \"%s\"\n";
  61. testmessage.submsg.int32value.funcs.decode = &print_int32;
  62. testmessage.submsg.int32value.arg = " int32value: %ld\n";
  63. testmessage.submsg.fixed32value.funcs.decode = &print_fixed32;
  64. testmessage.submsg.fixed32value.arg = " fixed32value: %ld\n";
  65. testmessage.submsg.fixed64value.funcs.decode = &print_fixed64;
  66. testmessage.submsg.fixed64value.arg = " fixed64value: %ld\n}\n";
  67. testmessage.stringvalue.funcs.decode = &print_string;
  68. testmessage.stringvalue.arg = "stringvalue: \"%s\"\n";
  69. testmessage.int32value.funcs.decode = &print_int32;
  70. testmessage.int32value.arg = "int32value: %ld\n";
  71. testmessage.fixed32value.funcs.decode = &print_fixed32;
  72. testmessage.fixed32value.arg = "fixed32value: %ld\n";
  73. testmessage.fixed64value.funcs.decode = &print_fixed64;
  74. testmessage.fixed64value.arg = "fixed64value: %ld\n";
  75. testmessage.repeatedstring.funcs.decode = &print_string;
  76. testmessage.repeatedstring.arg = "repeatedstring: \"%s\"\n";
  77. if (!pb_decode(&stream, TestMessage_fields, &testmessage))
  78. return 1;
  79. return 0;
  80. }