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:
Michael Poole
2011-12-21 04:36:10 +00:00
committed by Petteri Aimonen
parent 3979f9137f
commit accd93be8d
8 changed files with 676 additions and 48 deletions

View File

@@ -102,6 +102,7 @@ Part of a message structure, for fields with type PB_HTYPE_CALLBACK::
union {
bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void *arg);
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);
} funcs;
void *arg;
@@ -109,11 +110,11 @@ Part of a message structure, for fields with type PB_HTYPE_CALLBACK::
The *arg* is passed to the callback when calling. It can be used to store any information that the callback might need.
When calling `pb_encode`_, *funcs.encode* is used, and similarly when calling `pb_decode`_, *funcs.decode* is used. The function pointers are stored in the same memory location but are of incompatible types. You can set the function pointer to NULL to skip the field.
When calling `pb_encode`_, *funcs.encode* is used, and similarly when calling `pb_encode_buffer`_, *funcs.encode_buffer* is used, and when calling `pb_decode`_, *funcs.decode* is used. The function pointers are stored in the same memory location but are of incompatible types. You can set the function pointer to NULL to skip the field.
pb_wire_type_t
--------------
Protocol Buffers wire types. These are used with `pb_encode_tag`_. ::
Protocol Buffers wire types. These are used with `pb_encode_tag`_ and `pb_encbuf_tag`_. ::
typedef enum {
PB_WT_VARINT = 0,
@@ -311,6 +312,107 @@ In Protocol Buffers format, the submessage size must be written before the subme
If the submessage contains callback fields, the callback function might misbehave and write out a different amount of data on the second call. This situation is recognized and *false* is returned, but it is up to the caller to ensure that the receiver of the message does not interpret it as valid data.
pb_encode_buffer.h
==================
An important note about this module is that data is written from the
back of the buffer to the front. That is, when you call
*pb_buf_write()*, it will place the bytes (in the order you provide
them) before the data currently in the buffer.
pb_strstream_from_buffer
------------------------
Constructs a buffer descriptor. This is just a helper function, it doesn't do anything you couldn't do yourself in a callback function. ::
pb_strstream_t pb_strstream_from_buffer(uint8_t *buf, size_t bufsize);
:buf: Memory buffer to write into.
:bufsize: Maximum number of bytes to write.
:returns: The buffer descriptor.
The descriptor only tracks the amount of space left; it does not count how many bytes have been written.
pb_buf_write
------------
Prepends data to an in-memory buffer. Always use this function, instead of trying to manage the pointers inside the buffer descriptor. ::
bool pb_buf_write(pb_strstream_t *stream, const uint8_t *buf, size_t count);
:stream: Descriptor for buffer to write to.
:buf: Pointer to buffer with the data to be written.
:count: Number of bytes to write.
:returns: True on success, false if maximum length is exceeded.
If there is not enough space, *stream* is not modified.
pb_encode_buffer
----------------
Encodes the contents of a structure as a protocol buffers message and writes it to a buffer. ::
bool pb_encode_buffer(pb_strstream_t *stream, const pb_message_t *msg, const void *src_struct);
:stream: Descriptor for buffer to write to.
:msg: A message descriptor, usually autogenerated.
:src_struct: Pointer to the data that will be serialized.
:returns: True on success, false if the buffer is too small or if a field encoder returns false.
pb_encbuf_varint
----------------
Encodes an unsigned integer in the varint_ format. ::
bool pb_encbuf_varint(pb_strstream_t *stream, uint64_t value);
:stream: Descriptor for buffer to write to. 1-10 bytes will be written.
:value: Value to encode.
:returns: True on success, false on IO error.
.. _varint: http://code.google.com/apis/protocolbuffers/docs/encoding.html#varints
pb_encbuf_tag
-------------
Finishes a field in the Protocol Buffers binary format: encodes the field number and the wire type of the data. ::
bool pb_encbuf_tag(pb_strstream_t *stream, pb_wire_type_t wiretype, int field_number);
:stream: Descriptor for buffer to write to. 1-5 bytes will be written.
:wiretype: PB_WT_VARINT, PB_WT_64BIT, PB_WT_STRING or PB_WT_32BIT
:field_number: Identifier for the field, defined in the .proto file.
:returns: True on success, false on IO error.
pb_encbuf_tag_for_field
-----------------------
Same as `pb_encbuf_tag`_, except takes the parameters from a *pb_field_t* structure. ::
bool pb_encbuf_tag_for_field(pb_strstream_t *stream, const pb_field_t *field);
:stream: Descriptor for buffer to write to. 1-5 bytes will be written.
:field: Field description structure. Usually autogenerated.
:returns: True on success, false on IO error or unknown field type.
This function only considers the LTYPE of the field. You can use it from your field callbacks, because the source generator writes correct LTYPE also for callback type fields.
Wire type mapping is as follows:
========================= ============
LTYPEs Wire type
========================= ============
VARINT, SVARINT PB_WT_VARINT
FIXED64 PB_WT_64BIT
STRING, BYTES, SUBMESSAGE PB_WT_STRING
FIXED32 PB_WT_32BIT
========================= ============
pb_encbuf_string
----------------
Writes the length of a string as varint and then contents of the string. Used for writing fields with wire type PB_WT_STRING. ::
bool pb_encbuf_string(pb_strstream_t *stream, const uint8_t *buffer, size_t size);
:stream: Descriptor for buffer to write to.
:buffer: Pointer to string data.
:size: Number of bytes in the string.
:returns: True on success, false on IO error.
pb_decode.h
===========