Home | History | Annotate | Download | only in nanopb-c
      1 /* pb_encode.h: Functions to encode protocol buffers. Depends on pb_encode.c.
      2  * The main function is pb_encode. You also need an output stream, and the
      3  * field descriptions created by nanopb_generator.py.
      4  */
      5 
      6 #ifndef _PB_ENCODE_H_
      7 #define _PB_ENCODE_H_
      8 
      9 #include "pb.h"
     10 
     11 #ifdef __cplusplus
     12 extern "C" {
     13 #endif
     14 
     15 /* Structure for defining custom output streams. You will need to provide
     16  * a callback function to write the bytes to your storage, which can be
     17  * for example a file or a network socket.
     18  *
     19  * The callback must conform to these rules:
     20  *
     21  * 1) Return false on IO errors. This will cause encoding to abort.
     22  * 2) You can use state to store your own data (e.g. buffer pointer).
     23  * 3) pb_write will update bytes_written after your callback runs.
     24  * 4) Substreams will modify max_size and bytes_written. Don't use them
     25  *    to calculate any pointers.
     26  */
     27 struct _pb_ostream_t
     28 {
     29 #ifdef PB_BUFFER_ONLY
     30     /* Callback pointer is not used in buffer-only configuration.
     31      * Having an int pointer here allows binary compatibility but
     32      * gives an error if someone tries to assign callback function.
     33      * Also, NULL pointer marks a 'sizing stream' that does not
     34      * write anything.
     35      */
     36     int *callback;
     37 #else
     38     bool (*callback)(pb_ostream_t *stream, const uint8_t *buf, size_t count);
     39 #endif
     40     void *state;          /* Free field for use by callback implementation. */
     41     size_t max_size;      /* Limit number of output bytes written (or use SIZE_MAX). */
     42     size_t bytes_written; /* Number of bytes written so far. */
     43 
     44 #ifndef PB_NO_ERRMSG
     45     const char *errmsg;
     46 #endif
     47 };
     48 
     49 /***************************
     50  * Main encoding functions *
     51  ***************************/
     52 
     53 /* Encode a single protocol buffers message from C structure into a stream.
     54  * Returns true on success, false on any failure.
     55  * The actual struct pointed to by src_struct must match the description in fields.
     56  * All required fields in the struct are assumed to have been filled in.
     57  *
     58  * Example usage:
     59  *    MyMessage msg = {};
     60  *    uint8_t buffer[64];
     61  *    pb_ostream_t stream;
     62  *
     63  *    msg.field1 = 42;
     64  *    stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
     65  *    pb_encode(&stream, MyMessage_fields, &msg);
     66  */
     67 bool pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct);
     68 
     69 /* Same as pb_encode, but prepends the length of the message as a varint.
     70  * Corresponds to writeDelimitedTo() in Google's protobuf API.
     71  */
     72 bool pb_encode_delimited(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct);
     73 
     74 /* Encode the message to get the size of the encoded data, but do not store
     75  * the data. */
     76 bool pb_get_encoded_size(size_t *size, const pb_field_t fields[], const void *src_struct);
     77 
     78 /**************************************
     79  * Functions for manipulating streams *
     80  **************************************/
     81 
     82 /* Create an output stream for writing into a memory buffer.
     83  * The number of bytes written can be found in stream.bytes_written after
     84  * encoding the message.
     85  *
     86  * Alternatively, you can use a custom stream that writes directly to e.g.
     87  * a file or a network socket.
     88  */
     89 pb_ostream_t pb_ostream_from_buffer(uint8_t *buf, size_t bufsize);
     90 
     91 /* Pseudo-stream for measuring the size of a message without actually storing
     92  * the encoded data.
     93  *
     94  * Example usage:
     95  *    MyMessage msg = {};
     96  *    pb_ostream_t stream = PB_OSTREAM_SIZING;
     97  *    pb_encode(&stream, MyMessage_fields, &msg);
     98  *    printf("Message size is %d\n", stream.bytes_written);
     99  */
    100 #ifndef PB_NO_ERRMSG
    101 #define PB_OSTREAM_SIZING {0,0,0,0,0}
    102 #else
    103 #define PB_OSTREAM_SIZING {0,0,0,0}
    104 #endif
    105 
    106 /* Function to write into a pb_ostream_t stream. You can use this if you need
    107  * to append or prepend some custom headers to the message.
    108  */
    109 bool pb_write(pb_ostream_t *stream, const uint8_t *buf, size_t count);
    110 
    111 
    112 /************************************************
    113  * Helper functions for writing field callbacks *
    114  ************************************************/
    115 
    116 /* Encode field header based on type and field number defined in the field
    117  * structure. Call this from the callback before writing out field contents. */
    118 bool pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t *field);
    119 
    120 /* Encode field header by manually specifing wire type. You need to use this
    121  * if you want to write out packed arrays from a callback field. */
    122 bool pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number);
    123 
    124 /* Encode an integer in the varint format.
    125  * This works for bool, enum, int32, int64, uint32 and uint64 field types. */
    126 bool pb_encode_varint(pb_ostream_t *stream, uint64_t value);
    127 
    128 /* Encode an integer in the zig-zagged svarint format.
    129  * This works for sint32 and sint64. */
    130 bool pb_encode_svarint(pb_ostream_t *stream, int64_t value);
    131 
    132 /* Encode a string or bytes type field. For strings, pass strlen(s) as size. */
    133 bool pb_encode_string(pb_ostream_t *stream, const uint8_t *buffer, size_t size);
    134 
    135 /* Encode a fixed32, sfixed32 or float value.
    136  * You need to pass a pointer to a 4-byte wide C variable. */
    137 bool pb_encode_fixed32(pb_ostream_t *stream, const void *value);
    138 
    139 /* Encode a fixed64, sfixed64 or double value.
    140  * You need to pass a pointer to a 8-byte wide C variable. */
    141 bool pb_encode_fixed64(pb_ostream_t *stream, const void *value);
    142 
    143 /* Encode a submessage field.
    144  * You need to pass the pb_field_t array and pointer to struct, just like
    145  * with pb_encode(). This internally encodes the submessage twice, first to
    146  * calculate message size and then to actually write it out.
    147  */
    148 bool pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct);
    149 
    150 #ifdef __cplusplus
    151 } /* extern "C" */
    152 #endif
    153 
    154 #endif
    155