Create a message descriptor type.

This replaces the sentinel at the end of the pb_field_t
array for each message type.

git-svn-id: https://svn.kapsi.fi/jpa/nanopb-dev@1007 e3a754e5-d11d-0410-8d38-ebb782a927b9
This commit is contained in:
Michael Poole
2011-11-13 18:10:11 +00:00
committed by Petteri Aimonen
parent dcf43a6416
commit 43b8e20744
17 changed files with 127 additions and 101 deletions

View File

@@ -74,7 +74,7 @@ This is the way to get the size of the message without storing it anywhere::
Person myperson = ...;
pb_ostream_t sizestream = {0};
pb_encode(&sizestream, Person_fields, &myperson);
pb_encode(&sizestream, Person_msg, &myperson);
printf("Encoded size is %d\n", sizestream.bytes_written);
**Example 2:**
@@ -221,10 +221,10 @@ This callback reads multiple integers and prints them::
return true;
}
Field description array
=======================
Message descriptor
==================
For using the *pb_encode* and *pb_decode* functions, you need an array of pb_field_t constants describing the structure you wish to encode. This description is usually autogenerated from .proto file.
For using the *pb_encode* and *pb_decode* functions, you need a message descriptor describing the structure you wish to encode. This description is usually autogenerated from .proto file.
For example this submessage in the Person.proto file::
@@ -235,20 +235,27 @@ For example this submessage in the Person.proto file::
}
}
generates this field description array for the structure *Person_PhoneNumber*::
generates these declarations and definitions for the structure *Person_PhoneNumber*::
typedef PB_MSG_STRUCT(2) Person_PhoneNumber_msg_t;
extern const Person_PhoneNumber_msg_t Person_PhoneNumber_real_msg;
#define Person_PhoneNumber_msg ((const pb_message_t*)&Person_PhoneNumber_real_msg)
const Person_PhoneNumber_msg_t Person_PhoneNumber_real_msg = {
2,
{
const pb_field_t Person_PhoneNumber_fields[3] = {
{1, PB_HTYPE_REQUIRED | PB_LTYPE_STRING,
offsetof(Person_PhoneNumber, number), 0,
pb_membersize(Person_PhoneNumber, number), 0, 0},
{2, PB_HTYPE_OPTIONAL | PB_LTYPE_VARINT,
pb_delta(Person_PhoneNumber, type, number),
pb_delta_end(Person_PhoneNumber, type, number),
pb_delta(Person_PhoneNumber, has_type, type),
pb_membersize(Person_PhoneNumber, type), 0,
&Person_PhoneNumber_type_default},
PB_LAST_FIELD
}
};

View File

@@ -27,7 +27,7 @@ So a typical project might include these files:
- pb_encode.h and pb_encode.c (needed for encoding messages)
2) Protocol description (you can have many):
- person.proto (just an example)
- person.pb.c (autogenerated, contains initializers for const arrays)
- person.pb.c (autogenerated, contains initializers for message descriptors)
- person.pb.h (autogenerated, contains type declarations)
Features and limitations
@@ -74,14 +74,16 @@ You should now have in *message.pb.h*::
int32_t value;
} Example;
extern const pb_field_t Example_fields[2];
typedef PB_MSG_STRUCT(1) Example_msg_t;
extern const Example_msg_t Example_real_msg;
#define Example_msg ((const pb_message_t*)&Example_real_msg)
Now in your main program do this to encode a message::
Example mymessage = {42};
uint8_t buffer[10];
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
pb_encode(&stream, Example_fields, &mymessage);
pb_encode(&stream, Example_msg, &mymessage);
After that, buffer will contain the encoded message.
The number of bytes in the message is stored in *stream.bytes_written*.

View File

@@ -140,14 +140,14 @@ pb_encode
---------
Encodes the contents of a structure as a protocol buffers message and writes it to output stream. ::
bool pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct);
bool pb_encode(pb_ostream_t *stream, const pb_message_t *msg, const void *src_struct);
:stream: Output stream to write to.
:fields: A field description array, usually autogenerated.
:msg: A message descriptor, usually autogenerated.
:src_struct: Pointer to the data that will be serialized.
:returns: True on success, false on IO error, on detectable errors in field description, or if a field encoder returns false.
Normally pb_encode simply walks through the fields description array and serializes each field in turn. However, submessages must be serialized twice: first to calculate their size and then to actually write them to output. This causes some constraints for callback fields, which must return the same data on every call.
Normally pb_encode simply walks through the fields description array inside the message descriptor and serializes each field in turn. However, submessages must be serialized twice: first to calculate their size and then to actually write them to output. This causes some constraints for callback fields, which must return the same data on every call.
pb_encode_varint
----------------
@@ -289,7 +289,7 @@ Field encoder for PB_LTYPE_SUBMESSAGE. Calls `pb_encode`_ to perform the actual
bool pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src);
:stream: Output stream to write to.
:field: Field description structure. The *ptr* field must be a pointer to a field description array for the submessage.
:field: Field description structure. The *ptr* field must be a pointer to a valid *pb_message_t* descriptor for the submessage.
:src: Pointer to the structure where submessage data is.
:returns: True on success, false on IO errors, pb_encode errors or if submessage size changes between calls.
@@ -355,10 +355,10 @@ pb_decode
---------
Read and decode all fields of a structure. Reads until EOF on input stream. ::
bool pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct);
bool pb_decode(pb_istream_t *stream, const pb_message_t *msg, void *dest_struct);
:stream: Input stream to read from.
:fields: A field description array. Usually autogenerated.
:msg: A message descriptor. Usually autogenerated.
:dest_struct: Pointer to structure where data will be stored.
:returns: True on success, false on IO error, on detectable errors in field description, if a field encoder returns false or if a required field is missing.
@@ -459,5 +459,5 @@ Field decoder for PB_LTYPE_SUBMESSAGE. Calls `pb_decode`_ to perform the actual
:dest: Pointer to the destination structure.
:returns: True on success, false on IO error or if `pb_decode`_ fails.
The *field->ptr* should be a pointer to *pb_field_t* array describing the submessage.
The *field->ptr* should be a pointer to *pb_message_t* describing the submessage.

View File

@@ -27,7 +27,7 @@ bool printfile_callback(pb_istream_t *stream, const pb_field_t *field, void *arg
{
FileInfo fileinfo;
if (!pb_decode(stream, FileInfo_fields, &fileinfo))
if (!pb_decode(stream, FileInfo_msg, &fileinfo))
return false;
printf("%-10lld %s\n", fileinfo.inode, fileinfo.name);
@@ -59,7 +59,7 @@ bool listdir(int fd, char *path)
strcpy(request.path, path);
}
if (!pb_encode(&output, ListFilesRequest_fields, &request))
if (!pb_encode(&output, ListFilesRequest_msg, &request))
{
fprintf(stderr, "Encoding failed.\n");
return false;
@@ -70,7 +70,7 @@ bool listdir(int fd, char *path)
response.file.funcs.decode = &printfile_callback;
if (!pb_decode(&input, ListFilesResponse_fields, &response))
if (!pb_decode(&input, ListFilesResponse_msg, &response))
{
fprintf(stderr, "Decoding failed.\n");
return false;

View File

@@ -53,7 +53,7 @@ void handle_connection(int connfd)
pb_ostream_t output = pb_ostream_from_socket(connfd);
DIR *directory;
if (!pb_decode(&input, ListFilesRequest_fields, &request))
if (!pb_decode(&input, ListFilesRequest_msg, &request))
{
printf("Decoding failed.\n");
return;
@@ -78,7 +78,7 @@ void handle_connection(int connfd)
response.file.arg = directory;
}
if (!pb_encode(&output, ListFilesResponse_fields, &response))
if (!pb_encode(&output, ListFilesResponse_msg, &response))
{
printf("Encoding failed.\n");
}

View File

@@ -227,7 +227,7 @@ class Field:
result += ' 0,'
if self.ltype == 'PB_LTYPE_SUBMESSAGE':
result += '\n &%s_fields}' % self.submsgname
result += '\n %s_msg}' % self.submsgname
elif self.default is None or self.htype == 'PB_HTYPE_CALLBACK':
result += ' 0}'
else:
@@ -268,20 +268,24 @@ class Message:
result += default + '\n'
return result
def fields_declaration(self):
result = 'extern const pb_field_t %s_fields[%d];' % (self.name, len(self.fields) + 1)
def message_declaration(self):
result = 'typedef PB_MSG_STRUCT(%d) %s_msg_t;\n' % (len(self.fields), self.name)
result += 'extern const %s_msg_t %s_real_msg;\n' % (self.name, self.name)
result += '#define %s_msg ((const pb_message_t*)&%s_real_msg)\n' % (self.name, self.name)
return result
def fields_definition(self):
result = 'const pb_field_t %s_fields[%d] = {\n' % (self.name, len(self.fields) + 1)
def message_definition(self):
result = 'const %s_msg_t %s_real_msg = {\n' % (self.name, self.name)
result += ' %d,\n' % len(self.fields)
result += ' {\n\n'
prev = None
for field in self.ordered_fields:
result += field.pb_field_t(prev)
result += ',\n\n'
prev = field.name
result += ' PB_LAST_FIELD\n};'
result += ' }\n};'
return result
def iterate_messages(desc, names = Names()):
@@ -378,7 +382,7 @@ def generate_header(headername, enums, messages):
yield '/* Struct field encoding specification for nanopb */\n'
for msg in messages:
yield msg.fields_declaration() + '\n'
yield msg.message_declaration() + '\n'
yield '\n#endif\n'
@@ -394,7 +398,7 @@ def generate_source(headername, enums, messages):
yield '\n\n'
for msg in messages:
yield msg.fields_definition() + '\n\n'
yield msg.message_definition() + '\n\n'
if __name__ == '__main__':
import sys

13
pb.h
View File

@@ -112,6 +112,19 @@ typedef struct {
uint8_t bytes[1];
} pb_bytes_array_t;
/* This macro is define the type of a structure for a message with N
* fields.
*/
#define PB_MSG_STRUCT(N) struct { \
unsigned int field_count; \
pb_field_t fields[N]; \
}
/* This is the visible type for generated message structures.
* The actual number of fields at the end will vary by message type.
*/
typedef PB_MSG_STRUCT(1) pb_message_t;
/* This structure is used for giving the callback function.
* It is stored in the message structure and filled in by the method that
* calls pb_decode.

View File

@@ -185,7 +185,7 @@ static bool checkreturn make_string_substream(pb_istream_t *stream, pb_istream_t
/* Iterator for pb_field_t list */
typedef struct {
const pb_field_t *start;
const pb_message_t *msg;
const pb_field_t *current;
int field_index;
void *dest_struct;
@@ -193,9 +193,10 @@ typedef struct {
void *pSize;
} pb_field_iterator_t;
static void pb_field_init(pb_field_iterator_t *iter, const pb_field_t *fields, void *dest_struct)
static void pb_field_init(pb_field_iterator_t *iter, const pb_message_t *msg, void *dest_struct)
{
iter->start = iter->current = fields;
iter->msg = msg;
iter->current = msg->fields;
iter->field_index = 0;
iter->pData = (char*)dest_struct + iter->current->data_offset;
iter->pSize = (char*)iter->pData + iter->current->size_offset;
@@ -212,9 +213,9 @@ static bool pb_field_next(pb_field_iterator_t *iter)
iter->current++;
iter->field_index++;
if (iter->current->tag == 0)
if (iter->field_index >= iter->msg->field_count)
{
iter->current = iter->start;
iter->current = &iter->msg->fields[0];
iter->field_index = 0;
iter->pData = iter->dest_struct;
prev_size = 0;
@@ -334,15 +335,15 @@ static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_t
}
/* Initialize message fields to default values, recursively */
static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct)
static void pb_message_set_to_defaults(const pb_message_t *msg, void *dest_struct)
{
pb_field_iterator_t iter;
pb_field_init(&iter, fields, dest_struct);
pb_field_init(&iter, msg, dest_struct);
/* Initialize size/has fields and apply default values */
do
{
if (iter.current->tag == 0)
if (iter.field_index >= msg->field_count)
continue;
/* Initialize the size field for optional/repeated fields to 0. */
@@ -380,15 +381,15 @@ static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_str
* Decode all fields *
*********************/
bool checkreturn pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)
bool checkreturn pb_decode(pb_istream_t *stream, const pb_message_t *msg, void *dest_struct)
{
uint32_t fields_seen = 0; /* Used to check for required fields */
pb_field_iterator_t iter;
int i;
unsigned int i;
pb_message_set_to_defaults(fields, dest_struct);
pb_message_set_to_defaults(msg, dest_struct);
pb_field_init(&iter, fields, dest_struct);
pb_field_init(&iter, msg, dest_struct);
while (stream->bytes_left)
{
@@ -424,9 +425,9 @@ bool checkreturn pb_decode(pb_istream_t *stream, const pb_field_t fields[], void
}
/* Check that all required fields (mod 31) were present. */
for (i = 0; fields[i].tag != 0; i++)
for (i = 0; i < msg->field_count; i++)
{
if (PB_HTYPE(fields[i].type) == PB_HTYPE_REQUIRED &&
if (PB_HTYPE(msg->fields[i].type) == PB_HTYPE_REQUIRED &&
!(fields_seen & (1 << (i & 31))))
{
return false;
@@ -537,7 +538,7 @@ bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field
if (field->ptr == NULL)
return false;
status = pb_decode(&substream, (pb_field_t*)field->ptr, dest);
status = pb_decode(&substream, (const pb_message_t*)field->ptr, dest);
stream->state = substream.state;
return status;
}

View File

@@ -40,9 +40,9 @@ bool pb_read(pb_istream_t *stream, uint8_t *buf, size_t count);
/* Decode from stream to destination struct.
* Returns true on success, false on any failure.
* The actual struct pointed to by dest must match the description in fields.
* The actual struct pointed to by dest must match the description in msg.
*/
bool pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct);
bool pb_decode(pb_istream_t *stream, const pb_message_t *msg, void *dest_struct);
/* --- Helper functions ---
* You may want to use these from your caller or callbacks.

View File

@@ -140,15 +140,16 @@ static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *fie
return true;
}
bool checkreturn pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct)
bool checkreturn pb_encode(pb_ostream_t *stream, const pb_message_t *msg, const void *src_struct)
{
const pb_field_t *field = fields;
const void *pData = src_struct;
const void *pSize;
unsigned int i;
size_t prev_size = 0;
while (field->tag != 0)
for (i = 0; i < msg->field_count; i++)
{
const pb_field_t *field = &msg->fields[i];
pb_encoder_t func = PB_ENCODERS[PB_LTYPE(field->type)];
pData = (const char*)pData + prev_size + field->data_offset;
pSize = (const char*)pData + field->size_offset;
@@ -193,8 +194,6 @@ bool checkreturn pb_encode(pb_ostream_t *stream, const pb_field_t fields[], cons
break;
}
}
field++;
}
return true;
@@ -352,7 +351,7 @@ bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field
if (field->ptr == NULL)
return false;
if (!pb_encode(&substream, (pb_field_t*)field->ptr, src))
if (!pb_encode(&substream, (const pb_message_t*)field->ptr, src))
return false;
size = substream.bytes_written;
@@ -373,7 +372,7 @@ bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field
substream.max_size = size;
substream.bytes_written = 0;
status = pb_encode(&substream, (pb_field_t*)field->ptr, src);
status = pb_encode(&substream, (const pb_message_t*)field->ptr, src);
stream->bytes_written += substream.bytes_written;

View File

@@ -39,10 +39,10 @@ bool pb_write(pb_ostream_t *stream, const uint8_t *buf, size_t count);
/* Encode struct to given output stream.
* Returns true on success, false on any failure.
* The actual struct pointed to by src_struct must match the description in fields.
* The actual struct pointed to by src_struct must match the description in msg.
* All required fields in the struct are assumed to have been filled in.
*/
bool pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct);
bool pb_encode(pb_ostream_t *stream, const pb_message_t *msg, const void *src_struct);
/* --- Helper functions ---
* You may want to use these from your caller or callbacks.

View File

@@ -193,13 +193,13 @@ int main()
IntegerArray dest;
COMMENT("Testing pb_decode with repeated int32 field")
TEST((s = S(""), pb_decode(&s, IntegerArray_fields, &dest) && dest.data_count == 0))
TEST((s = S("\x08\x01\x08\x02"), pb_decode(&s, IntegerArray_fields, &dest)
TEST((s = S(""), pb_decode(&s, IntegerArray_msg, &dest) && dest.data_count == 0))
TEST((s = S("\x08\x01\x08\x02"), pb_decode(&s, IntegerArray_msg, &dest)
&& dest.data_count == 2 && dest.data[0] == 1 && dest.data[1] == 2))
s = S("\x08\x01\x08\x02\x08\x03\x08\x04\x08\x05\x08\x06\x08\x07\x08\x08\x08\x09\x08\x0A");
TEST(pb_decode(&s, IntegerArray_fields, &dest) && dest.data_count == 10 && dest.data[9] == 10)
TEST(pb_decode(&s, IntegerArray_msg, &dest) && dest.data_count == 10 && dest.data[9] == 10)
s = S("\x08\x01\x08\x02\x08\x03\x08\x04\x08\x05\x08\x06\x08\x07\x08\x08\x08\x09\x08\x0A\x08\x0B");
TEST(!pb_decode(&s, IntegerArray_fields, &dest))
TEST(!pb_decode(&s, IntegerArray_msg, &dest))
}
{
@@ -207,17 +207,17 @@ int main()
IntegerArray dest;
COMMENT("Testing pb_decode with packed int32 field")
TEST((s = S("\x0A\x00"), pb_decode(&s, IntegerArray_fields, &dest)
TEST((s = S("\x0A\x00"), pb_decode(&s, IntegerArray_msg, &dest)
&& dest.data_count == 0))
TEST((s = S("\x0A\x01\x01"), pb_decode(&s, IntegerArray_fields, &dest)
TEST((s = S("\x0A\x01\x01"), pb_decode(&s, IntegerArray_msg, &dest)
&& dest.data_count == 1 && dest.data[0] == 1))
TEST((s = S("\x0A\x0A\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A"), pb_decode(&s, IntegerArray_fields, &dest)
TEST((s = S("\x0A\x0A\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A"), pb_decode(&s, IntegerArray_msg, &dest)
&& dest.data_count == 10 && dest.data[0] == 1 && dest.data[9] == 10))
TEST((s = S("\x0A\x0B\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B"), !pb_decode(&s, IntegerArray_fields, &dest)))
TEST((s = S("\x0A\x0B\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B"), !pb_decode(&s, IntegerArray_msg, &dest)))
/* Test invalid wire data */
TEST((s = S("\x0A\xFF"), !pb_decode(&s, IntegerArray_fields, &dest)))
TEST((s = S("\x0A\x01"), !pb_decode(&s, IntegerArray_fields, &dest)))
TEST((s = S("\x0A\xFF"), !pb_decode(&s, IntegerArray_msg, &dest)))
TEST((s = S("\x0A\x01"), !pb_decode(&s, IntegerArray_msg, &dest)))
}
{
@@ -225,14 +225,14 @@ int main()
IntegerArray dest;
COMMENT("Testing pb_decode with unknown fields")
TEST((s = S("\x18\x0F\x08\x01"), pb_decode(&s, IntegerArray_fields, &dest)
TEST((s = S("\x18\x0F\x08\x01"), pb_decode(&s, IntegerArray_msg, &dest)
&& dest.data_count == 1 && dest.data[0] == 1))
TEST((s = S("\x19\x00\x00\x00\x00\x00\x00\x00\x00\x08\x01"), pb_decode(&s, IntegerArray_fields, &dest)
TEST((s = S("\x19\x00\x00\x00\x00\x00\x00\x00\x00\x08\x01"), pb_decode(&s, IntegerArray_msg, &dest)
&& dest.data_count == 1 && dest.data[0] == 1))
TEST((s = S("\x1A\x00\x08\x01"), pb_decode(&s, IntegerArray_fields, &dest)
TEST((s = S("\x1A\x00\x08\x01"), pb_decode(&s, IntegerArray_msg, &dest)
&& dest.data_count == 1 && dest.data[0] == 1))
TEST((s = S("\x1B\x08\x01"), !pb_decode(&s, IntegerArray_fields, &dest)))
TEST((s = S("\x1D\x00\x00\x00\x00\x08\x01"), pb_decode(&s, IntegerArray_fields, &dest)
TEST((s = S("\x1B\x08\x01"), !pb_decode(&s, IntegerArray_msg, &dest)))
TEST((s = S("\x1D\x00\x00\x00\x00\x08\x01"), pb_decode(&s, IntegerArray_msg, &dest)
&& dest.data_count == 1 && dest.data[0] == 1))
}
@@ -246,25 +246,25 @@ int main()
COMMENT("Testing pb_decode with callbacks")
/* Single varint */
ref.size = 1; ref.bytes[0] = 0x55;
TEST((s = S("\x08\x55"), pb_decode(&s, CallbackArray_fields, &dest)))
TEST((s = S("\x08\x55"), pb_decode(&s, CallbackArray_msg, &dest)))
/* Packed varint */
ref.size = 3; ref.bytes[0] = ref.bytes[1] = ref.bytes[2] = 0x55;
TEST((s = S("\x0A\x03\x55\x55\x55"), pb_decode(&s, CallbackArray_fields, &dest)))
TEST((s = S("\x0A\x03\x55\x55\x55"), pb_decode(&s, CallbackArray_msg, &dest)))
/* Packed varint with loop */
ref.size = 1; ref.bytes[0] = 0x55;
TEST((s = S("\x0A\x03\x55\x55\x55"), pb_decode(&s, CallbackArray_fields, &dest)))
TEST((s = S("\x0A\x03\x55\x55\x55"), pb_decode(&s, CallbackArray_msg, &dest)))
/* Single fixed32 */
ref.size = 4; ref.bytes[0] = ref.bytes[1] = ref.bytes[2] = ref.bytes[3] = 0xAA;
TEST((s = S("\x0D\xAA\xAA\xAA\xAA"), pb_decode(&s, CallbackArray_fields, &dest)))
TEST((s = S("\x0D\xAA\xAA\xAA\xAA"), pb_decode(&s, CallbackArray_msg, &dest)))
/* Single fixed64 */
ref.size = 8; memset(ref.bytes, 0xAA, 8);
TEST((s = S("\x09\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"), pb_decode(&s, CallbackArray_fields, &dest)))
TEST((s = S("\x09\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"), pb_decode(&s, CallbackArray_msg, &dest)))
/* Unsupported field type */
TEST((s = S("\x0B\x00"), !pb_decode(&s, CallbackArray_fields, &dest)))
TEST((s = S("\x0B\x00"), !pb_decode(&s, CallbackArray_msg, &dest)))
/* Just make sure that our test function works */
ref.size = 1; ref.bytes[0] = 0x56;
TEST((s = S("\x08\x55"), !pb_decode(&s, CallbackArray_fields, &dest)))
TEST((s = S("\x08\x55"), !pb_decode(&s, CallbackArray_msg, &dest)))
}
{
@@ -272,11 +272,11 @@ int main()
IntegerArray dest;
COMMENT("Testing pb_decode message termination")
TEST((s = S(""), pb_decode(&s, IntegerArray_fields, &dest)))
TEST((s = S("\x00"), pb_decode(&s, IntegerArray_fields, &dest)))
TEST((s = S("\x08\x01"), pb_decode(&s, IntegerArray_fields, &dest)))
TEST((s = S("\x08\x01\x00"), pb_decode(&s, IntegerArray_fields, &dest)))
TEST((s = S("\x08"), !pb_decode(&s, IntegerArray_fields, &dest)))
TEST((s = S(""), pb_decode(&s, IntegerArray_msg, &dest)))
TEST((s = S("\x00"), pb_decode(&s, IntegerArray_msg, &dest)))
TEST((s = S("\x08\x01"), pb_decode(&s, IntegerArray_msg, &dest)))
TEST((s = S("\x08\x01\x00"), pb_decode(&s, IntegerArray_msg, &dest)))
TEST((s = S("\x08"), !pb_decode(&s, IntegerArray_msg, &dest)))
}
if (status != 0)

View File

@@ -196,13 +196,13 @@ int main()
COMMENT("Test pb_encode with int32 array")
TEST(WRITES(pb_encode(&s, IntegerArray_fields, &msg), "\x0A\x05\x01\x02\x03\x04\x05"))
TEST(WRITES(pb_encode(&s, IntegerArray_msg, &msg), "\x0A\x05\x01\x02\x03\x04\x05"))
msg.data_count = 0;
TEST(WRITES(pb_encode(&s, IntegerArray_fields, &msg), ""))
TEST(WRITES(pb_encode(&s, IntegerArray_msg, &msg), ""))
msg.data_count = 10;
TEST(!pb_encode(&s, IntegerArray_fields, &msg))
TEST(!pb_encode(&s, IntegerArray_msg, &msg))
}
{
@@ -212,14 +212,14 @@ int main()
COMMENT("Test pb_encode with float array")
TEST(WRITES(pb_encode(&s, FloatArray_fields, &msg),
TEST(WRITES(pb_encode(&s, FloatArray_msg, &msg),
"\x0A\x04\x00\x00\xc6\x42"))
msg.data_count = 0;
TEST(WRITES(pb_encode(&s, FloatArray_fields, &msg), ""))
TEST(WRITES(pb_encode(&s, FloatArray_msg, &msg), ""))
msg.data_count = 3;
TEST(!pb_encode(&s, FloatArray_fields, &msg))
TEST(!pb_encode(&s, FloatArray_msg, &msg))
}
{
@@ -230,7 +230,7 @@ int main()
msg.data.funcs.encode = &fieldcallback;
COMMENT("Test pb_encode with callback field.")
TEST(WRITES(pb_encode(&s, CallbackArray_fields, &msg), "\x08\x55"))
TEST(WRITES(pb_encode(&s, CallbackArray_msg, &msg), "\x08\x55"))
}
{
@@ -239,7 +239,7 @@ int main()
IntegerContainer msg = {{5, {1,2,3,4,5}}};
COMMENT("Test pb_encode with packed array in a submessage.")
TEST(WRITES(pb_encode(&s, IntegerContainer_fields, &msg),
TEST(WRITES(pb_encode(&s, IntegerContainer_msg, &msg),
"\x0A\x07\x0A\x05\x01\x02\x03\x04\x05"))
}
@@ -254,8 +254,8 @@ int main()
msg2.submsg.submsg.data.funcs.encode = &fieldcallback;
COMMENT("Test pb_encode with callback field in a submessage.")
TEST(WRITES(pb_encode(&s, CallbackContainer_fields, &msg), "\x0A\x02\x08\x55"))
TEST(WRITES(pb_encode(&s, CallbackContainerContainer_fields, &msg2),
TEST(WRITES(pb_encode(&s, CallbackContainer_msg, &msg), "\x0A\x02\x08\x55"))
TEST(WRITES(pb_encode(&s, CallbackContainerContainer_msg, &msg2),
"\x0A\x04\x0A\x02\x08\x55"))
/* Misbehaving callback: varying output between calls */
@@ -264,9 +264,9 @@ int main()
msg2.submsg.submsg.data.funcs.encode = &crazyfieldcallback;
msg2.submsg.submsg.data.arg = &state;
TEST(!pb_encode(&s, CallbackContainer_fields, &msg))
TEST(!pb_encode(&s, CallbackContainer_msg, &msg))
state = 1;
TEST(!pb_encode(&s, CallbackContainerContainer_fields, &msg2))
TEST(!pb_encode(&s, CallbackContainerContainer_msg, &msg2))
}
if (status != 0)

View File

@@ -17,7 +17,7 @@ bool print_person(pb_istream_t *stream)
int i;
Person person;
if (!pb_decode(stream, Person_fields, &person))
if (!pb_decode(stream, Person_msg, &person))
return false;
/* Now the decoding is done, rest is just to print stuff out. */

View File

@@ -84,8 +84,8 @@ int main()
testmessage.fixed64value.funcs.decode = &print_fixed64;
testmessage.fixed64value.arg = "fixed64value: %lld\n";
if (!pb_decode(&stream, TestMessage_fields, &testmessage))
if (!pb_decode(&stream, TestMessage_msg, &testmessage))
return 1;
return 0;
}
}

View File

@@ -24,7 +24,7 @@ int main()
pb_ostream_t stream = {&streamcallback, stdout, SIZE_MAX, 0};
/* Now encode it and check if we succeeded. */
if (pb_encode(&stream, Person_fields, &person))
if (pb_encode(&stream, Person_msg, &person))
return 0; /* Success */
else
return 1; /* Failure */

View File

@@ -58,7 +58,7 @@ int main()
testmessage.submsg.fixed32value.funcs.encode = &encode_fixed32;
testmessage.submsg.fixed64value.funcs.encode = &encode_fixed64;
if (!pb_encode(&stream, TestMessage_fields, &testmessage))
if (!pb_encode(&stream, TestMessage_msg, &testmessage))
return 1;
if (fwrite(buffer, stream.bytes_written, 1, stdout) != 1)