many bug fixes, and lots of test code

git-svn-id: https://protobuf-c.googlecode.com/svn/trunk@36 00440858-1255-0410-a3e6-75ea37f81c3a
This commit is contained in:
lahiker42 2008-08-24 03:00:21 +00:00
parent 6ffe171d9f
commit 1265baa325
7 changed files with 1027 additions and 90 deletions

1
TODO
View File

@ -1,7 +1,6 @@
- check over documentation again - check over documentation again
- handle unknown fields when packing - handle unknown fields when packing
- test code - test code
- ensure enums are 32-bit
- make services derive from ProtobufCService; - make services derive from ProtobufCService;
be usable with a cast. be usable with a cast.
- provide example rpc - provide example rpc

View File

@ -1,6 +1,21 @@
#include <stdio.h> /* for occasional printf()s */ #include <stdio.h> /* for occasional printf()s */
#include <stdlib.h> /* for abort(), malloc() etc */ #include <stdlib.h> /* for abort(), malloc() etc */
#include <string.h> /* for strlen(), memcpy(), memmove() */ #include <string.h> /* for strlen(), memcpy(), memmove() */
#include <endian.h>
#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" #include "protobuf-c.h"
@ -123,6 +138,23 @@ uint32_size (uint32_t v)
else else
return 5; 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 static inline uint32_t
zigzag32 (int32_t v) zigzag32 (int32_t v)
{ {
@ -164,7 +196,7 @@ zigzag64 (int64_t v)
return v * 2; return v * 2;
} }
static inline size_t static inline size_t
sint64_size (int32_t v) sint64_size (int64_t v)
{ {
return uint64_size(zigzag64(v)); return uint64_size(zigzag64(v));
} }
@ -179,10 +211,11 @@ required_field_get_packed_size (const ProtobufCFieldDescriptor *field,
case PROTOBUF_C_TYPE_SINT32: case PROTOBUF_C_TYPE_SINT32:
return rv + sint32_size (*(int32_t *) member); return rv + sint32_size (*(int32_t *) member);
case PROTOBUF_C_TYPE_INT32: case PROTOBUF_C_TYPE_INT32:
return rv + int32_size (*(uint32_t *) member);
case PROTOBUF_C_TYPE_UINT32: case PROTOBUF_C_TYPE_UINT32:
return rv + uint32_size (*(uint32_t *) member); return rv + uint32_size (*(uint32_t *) member);
case PROTOBUF_C_TYPE_SINT64: 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_INT64:
case PROTOBUF_C_TYPE_UINT64: case PROTOBUF_C_TYPE_UINT64:
return rv + uint64_size (*(uint64_t *) member); 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]); rv += sint32_size (((int32_t*)array)[i]);
break; break;
case PROTOBUF_C_TYPE_INT32: 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_UINT32:
case PROTOBUF_C_TYPE_ENUM: case PROTOBUF_C_TYPE_ENUM:
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
@ -355,6 +391,23 @@ uint32_pack (uint32_t value, BYTE *out)
out[rv++] = value; out[rv++] = value;
return rv; 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) static inline size_t sint32_pack (int32_t value, BYTE *out)
{ {
return uint32_pack (zigzag32 (value), out); return uint32_pack (zigzag32 (value), out);
@ -367,7 +420,7 @@ uint64_pack (uint64_t value, BYTE *out)
unsigned rv; unsigned rv;
if (hi == 0) if (hi == 0)
return uint32_pack ((uint32_t)lo, out); return uint32_pack ((uint32_t)lo, out);
out[0] = (lo) & 0x7f; out[0] = (lo) | 0x80;
out[1] = (lo>>7) | 0x80; out[1] = (lo>>7) | 0x80;
out[2] = (lo>>14) | 0x80; out[2] = (lo>>14) | 0x80;
out[3] = (lo>>21) | 0x80; out[3] = (lo>>21) | 0x80;
@ -466,13 +519,15 @@ required_field_pack (const ProtobufCFieldDescriptor *field,
out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
return rv + sint32_pack (*(int32_t *) member, out + rv); return rv + sint32_pack (*(int32_t *) member, out + rv);
case PROTOBUF_C_TYPE_INT32: 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_UINT32:
case PROTOBUF_C_TYPE_ENUM: case PROTOBUF_C_TYPE_ENUM:
out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
return rv + uint32_pack (*(uint32_t *) member, out + rv); return rv + uint32_pack (*(uint32_t *) member, out + rv);
case PROTOBUF_C_TYPE_SINT64: case PROTOBUF_C_TYPE_SINT64:
out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; 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_INT64:
case PROTOBUF_C_TYPE_UINT64: case PROTOBUF_C_TYPE_UINT64:
out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
@ -622,6 +677,10 @@ required_field_pack_to_buffer (const ProtobufCFieldDescriptor *field,
buffer->append (buffer, rv, scratch); buffer->append (buffer, rv, scratch);
break; break;
case PROTOBUF_C_TYPE_INT32: 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_UINT32:
case PROTOBUF_C_TYPE_ENUM: case PROTOBUF_C_TYPE_ENUM:
scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
@ -630,7 +689,7 @@ required_field_pack_to_buffer (const ProtobufCFieldDescriptor *field,
break; break;
case PROTOBUF_C_TYPE_SINT64: case PROTOBUF_C_TYPE_SINT64:
scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; 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); buffer->append (buffer, rv, scratch);
break; break;
case PROTOBUF_C_TYPE_INT64: case PROTOBUF_C_TYPE_INT64:
@ -766,6 +825,12 @@ protobuf_c_message_pack_to_buffer (const ProtobufCMessage *message,
} }
/* === unpacking === */ /* === 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 static inline int
int_range_lookup (unsigned n_ranges, int_range_lookup (unsigned n_ranges,
const ProtobufCIntRange *ranges, const ProtobufCIntRange *ranges,
@ -866,11 +931,18 @@ scan_length_prefixed_data (size_t len, const BYTE *data, size_t *prefix_len_out)
break; break;
} }
if (i == hdr_max) if (i == hdr_max)
return 0; {
UNPACK_ERROR (("error parsing length for length-prefixed data"));
return 0;
}
hdr_len = i + 1; hdr_len = i + 1;
*prefix_len_out = hdr_len; *prefix_len_out = hdr_len;
if (hdr_len + val > 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; return hdr_len + val;
} }
@ -894,6 +966,11 @@ parse_uint32 (unsigned len, const BYTE *data)
} }
return rv; return rv;
} }
static inline uint32_t
parse_int32 (unsigned len, const BYTE *data)
{
return parse_uint32 (len, data);
}
static inline int32_t static inline int32_t
unzigzag32 (uint32_t v) unzigzag32 (uint32_t v)
{ {
@ -972,6 +1049,10 @@ parse_required_member (ScannedMember *scanned_member,
switch (scanned_member->field->type) switch (scanned_member->field->type)
{ {
case PROTOBUF_C_TYPE_INT32: 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: case PROTOBUF_C_TYPE_UINT32:
if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT) if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT)
return 0; return 0;
@ -988,7 +1069,7 @@ parse_required_member (ScannedMember *scanned_member,
if (wire_type != PROTOBUF_C_WIRE_TYPE_32BIT) if (wire_type != PROTOBUF_C_WIRE_TYPE_32BIT)
return 0; return 0;
*(uint32_t*)member = parse_fixed_uint32 (data); *(uint32_t*)member = parse_fixed_uint32 (data);
break; return 1;
case PROTOBUF_C_TYPE_INT64: case PROTOBUF_C_TYPE_INT64:
case PROTOBUF_C_TYPE_UINT64: case PROTOBUF_C_TYPE_UINT64:
@ -1167,7 +1248,11 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc,
const ProtobufCFieldDescriptor *field; const ProtobufCFieldDescriptor *field;
ScannedMember tmp; ScannedMember tmp;
if (used == 0) 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! */ /* XXX: consider optimizing for field[1].id == tag, if field[1] exists! */
if (last_field->id != tag) if (last_field->id != tag)
{ {
@ -1205,13 +1290,21 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc,
if ((at[i] & 0x80) == 0) if ((at[i] & 0x80) == 0)
break; break;
if (i == max_len) if (i == max_len)
goto error_cleanup; {
UNPACK_ERROR (("unterminated varint at offset %u",
(unsigned)(at-data)));
goto error_cleanup;
}
tmp.len = i + 1; tmp.len = i + 1;
} }
break; break;
case PROTOBUF_C_WIRE_TYPE_64BIT: case PROTOBUF_C_WIRE_TYPE_64BIT:
if (rem < 8) 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; tmp.len = 8;
break; break;
case PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED: case PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED:
@ -1219,7 +1312,10 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc,
size_t pref_len; size_t pref_len;
tmp.len = scan_length_prefixed_data (rem, at, &pref_len); tmp.len = scan_length_prefixed_data (rem, at, &pref_len);
if (tmp.len == 0) if (tmp.len == 0)
goto error_cleanup; {
/* NOTE: scan_length_prefixed_data calls UNPACK_ERROR */
goto error_cleanup;
}
tmp.length_prefix_len = pref_len; tmp.length_prefix_len = pref_len;
break; break;
} }
@ -1228,7 +1324,11 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc,
PROTOBUF_C_ASSERT_NOT_REACHED (); PROTOBUF_C_ASSERT_NOT_REACHED ();
case PROTOBUF_C_WIRE_TYPE_32BIT: case PROTOBUF_C_WIRE_TYPE_32BIT:
if (rem < 4) 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; tmp.len = 4;
break; break;
} }
@ -1285,7 +1385,11 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc,
for (j = 0; j < max; j++) for (j = 0; j < max; j++)
{ {
if (!parse_member (slab + j, rv, allocator)) 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;
}
} }
} }

View File

@ -68,7 +68,18 @@ void BytesFieldGenerator::GenerateStructMembers(io::Printer* printer) const
} }
void BytesFieldGenerator::GenerateStaticInit(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 void BytesFieldGenerator::GenerateDescriptorInitializer(io::Printer* printer) const
{ {

View File

@ -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 };

View File

@ -1,10 +1,16 @@
/* generate byte arrays that match the constructs in test-generated-code2.c. /* 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. */ * 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 "generated-code/test-full.pb.h"
#include <inttypes.h>
using namespace foo; using namespace foo;
#define protobuf_c_boolean bool
#include "common-test-arrays.h"
#define N_ELEMENTS(arr) (sizeof(arr)/sizeof((arr)[0]))
static void static void
dump_message_bytes(google::protobuf::Message *message, dump_message_bytes(google::protobuf::Message *message,
const char *label) const char *label)
@ -66,10 +72,254 @@ dump_test_field_numbers (void)
DUMP_ONE (33554432) DUMP_ONE (33554432)
#undef DUMP_ONE #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) int main(int argc, char **argv)
{ {
dump_test_enum_small (); dump_test_enum_small ();
dump_test_enum_big (); dump_test_enum_big ();
dump_test_field_numbers (); 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; return 0;
} }

View File

@ -58,7 +58,7 @@ message TestMess {
repeated fixed64 test_fixed64 = 10; repeated fixed64 test_fixed64 = 10;
repeated float test_float = 11; repeated float test_float = 11;
repeated double test_double = 12; repeated double test_double = 12;
repeated bool test_bool = 13; repeated bool test_boolean = 13;
repeated TestEnumSmall test_enum_small = 14; repeated TestEnumSmall test_enum_small = 14;
repeated TestEnum test_enum = 15; repeated TestEnum test_enum = 15;
repeated string test_string = 16; repeated string test_string = 16;
@ -79,7 +79,7 @@ message TestMessOptional {
optional fixed64 test_fixed64 = 10; optional fixed64 test_fixed64 = 10;
optional float test_float = 11; optional float test_float = 11;
optional double test_double = 12; optional double test_double = 12;
optional bool test_bool = 13; optional bool test_boolean = 13;
optional TestEnum test_enum = 14; optional TestEnum test_enum = 14;
optional string test_string = 15; optional string test_string = 15;
optional bytes test_bytes = 16; optional bytes test_bytes = 16;

View File

@ -4,6 +4,9 @@
#include "generated-code/test-full.pb-c.h" #include "generated-code/test-full.pb-c.h"
#include "generated-code/test-full-cxx-output.inc" #include "generated-code/test-full-cxx-output.inc"
#include "common-test-arrays.h"
#define N_ELEMENTS(arr) (sizeof(arr)/sizeof((arr)[0]))
/* ==== helper functions ==== */ /* ==== helper functions ==== */
static protobuf_c_boolean static protobuf_c_boolean
are_bytes_equal (unsigned actual_len, are_bytes_equal (unsigned actual_len,
@ -15,9 +18,39 @@ are_bytes_equal (unsigned actual_len,
return 0; return 0;
return memcmp (actual_data, expected_data, actual_len) == 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) \ #define TEST_VERSUS_STATIC_ARRAY(actual_len, actual_data, buf) \
assert(are_bytes_equal(actual_len,actual_data, \ test_versus_static_array(actual_len,actual_data, \
sizeof(buf), buf)) sizeof(buf), buf, #buf, __FILE__, __LINE__)
/* rv is unpacked message */ /* rv is unpacked message */
static void * static void *
@ -46,30 +79,52 @@ test_compare_pack_methods (ProtobufCMessage *message,
return rv; 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 === */ /* === the actual tests === */
static void test_enum_small (void) static void test_enum_small (void)
{ {
Foo__TestMessRequiredEnumSmall small = FOO__TEST_MESS_REQUIRED_ENUM_SMALL__INIT;
size_t len; #define DO_TEST(UC_VALUE) \
uint8_t *data; do{ \
Foo__TestMessRequiredEnumSmall *unpacked; 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); assert (sizeof (Foo__TestEnumSmall) == 4);
small.test = FOO__TEST_ENUM_SMALL__VALUE; DO_TEST(VALUE);
unpacked = test_compare_pack_methods ((ProtobufCMessage*)&small, &len, &data); DO_TEST(OTHER_VALUE);
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);
small.test = FOO__TEST_ENUM_SMALL__OTHER_VALUE; #undef DO_TEST
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);
} }
static void test_enum_big (void) static void test_enum_big (void)
@ -132,6 +187,492 @@ static void test_field_numbers (void)
DO_ONE_TEST (33554432, 5 + 1 + 3); DO_ONE_TEST (33554432, 5 + 1 + 3);
#undef DO_ONE_TEST #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 === */ /* === simple testing framework === */
@ -147,60 +688,60 @@ static Test tests[] =
{ "small enums", test_enum_small }, { "small enums", test_enum_small },
{ "big enums", test_enum_big }, { "big enums", test_enum_big },
{ "test field numbers", test_field_numbers }, { "test field numbers", test_field_numbers },
//{ "test repeated int32" ,test_repeated_int32 }, { "test repeated int32" ,test_repeated_int32 },
//{ "test repeated sint32" ,test_repeated_sint32 }, { "test repeated sint32" ,test_repeated_sint32 },
//{ "test repeated sfixed32" ,test_repeated_sfixed32 }, { "test repeated sfixed32" ,test_repeated_sfixed32 },
//{ "test repeated int64" ,test_repeated_int64 }, { "test repeated uint32", test_repeated_uint32 },
//{ "test repeated sint64" ,test_repeated_sint64 }, { "test repeated int64", test_repeated_int64 },
//{ "test repeated sfixed64" ,test_repeated_sfixed64 }, { "test repeated sint64", test_repeated_sint64 },
//{ "test repeated uint32" ,test_repeated_uint32 }, { "test repeated sfixed64", test_repeated_sfixed64 },
//{ "test repeated fixed32" ,test_repeated_fixed32 }, { "test repeated fixed32", test_repeated_fixed32 },
//{ "test repeated uint64" ,test_repeated_uint64 }, { "test repeated uint64", test_repeated_uint64 },
//{ "test repeated fixed64" ,test_repeated_fixed64 }, { "test repeated fixed64", test_repeated_fixed64 },
//{ "test repeated float" ,test_repeated_float }, { "test repeated float", test_repeated_float },
//{ "test repeated double" ,test_repeated_double }, { "test repeated double", test_repeated_double },
//{ "test repeated bool" ,test_repeated_bool }, { "test repeated boolean", test_repeated_boolean },
//{ "test repeated TestEnumSmall" ,test_repeated_TestEnumSmall }, //{ "test repeated TestEnumSmall", test_repeated_TestEnumSmall },
//{ "test repeated TestEnum" ,test_repeated_TestEnum }, //{ "test repeated TestEnum", test_repeated_TestEnum },
//{ "test repeated string" ,test_repeated_string }, //{ "test repeated string", test_repeated_string },
//{ "test repeated bytes" ,test_repeated_bytes }, //{ "test repeated bytes", test_repeated_bytes },
//{ "test repeated SubMess" ,test_repeated_SubMess }, //{ "test repeated SubMess", test_repeated_SubMess },
//{ "test optional int32" ,test_optional_int32 }, //{ "test optional int32", test_optional_int32 },
//{ "test optional sint32" ,test_optional_sint32 }, //{ "test optional sint32", test_optional_sint32 },
//{ "test optional sfixed32" ,test_optional_sfixed32 }, //{ "test optional sfixed32", test_optional_sfixed32 },
//{ "test optional int64" ,test_optional_int64 }, //{ "test optional int64", test_optional_int64 },
//{ "test optional sint64" ,test_optional_sint64 }, //{ "test optional sint64", test_optional_sint64 },
//{ "test optional sfixed64" ,test_optional_sfixed64 }, //{ "test optional sfixed64", test_optional_sfixed64 },
//{ "test optional uint32" ,test_optional_uint32 }, //{ "test optional uint32", test_optional_uint32 },
//{ "test optional fixed32" ,test_optional_fixed32 }, //{ "test optional fixed32", test_optional_fixed32 },
//{ "test optional uint64" ,test_optional_uint64 }, //{ "test optional uint64", test_optional_uint64 },
//{ "test optional fixed64" ,test_optional_fixed64 }, //{ "test optional fixed64", test_optional_fixed64 },
//{ "test optional float" ,test_optional_float }, //{ "test optional float", test_optional_float },
//{ "test optional double" ,test_optional_double }, //{ "test optional double", test_optional_double },
//{ "test optional bool" ,test_optional_bool }, //{ "test optional bool", test_optional_bool },
//{ "test optional TestEnumSmall" ,test_optional_TestEnumSmall }, //{ "test optional TestEnumSmall", test_optional_TestEnumSmall },
//{ "test optional TestEnum" ,test_optional_TestEnum }, //{ "test optional TestEnum", test_optional_TestEnum },
//{ "test optional string" ,test_optional_string }, //{ "test optional string", test_optional_string },
//{ "test optional bytes" ,test_optional_bytes }, //{ "test optional bytes", test_optional_bytes },
//{ "test optional SubMess" ,test_optional_SubMess }, //{ "test optional SubMess", test_optional_SubMess },
//{ "test required int32" ,test_required_int32 }, //{ "test required int32", test_required_int32 },
//{ "test required sint32" ,test_required_sint32 }, //{ "test required sint32", test_required_sint32 },
//{ "test required sfixed32" ,test_required_sfixed32 }, //{ "test required sfixed32", test_required_sfixed32 },
//{ "test required int64" ,test_required_int64 }, //{ "test required int64", test_required_int64 },
//{ "test required sint64" ,test_required_sint64 }, //{ "test required sint64", test_required_sint64 },
//{ "test required sfixed64" ,test_required_sfixed64 }, //{ "test required sfixed64", test_required_sfixed64 },
//{ "test required uint32" ,test_required_uint32 }, //{ "test required uint32", test_required_uint32 },
//{ "test required fixed32" ,test_required_fixed32 }, //{ "test required fixed32", test_required_fixed32 },
//{ "test required uint64" ,test_required_uint64 }, //{ "test required uint64", test_required_uint64 },
//{ "test required fixed64" ,test_required_fixed64 }, //{ "test required fixed64", test_required_fixed64 },
//{ "test required float" ,test_required_float }, //{ "test required float", test_required_float },
//{ "test required double" ,test_required_double }, //{ "test required double", test_required_double },
//{ "test required bool" ,test_required_bool }, //{ "test required bool", test_required_bool },
//{ "test required TestEnumSmall" ,test_required_TestEnumSmall }, //{ "test required TestEnumSmall", test_required_TestEnumSmall },
//{ "test required TestEnum" ,test_required_TestEnum }, //{ "test required TestEnum", test_required_TestEnum },
//{ "test required string" ,test_required_string }, //{ "test required string", test_required_string },
//{ "test required bytes" ,test_required_bytes }, //{ "test required bytes", test_required_bytes },
//{ "test required SubMess" ,test_required_SubMess }, //{ "test required SubMess", test_required_SubMess },
}; };
#define n_tests (sizeof(tests)/sizeof(Test)) #define n_tests (sizeof(tests)/sizeof(Test))