Add an encoder optimized for in-memory buffers.
git-svn-id: https://svn.kapsi.fi/jpa/nanopb-dev@1088 e3a754e5-d11d-0410-8d38-ebb782a927b9
This commit is contained in:
committed by
Petteri Aimonen
parent
3979f9137f
commit
accd93be8d
@@ -183,16 +183,20 @@ Encoding callbacks
|
||||
::
|
||||
|
||||
bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, const void *arg);
|
||||
bool (*encode_buffer)(pb_strstream_t *stream, const pb_field_t *field, const void *arg);
|
||||
|
||||
When encoding, the callback should write out complete fields, including the wire type and field number tag. It can write as many or as few fields as it likes. For example, if you want to write out an array as *repeated* field, you should do it all in a single call.
|
||||
When encoding, the callbacks should write out complete fields, including the wire type and field number tag. The callback can write as many or as few fields as it likes. For example, if you want to write out an array as *repeated* field, you should do it all in a single call.
|
||||
|
||||
Usually you can use `pb_encode_tag_for_field`_ to encode the wire type and tag number of the field. However, if you want to encode a repeated field as a packed array, you must call `pb_encode_tag`_ instead to specify a wire type of *PB_WT_STRING*.
|
||||
Usually you can use `pb_encode_tag_for_field`_ (or `pb_encbuf_tag_for_field`_ for the *encode_buffer* callback) to encode the wire type and tag number of the field. However, if you want to encode a repeated field as a packed array, you must call `pb_encode_tag`_ (respectively, `pb_encbuf_tag`_) instead to specify a wire type of *PB_WT_STRING*.
|
||||
|
||||
If the callback is used in a submessage, it will be called multiple times during a single call to `pb_encode`_. In this case, it must produce the same amount of data every time. If the callback is directly in the main message, it is called only once.
|
||||
If the callback is used in a submessage, *encode* will be called multiple times during a single call to `pb_encode`_. In this case, it must produce the same amount of data every time. If the callback is directly in the main message, or if you are using `pb_encode_buffer`_, the callback is called only once.
|
||||
|
||||
.. _`pb_encode`: reference.html#pb-encode
|
||||
.. _`pb_encode_buffer`: reference.html#pb-encode-buffer
|
||||
.. _`pb_encode_tag_for_field`: reference.html#pb-encode-tag-for-field
|
||||
.. _`pb_encbuf_tag_for_field`: reference.html#pb-encbuf-tag-for-field
|
||||
.. _`pb_encode_tag`: reference.html#pb-encode-tag
|
||||
.. _`pb_encbuf_tag`: reference.html#pb-encbuf-tag
|
||||
|
||||
This callback writes out a dynamically sized string::
|
||||
|
||||
@@ -205,6 +209,17 @@ This callback writes out a dynamically sized string::
|
||||
return pb_encode_string(stream, (uint8_t*)str, strlen(str));
|
||||
}
|
||||
|
||||
The equivalent for in-memory buffers has to write the elements in the opposite order, because the buffer writers prepend their data::
|
||||
|
||||
bool write_string_buf(pb_strstream_t *stream, const pb_field_t *field, const void *arg)
|
||||
{
|
||||
char *str = get_string_from_somewhere();
|
||||
if (!pb_encbuf_string(stream, (uint8_t*)str, strlen(str)))
|
||||
return false;
|
||||
|
||||
return pb_encbuf_tag_for_field(stream, field));
|
||||
}
|
||||
|
||||
Decoding callbacks
|
||||
------------------
|
||||
::
|
||||
@@ -234,7 +249,7 @@ This callback reads multiple integers and prints them::
|
||||
Message descriptor
|
||||
==================
|
||||
|
||||
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 using the *pb_encode*, *pb_encode_buffer* 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::
|
||||
|
||||
@@ -285,9 +300,9 @@ that array; in the previous example, they are
|
||||
*Person_PhoneNumber_has*, *Person_PhoneNumber_set* and
|
||||
*Person_PhoneNumber_clear*.
|
||||
|
||||
For convenience, *pb_encode* only checks these bits for optional
|
||||
fields. *pb_decode* sets the corresponding bit for every field it
|
||||
decodes, whether the field is optional or not.
|
||||
For convenience, *pb_encode* and *pb_encode_buffer* only check these
|
||||
bits for optional fields. *pb_decode* sets the corresponding bit for
|
||||
every field it decodes, whether the field is optional or not.
|
||||
|
||||
.. Should there be a section here on pointer fields?
|
||||
|
||||
|
||||
Reference in New Issue
Block a user