diff options
author | Petteri Aimonen <jpa@git.mail.kapsi.fi> | 2014-03-16 15:52:19 +0200 |
---|---|---|
committer | Petteri Aimonen <jpa@git.mail.kapsi.fi> | 2014-03-16 15:52:19 +0200 |
commit | ab62402059ff3752660ffc9f292cf210aef59be0 (patch) | |
tree | 669db214120b26e1ea939e4e529f1c434534ec95 | |
parent | 108864963faf54762629a8bdf1f8bd614f0abd16 (diff) |
Documentation updates
-rw-r--r-- | docs/reference.rst | 51 | ||||
-rw-r--r-- | pb_decode.c | 10 | ||||
-rw-r--r-- | pb_decode.h | 7 | ||||
-rw-r--r-- | tests/alltypes_pointer/decode_alltypes_pointer.c | 3 |
4 files changed, 63 insertions, 8 deletions
diff --git a/docs/reference.rst b/docs/reference.rst index 32283734..79fa7333 100644 --- a/docs/reference.rst +++ b/docs/reference.rst @@ -28,6 +28,8 @@ NANOPB_INTERNALS Set this to expose the field encoder functions that are hidden since nanopb-0.1.3. Starting with nanopb-0.2.4, this flag does nothing. Use the newer functions that have better interface. +PB_ENABLE_MALLOC Set this to enable dynamic allocation support + in the decoder. PB_MAX_REQUIRED_FIELDS Maximum number of required fields to check for presence. Default value is 64. Increases stack usage 1 byte per every 8 fields. Compiler @@ -77,8 +79,9 @@ max_count Allocated number of entries in arrays (*repeated* fields). type Type of the generated field. Default value is *FT_DEFAULT*, which selects automatically. - You can use *FT_CALLBACK*, *FT_STATIC* or - *FT_IGNORE* to force a callback field, a static + You can use *FT_CALLBACK*, *FT_POINTER*, + *FT_STATIC* or *FT_IGNORE* to force a callback + field, a dynamically allocated field, a static field or to completely ignore the field. long_names Prefix the enum name to the enum value in definitions, i.e. *EnumName_EnumValue*. Enabled @@ -417,6 +420,17 @@ Encodes the contents of a structure as a protocol buffers message and writes it 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. +pb_encode_delimited +------------------- +Calculates the length of the message, encodes it as varint and then encodes the message. :: + + bool pb_encode_delimited(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); + +(parameters are the same as for `pb_encode`_.) + +A common way to indicate the message length in Protocol Buffers is to prefix it with a varint. +This function does this, and it is compatible with *parseDelimitedFrom* in Google's protobuf library. + .. sidebar:: Encoding fields manually The functions with names *pb_encode_\** are used when dealing with callback fields. The typical reason for using callbacks is to have an array of unlimited size. In that case, `pb_encode`_ will call your callback function, which in turn will call *pb_encode_\** functions repeatedly to write out values. @@ -579,6 +593,10 @@ In addition to EOF, the pb_decode implementation supports terminating a message For optional fields, this function applies the default value and sets *has_<field>* to false if the field is not present. +If *PB_ENABLE_MALLOC* is defined, this function may allocate storage for any pointer type fields. +In this case, you have to call `pb_release`_ to release the memory after you are done with the message. +On error return `pb_decode` will release the memory itself. + pb_decode_noinit ---------------- Same as `pb_decode`_, except does not apply the default values to fields. :: @@ -589,6 +607,35 @@ Same as `pb_decode`_, except does not apply the default values to fields. :: The destination structure should be filled with zeros before calling this function. Doing a *memset* manually can be slightly faster than using `pb_decode`_ if you don't need any default values. +In addition to decoding a single message, this function can be used to merge two messages, so that +values from previous message will remain if the new message does not contain a field. + +This function *will not* release the message even on error return. If you use *PB_ENABLE_MALLOC*, +you will need to call `pb_release`_ yourself. + +pb_decode_delimited +------------------- +Same as `pb_decode`_, except that it first reads a varint with the length of the message. :: + + bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); + +(parameters are the same as for `pb_decode`_.) + +A common method to indicate message size in Protocol Buffers is to prefix it with a varint. +This function is compatible with *writeDelimitedTo* in the Google's Protocol Buffers library. + +pb_release +---------- +Releases any dynamically allocated fields. + + void pb_release(const pb_field_t fields[], void *dest_struct); + +:fields: A field description array. Usually autogenerated. +:dest_struct: Pointer to structure where data will be stored. + +This function is only available if *PB_ENABLE_MALLOC* is defined. It will release any +pointer type fields in the structure and set the pointers to NULL. + pb_skip_varint -------------- Skip a varint_ encoded integer without decoding it. :: diff --git a/pb_decode.c b/pb_decode.c index 81febb9b..7938d70b 100644 --- a/pb_decode.c +++ b/pb_decode.c @@ -894,8 +894,16 @@ bool checkreturn pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[ bool checkreturn pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) { + bool status; pb_message_set_to_defaults(fields, dest_struct); - return pb_decode_noinit(stream, fields, dest_struct); + status = pb_decode_noinit(stream, fields, dest_struct); + +#ifdef PB_ENABLE_MALLOC + if (!status) + pb_release(fields, dest_struct); +#endif + + return status; } bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) diff --git a/pb_decode.h b/pb_decode.h index 2e1da5a6..8dc67408 100644 --- a/pb_decode.h +++ b/pb_decode.h @@ -73,6 +73,9 @@ bool pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struc * * This can also be used for 'merging' two messages, i.e. update only the * fields that exist in the new message. + * + * Note: If this function returns with an error, it will not release any + * dynamically allocated fields. You will need to call pb_release() yourself. */ bool pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); @@ -84,8 +87,8 @@ bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void * #ifdef PB_ENABLE_MALLOC /* Release any allocated pointer fields. If you use dynamic allocation, you should - * call this for any decoded message when you are done with it. You also need to - * free messages even if pb_decode() returned with error. + * call this for any successfully decoded message when you are done with it. If + * pb_decode() returns with an error, the message is already released. */ void pb_release(const pb_field_t fields[], void *dest_struct); #endif diff --git a/tests/alltypes_pointer/decode_alltypes_pointer.c b/tests/alltypes_pointer/decode_alltypes_pointer.c index d0cdcde0..889676b4 100644 --- a/tests/alltypes_pointer/decode_alltypes_pointer.c +++ b/tests/alltypes_pointer/decode_alltypes_pointer.c @@ -21,10 +21,7 @@ bool check_alltypes(pb_istream_t *stream, int mode) memset(&alltypes, 0xAA, sizeof(alltypes)); if (!pb_decode(stream, AllTypes_fields, &alltypes)) - { - pb_release(AllTypes_fields, &alltypes); return false; - } TEST(alltypes.req_int32 && *alltypes.req_int32 == -1001); TEST(alltypes.req_int64 && *alltypes.req_int64 == -1002); |