Document field extensions support
Update issue 17 Status: FixedInGit
This commit is contained in:
@@ -256,6 +256,50 @@ generates this field description array for the structure *Person_PhoneNumber*::
|
||||
};
|
||||
|
||||
|
||||
Extension fields
|
||||
================
|
||||
Protocol Buffers supports a concept of `extension fields`_, which are
|
||||
additional fields to a message, but defined outside the actual message.
|
||||
The definition can even be in a completely separate .proto file.
|
||||
|
||||
The base message is declared as extensible by keyword *extensions* in
|
||||
the .proto file::
|
||||
|
||||
message MyMessage {
|
||||
.. fields ..
|
||||
extensions 100 to 199;
|
||||
}
|
||||
|
||||
For each extensible message, *nanopb_generator.py* declares an additional
|
||||
callback field called *extensions*. The field and associated datatype
|
||||
*pb_extension_t* forms a linked list of handlers. When an unknown field is
|
||||
encountered, the decoder calls each handler in turn until either one of them
|
||||
handles the field, or the list is exhausted.
|
||||
|
||||
The actual extensions are declared using the *extend* keyword in the .proto,
|
||||
and are in the global namespace::
|
||||
|
||||
extend MyMessage {
|
||||
optional int32 myextension = 100;
|
||||
}
|
||||
|
||||
For each extension, *nanopb_generator.py* creates a constant of type
|
||||
*pb_extension_type_t*. To link together the base message and the extension,
|
||||
you have to:
|
||||
|
||||
1. Allocate storage for your field, matching the datatype in the .proto.
|
||||
For example, for a *int32* field, you need a *int32_t* variable to store
|
||||
the value.
|
||||
2. Create a *pb_extension_t* constant, with pointers to your variable and
|
||||
to the generated *pb_extension_type_t*.
|
||||
3. Set the *message.extensions* pointer to point to the *pb_extension_t*.
|
||||
|
||||
An example of this is available in *tests/test_encode_extensions.c* and
|
||||
*tests/test_decode_extensions.c*.
|
||||
|
||||
.. _`extension fields`: https://developers.google.com/protocol-buffers/docs/proto#extensions
|
||||
|
||||
|
||||
Return values and error handling
|
||||
================================
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ Features and limitations
|
||||
#) Allows specifying maximum size for strings and arrays, so that they can be allocated statically.
|
||||
#) No malloc needed: everything can be allocated statically or on the stack.
|
||||
#) You can use either encoder or decoder alone to cut the code size in half.
|
||||
#) Support for most protobuf features, including: all data types, nested submessages, default values, repeated and optional fields, packed arrays.
|
||||
#) Support for most protobuf features, including: all data types, nested submessages, default values, repeated and optional fields, packed arrays, extension fields.
|
||||
#) Callback mechanism for handling messages larger than can fit in available RAM.
|
||||
#) Extensive set of tests.
|
||||
|
||||
|
||||
@@ -304,6 +304,41 @@ Protocol Buffers wire types. These are used with `pb_encode_tag`_. ::
|
||||
PB_WT_32BIT = 5
|
||||
} pb_wire_type_t;
|
||||
|
||||
pb_extension_type_t
|
||||
-------------------
|
||||
Defines the handler functions and auxiliary data for a field that extends
|
||||
another message. Usually autogenerated by *nanopb_generator.py*::
|
||||
|
||||
typedef struct {
|
||||
bool (*decode)(pb_istream_t *stream, pb_extension_t *extension,
|
||||
uint32_t tag, pb_wire_type_t wire_type);
|
||||
bool (*encode)(pb_ostream_t *stream, const pb_extension_t *extension);
|
||||
const void *arg;
|
||||
} pb_extension_type_t;
|
||||
|
||||
In the normal case, the function pointers are *NULL* and the decoder and
|
||||
encoder use their internal implementations. The internal implementations
|
||||
assume that *arg* points to a *pb_field_t* that describes the field in question.
|
||||
|
||||
To implement custom processing of unknown fields, you can provide pointers
|
||||
to your own functions. Their functionality is mostly the same as for normal
|
||||
callback fields, except that they get called for any unknown field when decoding.
|
||||
|
||||
pb_extension_t
|
||||
--------------
|
||||
Ties together the extension field type and the storage for the field value::
|
||||
|
||||
typedef struct {
|
||||
const pb_extension_type_t *type;
|
||||
void *dest;
|
||||
pb_extension_t *next;
|
||||
} pb_extension_t;
|
||||
|
||||
:type: Pointer to the structure that defines the callback functions.
|
||||
:dest: Pointer to the variable that stores the field value
|
||||
(as used by the default extension callback functions.)
|
||||
:next: Pointer to the next extension handler, or *NULL*.
|
||||
|
||||
PB_GET_ERROR
|
||||
------------
|
||||
Get the current error message from a stream, or a placeholder string if
|
||||
|
||||
Reference in New Issue
Block a user