aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetteri Aimonen <jpa@git.mail.kapsi.fi>2013-01-13 18:44:15 +0200
committerPetteri Aimonen <jpa@git.mail.kapsi.fi>2013-01-13 18:44:15 +0200
commitb9baec6b4c3a04136ea0430109bc7bc1eda12685 (patch)
tree596e2c2c1cba87462aed032d23844886927ce417
parentd2c1604d6d239cdab6b21f3daf6634eb112ae318 (diff)
Add a test for the backwards compatibility of generated files.
It is not necessary to maintain full compatibility of generated files for all of eternity, but this test will warn us if there is a need to regenerate the files.
-rw-r--r--tests/Makefile6
-rw-r--r--tests/bc_alltypes.pb.c326
-rw-r--r--tests/bc_alltypes.pb.h155
-rw-r--r--tests/bc_decode.c197
-rw-r--r--tests/bc_encode.c131
5 files changed, 814 insertions, 1 deletions
diff --git a/tests/Makefile b/tests/Makefile
index 58b84a3b..63830999 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -7,7 +7,8 @@ TESTS= decode_unittests encode_unittests \
test_encode1 test_encode2 test_encode3 \
test_decode_callbacks test_encode_callbacks \
test_missing_fields test_no_messages \
- test_multiple_files test_cxxcompile test_options
+ test_multiple_files test_cxxcompile test_options \
+ bc_encode bc_decode
# More strict checks for the core part of nanopb
CC_VERSION=$(shell $(CC) -v 2>&1)
@@ -57,6 +58,8 @@ test_missing_fields: test_missing_fields.o pb_encode.o pb_decode.o missing_field
decode_unittests: decode_unittests.o pb_decode.o unittestproto.pb.o
encode_unittests: encode_unittests.o pb_encode.o unittestproto.pb.o
test_no_messages: no_messages.pb.h no_messages.pb.c no_messages.pb.o
+bc_encode: bc_alltypes.pb.o pb_encode.o bc_encode.o
+bc_decode: bc_alltypes.pb.o pb_decode.o bc_decode.o
%.pb: %.proto
protoc -I. -I../generator -I/usr/include -o$@ $<
@@ -95,6 +98,7 @@ run_unittests: $(TESTS)
./test_encode3 | ./test_decode3
./test_encode3 1 | ./test_decode3 1
./test_encode3 1 | protoc --decode=AllTypes -I. -I../generator -I/usr/include alltypes.proto >/dev/null
+ ./bc_encode | ./bc_decode
./test_missing_fields
diff --git a/tests/bc_alltypes.pb.c b/tests/bc_alltypes.pb.c
new file mode 100644
index 00000000..322b634e
--- /dev/null
+++ b/tests/bc_alltypes.pb.c
@@ -0,0 +1,326 @@
+/* Automatically generated nanopb constant definitions */
+#include "bc_alltypes.pb.h"
+
+const char SubMessage_substuff1_default[17] = "1";
+const int32_t SubMessage_substuff2_default = 2;
+const uint32_t SubMessage_substuff3_default = 3;
+const int32_t AllTypes_opt_int32_default = 4041;
+const int64_t AllTypes_opt_int64_default = 4042;
+const uint32_t AllTypes_opt_uint32_default = 4043;
+const uint64_t AllTypes_opt_uint64_default = 4044;
+const int32_t AllTypes_opt_sint32_default = 4045;
+const int64_t AllTypes_opt_sint64_default = 4046;
+const bool AllTypes_opt_bool_default = false;
+const uint32_t AllTypes_opt_fixed32_default = 4048;
+const int32_t AllTypes_opt_sfixed32_default = 4049;
+const float AllTypes_opt_float_default = 4050;
+const uint64_t AllTypes_opt_fixed64_default = 4051;
+const int64_t AllTypes_opt_sfixed64_default = 4052;
+const double AllTypes_opt_double_default = 4053;
+const char AllTypes_opt_string_default[17] = "4054";
+const AllTypes_opt_bytes_t AllTypes_opt_bytes_default = {4, {0x34,0x30,0x35,0x35}};
+const MyEnum AllTypes_opt_enum_default = MyEnum_Second;
+
+
+const pb_field_t SubMessage_fields[4] = {
+ {1, PB_HTYPE_REQUIRED | PB_LTYPE_STRING,
+ offsetof(SubMessage, substuff1), 0,
+ pb_membersize(SubMessage, substuff1), 0,
+ &SubMessage_substuff1_default},
+
+ {2, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT,
+ pb_delta_end(SubMessage, substuff2, substuff1), 0,
+ pb_membersize(SubMessage, substuff2), 0,
+ &SubMessage_substuff2_default},
+
+ {3, PB_HTYPE_OPTIONAL | PB_LTYPE_FIXED32,
+ pb_delta_end(SubMessage, substuff3, substuff2),
+ pb_delta(SubMessage, has_substuff3, substuff3),
+ pb_membersize(SubMessage, substuff3), 0,
+ &SubMessage_substuff3_default},
+
+ PB_LAST_FIELD
+};
+
+const pb_field_t AllTypes_fields[53] = {
+ {1, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT,
+ offsetof(AllTypes, req_int32), 0,
+ pb_membersize(AllTypes, req_int32), 0, 0},
+
+ {2, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT,
+ pb_delta_end(AllTypes, req_int64, req_int32), 0,
+ pb_membersize(AllTypes, req_int64), 0, 0},
+
+ {3, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT,
+ pb_delta_end(AllTypes, req_uint32, req_int64), 0,
+ pb_membersize(AllTypes, req_uint32), 0, 0},
+
+ {4, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT,
+ pb_delta_end(AllTypes, req_uint64, req_uint32), 0,
+ pb_membersize(AllTypes, req_uint64), 0, 0},
+
+ {5, PB_HTYPE_REQUIRED | PB_LTYPE_SVARINT,
+ pb_delta_end(AllTypes, req_sint32, req_uint64), 0,
+ pb_membersize(AllTypes, req_sint32), 0, 0},
+
+ {6, PB_HTYPE_REQUIRED | PB_LTYPE_SVARINT,
+ pb_delta_end(AllTypes, req_sint64, req_sint32), 0,
+ pb_membersize(AllTypes, req_sint64), 0, 0},
+
+ {7, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT,
+ pb_delta_end(AllTypes, req_bool, req_sint64), 0,
+ pb_membersize(AllTypes, req_bool), 0, 0},
+
+ {8, PB_HTYPE_REQUIRED | PB_LTYPE_FIXED32,
+ pb_delta_end(AllTypes, req_fixed32, req_bool), 0,
+ pb_membersize(AllTypes, req_fixed32), 0, 0},
+
+ {9, PB_HTYPE_REQUIRED | PB_LTYPE_FIXED32,
+ pb_delta_end(AllTypes, req_sfixed32, req_fixed32), 0,
+ pb_membersize(AllTypes, req_sfixed32), 0, 0},
+
+ {10, PB_HTYPE_REQUIRED | PB_LTYPE_FIXED32,
+ pb_delta_end(AllTypes, req_float, req_sfixed32), 0,
+ pb_membersize(AllTypes, req_float), 0, 0},
+
+ {11, PB_HTYPE_REQUIRED | PB_LTYPE_FIXED64,
+ pb_delta_end(AllTypes, req_fixed64, req_float), 0,
+ pb_membersize(AllTypes, req_fixed64), 0, 0},
+
+ {12, PB_HTYPE_REQUIRED | PB_LTYPE_FIXED64,
+ pb_delta_end(AllTypes, req_sfixed64, req_fixed64), 0,
+ pb_membersize(AllTypes, req_sfixed64), 0, 0},
+
+ {13, PB_HTYPE_REQUIRED | PB_LTYPE_FIXED64,
+ pb_delta_end(AllTypes, req_double, req_sfixed64), 0,
+ pb_membersize(AllTypes, req_double), 0, 0},
+
+ {14, PB_HTYPE_REQUIRED | PB_LTYPE_STRING,
+ pb_delta_end(AllTypes, req_string, req_double), 0,
+ pb_membersize(AllTypes, req_string), 0, 0},
+
+ {15, PB_HTYPE_REQUIRED | PB_LTYPE_BYTES,
+ pb_delta_end(AllTypes, req_bytes, req_string), 0,
+ pb_membersize(AllTypes, req_bytes), 0, 0},
+
+ {16, PB_HTYPE_REQUIRED | PB_LTYPE_SUBMESSAGE,
+ pb_delta_end(AllTypes, req_submsg, req_bytes), 0,
+ pb_membersize(AllTypes, req_submsg), 0,
+ &SubMessage_fields},
+
+ {17, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT,
+ pb_delta_end(AllTypes, req_enum, req_submsg), 0,
+ pb_membersize(AllTypes, req_enum), 0, 0},
+
+ {21, PB_HTYPE_ARRAY | PB_LTYPE_VARINT,
+ pb_delta_end(AllTypes, rep_int32, req_enum),
+ pb_delta(AllTypes, rep_int32_count, rep_int32),
+ pb_membersize(AllTypes, rep_int32[0]),
+ pb_membersize(AllTypes, rep_int32) / pb_membersize(AllTypes, rep_int32[0]), 0},
+
+ {22, PB_HTYPE_ARRAY | PB_LTYPE_VARINT,
+ pb_delta_end(AllTypes, rep_int64, rep_int32),
+ pb_delta(AllTypes, rep_int64_count, rep_int64),
+ pb_membersize(AllTypes, rep_int64[0]),
+ pb_membersize(AllTypes, rep_int64) / pb_membersize(AllTypes, rep_int64[0]), 0},
+
+ {23, PB_HTYPE_ARRAY | PB_LTYPE_VARINT,
+ pb_delta_end(AllTypes, rep_uint32, rep_int64),
+ pb_delta(AllTypes, rep_uint32_count, rep_uint32),
+ pb_membersize(AllTypes, rep_uint32[0]),
+ pb_membersize(AllTypes, rep_uint32) / pb_membersize(AllTypes, rep_uint32[0]), 0},
+
+ {24, PB_HTYPE_ARRAY | PB_LTYPE_VARINT,
+ pb_delta_end(AllTypes, rep_uint64, rep_uint32),
+ pb_delta(AllTypes, rep_uint64_count, rep_uint64),
+ pb_membersize(AllTypes, rep_uint64[0]),
+ pb_membersize(AllTypes, rep_uint64) / pb_membersize(AllTypes, rep_uint64[0]), 0},
+
+ {25, PB_HTYPE_ARRAY | PB_LTYPE_SVARINT,
+ pb_delta_end(AllTypes, rep_sint32, rep_uint64),
+ pb_delta(AllTypes, rep_sint32_count, rep_sint32),
+ pb_membersize(AllTypes, rep_sint32[0]),
+ pb_membersize(AllTypes, rep_sint32) / pb_membersize(AllTypes, rep_sint32[0]), 0},
+
+ {26, PB_HTYPE_ARRAY | PB_LTYPE_SVARINT,
+ pb_delta_end(AllTypes, rep_sint64, rep_sint32),
+ pb_delta(AllTypes, rep_sint64_count, rep_sint64),
+ pb_membersize(AllTypes, rep_sint64[0]),
+ pb_membersize(AllTypes, rep_sint64) / pb_membersize(AllTypes, rep_sint64[0]), 0},
+
+ {27, PB_HTYPE_ARRAY | PB_LTYPE_VARINT,
+ pb_delta_end(AllTypes, rep_bool, rep_sint64),
+ pb_delta(AllTypes, rep_bool_count, rep_bool),
+ pb_membersize(AllTypes, rep_bool[0]),
+ pb_membersize(AllTypes, rep_bool) / pb_membersize(AllTypes, rep_bool[0]), 0},
+
+ {28, PB_HTYPE_ARRAY | PB_LTYPE_FIXED32,
+ pb_delta_end(AllTypes, rep_fixed32, rep_bool),
+ pb_delta(AllTypes, rep_fixed32_count, rep_fixed32),
+ pb_membersize(AllTypes, rep_fixed32[0]),
+ pb_membersize(AllTypes, rep_fixed32) / pb_membersize(AllTypes, rep_fixed32[0]), 0},
+
+ {29, PB_HTYPE_ARRAY | PB_LTYPE_FIXED32,
+ pb_delta_end(AllTypes, rep_sfixed32, rep_fixed32),
+ pb_delta(AllTypes, rep_sfixed32_count, rep_sfixed32),
+ pb_membersize(AllTypes, rep_sfixed32[0]),
+ pb_membersize(AllTypes, rep_sfixed32) / pb_membersize(AllTypes, rep_sfixed32[0]), 0},
+
+ {30, PB_HTYPE_ARRAY | PB_LTYPE_FIXED32,
+ pb_delta_end(AllTypes, rep_float, rep_sfixed32),
+ pb_delta(AllTypes, rep_float_count, rep_float),
+ pb_membersize(AllTypes, rep_float[0]),
+ pb_membersize(AllTypes, rep_float) / pb_membersize(AllTypes, rep_float[0]), 0},
+
+ {31, PB_HTYPE_ARRAY | PB_LTYPE_FIXED64,
+ pb_delta_end(AllTypes, rep_fixed64, rep_float),
+ pb_delta(AllTypes, rep_fixed64_count, rep_fixed64),
+ pb_membersize(AllTypes, rep_fixed64[0]),
+ pb_membersize(AllTypes, rep_fixed64) / pb_membersize(AllTypes, rep_fixed64[0]), 0},
+
+ {32, PB_HTYPE_ARRAY | PB_LTYPE_FIXED64,
+ pb_delta_end(AllTypes, rep_sfixed64, rep_fixed64),
+ pb_delta(AllTypes, rep_sfixed64_count, rep_sfixed64),
+ pb_membersize(AllTypes, rep_sfixed64[0]),
+ pb_membersize(AllTypes, rep_sfixed64) / pb_membersize(AllTypes, rep_sfixed64[0]), 0},
+
+ {33, PB_HTYPE_ARRAY | PB_LTYPE_FIXED64,
+ pb_delta_end(AllTypes, rep_double, rep_sfixed64),
+ pb_delta(AllTypes, rep_double_count, rep_double),
+ pb_membersize(AllTypes, rep_double[0]),
+ pb_membersize(AllTypes, rep_double) / pb_membersize(AllTypes, rep_double[0]), 0},
+
+ {34, PB_HTYPE_ARRAY | PB_LTYPE_STRING,
+ pb_delta_end(AllTypes, rep_string, rep_double),
+ pb_delta(AllTypes, rep_string_count, rep_string),
+ pb_membersize(AllTypes, rep_string[0]),
+ pb_membersize(AllTypes, rep_string) / pb_membersize(AllTypes, rep_string[0]), 0},
+
+ {35, PB_HTYPE_ARRAY | PB_LTYPE_BYTES,
+ pb_delta_end(AllTypes, rep_bytes, rep_string),
+ pb_delta(AllTypes, rep_bytes_count, rep_bytes),
+ pb_membersize(AllTypes, rep_bytes[0]),
+ pb_membersize(AllTypes, rep_bytes) / pb_membersize(AllTypes, rep_bytes[0]), 0},
+
+ {36, PB_HTYPE_ARRAY | PB_LTYPE_SUBMESSAGE,
+ pb_delta_end(AllTypes, rep_submsg, rep_bytes),
+ pb_delta(AllTypes, rep_submsg_count, rep_submsg),
+ pb_membersize(AllTypes, rep_submsg[0]),
+ pb_membersize(AllTypes, rep_submsg) / pb_membersize(AllTypes, rep_submsg[0]),
+ &SubMessage_fields},
+
+ {37, PB_HTYPE_ARRAY | PB_LTYPE_VARINT,
+ pb_delta_end(AllTypes, rep_enum, rep_submsg),
+ pb_delta(AllTypes, rep_enum_count, rep_enum),
+ pb_membersize(AllTypes, rep_enum[0]),
+ pb_membersize(AllTypes, rep_enum) / pb_membersize(AllTypes, rep_enum[0]), 0},
+
+ {41, PB_HTYPE_OPTIONAL | PB_LTYPE_VARINT,
+ pb_delta_end(AllTypes, opt_int32, rep_enum),
+ pb_delta(AllTypes, has_opt_int32, opt_int32),
+ pb_membersize(AllTypes, opt_int32), 0,
+ &AllTypes_opt_int32_default},
+
+ {42, PB_HTYPE_OPTIONAL | PB_LTYPE_VARINT,
+ pb_delta_end(AllTypes, opt_int64, opt_int32),
+ pb_delta(AllTypes, has_opt_int64, opt_int64),
+ pb_membersize(AllTypes, opt_int64), 0,
+ &AllTypes_opt_int64_default},
+
+ {43, PB_HTYPE_OPTIONAL | PB_LTYPE_VARINT,
+ pb_delta_end(AllTypes, opt_uint32, opt_int64),
+ pb_delta(AllTypes, has_opt_uint32, opt_uint32),
+ pb_membersize(AllTypes, opt_uint32), 0,
+ &AllTypes_opt_uint32_default},
+
+ {44, PB_HTYPE_OPTIONAL | PB_LTYPE_VARINT,
+ pb_delta_end(AllTypes, opt_uint64, opt_uint32),
+ pb_delta(AllTypes, has_opt_uint64, opt_uint64),
+ pb_membersize(AllTypes, opt_uint64), 0,
+ &AllTypes_opt_uint64_default},
+
+ {45, PB_HTYPE_OPTIONAL | PB_LTYPE_SVARINT,
+ pb_delta_end(AllTypes, opt_sint32, opt_uint64),
+ pb_delta(AllTypes, has_opt_sint32, opt_sint32),
+ pb_membersize(AllTypes, opt_sint32), 0,
+ &AllTypes_opt_sint32_default},
+
+ {46, PB_HTYPE_OPTIONAL | PB_LTYPE_SVARINT,
+ pb_delta_end(AllTypes, opt_sint64, opt_sint32),
+ pb_delta(AllTypes, has_opt_sint64, opt_sint64),
+ pb_membersize(AllTypes, opt_sint64), 0,
+ &AllTypes_opt_sint64_default},
+
+ {47, PB_HTYPE_OPTIONAL | PB_LTYPE_VARINT,
+ pb_delta_end(AllTypes, opt_bool, opt_sint64),
+ pb_delta(AllTypes, has_opt_bool, opt_bool),
+ pb_membersize(AllTypes, opt_bool), 0,
+ &AllTypes_opt_bool_default},
+
+ {48, PB_HTYPE_OPTIONAL | PB_LTYPE_FIXED32,
+ pb_delta_end(AllTypes, opt_fixed32, opt_bool),
+ pb_delta(AllTypes, has_opt_fixed32, opt_fixed32),
+ pb_membersize(AllTypes, opt_fixed32), 0,
+ &AllTypes_opt_fixed32_default},
+
+ {49, PB_HTYPE_OPTIONAL | PB_LTYPE_FIXED32,
+ pb_delta_end(AllTypes, opt_sfixed32, opt_fixed32),
+ pb_delta(AllTypes, has_opt_sfixed32, opt_sfixed32),
+ pb_membersize(AllTypes, opt_sfixed32), 0,
+ &AllTypes_opt_sfixed32_default},
+
+ {50, PB_HTYPE_OPTIONAL | PB_LTYPE_FIXED32,
+ pb_delta_end(AllTypes, opt_float, opt_sfixed32),
+ pb_delta(AllTypes, has_opt_float, opt_float),
+ pb_membersize(AllTypes, opt_float), 0,
+ &AllTypes_opt_float_default},
+
+ {51, PB_HTYPE_OPTIONAL | PB_LTYPE_FIXED64,
+ pb_delta_end(AllTypes, opt_fixed64, opt_float),
+ pb_delta(AllTypes, has_opt_fixed64, opt_fixed64),
+ pb_membersize(AllTypes, opt_fixed64), 0,
+ &AllTypes_opt_fixed64_default},
+
+ {52, PB_HTYPE_OPTIONAL | PB_LTYPE_FIXED64,
+ pb_delta_end(AllTypes, opt_sfixed64, opt_fixed64),
+ pb_delta(AllTypes, has_opt_sfixed64, opt_sfixed64),
+ pb_membersize(AllTypes, opt_sfixed64), 0,
+ &AllTypes_opt_sfixed64_default},
+
+ {53, PB_HTYPE_OPTIONAL | PB_LTYPE_FIXED64,
+ pb_delta_end(AllTypes, opt_double, opt_sfixed64),
+ pb_delta(AllTypes, has_opt_double, opt_double),
+ pb_membersize(AllTypes, opt_double), 0,
+ &AllTypes_opt_double_default},
+
+ {54, PB_HTYPE_OPTIONAL | PB_LTYPE_STRING,
+ pb_delta_end(AllTypes, opt_string, opt_double),
+ pb_delta(AllTypes, has_opt_string, opt_string),
+ pb_membersize(AllTypes, opt_string), 0,
+ &AllTypes_opt_string_default},
+
+ {55, PB_HTYPE_OPTIONAL | PB_LTYPE_BYTES,
+ pb_delta_end(AllTypes, opt_bytes, opt_string),
+ pb_delta(AllTypes, has_opt_bytes, opt_bytes),
+ pb_membersize(AllTypes, opt_bytes), 0,
+ &AllTypes_opt_bytes_default},
+
+ {56, PB_HTYPE_OPTIONAL | PB_LTYPE_SUBMESSAGE,
+ pb_delta_end(AllTypes, opt_submsg, opt_bytes),
+ pb_delta(AllTypes, has_opt_submsg, opt_submsg),
+ pb_membersize(AllTypes, opt_submsg), 0,
+ &SubMessage_fields},
+
+ {57, PB_HTYPE_OPTIONAL | PB_LTYPE_VARINT,
+ pb_delta_end(AllTypes, opt_enum, opt_submsg),
+ pb_delta(AllTypes, has_opt_enum, opt_enum),
+ pb_membersize(AllTypes, opt_enum), 0,
+ &AllTypes_opt_enum_default},
+
+ {99, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT,
+ pb_delta_end(AllTypes, end, opt_enum), 0,
+ pb_membersize(AllTypes, end), 0, 0},
+
+ PB_LAST_FIELD
+};
+
diff --git a/tests/bc_alltypes.pb.h b/tests/bc_alltypes.pb.h
new file mode 100644
index 00000000..fe0b8f76
--- /dev/null
+++ b/tests/bc_alltypes.pb.h
@@ -0,0 +1,155 @@
+/* Automatically generated nanopb header */
+/* This is a file generated using nanopb-0.1.1.
+ * It is used as a part of test suite in order to detect any
+ * incompatible changes made to the generator in future versions.
+ */
+#ifndef _PB_BC_ALLTYPES_PB_H_
+#define _PB_BC_ALLTYPES_PB_H_
+#include <pb.h>
+
+/* Enum definitions */
+typedef enum {
+ MyEnum_Zero = 0,
+ MyEnum_First = 1,
+ MyEnum_Second = 2,
+ MyEnum_Truth = 42
+} MyEnum;
+
+/* Struct definitions */
+typedef struct {
+ char substuff1[16];
+ int32_t substuff2;
+ bool has_substuff3;
+ uint32_t substuff3;
+} SubMessage;
+
+typedef struct {
+ size_t size;
+ uint8_t bytes[16];
+} AllTypes_req_bytes_t;
+
+typedef struct {
+ size_t size;
+ uint8_t bytes[16];
+} AllTypes_rep_bytes_t;
+
+typedef struct {
+ size_t size;
+ uint8_t bytes[16];
+} AllTypes_opt_bytes_t;
+
+typedef struct {
+ int32_t req_int32;
+ int64_t req_int64;
+ uint32_t req_uint32;
+ uint64_t req_uint64;
+ int32_t req_sint32;
+ int64_t req_sint64;
+ bool req_bool;
+ uint32_t req_fixed32;
+ int32_t req_sfixed32;
+ float req_float;
+ uint64_t req_fixed64;
+ int64_t req_sfixed64;
+ double req_double;
+ char req_string[16];
+ AllTypes_req_bytes_t req_bytes;
+ SubMessage req_submsg;
+ MyEnum req_enum;
+ size_t rep_int32_count;
+ int32_t rep_int32[5];
+ size_t rep_int64_count;
+ int64_t rep_int64[5];
+ size_t rep_uint32_count;
+ uint32_t rep_uint32[5];
+ size_t rep_uint64_count;
+ uint64_t rep_uint64[5];
+ size_t rep_sint32_count;
+ int32_t rep_sint32[5];
+ size_t rep_sint64_count;
+ int64_t rep_sint64[5];
+ size_t rep_bool_count;
+ bool rep_bool[5];
+ size_t rep_fixed32_count;
+ uint32_t rep_fixed32[5];
+ size_t rep_sfixed32_count;
+ int32_t rep_sfixed32[5];
+ size_t rep_float_count;
+ float rep_float[5];
+ size_t rep_fixed64_count;
+ uint64_t rep_fixed64[5];
+ size_t rep_sfixed64_count;
+ int64_t rep_sfixed64[5];
+ size_t rep_double_count;
+ double rep_double[5];
+ size_t rep_string_count;
+ char rep_string[5][16];
+ size_t rep_bytes_count;
+ AllTypes_rep_bytes_t rep_bytes[5];
+ size_t rep_submsg_count;
+ SubMessage rep_submsg[5];
+ size_t rep_enum_count;
+ MyEnum rep_enum[5];
+ bool has_opt_int32;
+ int32_t opt_int32;
+ bool has_opt_int64;
+ int64_t opt_int64;
+ bool has_opt_uint32;
+ uint32_t opt_uint32;
+ bool has_opt_uint64;
+ uint64_t opt_uint64;
+ bool has_opt_sint32;
+ int32_t opt_sint32;
+ bool has_opt_sint64;
+ int64_t opt_sint64;
+ bool has_opt_bool;
+ bool opt_bool;
+ bool has_opt_fixed32;
+ uint32_t opt_fixed32;
+ bool has_opt_sfixed32;
+ int32_t opt_sfixed32;
+ bool has_opt_float;
+ float opt_float;
+ bool has_opt_fixed64;
+ uint64_t opt_fixed64;
+ bool has_opt_sfixed64;
+ int64_t opt_sfixed64;
+ bool has_opt_double;
+ double opt_double;
+ bool has_opt_string;
+ char opt_string[16];
+ bool has_opt_bytes;
+ AllTypes_opt_bytes_t opt_bytes;
+ bool has_opt_submsg;
+ SubMessage opt_submsg;
+ bool has_opt_enum;
+ MyEnum opt_enum;
+ int32_t end;
+} AllTypes;
+
+/* Default values for struct fields */
+extern const char SubMessage_substuff1_default[17];
+extern const int32_t SubMessage_substuff2_default;
+extern const uint32_t SubMessage_substuff3_default;
+extern const int32_t AllTypes_opt_int32_default;
+extern const int64_t AllTypes_opt_int64_default;
+extern const uint32_t AllTypes_opt_uint32_default;
+extern const uint64_t AllTypes_opt_uint64_default;
+extern const int32_t AllTypes_opt_sint32_default;
+extern const int64_t AllTypes_opt_sint64_default;
+extern const bool AllTypes_opt_bool_default;
+extern const uint32_t AllTypes_opt_fixed32_default;
+extern const int32_t AllTypes_opt_sfixed32_default;
+extern const float AllTypes_opt_float_default;
+extern const uint64_t AllTypes_opt_fixed64_default;
+extern const int64_t AllTypes_opt_sfixed64_default;
+extern const double AllTypes_opt_double_default;
+extern const char AllTypes_opt_string_default[17];
+extern const AllTypes_opt_bytes_t AllTypes_opt_bytes_default;
+extern const MyEnum AllTypes_opt_enum_default;
+
+/* Struct field encoding specification for nanopb */
+extern const pb_field_t SubMessage_fields[4];
+extern const pb_field_t AllTypes_fields[53];
+
+#endif
diff --git a/tests/bc_decode.c b/tests/bc_decode.c
new file mode 100644
index 00000000..b74172fd
--- /dev/null
+++ b/tests/bc_decode.c
@@ -0,0 +1,197 @@
+/* Tests the decoding of all types.
+ * This is a backwards-compatibility test, using bc_alltypes.pb.h.
+ * It is similar to test_decode3, but duplicated in order to allow
+ * test_decode3 to test any new features introduced later.
+ *
+ * Run e.g. ./bc_encode | ./bc_decode
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pb_decode.h>
+#include "bc_alltypes.pb.h"
+
+#define TEST(x) if (!(x)) { \
+ printf("Test " #x " failed.\n"); \
+ return false; \
+ }
+
+/* This function is called once from main(), it handles
+ the decoding and checks the fields. */
+bool check_alltypes(pb_istream_t *stream, int mode)
+{
+ AllTypes alltypes;
+
+ /* Fill with garbage to better detect initialization errors */
+ memset(&alltypes, 0xAA, sizeof(alltypes));
+
+ if (!pb_decode(stream, AllTypes_fields, &alltypes))
+ return false;
+
+ TEST(alltypes.req_int32 == -1001);
+ TEST(alltypes.req_int64 == -1002);
+ TEST(alltypes.req_uint32 == 1003);
+ TEST(alltypes.req_uint64 == 1004);
+ TEST(alltypes.req_sint32 == -1005);
+ TEST(alltypes.req_sint64 == -1006);
+ TEST(alltypes.req_bool == true);
+
+ TEST(alltypes.req_fixed32 == 1008);
+ TEST(alltypes.req_sfixed32 == -1009);
+ TEST(alltypes.req_float == 1010.0f);
+
+ TEST(alltypes.req_fixed64 == 1011);
+ TEST(alltypes.req_sfixed64 == -1012);
+ TEST(alltypes.req_double == 1013.0f);
+
+ TEST(strcmp(alltypes.req_string, "1014") == 0);
+ TEST(alltypes.req_bytes.size == 4);
+ TEST(memcmp(alltypes.req_bytes.bytes, "1015", 4) == 0);
+ TEST(strcmp(alltypes.req_submsg.substuff1, "1016") == 0);
+ TEST(alltypes.req_submsg.substuff2 == 1016);
+ TEST(alltypes.req_submsg.substuff3 == 3);
+ TEST(alltypes.req_enum == MyEnum_Truth);
+
+ TEST(alltypes.rep_int32_count == 5 && alltypes.rep_int32[4] == -2001 && alltypes.rep_int32[0] == 0);
+ TEST(alltypes.rep_int64_count == 5 && alltypes.rep_int64[4] == -2002 && alltypes.rep_int64[0] == 0);
+ TEST(alltypes.rep_uint32_count == 5 && alltypes.rep_uint32[4] == 2003 && alltypes.rep_uint32[0] == 0);
+ TEST(alltypes.rep_uint64_count == 5 && alltypes.rep_uint64[4] == 2004 && alltypes.rep_uint64[0] == 0);
+ TEST(alltypes.rep_sint32_count == 5 && alltypes.rep_sint32[4] == -2005 && alltypes.rep_sint32[0] == 0);
+ TEST(alltypes.rep_sint64_count == 5 && alltypes.rep_sint64[4] == -2006 && alltypes.rep_sint64[0] == 0);
+ TEST(alltypes.rep_bool_count == 5 && alltypes.rep_bool[4] == true && alltypes.rep_bool[0] == false);
+
+ TEST(alltypes.rep_fixed32_count == 5 && alltypes.rep_fixed32[4] == 2008 && alltypes.rep_fixed32[0] == 0);
+ TEST(alltypes.rep_sfixed32_count == 5 && alltypes.rep_sfixed32[4] == -2009 && alltypes.rep_sfixed32[0] == 0);
+ TEST(alltypes.rep_float_count == 5 && alltypes.rep_float[4] == 2010.0f && alltypes.rep_float[0] == 0.0f);
+
+ TEST(alltypes.rep_fixed64_count == 5 && alltypes.rep_fixed64[4] == 2011 && alltypes.rep_fixed64[0] == 0);
+ TEST(alltypes.rep_sfixed64_count == 5 && alltypes.rep_sfixed64[4] == -2012 && alltypes.rep_sfixed64[0] == 0);
+ TEST(alltypes.rep_double_count == 5 && alltypes.rep_double[4] == 2013.0 && alltypes.rep_double[0] == 0.0);
+
+ TEST(alltypes.rep_string_count == 5 && strcmp(alltypes.rep_string[4], "2014") == 0 && alltypes.rep_string[0][0] == '\0');
+ TEST(alltypes.rep_bytes_count == 5 && alltypes.rep_bytes[4].size == 4 && alltypes.rep_bytes[0].size == 0);
+ TEST(memcmp(alltypes.rep_bytes[4].bytes, "2015", 4) == 0);
+
+ TEST(alltypes.rep_submsg_count == 5);
+ TEST(strcmp(alltypes.rep_submsg[4].substuff1, "2016") == 0 && alltypes.rep_submsg[0].substuff1[0] == '\0');
+ TEST(alltypes.rep_submsg[4].substuff2 == 2016 && alltypes.rep_submsg[0].substuff2 == 0);
+ TEST(alltypes.rep_submsg[4].substuff3 == 2016 && alltypes.rep_submsg[0].substuff3 == 3);
+
+ TEST(alltypes.rep_enum_count == 5 && alltypes.rep_enum[4] == MyEnum_Truth && alltypes.rep_enum[0] == MyEnum_Zero);
+
+ if (mode == 0)
+ {
+ /* Expect default values */
+ TEST(alltypes.has_opt_int32 == false);
+ TEST(alltypes.opt_int32 == 4041);
+ TEST(alltypes.has_opt_int64 == false);
+ TEST(alltypes.opt_int64 == 4042);
+ TEST(alltypes.has_opt_uint32 == false);
+ TEST(alltypes.opt_uint32 == 4043);
+ TEST(alltypes.has_opt_uint64 == false);
+ TEST(alltypes.opt_uint64 == 4044);
+ TEST(alltypes.has_opt_sint32 == false);
+ TEST(alltypes.opt_sint32 == 4045);
+ TEST(alltypes.has_opt_sint64 == false);
+ TEST(alltypes.opt_sint64 == 4046);
+ TEST(alltypes.has_opt_bool == false);
+ TEST(alltypes.opt_bool == false);
+
+ TEST(alltypes.has_opt_fixed32 == false);
+ TEST(alltypes.opt_fixed32 == 4048);
+ TEST(alltypes.has_opt_sfixed32 == false);
+ TEST(alltypes.opt_sfixed32 == 4049);
+ TEST(alltypes.has_opt_float == false);
+ TEST(alltypes.opt_float == 4050.0f);
+
+ TEST(alltypes.has_opt_fixed64 == false);
+ TEST(alltypes.opt_fixed64 == 4051);
+ TEST(alltypes.has_opt_sfixed64 == false);
+ TEST(alltypes.opt_sfixed64 == 4052);
+ TEST(alltypes.has_opt_double == false);
+ TEST(alltypes.opt_double == 4053.0);
+
+ TEST(alltypes.has_opt_string == false);
+ TEST(strcmp(alltypes.opt_string, "4054") == 0);
+ TEST(alltypes.has_opt_bytes == false);
+ TEST(alltypes.opt_bytes.size == 4);
+ TEST(memcmp(alltypes.opt_bytes.bytes, "4055", 4) == 0);
+ TEST(alltypes.has_opt_submsg == false);
+ TEST(strcmp(alltypes.opt_submsg.substuff1, "1") == 0);
+ TEST(alltypes.opt_submsg.substuff2 == 2);
+ TEST(alltypes.opt_submsg.substuff3 == 3);
+ TEST(alltypes.has_opt_enum == false);
+ TEST(alltypes.opt_enum == MyEnum_Second);
+ }
+ else
+ {
+ /* Expect filled-in values */
+ TEST(alltypes.has_opt_int32 == true);
+ TEST(alltypes.opt_int32 == 3041);
+ TEST(alltypes.has_opt_int64 == true);
+ TEST(alltypes.opt_int64 == 3042);
+ TEST(alltypes.has_opt_uint32 == true);
+ TEST(alltypes.opt_uint32 == 3043);
+ TEST(alltypes.has_opt_uint64 == true);
+ TEST(alltypes.opt_uint64 == 3044);
+ TEST(alltypes.has_opt_sint32 == true);
+ TEST(alltypes.opt_sint32 == 3045);
+ TEST(alltypes.has_opt_sint64 == true);
+ TEST(alltypes.opt_sint64 == 3046);
+ TEST(alltypes.has_opt_bool == true);
+ TEST(alltypes.opt_bool == true);
+
+ TEST(alltypes.has_opt_fixed32 == true);
+ TEST(alltypes.opt_fixed32 == 3048);
+ TEST(alltypes.has_opt_sfixed32 == true);
+ TEST(alltypes.opt_sfixed32 == 3049);
+ TEST(alltypes.has_opt_float == true);
+ TEST(alltypes.opt_float == 3050.0f);
+
+ TEST(alltypes.has_opt_fixed64 == true);
+ TEST(alltypes.opt_fixed64 == 3051);
+ TEST(alltypes.has_opt_sfixed64 == true);
+ TEST(alltypes.opt_sfixed64 == 3052);
+ TEST(alltypes.has_opt_double == true);
+ TEST(alltypes.opt_double == 3053.0);
+
+ TEST(alltypes.has_opt_string == true);
+ TEST(strcmp(alltypes.opt_string, "3054") == 0);
+ TEST(alltypes.has_opt_bytes == true);
+ TEST(alltypes.opt_bytes.size == 4);
+ TEST(memcmp(alltypes.opt_bytes.bytes, "3055", 4) == 0);
+ TEST(alltypes.has_opt_submsg == true);
+ TEST(strcmp(alltypes.opt_submsg.substuff1, "3056") == 0);
+ TEST(alltypes.opt_submsg.substuff2 == 3056);
+ TEST(alltypes.opt_submsg.substuff3 == 3);
+ TEST(alltypes.has_opt_enum == true);
+ TEST(alltypes.opt_enum == MyEnum_Truth);
+ }
+
+ TEST(alltypes.end == 1099);
+
+ return true;
+}
+
+int main(int argc, char **argv)
+{
+ /* Whether to expect the optional values or the default values. */
+ int mode = (argc > 1) ? atoi(argv[1]) : 0;
+
+ /* Read the data into buffer */
+ uint8_t buffer[1024];
+ size_t count = fread(buffer, 1, sizeof(buffer), stdin);
+
+ /* Construct a pb_istream_t for reading from the buffer */
+ pb_istream_t stream = pb_istream_from_buffer(buffer, count);
+
+ /* Decode and print out the stuff */
+ if (!check_alltypes(&stream, mode))
+ {
+ printf("Parsing failed: %s\n", PB_GET_ERROR(&stream));
+ return 1;
+ } else {
+ return 0;
+ }
+}
diff --git a/tests/bc_encode.c b/tests/bc_encode.c
new file mode 100644
index 00000000..e84f0908
--- /dev/null
+++ b/tests/bc_encode.c
@@ -0,0 +1,131 @@
+/* Attempts to test all the datatypes supported by ProtoBuf.
+ * This is a backwards-compatibility test, using bc_alltypes.pb.h.
+ * It is similar to test_encode3, but duplicated in order to allow
+ * test_encode3 to test any new features introduced later.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pb_encode.h>
+#include "bc_alltypes.pb.h"
+
+int main(int argc, char **argv)
+{
+ int mode = (argc > 1) ? atoi(argv[1]) : 0;
+
+ /* Initialize the structure with constants */
+ AllTypes alltypes = {0};
+
+ alltypes.req_int32 = -1001;
+ alltypes.req_int64 = -1002;
+ alltypes.req_uint32 = 1003;
+ alltypes.req_uint64 = 1004;
+ alltypes.req_sint32 = -1005;
+ alltypes.req_sint64 = -1006;
+ alltypes.req_bool = true;
+
+ alltypes.req_fixed32 = 1008;
+ alltypes.req_sfixed32 = -1009;
+ alltypes.req_float = 1010.0f;
+
+ alltypes.req_fixed64 = 1011;
+ alltypes.req_sfixed64 = -1012;
+ alltypes.req_double = 1013.0;
+
+ strcpy(alltypes.req_string, "1014");
+ alltypes.req_bytes.size = 4;
+ memcpy(alltypes.req_bytes.bytes, "1015", 4);
+ strcpy(alltypes.req_submsg.substuff1, "1016");
+ alltypes.req_submsg.substuff2 = 1016;
+ alltypes.req_enum = MyEnum_Truth;
+
+ alltypes.rep_int32_count = 5; alltypes.rep_int32[4] = -2001;
+ alltypes.rep_int64_count = 5; alltypes.rep_int64[4] = -2002;
+ alltypes.rep_uint32_count = 5; alltypes.rep_uint32[4] = 2003;
+ alltypes.rep_uint64_count = 5; alltypes.rep_uint64[4] = 2004;
+ alltypes.rep_sint32_count = 5; alltypes.rep_sint32[4] = -2005;
+ alltypes.rep_sint64_count = 5; alltypes.rep_sint64[4] = -2006;
+ alltypes.rep_bool_count = 5; alltypes.rep_bool[4] = true;
+
+ alltypes.rep_fixed32_count = 5; alltypes.rep_fixed32[4] = 2008;
+ alltypes.rep_sfixed32_count = 5; alltypes.rep_sfixed32[4] = -2009;
+ alltypes.rep_float_count = 5; alltypes.rep_float[4] = 2010.0f;
+
+ alltypes.rep_fixed64_count = 5; alltypes.rep_fixed64[4] = 2011;
+ alltypes.rep_sfixed64_count = 5; alltypes.rep_sfixed64[4] = -2012;
+ alltypes.rep_double_count = 5; alltypes.rep_double[4] = 2013.0;
+
+ alltypes.rep_string_count = 5; strcpy(alltypes.rep_string[4], "2014");
+ alltypes.rep_bytes_count = 5; alltypes.rep_bytes[4].size = 4;
+ memcpy(alltypes.rep_bytes[4].bytes, "2015", 4);
+
+ alltypes.rep_submsg_count = 5;
+ strcpy(alltypes.rep_submsg[4].substuff1, "2016");
+ alltypes.rep_submsg[4].substuff2 = 2016;
+ alltypes.rep_submsg[4].has_substuff3 = true;
+ alltypes.rep_submsg[4].substuff3 = 2016;
+
+ alltypes.rep_enum_count = 5; alltypes.rep_enum[4] = MyEnum_Truth;
+
+ if (mode != 0)
+ {
+ /* Fill in values for optional fields */
+ alltypes.has_opt_int32 = true;
+ alltypes.opt_int32 = 3041;
+ alltypes.has_opt_int64 = true;
+ alltypes.opt_int64 = 3042;
+ alltypes.has_opt_uint32 = true;
+ alltypes.opt_uint32 = 3043;
+ alltypes.has_opt_uint64 = true;
+ alltypes.opt_uint64 = 3044;
+ alltypes.has_opt_sint32 = true;
+ alltypes.opt_sint32 = 3045;
+ alltypes.has_opt_sint64 = true;
+ alltypes.opt_sint64 = 3046;
+ alltypes.has_opt_bool = true;
+ alltypes.opt_bool = true;
+
+ alltypes.has_opt_fixed32 = true;
+ alltypes.opt_fixed32 = 3048;
+ alltypes.has_opt_sfixed32 = true;
+ alltypes.opt_sfixed32 = 3049;
+ alltypes.has_opt_float = true;
+ alltypes.opt_float = 3050.0f;
+
+ alltypes.has_opt_fixed64 = true;
+ alltypes.opt_fixed64 = 3051;
+ alltypes.has_opt_sfixed64 = true;
+ alltypes.opt_sfixed64 = 3052;
+ alltypes.has_opt_double = true;
+ alltypes.opt_double = 3053.0;
+
+ alltypes.has_opt_string = true;
+ strcpy(alltypes.opt_string, "3054");
+ alltypes.has_opt_bytes = true;
+ alltypes.opt_bytes.size = 4;
+ memcpy(alltypes.opt_bytes.bytes, "3055", 4);
+ alltypes.has_opt_submsg = true;
+ strcpy(alltypes.opt_submsg.substuff1, "3056");
+ alltypes.opt_submsg.substuff2 = 3056;
+ alltypes.has_opt_enum = true;
+ alltypes.opt_enum = MyEnum_Truth;
+ }
+
+ alltypes.end = 1099;
+
+ uint8_t buffer[1024];
+ pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
+
+ /* Now encode it and check if we succeeded. */
+ if (pb_encode(&stream, AllTypes_fields, &alltypes))
+ {
+ fwrite(buffer, 1, stream.bytes_written, stdout);
+ return 0; /* Success */
+ }
+ else
+ {
+ fprintf(stderr, "Encoding failed!\n");
+ return 1; /* Failure */
+ }
+}