From 1265baa325cc1f27061d088082f31c95eaf5d135 Mon Sep 17 00:00:00 2001 From: lahiker42 Date: Sun, 24 Aug 2008 03:00:21 +0000 Subject: [PATCH] many bug fixes, and lots of test code git-svn-id: https://protobuf-c.googlecode.com/svn/trunk@36 00440858-1255-0410-a3e6-75ea37f81c3a --- TODO | 1 - src/google/protobuf-c/protobuf-c.c | 132 +++- .../protobuf/compiler/c/c_bytes_field.cc | 13 +- src/test/common-test-arrays.h | 32 + src/test/cxx-generate-packed-data.cc | 250 +++++++ src/test/test-full.proto | 4 +- src/test/test-generated-code2.c | 685 ++++++++++++++++-- 7 files changed, 1027 insertions(+), 90 deletions(-) create mode 100644 src/test/common-test-arrays.h diff --git a/TODO b/TODO index 89a0358..67e7be5 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,6 @@ - check over documentation again - handle unknown fields when packing - test code - - ensure enums are 32-bit - make services derive from ProtobufCService; be usable with a cast. - provide example rpc diff --git a/src/google/protobuf-c/protobuf-c.c b/src/google/protobuf-c/protobuf-c.c index e464369..12055eb 100644 --- a/src/google/protobuf-c/protobuf-c.c +++ b/src/google/protobuf-c/protobuf-c.c @@ -1,6 +1,21 @@ #include /* for occasional printf()s */ #include /* for abort(), malloc() etc */ #include /* for strlen(), memcpy(), memmove() */ +#include + +#define DO_LITTLE_ENDIAN_OPTIMIZATIONS 0 +#define PRINT_UNPACK_ERRORS 1 + +#if DO_LITTLE_ENDIAN_OPTIMIZATIONS +# if (__LITTLE_ENDIAN == __BYTE_ORDER) +# define IS_LITTLE_ENDIAN 1 +# else +# define IS_LITTLE_ENDIAN 0 +# endif +#endif + + +/* This file defines `__BYTE_ORDER' for the particular machine. */ #include "protobuf-c.h" @@ -123,6 +138,23 @@ uint32_size (uint32_t v) else return 5; } +static inline size_t +int32_size (int32_t v) +{ + if (v < 0) + return 10; + else + if (v < (1<<7)) + return 1; + else if (v < (1<<14)) + return 2; + else if (v < (1<<21)) + return 3; + else if (v < (1<<28)) + return 4; + else + return 5; +} static inline uint32_t zigzag32 (int32_t v) { @@ -164,7 +196,7 @@ zigzag64 (int64_t v) return v * 2; } static inline size_t -sint64_size (int32_t v) +sint64_size (int64_t v) { return uint64_size(zigzag64(v)); } @@ -179,10 +211,11 @@ required_field_get_packed_size (const ProtobufCFieldDescriptor *field, case PROTOBUF_C_TYPE_SINT32: return rv + sint32_size (*(int32_t *) member); case PROTOBUF_C_TYPE_INT32: + return rv + int32_size (*(uint32_t *) member); case PROTOBUF_C_TYPE_UINT32: return rv + uint32_size (*(uint32_t *) member); case PROTOBUF_C_TYPE_SINT64: - return rv + sint64_size (*(int32_t *) member); + return rv + sint64_size (*(int64_t *) member); case PROTOBUF_C_TYPE_INT64: case PROTOBUF_C_TYPE_UINT64: return rv + uint64_size (*(uint64_t *) member); @@ -256,6 +289,9 @@ repeated_field_get_packed_size (const ProtobufCFieldDescriptor *field, rv += sint32_size (((int32_t*)array)[i]); break; case PROTOBUF_C_TYPE_INT32: + for (i = 0; i < count; i++) + rv += int32_size (((uint32_t*)array)[i]); + break; case PROTOBUF_C_TYPE_UINT32: case PROTOBUF_C_TYPE_ENUM: for (i = 0; i < count; i++) @@ -355,6 +391,23 @@ uint32_pack (uint32_t value, BYTE *out) out[rv++] = value; return rv; } +static inline size_t +int32_pack (int32_t value, BYTE *out) +{ + if (value < 0) + { + out[0] = value | 0x80; + out[1] = (value>>7) | 0x80; + out[2] = (value>>14) | 0x80; + out[3] = (value>>21) | 0x80; + out[4] = (value>>28) | 0x80; + out[5] = out[6] = out[7] = out[8] = 0xff; + out[9] = 0x01; + return 10; + } + else + return uint32_pack (value, out); +} static inline size_t sint32_pack (int32_t value, BYTE *out) { return uint32_pack (zigzag32 (value), out); @@ -367,7 +420,7 @@ uint64_pack (uint64_t value, BYTE *out) unsigned rv; if (hi == 0) return uint32_pack ((uint32_t)lo, out); - out[0] = (lo) & 0x7f; + out[0] = (lo) | 0x80; out[1] = (lo>>7) | 0x80; out[2] = (lo>>14) | 0x80; out[3] = (lo>>21) | 0x80; @@ -466,13 +519,15 @@ required_field_pack (const ProtobufCFieldDescriptor *field, out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; return rv + sint32_pack (*(int32_t *) member, out + rv); case PROTOBUF_C_TYPE_INT32: + out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; + return rv + int32_pack (*(uint32_t *) member, out + rv); case PROTOBUF_C_TYPE_UINT32: case PROTOBUF_C_TYPE_ENUM: out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; return rv + uint32_pack (*(uint32_t *) member, out + rv); case PROTOBUF_C_TYPE_SINT64: out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; - return rv + sint64_pack (*(int32_t *) member, out + rv); + return rv + sint64_pack (*(int64_t *) member, out + rv); case PROTOBUF_C_TYPE_INT64: case PROTOBUF_C_TYPE_UINT64: out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; @@ -622,6 +677,10 @@ required_field_pack_to_buffer (const ProtobufCFieldDescriptor *field, buffer->append (buffer, rv, scratch); break; case PROTOBUF_C_TYPE_INT32: + scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; + rv += int32_pack (*(uint32_t *) member, scratch + rv); + buffer->append (buffer, rv, scratch); + break; case PROTOBUF_C_TYPE_UINT32: case PROTOBUF_C_TYPE_ENUM: scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; @@ -630,7 +689,7 @@ required_field_pack_to_buffer (const ProtobufCFieldDescriptor *field, break; case PROTOBUF_C_TYPE_SINT64: scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; - rv += sint64_pack (*(int32_t *) member, scratch + rv); + rv += sint64_pack (*(int64_t *) member, scratch + rv); buffer->append (buffer, rv, scratch); break; case PROTOBUF_C_TYPE_INT64: @@ -766,6 +825,12 @@ protobuf_c_message_pack_to_buffer (const ProtobufCMessage *message, } /* === unpacking === */ +#if PRINT_UNPACK_ERRORS +# define UNPACK_ERROR(args) do { printf args;printf("\n"); }while(0) +#else +# define UNPACK_ERROR(args) do { } while (0) +#endif + static inline int int_range_lookup (unsigned n_ranges, const ProtobufCIntRange *ranges, @@ -866,11 +931,18 @@ scan_length_prefixed_data (size_t len, const BYTE *data, size_t *prefix_len_out) break; } if (i == hdr_max) - return 0; + { + UNPACK_ERROR (("error parsing length for length-prefixed data")); + return 0; + } hdr_len = i + 1; *prefix_len_out = hdr_len; if (hdr_len + val > len) - return 0; + { + UNPACK_ERROR (("data too short after length-prefix of %u", + val)); + return 0; + } return hdr_len + val; } @@ -894,6 +966,11 @@ parse_uint32 (unsigned len, const BYTE *data) } return rv; } +static inline uint32_t +parse_int32 (unsigned len, const BYTE *data) +{ + return parse_uint32 (len, data); +} static inline int32_t unzigzag32 (uint32_t v) { @@ -972,6 +1049,10 @@ parse_required_member (ScannedMember *scanned_member, switch (scanned_member->field->type) { case PROTOBUF_C_TYPE_INT32: + if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT) + return 0; + *(uint32_t*)member = parse_int32 (len, data); + return 1; case PROTOBUF_C_TYPE_UINT32: if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT) return 0; @@ -988,7 +1069,7 @@ parse_required_member (ScannedMember *scanned_member, if (wire_type != PROTOBUF_C_WIRE_TYPE_32BIT) return 0; *(uint32_t*)member = parse_fixed_uint32 (data); - break; + return 1; case PROTOBUF_C_TYPE_INT64: case PROTOBUF_C_TYPE_UINT64: @@ -1167,7 +1248,11 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc, const ProtobufCFieldDescriptor *field; ScannedMember tmp; if (used == 0) - goto error_cleanup; + { + UNPACK_ERROR (("error parsing tag/wiretype at offset %u", + (unsigned)(at-data))); + goto error_cleanup; + } /* XXX: consider optimizing for field[1].id == tag, if field[1] exists! */ if (last_field->id != tag) { @@ -1205,13 +1290,21 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc, if ((at[i] & 0x80) == 0) break; if (i == max_len) - goto error_cleanup; + { + UNPACK_ERROR (("unterminated varint at offset %u", + (unsigned)(at-data))); + goto error_cleanup; + } tmp.len = i + 1; } break; case PROTOBUF_C_WIRE_TYPE_64BIT: if (rem < 8) - goto error_cleanup; + { + UNPACK_ERROR (("too short after 64bit wiretype at offset %u", + (unsigned)(at-data))); + goto error_cleanup; + } tmp.len = 8; break; case PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED: @@ -1219,7 +1312,10 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc, size_t pref_len; tmp.len = scan_length_prefixed_data (rem, at, &pref_len); if (tmp.len == 0) - goto error_cleanup; + { + /* NOTE: scan_length_prefixed_data calls UNPACK_ERROR */ + goto error_cleanup; + } tmp.length_prefix_len = pref_len; break; } @@ -1228,7 +1324,11 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc, PROTOBUF_C_ASSERT_NOT_REACHED (); case PROTOBUF_C_WIRE_TYPE_32BIT: if (rem < 4) - goto error_cleanup; + { + UNPACK_ERROR (("too short after 32bit wiretype at offset %u", + (unsigned)(at-data))); + goto error_cleanup; + } tmp.len = 4; break; } @@ -1285,7 +1385,11 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc, for (j = 0; j < max; j++) { if (!parse_member (slab + j, rv, allocator)) - goto error_cleanup; + { + UNPACK_ERROR (("error parsing member %s of %s", + slab->field->name, desc->name)); + goto error_cleanup; + } } } diff --git a/src/google/protobuf/compiler/c/c_bytes_field.cc b/src/google/protobuf/compiler/c/c_bytes_field.cc index d00f384..7322699 100644 --- a/src/google/protobuf/compiler/c/c_bytes_field.cc +++ b/src/google/protobuf/compiler/c/c_bytes_field.cc @@ -68,7 +68,18 @@ void BytesFieldGenerator::GenerateStructMembers(io::Printer* printer) const } void BytesFieldGenerator::GenerateStaticInit(io::Printer* printer) const { - printer->Print("{0,NULL}"); + switch (descriptor_->label()) { + case FieldDescriptor::LABEL_REQUIRED: + printer->Print(variables_, "{0,NULL}"); + break; + case FieldDescriptor::LABEL_OPTIONAL: + printer->Print(variables_, "0,{0,NULL}"); + break; + case FieldDescriptor::LABEL_REPEATED: + // no support for default? + printer->Print("0,NULL"); + break; + } } void BytesFieldGenerator::GenerateDescriptorInitializer(io::Printer* printer) const { diff --git a/src/test/common-test-arrays.h b/src/test/common-test-arrays.h new file mode 100644 index 0000000..5617f39 --- /dev/null +++ b/src/test/common-test-arrays.h @@ -0,0 +1,32 @@ + +#define THOUSAND 1000 +#define MILLION 1000000 +#define BILLION 1000000000 +#define TRILLION 1000000000000LL +#define QUADRILLION 1000000000000000LL +#define QUINTILLION 1000000000000000000LL + +int64_t int64_roundnumbers[15] = { -QUINTILLION, -QUADRILLION, -TRILLION, + -BILLION, -MILLION, -THOUSAND, + 1, + THOUSAND, MILLION, BILLION, + TRILLION, QUADRILLION, QUINTILLION }; +int64_t int64_min_max[2] = { INT64_MIN, INT64_MAX }; + +uint64_t uint64_roundnumbers[9] = { 1, + THOUSAND, MILLION, BILLION, + TRILLION, QUADRILLION, QUINTILLION }; +uint64_t uint64_0_1_max[3] = { 0, 1, UINT64_MAX }; +uint64_t uint64_random[] = {0, + 666, + 4200000000ULL, + 16ULL * (uint64_t) QUINTILLION + 33 }; + +#define FLOATING_POINT_RANDOM \ +-1000.0, -100.0, -42.0, 0, 666, 131313 +float float_random[] = { FLOATING_POINT_RANDOM }; +double double_random[] = { FLOATING_POINT_RANDOM }; + +protobuf_c_boolean boolean_0[] = {0 }; +protobuf_c_boolean boolean_1[] = {1 }; +protobuf_c_boolean boolean_random[] = {0,1,1,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,1,0,1,1,0,1,1,0 }; diff --git a/src/test/cxx-generate-packed-data.cc b/src/test/cxx-generate-packed-data.cc index 2b4ade4..ceeb9b6 100644 --- a/src/test/cxx-generate-packed-data.cc +++ b/src/test/cxx-generate-packed-data.cc @@ -1,10 +1,16 @@ /* generate byte arrays that match the constructs in test-generated-code2.c. * these are tested against eachother to make sure the c and c++ agree. */ +#define __STDC_LIMIT_MACROS #include "generated-code/test-full.pb.h" +#include using namespace foo; +#define protobuf_c_boolean bool +#include "common-test-arrays.h" +#define N_ELEMENTS(arr) (sizeof(arr)/sizeof((arr)[0])) + static void dump_message_bytes(google::protobuf::Message *message, const char *label) @@ -66,10 +72,254 @@ dump_test_field_numbers (void) DUMP_ONE (33554432) #undef DUMP_ONE } +static void dump_test_repeated_int32 (void) +{ + TestMess mess; + + mess.clear_test_int32 (); + dump_message_bytes(&mess, "test_repeated_int32__empty"); + mess.add_test_int32(-1); + dump_message_bytes(&mess, "test_repeated_int32_m1"); + mess.add_test_int32(1); + dump_message_bytes(&mess, "test_repeated_int32_m1_1"); + mess.clear_test_int32 (); + mess.add_test_int32(1); + dump_message_bytes(&mess, "test_repeated_int32_1"); + mess.clear_test_int32 (); + mess.add_test_int32(42); + mess.add_test_int32(666); + mess.add_test_int32(-1123123); + mess.add_test_int32(0); + mess.add_test_int32(47); + dump_message_bytes(&mess, "test_repeated_int32_42_666_m1123123_0_47"); + mess.clear_test_int32 (); + mess.add_test_int32(INT32_MIN); + dump_message_bytes(&mess, "test_repeated_int32_min"); + mess.clear_test_int32 (); + mess.add_test_int32(INT32_MAX); + dump_message_bytes(&mess, "test_repeated_int32_max"); +} +static void dump_test_repeated_sint32 (void) +{ + TestMess mess; + + mess.clear_test_sint32 (); + dump_message_bytes(&mess, "test_repeated_sint32__empty"); + mess.add_test_sint32(-1); + dump_message_bytes(&mess, "test_repeated_sint32_m1"); + mess.add_test_sint32(1); + dump_message_bytes(&mess, "test_repeated_sint32_m1_1"); + mess.clear_test_sint32 (); + mess.add_test_sint32(1); + dump_message_bytes(&mess, "test_repeated_sint32_1"); + mess.clear_test_sint32 (); + mess.add_test_sint32(42); + mess.add_test_sint32(666); + mess.add_test_sint32(-1123123); + mess.add_test_sint32(0); + mess.add_test_sint32(47); + dump_message_bytes(&mess, "test_repeated_sint32_42_666_m1123123_0_47"); + mess.clear_test_sint32 (); + mess.add_test_sint32(INT32_MIN); + dump_message_bytes(&mess, "test_repeated_sint32_min"); + mess.clear_test_sint32 (); + mess.add_test_sint32(INT32_MAX); + dump_message_bytes(&mess, "test_repeated_sint32_max"); +} +static void dump_test_repeated_uint32 (void) +{ + TestMess mess; + mess.add_test_uint32(BILLION); + mess.add_test_uint32(MILLION); + mess.add_test_uint32(1); + mess.add_test_uint32(0); + dump_message_bytes (&mess, "test_repeated_uint32_bil_mil_1_0"); + mess.clear_test_uint32(); + mess.add_test_uint32(0); + dump_message_bytes (&mess, "test_repeated_uint32_0"); + mess.clear_test_uint32(); + mess.add_test_uint32(UINT32_MAX); + dump_message_bytes (&mess, "test_repeated_uint32_max"); +} +static void dump_test_repeated_sfixed32 (void) +{ + TestMess mess; + + mess.clear_test_sfixed32 (); + dump_message_bytes(&mess, "test_repeated_sfixed32__empty"); + mess.add_test_sfixed32(-1); + dump_message_bytes(&mess, "test_repeated_sfixed32_m1"); + mess.add_test_sfixed32(1); + dump_message_bytes(&mess, "test_repeated_sfixed32_m1_1"); + mess.clear_test_sfixed32 (); + mess.add_test_sfixed32(1); + dump_message_bytes(&mess, "test_repeated_sfixed32_1"); + mess.clear_test_sfixed32 (); + mess.add_test_sfixed32(42); + mess.add_test_sfixed32(666); + mess.add_test_sfixed32(-1123123); + mess.add_test_sfixed32(0); + mess.add_test_sfixed32(47); + dump_message_bytes(&mess, "test_repeated_sfixed32_42_666_m1123123_0_47"); + mess.clear_test_sfixed32 (); + mess.add_test_sfixed32(INT32_MIN); + dump_message_bytes(&mess, "test_repeated_sfixed32_min"); + mess.clear_test_sfixed32 (); + mess.add_test_sfixed32(INT32_MAX); + dump_message_bytes(&mess, "test_repeated_sfixed32_max"); +} +static void dump_test_repeated_fixed32 (void) +{ + TestMess mess; + mess.add_test_fixed32(BILLION); + mess.add_test_fixed32(MILLION); + mess.add_test_fixed32(1); + mess.add_test_fixed32(0); + dump_message_bytes (&mess, "test_repeated_fixed32_bil_mil_1_0"); + mess.clear_test_fixed32(); + mess.add_test_fixed32(0); + dump_message_bytes (&mess, "test_repeated_fixed32_0"); + mess.clear_test_fixed32(); + mess.add_test_fixed32(UINT32_MAX); + dump_message_bytes (&mess, "test_repeated_fixed32_max"); +} +static void dump_test_repeated_int64 (void) +{ + TestMess mess; + for (unsigned i = 0; i < N_ELEMENTS (int64_roundnumbers); i++) + mess.add_test_int64(int64_roundnumbers[i]); + dump_message_bytes(&mess, "test_repeated_int64_roundnumbers"); + mess.clear_test_int64(); + for (unsigned i = 0; i < N_ELEMENTS (int64_min_max); i++) + mess.add_test_int64(int64_min_max[i]); + dump_message_bytes(&mess, "test_repeated_int64_min_max"); +} + +static void dump_test_repeated_sint64 (void) +{ + TestMess mess; + for (unsigned i = 0; i < N_ELEMENTS (int64_roundnumbers); i++) + mess.add_test_sint64(int64_roundnumbers[i]); + dump_message_bytes(&mess, "test_repeated_sint64_roundnumbers"); + mess.clear_test_sint64(); + for (unsigned i = 0; i < N_ELEMENTS (int64_min_max); i++) + mess.add_test_sint64(int64_min_max[i]); + dump_message_bytes(&mess, "test_repeated_sint64_min_max"); +} + +static void dump_test_repeated_sfixed64 (void) +{ + TestMess mess; + for (unsigned i = 0; i < N_ELEMENTS (int64_roundnumbers); i++) + mess.add_test_sfixed64(int64_roundnumbers[i]); + dump_message_bytes(&mess, "test_repeated_sfixed64_roundnumbers"); + mess.clear_test_sfixed64(); + for (unsigned i = 0; i < N_ELEMENTS (int64_min_max); i++) + mess.add_test_sfixed64(int64_min_max[i]); + dump_message_bytes(&mess, "test_repeated_sfixed64_min_max"); +} +static void dump_test_repeated_uint64 (void) +{ + TestMess mess; +#define DUMP_STATIC_ARRAY(static_array, output_array_name) \ + do{ \ + mess.clear_test_uint64(); \ + for (unsigned i = 0; i < N_ELEMENTS (static_array); i++) \ + mess.add_test_uint64(static_array[i]); \ + dump_message_bytes(&mess, output_array_name); \ + }while(0) + + DUMP_STATIC_ARRAY(uint64_roundnumbers, "test_repeated_uint64_roundnumbers"); + DUMP_STATIC_ARRAY(uint64_0_1_max, "test_repeated_uint64_0_1_max"); + DUMP_STATIC_ARRAY(uint64_random, "test_repeated_uint64_random"); + +#undef DUMP_STATIC_ARRAY +} +static void dump_test_repeated_fixed64 (void) +{ + TestMess mess; +#define DUMP_STATIC_ARRAY(static_array, output_array_name) \ + do{ \ + mess.clear_test_fixed64(); \ + for (unsigned i = 0; i < N_ELEMENTS (static_array); i++) \ + mess.add_test_fixed64(static_array[i]); \ + dump_message_bytes(&mess, output_array_name); \ + }while(0) + + DUMP_STATIC_ARRAY(uint64_roundnumbers, "test_repeated_fixed64_roundnumbers"); + DUMP_STATIC_ARRAY(uint64_0_1_max, "test_repeated_fixed64_0_1_max"); + DUMP_STATIC_ARRAY(uint64_random, "test_repeated_fixed64_random"); + +#undef DUMP_STATIC_ARRAY +} + +static void dump_test_repeated_float (void) +{ + TestMess mess; +#define DUMP_STATIC_ARRAY(static_array, output_array_name) \ + do{ \ + mess.clear_test_float(); \ + for (unsigned i = 0; i < N_ELEMENTS (static_array); i++) \ + mess.add_test_float(static_array[i]); \ + dump_message_bytes(&mess, output_array_name); \ + }while(0) + + DUMP_STATIC_ARRAY(float_random, "test_repeated_float_random"); + +#undef DUMP_STATIC_ARRAY +} + +static void dump_test_repeated_double (void) +{ + TestMess mess; +#define DUMP_STATIC_ARRAY(static_array, output_array_name) \ + do{ \ + mess.clear_test_double(); \ + for (unsigned i = 0; i < N_ELEMENTS (static_array); i++) \ + mess.add_test_double(static_array[i]); \ + dump_message_bytes(&mess, output_array_name); \ + }while(0) + + DUMP_STATIC_ARRAY(double_random, "test_repeated_double_random"); + +#undef DUMP_STATIC_ARRAY +} +static void dump_test_repeated_boolean (void) +{ + TestMess mess; +#define DUMP_STATIC_ARRAY(static_array, output_array_name) \ + do{ \ + mess.clear_test_boolean(); \ + for (unsigned i = 0; i < N_ELEMENTS (static_array); i++) \ + mess.add_test_boolean(static_array[i]); \ + dump_message_bytes(&mess, output_array_name); \ + }while(0) + + DUMP_STATIC_ARRAY(boolean_0, "test_repeated_boolean_0"); + DUMP_STATIC_ARRAY(boolean_1, "test_repeated_boolean_1"); + DUMP_STATIC_ARRAY(boolean_random, "test_repeated_boolean_random"); + +#undef DUMP_STATIC_ARRAY +} + + int main(int argc, char **argv) { dump_test_enum_small (); dump_test_enum_big (); dump_test_field_numbers (); + dump_test_repeated_int32 (); + dump_test_repeated_sint32 (); + dump_test_repeated_uint32 (); + dump_test_repeated_sfixed32 (); + dump_test_repeated_fixed32 (); + dump_test_repeated_int64 (); + dump_test_repeated_sint64 (); + dump_test_repeated_sfixed64 (); + dump_test_repeated_uint64 (); + dump_test_repeated_fixed64 (); + dump_test_repeated_float (); + dump_test_repeated_double (); + dump_test_repeated_boolean (); return 0; } diff --git a/src/test/test-full.proto b/src/test/test-full.proto index 34b0f85..941e73f 100644 --- a/src/test/test-full.proto +++ b/src/test/test-full.proto @@ -58,7 +58,7 @@ message TestMess { repeated fixed64 test_fixed64 = 10; repeated float test_float = 11; repeated double test_double = 12; - repeated bool test_bool = 13; + repeated bool test_boolean = 13; repeated TestEnumSmall test_enum_small = 14; repeated TestEnum test_enum = 15; repeated string test_string = 16; @@ -79,7 +79,7 @@ message TestMessOptional { optional fixed64 test_fixed64 = 10; optional float test_float = 11; optional double test_double = 12; - optional bool test_bool = 13; + optional bool test_boolean = 13; optional TestEnum test_enum = 14; optional string test_string = 15; optional bytes test_bytes = 16; diff --git a/src/test/test-generated-code2.c b/src/test/test-generated-code2.c index 820ccac..faf393c 100644 --- a/src/test/test-generated-code2.c +++ b/src/test/test-generated-code2.c @@ -4,6 +4,9 @@ #include "generated-code/test-full.pb-c.h" #include "generated-code/test-full-cxx-output.inc" +#include "common-test-arrays.h" +#define N_ELEMENTS(arr) (sizeof(arr)/sizeof((arr)[0])) + /* ==== helper functions ==== */ static protobuf_c_boolean are_bytes_equal (unsigned actual_len, @@ -15,9 +18,39 @@ are_bytes_equal (unsigned actual_len, return 0; return memcmp (actual_data, expected_data, actual_len) == 0; } +static void +dump_bytes_stderr (size_t len, const uint8_t *data) +{ + size_t i; + for (i = 0; i < len; i++) + fprintf(stderr," %02x", data[i]); + fprintf(stderr,"\n"); +} +static void +test_versus_static_array(unsigned actual_len, + const uint8_t *actual_data, + unsigned expected_len, + const uint8_t *expected_data, + const char *static_buf_name, + const char *filename, + unsigned lineno) +{ + if (are_bytes_equal (actual_len, actual_data, expected_len, expected_data)) + return; + + fprintf (stderr, "test_versus_static_array failed:\n" + "actual: [length=%u]\n", actual_len); + dump_bytes_stderr (actual_len, actual_data); + fprintf (stderr, "expected: [length=%u] [buffer %s]\n", + expected_len, static_buf_name); + dump_bytes_stderr (expected_len, expected_data); + fprintf (stderr, "at line %u of %s.\n", lineno, filename); + abort(); +} + #define TEST_VERSUS_STATIC_ARRAY(actual_len, actual_data, buf) \ - assert(are_bytes_equal(actual_len,actual_data, \ - sizeof(buf), buf)) + test_versus_static_array(actual_len,actual_data, \ + sizeof(buf), buf, #buf, __FILE__, __LINE__) /* rv is unpacked message */ static void * @@ -46,30 +79,52 @@ test_compare_pack_methods (ProtobufCMessage *message, return rv; } +#define NUMERIC_EQUALS(a,b) ((a) == (b)) +#define STRING_EQUALS(a,b) (strcmp((a),(b))==0) +#define DO_TEST_REPEATED(lc_member_name, static_array, example_packed_data, \ + equals_macro) \ + do{ \ + Foo__TestMess mess = FOO__TEST_MESS__INIT; \ + Foo__TestMess *mess2; \ + size_t len; \ + uint8_t *data; \ + unsigned i; \ + mess.n_##lc_member_name = N_ELEMENTS (static_array); \ + mess.lc_member_name = static_array; \ + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); \ + assert(mess2->n_##lc_member_name == N_ELEMENTS (static_array)); \ + for (i = 0; i < N_ELEMENTS (static_array); i++) \ + assert(equals_macro(mess2->lc_member_name[i], static_array[i])); \ + TEST_VERSUS_STATIC_ARRAY (len, data, example_packed_data); \ + free (data); \ + foo__test_mess__free_unpacked (mess2, NULL); \ + }while(0) + /* === the actual tests === */ static void test_enum_small (void) { - Foo__TestMessRequiredEnumSmall small = FOO__TEST_MESS_REQUIRED_ENUM_SMALL__INIT; - size_t len; - uint8_t *data; - Foo__TestMessRequiredEnumSmall *unpacked; + +#define DO_TEST(UC_VALUE) \ + do{ \ + Foo__TestMessRequiredEnumSmall small = FOO__TEST_MESS_REQUIRED_ENUM_SMALL__INIT; \ + size_t len; \ + uint8_t *data; \ + Foo__TestMessRequiredEnumSmall *unpacked; \ + small.test = FOO__TEST_ENUM_SMALL__##UC_VALUE; \ + unpacked = test_compare_pack_methods ((ProtobufCMessage*)&small, &len, &data); \ + assert (unpacked->test == FOO__TEST_ENUM_SMALL__##UC_VALUE); \ + foo__test_mess_required_enum_small__free_unpacked (unpacked, NULL); \ + TEST_VERSUS_STATIC_ARRAY (len, data, test_enum_small_##UC_VALUE); \ + free (data); \ + }while(0) assert (sizeof (Foo__TestEnumSmall) == 4); - small.test = FOO__TEST_ENUM_SMALL__VALUE; - unpacked = test_compare_pack_methods ((ProtobufCMessage*)&small, &len, &data); - assert (unpacked->test == FOO__TEST_ENUM_SMALL__VALUE); - foo__test_mess_required_enum_small__free_unpacked (unpacked, NULL); - TEST_VERSUS_STATIC_ARRAY (len, data, test_enum_small_VALUE); - free (data); + DO_TEST(VALUE); + DO_TEST(OTHER_VALUE); - small.test = FOO__TEST_ENUM_SMALL__OTHER_VALUE; - unpacked = test_compare_pack_methods ((ProtobufCMessage*)&small, &len, &data); - assert (unpacked->test == FOO__TEST_ENUM_SMALL__OTHER_VALUE); - foo__test_mess_required_enum_small__free_unpacked (unpacked, NULL); - TEST_VERSUS_STATIC_ARRAY (len, data, test_enum_small_OTHER_VALUE); - free (data); +#undef DO_TEST } static void test_enum_big (void) @@ -132,6 +187,492 @@ static void test_field_numbers (void) DO_ONE_TEST (33554432, 5 + 1 + 3); #undef DO_ONE_TEST } +static void test_repeated_int32 (void) +{ + Foo__TestMess mess = FOO__TEST_MESS__INIT; + Foo__TestMess *mess2; + int32_t arr0[2] = { -1, 1 }; + int32_t arr1[5] = { 42, 666, -1123123, 0, 47 }; + int32_t arr_min[1] = { INT32_MIN }; + int32_t arr_max[1] = { INT32_MAX }; + size_t len; + uint8_t *data; + + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_int32 == 0); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_int32__empty); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); + + mess.n_test_int32 = 1; + mess.test_int32 = arr0; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_int32 == 1); + assert(mess2->test_int32[0] == -1); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_int32_m1); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); + + mess.n_test_int32 = 1; + mess.test_int32 = arr0+1; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_int32 == 1); + assert(mess2->test_int32[0] == 1); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_int32_1); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); + + mess.n_test_int32 = 2; + mess.test_int32 = arr0; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_int32 == 2); + assert(mess2->test_int32[0] == -1); + assert(mess2->test_int32[1] == 1); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_int32_m1_1); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); + + mess.n_test_int32 = 5; + mess.test_int32 = arr1; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_int32 == 5); + assert(memcmp (mess2->test_int32, arr1, 4*5)==0); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_int32_42_666_m1123123_0_47); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); + + mess.n_test_int32 = 1; + mess.test_int32 = arr_min; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_int32 == 1); + assert(mess2->test_int32[0] == INT32_MIN); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_int32_min); + free (data); + + mess.n_test_int32 = 1; + mess.test_int32 = arr_max; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_int32 == 1); + assert(mess2->test_int32[0] == INT32_MAX); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_int32_max); + free (data); +} + +static void test_repeated_sint32 (void) +{ + Foo__TestMess mess = FOO__TEST_MESS__INIT; + Foo__TestMess *mess2; + int32_t arr0[2] = { -1, 1 }; + int32_t arr1[5] = { 42, 666, -1123123, 0, 47 }; + int32_t arr_min[1] = { INT32_MIN }; + int32_t arr_max[1] = { INT32_MAX }; + size_t len; + uint8_t *data; + + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_sint32 == 0); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sint32__empty); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); + + mess.n_test_sint32 = 1; + mess.test_sint32 = arr0; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_sint32 == 1); + assert(mess2->test_sint32[0] == -1); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sint32_m1); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); + + mess.n_test_sint32 = 1; + mess.test_sint32 = arr0+1; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_sint32 == 1); + assert(mess2->test_sint32[0] == 1); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sint32_1); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); + + mess.n_test_sint32 = 2; + mess.test_sint32 = arr0; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_sint32 == 2); + assert(mess2->test_sint32[0] == -1); + assert(mess2->test_sint32[1] == 1); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sint32_m1_1); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); + + mess.n_test_sint32 = 5; + mess.test_sint32 = arr1; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_sint32 == 5); + assert(memcmp (mess2->test_sint32, arr1, 4*5)==0); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sint32_42_666_m1123123_0_47); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); + + mess.n_test_sint32 = 1; + mess.test_sint32 = arr_min; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_sint32 == 1); + assert(mess2->test_sint32[0] == INT32_MIN); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sint32_min); + free (data); + + mess.n_test_sint32 = 1; + mess.test_sint32 = arr_max; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_sint32 == 1); + assert(mess2->test_sint32[0] == INT32_MAX); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sint32_max); + free (data); +} + +static void test_repeated_sfixed32 (void) +{ + Foo__TestMess mess = FOO__TEST_MESS__INIT; + Foo__TestMess *mess2; + int32_t arr0[2] = { -1, 1 }; + int32_t arr1[5] = { 42, 666, -1123123, 0, 47 }; + int32_t arr_min[1] = { INT32_MIN }; + int32_t arr_max[1] = { INT32_MAX }; + size_t len; + uint8_t *data; + + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_sfixed32 == 0); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sfixed32__empty); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); + + mess.n_test_sfixed32 = 1; + mess.test_sfixed32 = arr0; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_sfixed32 == 1); + assert(mess2->test_sfixed32[0] == -1); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sfixed32_m1); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); + + mess.n_test_sfixed32 = 1; + mess.test_sfixed32 = arr0+1; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_sfixed32 == 1); + assert(mess2->test_sfixed32[0] == 1); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sfixed32_1); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); + + mess.n_test_sfixed32 = 2; + mess.test_sfixed32 = arr0; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_sfixed32 == 2); + assert(mess2->test_sfixed32[0] == -1); + assert(mess2->test_sfixed32[1] == 1); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sfixed32_m1_1); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); + + mess.n_test_sfixed32 = 5; + mess.test_sfixed32 = arr1; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_sfixed32 == 5); + assert(memcmp (mess2->test_sfixed32, arr1, 4*5)==0); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sfixed32_42_666_m1123123_0_47); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); + + mess.n_test_sfixed32 = 1; + mess.test_sfixed32 = arr_min; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_sfixed32 == 1); + assert(mess2->test_sfixed32[0] == INT32_MIN); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sfixed32_min); + free (data); + + mess.n_test_sfixed32 = 1; + mess.test_sfixed32 = arr_max; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_sfixed32 == 1); + assert(mess2->test_sfixed32[0] == INT32_MAX); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sfixed32_max); + free (data); +} + +static void test_repeated_uint32 (void) +{ + Foo__TestMess mess = FOO__TEST_MESS__INIT; + Foo__TestMess *mess2; + uint32_t arr0[4] = { BILLION, MILLION, 1, 0 }; + uint32_t arr_zero[1] = { 0 }; + uint32_t arr_max[1] = { UINT32_MAX }; + size_t len; + uint8_t *data; + + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_uint32 == 0); + assert(len == 0); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); + + mess.n_test_uint32 = 4; + mess.test_uint32 = arr0; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_uint32 == 4); + assert(mess2->test_uint32[0] == BILLION); + assert(mess2->test_uint32[1] == MILLION); + assert(mess2->test_uint32[2] == 1); + assert(mess2->test_uint32[3] == 0); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_uint32_bil_mil_1_0); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); + + mess.n_test_uint32 = 1; + mess.test_uint32 = arr_zero; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_uint32 == 1); + assert(mess2->test_uint32[0] == 0); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_uint32_0); + free (data); + + mess.n_test_uint32 = 1; + mess.test_uint32 = arr_max; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_uint32 == 1); + assert(mess2->test_uint32[0] == UINT32_MAX); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_uint32_max); + free (data); +} + +static void test_repeated_fixed32 (void) +{ + Foo__TestMess mess = FOO__TEST_MESS__INIT; + Foo__TestMess *mess2; + uint32_t arr0[4] = { BILLION, MILLION, 1, 0 }; + uint32_t arr_zero[1] = { 0 }; + uint32_t arr_max[1] = { UINT32_MAX }; + size_t len; + uint8_t *data; + + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_fixed32 == 0); + assert(len == 0); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); + + mess.n_test_fixed32 = 4; + mess.test_fixed32 = arr0; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_fixed32 == 4); + assert(mess2->test_fixed32[0] == BILLION); + assert(mess2->test_fixed32[1] == MILLION); + assert(mess2->test_fixed32[2] == 1); + assert(mess2->test_fixed32[3] == 0); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_fixed32_bil_mil_1_0); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); + + mess.n_test_fixed32 = 1; + mess.test_fixed32 = arr_zero; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_fixed32 == 1); + assert(mess2->test_fixed32[0] == 0); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_fixed32_0); + free (data); + + mess.n_test_fixed32 = 1; + mess.test_fixed32 = arr_max; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_fixed32 == 1); + assert(mess2->test_fixed32[0] == UINT32_MAX); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_fixed32_max); + free (data); +} + +static void test_repeated_int64 (void) +{ + Foo__TestMess mess = FOO__TEST_MESS__INIT; + Foo__TestMess *mess2; + size_t len; + uint8_t *data; + unsigned i; + + mess.n_test_int64 = N_ELEMENTS (int64_roundnumbers); + mess.test_int64 = int64_roundnumbers; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_int64 == N_ELEMENTS (int64_roundnumbers)); + for (i = 0; i < N_ELEMENTS (int64_roundnumbers); i++) + assert(mess2->test_int64[i] == int64_roundnumbers[i]); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_int64_roundnumbers); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); + + mess.n_test_int64 = N_ELEMENTS (int64_min_max); + mess.test_int64 = int64_min_max; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_int64 == N_ELEMENTS (int64_min_max)); + assert(mess2->test_int64[0] == INT64_MIN); + assert(mess2->test_int64[1] == INT64_MAX); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_int64_min_max); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); +} + +static void test_repeated_sint64 (void) +{ + Foo__TestMess mess = FOO__TEST_MESS__INIT; + Foo__TestMess *mess2; + size_t len; + uint8_t *data; + unsigned i; + + mess.n_test_sint64 = N_ELEMENTS (int64_roundnumbers); + mess.test_sint64 = int64_roundnumbers; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_sint64 == N_ELEMENTS (int64_roundnumbers)); + for (i = 0; i < N_ELEMENTS (int64_roundnumbers); i++) + assert(mess2->test_sint64[i] == int64_roundnumbers[i]); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sint64_roundnumbers); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); + + mess.n_test_sint64 = N_ELEMENTS (int64_min_max); + mess.test_sint64 = int64_min_max; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_sint64 == N_ELEMENTS (int64_min_max)); + assert(mess2->test_sint64[0] == INT64_MIN); + assert(mess2->test_sint64[1] == INT64_MAX); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sint64_min_max); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); +} + +static void test_repeated_sfixed64 (void) +{ + Foo__TestMess mess = FOO__TEST_MESS__INIT; + Foo__TestMess *mess2; + size_t len; + uint8_t *data; + unsigned i; + + mess.n_test_sfixed64 = N_ELEMENTS (int64_roundnumbers); + mess.test_sfixed64 = int64_roundnumbers; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_sfixed64 == N_ELEMENTS (int64_roundnumbers)); + for (i = 0; i < N_ELEMENTS (int64_roundnumbers); i++) + assert(mess2->test_sfixed64[i] == int64_roundnumbers[i]); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sfixed64_roundnumbers); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); + + mess.n_test_sfixed64 = N_ELEMENTS (int64_min_max); + mess.test_sfixed64 = int64_min_max; + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); + assert(mess2->n_test_sfixed64 == N_ELEMENTS (int64_min_max)); + assert(mess2->test_sfixed64[0] == INT64_MIN); + assert(mess2->test_sfixed64[1] == INT64_MAX); + TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sfixed64_min_max); + free (data); + foo__test_mess__free_unpacked (mess2, NULL); +} + +static void test_repeated_uint64 (void) +{ + Foo__TestMess mess = FOO__TEST_MESS__INIT; + Foo__TestMess *mess2; + size_t len; + uint8_t *data; + unsigned i; + +#define DO_TEST(static_array, example_packed_data) \ + do{ \ + mess.n_test_uint64 = N_ELEMENTS (static_array); \ + mess.test_uint64 = static_array; \ + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); \ + assert(mess2->n_test_uint64 == N_ELEMENTS (static_array)); \ + for (i = 0; i < N_ELEMENTS (static_array); i++) \ + assert(mess2->test_uint64[i] == static_array[i]); \ + TEST_VERSUS_STATIC_ARRAY (len, data, example_packed_data); \ + free (data); \ + foo__test_mess__free_unpacked (mess2, NULL); \ + }while(0) + + DO_TEST(uint64_roundnumbers, test_repeated_uint64_roundnumbers); + DO_TEST(uint64_0_1_max, test_repeated_uint64_0_1_max); + DO_TEST(uint64_random, test_repeated_uint64_random); + +#undef DO_TEST +} + +static void test_repeated_fixed64 (void) +{ + Foo__TestMess mess = FOO__TEST_MESS__INIT; + Foo__TestMess *mess2; + size_t len; + uint8_t *data; + unsigned i; + +#define DO_TEST(static_array, example_packed_data) \ + do{ \ + mess.n_test_fixed64 = N_ELEMENTS (static_array); \ + mess.test_fixed64 = static_array; \ + mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); \ + assert(mess2->n_test_fixed64 == N_ELEMENTS (static_array)); \ + for (i = 0; i < N_ELEMENTS (static_array); i++) \ + assert(mess2->test_fixed64[i] == static_array[i]); \ + TEST_VERSUS_STATIC_ARRAY (len, data, example_packed_data); \ + free (data); \ + foo__test_mess__free_unpacked (mess2, NULL); \ + }while(0) + + DO_TEST(uint64_roundnumbers, test_repeated_fixed64_roundnumbers); + DO_TEST(uint64_0_1_max, test_repeated_fixed64_0_1_max); + DO_TEST(uint64_random, test_repeated_fixed64_random); + +#undef DO_TEST +} + +static void test_repeated_float (void) +{ + +#define DO_TEST(static_array, example_packed_data) \ + DO_TEST_REPEATED(test_float, \ + static_array, example_packed_data, \ + NUMERIC_EQUALS) + + DO_TEST(float_random, test_repeated_float_random); + +#undef DO_TEST +} + +static void test_repeated_double (void) +{ + +#define DO_TEST(static_array, example_packed_data) \ + DO_TEST_REPEATED(test_double, \ + static_array, example_packed_data, \ + NUMERIC_EQUALS) + + DO_TEST(double_random, test_repeated_double_random); + +#undef DO_TEST +} + +static void test_repeated_boolean (void) +{ + +#define DO_TEST(static_array, example_packed_data) \ + DO_TEST_REPEATED(test_boolean, \ + static_array, example_packed_data, \ + NUMERIC_EQUALS) + + DO_TEST(boolean_0, test_repeated_boolean_0); + DO_TEST(boolean_1, test_repeated_boolean_1); + DO_TEST(boolean_random, test_repeated_boolean_random); + +#undef DO_TEST +} /* === simple testing framework === */ @@ -147,60 +688,60 @@ static Test tests[] = { "small enums", test_enum_small }, { "big enums", test_enum_big }, { "test field numbers", test_field_numbers }, - //{ "test repeated int32" ,test_repeated_int32 }, - //{ "test repeated sint32" ,test_repeated_sint32 }, - //{ "test repeated sfixed32" ,test_repeated_sfixed32 }, - //{ "test repeated int64" ,test_repeated_int64 }, - //{ "test repeated sint64" ,test_repeated_sint64 }, - //{ "test repeated sfixed64" ,test_repeated_sfixed64 }, - //{ "test repeated uint32" ,test_repeated_uint32 }, - //{ "test repeated fixed32" ,test_repeated_fixed32 }, - //{ "test repeated uint64" ,test_repeated_uint64 }, - //{ "test repeated fixed64" ,test_repeated_fixed64 }, - //{ "test repeated float" ,test_repeated_float }, - //{ "test repeated double" ,test_repeated_double }, - //{ "test repeated bool" ,test_repeated_bool }, - //{ "test repeated TestEnumSmall" ,test_repeated_TestEnumSmall }, - //{ "test repeated TestEnum" ,test_repeated_TestEnum }, - //{ "test repeated string" ,test_repeated_string }, - //{ "test repeated bytes" ,test_repeated_bytes }, - //{ "test repeated SubMess" ,test_repeated_SubMess }, - //{ "test optional int32" ,test_optional_int32 }, - //{ "test optional sint32" ,test_optional_sint32 }, - //{ "test optional sfixed32" ,test_optional_sfixed32 }, - //{ "test optional int64" ,test_optional_int64 }, - //{ "test optional sint64" ,test_optional_sint64 }, - //{ "test optional sfixed64" ,test_optional_sfixed64 }, - //{ "test optional uint32" ,test_optional_uint32 }, - //{ "test optional fixed32" ,test_optional_fixed32 }, - //{ "test optional uint64" ,test_optional_uint64 }, - //{ "test optional fixed64" ,test_optional_fixed64 }, - //{ "test optional float" ,test_optional_float }, - //{ "test optional double" ,test_optional_double }, - //{ "test optional bool" ,test_optional_bool }, - //{ "test optional TestEnumSmall" ,test_optional_TestEnumSmall }, - //{ "test optional TestEnum" ,test_optional_TestEnum }, - //{ "test optional string" ,test_optional_string }, - //{ "test optional bytes" ,test_optional_bytes }, - //{ "test optional SubMess" ,test_optional_SubMess }, - //{ "test required int32" ,test_required_int32 }, - //{ "test required sint32" ,test_required_sint32 }, - //{ "test required sfixed32" ,test_required_sfixed32 }, - //{ "test required int64" ,test_required_int64 }, - //{ "test required sint64" ,test_required_sint64 }, - //{ "test required sfixed64" ,test_required_sfixed64 }, - //{ "test required uint32" ,test_required_uint32 }, - //{ "test required fixed32" ,test_required_fixed32 }, - //{ "test required uint64" ,test_required_uint64 }, - //{ "test required fixed64" ,test_required_fixed64 }, - //{ "test required float" ,test_required_float }, - //{ "test required double" ,test_required_double }, - //{ "test required bool" ,test_required_bool }, - //{ "test required TestEnumSmall" ,test_required_TestEnumSmall }, - //{ "test required TestEnum" ,test_required_TestEnum }, - //{ "test required string" ,test_required_string }, - //{ "test required bytes" ,test_required_bytes }, - //{ "test required SubMess" ,test_required_SubMess }, + { "test repeated int32" ,test_repeated_int32 }, + { "test repeated sint32" ,test_repeated_sint32 }, + { "test repeated sfixed32" ,test_repeated_sfixed32 }, + { "test repeated uint32", test_repeated_uint32 }, + { "test repeated int64", test_repeated_int64 }, + { "test repeated sint64", test_repeated_sint64 }, + { "test repeated sfixed64", test_repeated_sfixed64 }, + { "test repeated fixed32", test_repeated_fixed32 }, + { "test repeated uint64", test_repeated_uint64 }, + { "test repeated fixed64", test_repeated_fixed64 }, + { "test repeated float", test_repeated_float }, + { "test repeated double", test_repeated_double }, + { "test repeated boolean", test_repeated_boolean }, + //{ "test repeated TestEnumSmall", test_repeated_TestEnumSmall }, + //{ "test repeated TestEnum", test_repeated_TestEnum }, + //{ "test repeated string", test_repeated_string }, + //{ "test repeated bytes", test_repeated_bytes }, + //{ "test repeated SubMess", test_repeated_SubMess }, + //{ "test optional int32", test_optional_int32 }, + //{ "test optional sint32", test_optional_sint32 }, + //{ "test optional sfixed32", test_optional_sfixed32 }, + //{ "test optional int64", test_optional_int64 }, + //{ "test optional sint64", test_optional_sint64 }, + //{ "test optional sfixed64", test_optional_sfixed64 }, + //{ "test optional uint32", test_optional_uint32 }, + //{ "test optional fixed32", test_optional_fixed32 }, + //{ "test optional uint64", test_optional_uint64 }, + //{ "test optional fixed64", test_optional_fixed64 }, + //{ "test optional float", test_optional_float }, + //{ "test optional double", test_optional_double }, + //{ "test optional bool", test_optional_bool }, + //{ "test optional TestEnumSmall", test_optional_TestEnumSmall }, + //{ "test optional TestEnum", test_optional_TestEnum }, + //{ "test optional string", test_optional_string }, + //{ "test optional bytes", test_optional_bytes }, + //{ "test optional SubMess", test_optional_SubMess }, + //{ "test required int32", test_required_int32 }, + //{ "test required sint32", test_required_sint32 }, + //{ "test required sfixed32", test_required_sfixed32 }, + //{ "test required int64", test_required_int64 }, + //{ "test required sint64", test_required_sint64 }, + //{ "test required sfixed64", test_required_sfixed64 }, + //{ "test required uint32", test_required_uint32 }, + //{ "test required fixed32", test_required_fixed32 }, + //{ "test required uint64", test_required_uint64 }, + //{ "test required fixed64", test_required_fixed64 }, + //{ "test required float", test_required_float }, + //{ "test required double", test_required_double }, + //{ "test required bool", test_required_bool }, + //{ "test required TestEnumSmall", test_required_TestEnumSmall }, + //{ "test required TestEnum", test_required_TestEnum }, + //{ "test required string", test_required_string }, + //{ "test required bytes", test_required_bytes }, + //{ "test required SubMess", test_required_SubMess }, }; #define n_tests (sizeof(tests)/sizeof(Test))