mirror of
https://github.com/protobuf-c/protobuf-c.git
synced 2024-12-26 21:04:23 +08:00
use uint8_t and size_t where appropriate.
implement and test unknown fields git-svn-id: https://protobuf-c.googlecode.com/svn/trunk@44 00440858-1255-0410-a3e6-75ea37f81c3a
This commit is contained in:
parent
348d300628
commit
f87e0849ea
7
TODO
7
TODO
@ -1,11 +1,6 @@
|
||||
- check over documentation again
|
||||
- handle unknown fields when packing
|
||||
- test code
|
||||
- make services derive from ProtobufCService;
|
||||
be usable with a cast.
|
||||
- make services derive from ProtobufCService; be usable with a cast.
|
||||
- provide example rpc
|
||||
- use size_t wherever appropriate in generated code,
|
||||
and in uses of that code (eg pack and unpack)
|
||||
|
||||
- To document:
|
||||
- __INIT macro
|
||||
|
@ -7,7 +7,7 @@
|
||||
#define PRINT_UNPACK_ERRORS 1
|
||||
|
||||
#if DO_LITTLE_ENDIAN_OPTIMIZATIONS
|
||||
# if (__LITTLE_ENDIAN == __BYTE_ORDER)
|
||||
# if (__LITTLE_ENDIAN == __uint8_t_ORDER)
|
||||
# define IS_LITTLE_ENDIAN 1
|
||||
# else
|
||||
# define IS_LITTLE_ENDIAN 0
|
||||
@ -15,7 +15,7 @@
|
||||
#endif
|
||||
|
||||
|
||||
/* This file defines `__BYTE_ORDER' for the particular machine. */
|
||||
/* This file defines `__uint8_t_ORDER' for the particular machine. */
|
||||
|
||||
#include "protobuf-c.h"
|
||||
|
||||
@ -27,12 +27,11 @@
|
||||
#define FREE(allocator, ptr) ((allocator)->free ((allocator)->allocator_data, (ptr)))
|
||||
#define UNALIGNED_ALLOC(allocator, size) ALLOC (allocator, size) /* placeholder */
|
||||
#define STRUCT_MEMBER_P(struct_p, struct_offset) \
|
||||
((void *) ((BYTE*) (struct_p) + (struct_offset)))
|
||||
((void *) ((uint8_t*) (struct_p) + (struct_offset)))
|
||||
#define STRUCT_MEMBER(member_type, struct_p, struct_offset) \
|
||||
(*(member_type*) STRUCT_MEMBER_P ((struct_p), (struct_offset)))
|
||||
#define STRUCT_MEMBER_PTR(member_type, struct_p, struct_offset) \
|
||||
((member_type*) STRUCT_MEMBER_P ((struct_p), (struct_offset)))
|
||||
typedef unsigned char BYTE;
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
@ -86,14 +85,14 @@ ProtobufCAllocator protobuf_c_system_allocator =
|
||||
void
|
||||
protobuf_c_buffer_simple_append (ProtobufCBuffer *buffer,
|
||||
size_t len,
|
||||
const unsigned char *data)
|
||||
const uint8_t *data)
|
||||
{
|
||||
ProtobufCBufferSimple *simp = (ProtobufCBufferSimple *) buffer;
|
||||
size_t new_len = simp->len + len;
|
||||
if (new_len > simp->alloced)
|
||||
{
|
||||
size_t new_alloced = simp->alloced * 2;
|
||||
unsigned char *new_data;
|
||||
uint8_t *new_data;
|
||||
while (new_alloced < new_len)
|
||||
new_alloced += new_alloced;
|
||||
new_data = ALLOC (&protobuf_c_default_allocator, new_alloced);
|
||||
@ -239,7 +238,6 @@ required_field_get_packed_size (const ProtobufCFieldDescriptor *field,
|
||||
size_t len = strlen (*(char**) member);
|
||||
return rv + uint32_size (len) + len;
|
||||
}
|
||||
|
||||
case PROTOBUF_C_TYPE_BYTES:
|
||||
{
|
||||
size_t len = ((ProtobufCBinaryData*) member)->len;
|
||||
@ -345,6 +343,13 @@ repeated_field_get_packed_size (const ProtobufCFieldDescriptor *field,
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
unknown_field_get_packed_size (const ProtobufCMessageUnknownField *field)
|
||||
{
|
||||
return get_tag_size (field->tag) + field->len;
|
||||
}
|
||||
|
||||
size_t protobuf_c_message_get_packed_size(const ProtobufCMessage *message)
|
||||
{
|
||||
unsigned i;
|
||||
@ -362,12 +367,14 @@ size_t protobuf_c_message_get_packed_size(const ProtobufCMessage *message)
|
||||
else
|
||||
rv += repeated_field_get_packed_size (field, * (size_t *) qmember, member);
|
||||
}
|
||||
for (i = 0; i < message->n_unknown_fields; i++)
|
||||
rv += unknown_field_get_packed_size (&message->unknown_fields[i]);
|
||||
|
||||
return rv;
|
||||
}
|
||||
/* === pack() === */
|
||||
static inline size_t
|
||||
uint32_pack (uint32_t value, BYTE *out)
|
||||
uint32_pack (uint32_t value, uint8_t *out)
|
||||
{
|
||||
unsigned rv = 0;
|
||||
if (value >= 0x80)
|
||||
@ -395,7 +402,7 @@ uint32_pack (uint32_t value, BYTE *out)
|
||||
return rv;
|
||||
}
|
||||
static inline size_t
|
||||
int32_pack (int32_t value, BYTE *out)
|
||||
int32_pack (int32_t value, uint8_t *out)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
@ -411,12 +418,12 @@ int32_pack (int32_t value, BYTE *out)
|
||||
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, uint8_t *out)
|
||||
{
|
||||
return uint32_pack (zigzag32 (value), out);
|
||||
}
|
||||
static size_t
|
||||
uint64_pack (uint64_t value, BYTE *out)
|
||||
uint64_pack (uint64_t value, uint8_t *out)
|
||||
{
|
||||
uint32_t hi = value>>32;
|
||||
uint32_t lo = value;
|
||||
@ -446,11 +453,11 @@ uint64_pack (uint64_t value, BYTE *out)
|
||||
out[rv++] = hi;
|
||||
return rv;
|
||||
}
|
||||
static inline size_t sint64_pack (int64_t value, BYTE *out)
|
||||
static inline size_t sint64_pack (int64_t value, uint8_t *out)
|
||||
{
|
||||
return uint64_pack (zigzag64 (value), out);
|
||||
}
|
||||
static inline size_t fixed32_pack (uint32_t value, BYTE *out)
|
||||
static inline size_t fixed32_pack (uint32_t value, uint8_t *out)
|
||||
{
|
||||
#if IS_LITTLE_ENDIAN
|
||||
memcpy (out, &value, 4);
|
||||
@ -462,7 +469,7 @@ static inline size_t fixed32_pack (uint32_t value, BYTE *out)
|
||||
#endif
|
||||
return 4;
|
||||
}
|
||||
static inline size_t fixed64_pack (uint64_t value, BYTE *out)
|
||||
static inline size_t fixed64_pack (uint64_t value, uint8_t *out)
|
||||
{
|
||||
#if IS_LITTLE_ENDIAN
|
||||
memcpy (out, &value, 8);
|
||||
@ -472,19 +479,19 @@ static inline size_t fixed64_pack (uint64_t value, BYTE *out)
|
||||
#endif
|
||||
return 8;
|
||||
}
|
||||
static inline size_t boolean_pack (protobuf_c_boolean value, BYTE *out)
|
||||
static inline size_t boolean_pack (protobuf_c_boolean value, uint8_t *out)
|
||||
{
|
||||
*out = value ? 1 : 0;
|
||||
return 1;
|
||||
}
|
||||
static inline size_t string_pack (const char * str, BYTE *out)
|
||||
static inline size_t string_pack (const char * str, uint8_t *out)
|
||||
{
|
||||
size_t len = strlen (str);
|
||||
size_t rv = uint32_pack (len, out);
|
||||
memcpy (out + rv, str, len);
|
||||
return rv + len;
|
||||
}
|
||||
static inline size_t binary_data_pack (const ProtobufCBinaryData *bd, BYTE *out)
|
||||
static inline size_t binary_data_pack (const ProtobufCBinaryData *bd, uint8_t *out)
|
||||
{
|
||||
size_t len = bd->len;
|
||||
size_t rv = uint32_pack (len, out);
|
||||
@ -493,7 +500,7 @@ static inline size_t binary_data_pack (const ProtobufCBinaryData *bd, BYTE *out)
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
prefixed_message_pack (const ProtobufCMessage *message, BYTE *out)
|
||||
prefixed_message_pack (const ProtobufCMessage *message, uint8_t *out)
|
||||
{
|
||||
size_t rv = protobuf_c_message_pack (message, out + 1);
|
||||
uint32_t rv_packed_size = uint32_size (rv);
|
||||
@ -503,7 +510,7 @@ prefixed_message_pack (const ProtobufCMessage *message, BYTE *out)
|
||||
}
|
||||
|
||||
/* wire-type will be added in required_field_pack() */
|
||||
static size_t tag_pack (uint32_t id, BYTE *out)
|
||||
static size_t tag_pack (uint32_t id, uint8_t *out)
|
||||
{
|
||||
if (id < (1<<(32-3)))
|
||||
return uint32_pack (id<<3, out);
|
||||
@ -513,7 +520,7 @@ static size_t tag_pack (uint32_t id, BYTE *out)
|
||||
static size_t
|
||||
required_field_pack (const ProtobufCFieldDescriptor *field,
|
||||
void *member,
|
||||
BYTE *out)
|
||||
uint8_t *out)
|
||||
{
|
||||
size_t rv = tag_pack (field->id, out);
|
||||
switch (field->type)
|
||||
@ -575,7 +582,7 @@ static size_t
|
||||
optional_field_pack (const ProtobufCFieldDescriptor *field,
|
||||
const protobuf_c_boolean *has,
|
||||
void *member,
|
||||
BYTE *out)
|
||||
uint8_t *out)
|
||||
{
|
||||
if (field->type == PROTOBUF_C_TYPE_MESSAGE
|
||||
|| field->type == PROTOBUF_C_TYPE_STRING)
|
||||
@ -626,7 +633,7 @@ static size_t
|
||||
repeated_field_pack (const ProtobufCFieldDescriptor *field,
|
||||
size_t count,
|
||||
void *member,
|
||||
BYTE *out)
|
||||
uint8_t *out)
|
||||
{
|
||||
char *array = * (char **) member;
|
||||
size_t siz;
|
||||
@ -641,8 +648,17 @@ repeated_field_pack (const ProtobufCFieldDescriptor *field,
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
static size_t
|
||||
unknown_field_pack (const ProtobufCMessageUnknownField *field, uint8_t *out)
|
||||
{
|
||||
size_t rv = tag_pack (field->tag, out);
|
||||
out[0] |= field->wire_type;
|
||||
memcpy (out + rv, field->data, field->len);
|
||||
return rv + field->len;
|
||||
}
|
||||
|
||||
size_t protobuf_c_message_pack (const ProtobufCMessage *message,
|
||||
unsigned char *out)
|
||||
uint8_t *out)
|
||||
{
|
||||
unsigned i;
|
||||
size_t rv = 0;
|
||||
@ -659,7 +675,8 @@ size_t protobuf_c_message_pack (const ProtobufCMessage *message,
|
||||
else
|
||||
rv += repeated_field_pack (field, * (size_t *) qmember, member, out + rv);
|
||||
}
|
||||
|
||||
for (i = 0; i < message->n_unknown_fields; i++)
|
||||
rv += unknown_field_pack (&message->unknown_fields[i], out + rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -670,7 +687,7 @@ required_field_pack_to_buffer (const ProtobufCFieldDescriptor *field,
|
||||
ProtobufCBuffer *buffer)
|
||||
{
|
||||
size_t rv;
|
||||
BYTE scratch[MAX_UINT64_ENCODED_SIZE * 2];
|
||||
uint8_t scratch[MAX_UINT64_ENCODED_SIZE * 2];
|
||||
rv = tag_pack (field->id, scratch);
|
||||
switch (field->type)
|
||||
{
|
||||
@ -726,7 +743,7 @@ required_field_pack_to_buffer (const ProtobufCFieldDescriptor *field,
|
||||
scratch[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
|
||||
rv += uint32_pack (sublen, scratch + rv);
|
||||
buffer->append (buffer, rv, scratch);
|
||||
buffer->append (buffer, sublen, *(BYTE**)member);
|
||||
buffer->append (buffer, sublen, *(uint8_t**)member);
|
||||
rv += sublen;
|
||||
break;
|
||||
}
|
||||
@ -745,7 +762,7 @@ required_field_pack_to_buffer (const ProtobufCFieldDescriptor *field,
|
||||
//PROTOBUF_C_TYPE_GROUP, // NOT SUPPORTED
|
||||
case PROTOBUF_C_TYPE_MESSAGE:
|
||||
{
|
||||
BYTE simple_buffer_scratch[256];
|
||||
uint8_t simple_buffer_scratch[256];
|
||||
size_t sublen;
|
||||
ProtobufCBufferSimple simple_buffer
|
||||
= PROTOBUF_C_BUFFER_SIMPLE_INIT (simple_buffer_scratch);
|
||||
@ -804,6 +821,18 @@ repeated_field_pack_to_buffer (const ProtobufCFieldDescriptor *field,
|
||||
return rv;
|
||||
}
|
||||
|
||||
static size_t
|
||||
unknown_field_pack_to_buffer (const ProtobufCMessageUnknownField *field,
|
||||
ProtobufCBuffer *buffer)
|
||||
{
|
||||
uint8_t header[MAX_UINT64_ENCODED_SIZE];
|
||||
size_t rv = tag_pack (field->tag, header);
|
||||
header[0] |= field->wire_type;
|
||||
buffer->append (buffer, rv, header);
|
||||
buffer->append (buffer, field->len, field->data);
|
||||
return rv + field->len;
|
||||
}
|
||||
|
||||
size_t
|
||||
protobuf_c_message_pack_to_buffer (const ProtobufCMessage *message,
|
||||
ProtobufCBuffer *buffer)
|
||||
@ -823,6 +852,8 @@ protobuf_c_message_pack_to_buffer (const ProtobufCMessage *message,
|
||||
else
|
||||
rv += repeated_field_pack_to_buffer (field, * (size_t *) qmember, member, buffer);
|
||||
}
|
||||
for (i = 0; i < message->n_unknown_fields; i++)
|
||||
rv += unknown_field_pack_to_buffer (&message->unknown_fields[i], buffer);
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -874,7 +905,7 @@ int_range_lookup (unsigned n_ranges,
|
||||
|
||||
static size_t
|
||||
parse_tag_and_wiretype (size_t len,
|
||||
const BYTE *data,
|
||||
const uint8_t *data,
|
||||
uint32_t *tag_out,
|
||||
ProtobufCWireType *wiretype_out)
|
||||
{
|
||||
@ -908,10 +939,10 @@ struct _ScannedMember
|
||||
{
|
||||
uint32_t tag;
|
||||
const ProtobufCFieldDescriptor *field;
|
||||
BYTE wire_type;
|
||||
BYTE length_prefix_len;
|
||||
uint8_t wire_type;
|
||||
uint8_t length_prefix_len;
|
||||
size_t len;
|
||||
const unsigned char *data;
|
||||
const uint8_t *data;
|
||||
};
|
||||
|
||||
#define MESSAGE_GET_UNKNOWNS(message) \
|
||||
@ -919,7 +950,7 @@ struct _ScannedMember
|
||||
(message), (message)->descriptor->unknown_field_array_offset)
|
||||
|
||||
static inline uint32_t
|
||||
scan_length_prefixed_data (size_t len, const BYTE *data, size_t *prefix_len_out)
|
||||
scan_length_prefixed_data (size_t len, const uint8_t *data, size_t *prefix_len_out)
|
||||
{
|
||||
unsigned hdr_max = len < 5 ? len : 5;
|
||||
unsigned hdr_len;
|
||||
@ -950,7 +981,7 @@ scan_length_prefixed_data (size_t len, const BYTE *data, size_t *prefix_len_out)
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
parse_uint32 (unsigned len, const BYTE *data)
|
||||
parse_uint32 (unsigned len, const uint8_t *data)
|
||||
{
|
||||
unsigned rv = data[0] & 0x7f;
|
||||
if (len > 1)
|
||||
@ -970,7 +1001,7 @@ parse_uint32 (unsigned len, const BYTE *data)
|
||||
return rv;
|
||||
}
|
||||
static inline uint32_t
|
||||
parse_int32 (unsigned len, const BYTE *data)
|
||||
parse_int32 (unsigned len, const uint8_t *data)
|
||||
{
|
||||
return parse_uint32 (len, data);
|
||||
}
|
||||
@ -983,7 +1014,7 @@ unzigzag32 (uint32_t v)
|
||||
return v>>1;
|
||||
}
|
||||
static inline uint32_t
|
||||
parse_fixed_uint32 (const BYTE *data)
|
||||
parse_fixed_uint32 (const uint8_t *data)
|
||||
{
|
||||
#if IS_LITTLE_ENDIAN
|
||||
uint32_t t;
|
||||
@ -994,7 +1025,7 @@ parse_fixed_uint32 (const BYTE *data)
|
||||
#endif
|
||||
}
|
||||
static uint64_t
|
||||
parse_uint64 (unsigned len, const BYTE *data)
|
||||
parse_uint64 (unsigned len, const uint8_t *data)
|
||||
{
|
||||
unsigned shift, i;
|
||||
if (len < 5)
|
||||
@ -1020,7 +1051,7 @@ unzigzag64 (uint64_t v)
|
||||
return v>>1;
|
||||
}
|
||||
static inline uint64_t
|
||||
parse_fixed_uint64 (const BYTE *data)
|
||||
parse_fixed_uint64 (const uint8_t *data)
|
||||
{
|
||||
#if IS_LITTLE_ENDIAN
|
||||
uint32_t t;
|
||||
@ -1032,7 +1063,7 @@ parse_fixed_uint64 (const BYTE *data)
|
||||
#endif
|
||||
}
|
||||
static protobuf_c_boolean
|
||||
parse_boolean (unsigned len, const BYTE *data)
|
||||
parse_boolean (unsigned len, const uint8_t *data)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < len; i++)
|
||||
@ -1047,7 +1078,7 @@ parse_required_member (ScannedMember *scanned_member,
|
||||
protobuf_c_boolean maybe_clear)
|
||||
{
|
||||
unsigned len = scanned_member->len;
|
||||
const BYTE *data = scanned_member->data;
|
||||
const uint8_t *data = scanned_member->data;
|
||||
ProtobufCWireType wire_type = scanned_member->wire_type;
|
||||
switch (scanned_member->field->type)
|
||||
{
|
||||
@ -1221,11 +1252,11 @@ ProtobufCMessage *
|
||||
protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc,
|
||||
ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const unsigned char *data)
|
||||
const uint8_t *data)
|
||||
{
|
||||
ProtobufCMessage *rv;
|
||||
size_t rem = len;
|
||||
const BYTE *at = data;
|
||||
const uint8_t *at = data;
|
||||
const ProtobufCFieldDescriptor *last_field = desc->fields + 0;
|
||||
ScannedMember first_member_slab[16];
|
||||
ScannedMember *scanned_member_slabs[30]; /* size of member i is (1<<(i+4)) */
|
||||
|
@ -5,6 +5,15 @@
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define PROTOBUF_C_BEGIN_DECLS extern "C" {
|
||||
# define PROTOBUF_C_END_DECLS }
|
||||
#else
|
||||
# define PROTOBUF_C_BEGIN_DECLS
|
||||
# define PROTOBUF_C_END_DECLS
|
||||
#endif
|
||||
|
||||
PROTOBUF_C_BEGIN_DECLS
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@ -45,7 +54,7 @@ typedef struct _ProtobufCBinaryData ProtobufCBinaryData;
|
||||
struct _ProtobufCBinaryData
|
||||
{
|
||||
size_t len;
|
||||
unsigned char *data;
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
typedef struct _ProtobufCIntRange ProtobufCIntRange; /* private */
|
||||
@ -71,7 +80,7 @@ struct _ProtobufCBuffer
|
||||
{
|
||||
void (*append)(ProtobufCBuffer *buffer,
|
||||
size_t len,
|
||||
const unsigned char *data);
|
||||
const uint8_t *data);
|
||||
};
|
||||
/* --- enums --- */
|
||||
typedef struct _ProtobufCEnumValue ProtobufCEnumValue;
|
||||
@ -147,7 +156,7 @@ struct _ProtobufCMessage
|
||||
|
||||
size_t protobuf_c_message_get_packed_size(const ProtobufCMessage *message);
|
||||
size_t protobuf_c_message_pack (const ProtobufCMessage *message,
|
||||
unsigned char *out);
|
||||
uint8_t *out);
|
||||
size_t protobuf_c_message_pack_to_buffer (const ProtobufCMessage *message,
|
||||
ProtobufCBuffer *buffer);
|
||||
|
||||
@ -155,7 +164,7 @@ ProtobufCMessage *
|
||||
protobuf_c_message_unpack (const ProtobufCMessageDescriptor *,
|
||||
ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const unsigned char *data);
|
||||
const uint8_t *data);
|
||||
void protobuf_c_message_free_unpacked (ProtobufCMessage *message,
|
||||
ProtobufCAllocator *allocator);
|
||||
|
||||
@ -219,7 +228,7 @@ struct _ProtobufCMessageUnknownField
|
||||
uint32_t tag;
|
||||
ProtobufCWireType wire_type;
|
||||
size_t len;
|
||||
unsigned char *data;
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
/* --- extra (superfluous) api: trivial buffer --- */
|
||||
@ -229,7 +238,7 @@ struct _ProtobufCBufferSimple
|
||||
ProtobufCBuffer base;
|
||||
size_t alloced;
|
||||
size_t len;
|
||||
unsigned char *data;
|
||||
uint8_t *data;
|
||||
protobuf_c_boolean must_free_data;
|
||||
};
|
||||
#define PROTOBUF_C_BUFFER_SIMPLE_INIT(array_of_bytes) \
|
||||
@ -241,4 +250,7 @@ struct _ProtobufCBufferSimple
|
||||
|
||||
/* ====== private ====== */
|
||||
#include "protobuf-c-private.h"
|
||||
|
||||
PROTOBUF_C_END_DECLS
|
||||
|
||||
#endif /* __PROTOBUF_C_RUNTIME_H_ */
|
||||
|
@ -61,7 +61,7 @@ void BytesFieldGenerator::GenerateStructMembers(io::Printer* printer) const
|
||||
printer->Print(variables_, "ProtobufCBinaryData $name$;\n");
|
||||
break;
|
||||
case FieldDescriptor::LABEL_REPEATED:
|
||||
printer->Print(variables_, "unsigned n_$name$;\n");
|
||||
printer->Print(variables_, "size_t n_$name$;\n");
|
||||
printer->Print(variables_, "ProtobufCBinaryData *$name$;\n");
|
||||
break;
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ void EnumFieldGenerator::GenerateStructMembers(io::Printer* printer) const
|
||||
printer->Print(variables_, "$type$ $name$;\n");
|
||||
break;
|
||||
case FieldDescriptor::LABEL_REPEATED:
|
||||
printer->Print(variables_, "unsigned n_$name$;\n");
|
||||
printer->Print(variables_, "size_t n_$name$;\n");
|
||||
printer->Print(variables_, "$type$ *$name$;\n");
|
||||
break;
|
||||
}
|
||||
|
@ -84,6 +84,8 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
|
||||
"#define PROTOBUF_C_$filename_identifier$__INCLUDED\n"
|
||||
"\n"
|
||||
"#include <google/protobuf-c/protobuf-c.h>\n"
|
||||
"\n"
|
||||
"PROTOBUF_C_BEGIN_DECLS\n"
|
||||
"\n",
|
||||
"filename_identifier", filename_identifier);
|
||||
|
||||
@ -169,6 +171,8 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
|
||||
}
|
||||
|
||||
printer->Print(
|
||||
"\n"
|
||||
"PROTOBUF_C_END_DECLS\n"
|
||||
"\n\n#endif // PROTOBUF_$filename_identifier$__INCLUDED\n",
|
||||
"filename_identifier", filename_identifier);
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ GenerateHelperFunctionDeclarations(io::Printer* printer)
|
||||
" (const $classname$ *message);\n"
|
||||
"size_t $lcclassname$__pack\n"
|
||||
" (const $classname$ *message,\n"
|
||||
" unsigned char *out);\n"
|
||||
" uint8_t *out);\n"
|
||||
"size_t $lcclassname$__pack_to_buffer\n"
|
||||
" (const $classname$ *message,\n"
|
||||
" ProtobufCBuffer *buffer);\n"
|
||||
@ -153,7 +153,7 @@ GenerateHelperFunctionDeclarations(io::Printer* printer)
|
||||
" $lcclassname$__unpack\n"
|
||||
" (ProtobufCAllocator *allocator,\n"
|
||||
" size_t len,\n"
|
||||
" const unsigned char *data);\n"
|
||||
" const uint8_t *data);\n"
|
||||
"void $lcclassname$__free_unpacked\n"
|
||||
" ($classname$ *message,\n"
|
||||
" ProtobufCAllocator *allocator);\n"
|
||||
@ -211,7 +211,7 @@ GenerateHelperFunctionDefinitions(io::Printer* printer)
|
||||
"}\n"
|
||||
"size_t $lcclassname$__pack\n"
|
||||
" (const $classname$ *message,\n"
|
||||
" unsigned char *out)\n"
|
||||
" uint8_t *out)\n"
|
||||
"{\n"
|
||||
" PROTOBUF_C_ASSERT (message->base.descriptor == &$lcclassname$__descriptor);\n"
|
||||
" return protobuf_c_message_pack ((ProtobufCMessage*)message, out);\n"
|
||||
@ -227,7 +227,7 @@ GenerateHelperFunctionDefinitions(io::Printer* printer)
|
||||
" $lcclassname$__unpack\n"
|
||||
" (ProtobufCAllocator *allocator,\n"
|
||||
" size_t len,\n"
|
||||
" const unsigned char *data)\n"
|
||||
" const uint8_t *data)\n"
|
||||
"{\n"
|
||||
" return ($classname$ *)\n"
|
||||
" protobuf_c_message_unpack (&$lcclassname$__descriptor,\n"
|
||||
|
@ -52,7 +52,7 @@ void MessageFieldGenerator::GenerateStructMembers(io::Printer* printer) const
|
||||
printer->Print(vars, "$type$ *$name$;\n");
|
||||
break;
|
||||
case FieldDescriptor::LABEL_REPEATED:
|
||||
printer->Print(vars, "unsigned n_$name$;\n");
|
||||
printer->Print(vars, "size_t n_$name$;\n");
|
||||
printer->Print(vars, "$type$ **$name$;\n");
|
||||
break;
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ void PrimitiveFieldGenerator::GenerateStructMembers(io::Printer* printer) const
|
||||
printer->Print(vars, "$c_type$ $name$;\n");
|
||||
break;
|
||||
case FieldDescriptor::LABEL_REPEATED:
|
||||
printer->Print(vars, "unsigned n_$name$;\n");
|
||||
printer->Print(vars, "size_t n_$name$;\n");
|
||||
printer->Print(vars, "$c_type$ *$name$;\n");
|
||||
break;
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ void StringFieldGenerator::GenerateStructMembers(io::Printer* printer) const
|
||||
printer->Print(variables_, "char *$name$;\n");
|
||||
break;
|
||||
case FieldDescriptor::LABEL_REPEATED:
|
||||
printer->Print(variables_, "unsigned n_$name$;\n");
|
||||
printer->Print(variables_, "size_t n_$name$;\n");
|
||||
printer->Print(variables_, "char **$name$;\n");
|
||||
break;
|
||||
}
|
||||
|
@ -752,6 +752,26 @@ static void dump_test_repeated_SubMess (void)
|
||||
dump_message_bytes(&mess, "test_repeated_submess_1");
|
||||
}
|
||||
|
||||
static void dump_test_unknown_fields (void)
|
||||
{
|
||||
EmptyMess mess;
|
||||
google::protobuf::Message::Reflection *reflection = mess.GetReflection();
|
||||
google::protobuf::UnknownFieldSet *fs = reflection->MutableUnknownFields();
|
||||
google::protobuf::UnknownField *f;
|
||||
f = fs->AddField(5454);
|
||||
f->add_varint(255);
|
||||
f = fs->AddField(5555);
|
||||
f->add_fixed32(260);
|
||||
dump_message_bytes (&mess, "test_unknown_fields_0");
|
||||
|
||||
fs->Clear();
|
||||
f = fs->AddField(6666);
|
||||
f->add_length_delimited("xxxxxxxx");
|
||||
f = fs->AddField(7777);
|
||||
f->add_fixed64(0x10101);
|
||||
dump_message_bytes (&mess, "test_unknown_fields_1");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
dump_test_enum_small ();
|
||||
@ -811,5 +831,6 @@ int main()
|
||||
dump_test_repeated_string ();
|
||||
dump_test_repeated_bytes ();
|
||||
dump_test_repeated_SubMess ();
|
||||
dump_test_unknown_fields ();
|
||||
return 0;
|
||||
}
|
||||
|
@ -142,4 +142,6 @@ message TestMessRequiredBytes {
|
||||
message TestMessRequiredMessage {
|
||||
required SubMess test = 1;
|
||||
}
|
||||
message EmptyMess {
|
||||
}
|
||||
|
||||
|
@ -975,6 +975,62 @@ static void test_repeated_SubMess (void)
|
||||
#undef DO_TEST
|
||||
}
|
||||
|
||||
static void test_unknown_fields (void)
|
||||
{
|
||||
static Foo__EmptyMess mess = FOO__EMPTY_MESS__INIT;
|
||||
static Foo__EmptyMess *mess2;
|
||||
ProtobufCMessageUnknownField fields[2];
|
||||
size_t len; uint8_t *data;
|
||||
|
||||
mess.base.n_unknown_fields = 2;
|
||||
mess.base.unknown_fields = fields;
|
||||
|
||||
fields[0].tag = 5454;
|
||||
fields[0].wire_type = PROTOBUF_C_WIRE_TYPE_VARINT;
|
||||
fields[0].len = 2;
|
||||
fields[0].data = (uint8_t*)"\377\1";
|
||||
fields[1].tag = 5555;
|
||||
fields[1].wire_type = PROTOBUF_C_WIRE_TYPE_32BIT;
|
||||
fields[1].len = 4;
|
||||
fields[1].data = (uint8_t*)"\4\1\0\0";
|
||||
mess2 = test_compare_pack_methods (&mess.base, &len, &data);
|
||||
assert (mess2->base.n_unknown_fields == 2);
|
||||
assert (mess2->base.unknown_fields[0].tag == 5454);
|
||||
assert (mess2->base.unknown_fields[0].wire_type == PROTOBUF_C_WIRE_TYPE_VARINT);
|
||||
assert (mess2->base.unknown_fields[0].len == 2);
|
||||
assert (memcmp (mess2->base.unknown_fields[0].data, fields[0].data, 2) == 0);
|
||||
assert (mess2->base.unknown_fields[1].tag == 5555);
|
||||
assert (mess2->base.unknown_fields[1].wire_type == PROTOBUF_C_WIRE_TYPE_32BIT);
|
||||
assert (mess2->base.unknown_fields[1].len == 4);
|
||||
assert (memcmp (mess2->base.unknown_fields[1].data, fields[1].data, 4) == 0);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_unknown_fields_0);
|
||||
free (data);
|
||||
foo__empty_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
fields[0].tag = 6666;
|
||||
fields[0].wire_type = PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
|
||||
fields[0].len = 9;
|
||||
fields[0].data = (uint8_t*)"\10xxxxxxxx";
|
||||
fields[1].tag = 7777;
|
||||
fields[1].wire_type = PROTOBUF_C_WIRE_TYPE_64BIT;
|
||||
fields[1].len = 8;
|
||||
fields[1].data = (uint8_t*)"\1\1\1\0\0\0\0\0";
|
||||
mess2 = test_compare_pack_methods (&mess.base, &len, &data);
|
||||
assert (mess2->base.n_unknown_fields == 2);
|
||||
assert (mess2->base.unknown_fields[0].tag == 6666);
|
||||
assert (mess2->base.unknown_fields[0].wire_type == PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED);
|
||||
assert (mess2->base.unknown_fields[0].len == 9);
|
||||
assert (memcmp (mess2->base.unknown_fields[0].data, fields[0].data, 9) == 0);
|
||||
assert (mess2->base.unknown_fields[1].tag == 7777);
|
||||
assert (mess2->base.unknown_fields[1].wire_type == PROTOBUF_C_WIRE_TYPE_64BIT);
|
||||
assert (mess2->base.unknown_fields[1].len == 8);
|
||||
assert (memcmp (mess2->base.unknown_fields[1].data, fields[1].data, 8) == 0);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_unknown_fields_1);
|
||||
free (data);
|
||||
foo__empty_mess__free_unpacked (mess2, NULL);
|
||||
}
|
||||
|
||||
|
||||
/* === simple testing framework === */
|
||||
|
||||
typedef void (*TestFunc) (void);
|
||||
@ -1048,6 +1104,8 @@ static Test tests[] =
|
||||
{ "test repeated string", test_repeated_string },
|
||||
{ "test repeated bytes", test_repeated_bytes },
|
||||
{ "test repeated SubMess", test_repeated_SubMess },
|
||||
|
||||
{ "test unknown fields", test_unknown_fields }
|
||||
};
|
||||
#define n_tests (sizeof(tests)/sizeof(Test))
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user