LCOV - code coverage report
Current view: top level - flamenco/nanopb - pb_decode.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 3 4 75.0 %
Date: 2025-01-08 12:08:44 Functions: 0 0 -

          Line data    Source code
       1             : /* pb_decode.h: Functions to decode protocol buffers. Depends on pb_decode.c.
       2             :  * The main function is pb_decode. You also need an input stream, and the
       3             :  * field descriptions created by nanopb_generator.py.
       4             :  */
       5             : 
       6             : #ifndef PB_DECODE_H_INCLUDED
       7             : #define PB_DECODE_H_INCLUDED
       8             : 
       9             : #include "pb_firedancer.h"
      10             : 
      11             : #ifdef __cplusplus
      12             : extern "C" {
      13             : #endif
      14             : 
      15             : /* Structure for defining custom input streams. You will need to provide
      16             :  * a callback function to read the bytes from 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 decoding to abort.
      22             :  * 2) You can use state to store your own data (e.g. buffer pointer),
      23             :  *    and rely on pb_read to verify that no-body reads past bytes_left.
      24             :  * 3) Your callback may be used with substreams, in which case bytes_left
      25             :  *    is different than from the main stream. Don't use bytes_left to compute
      26             :  *    any pointers.
      27             :  */
      28             : struct pb_istream_s
      29             : {
      30             : #ifdef PB_BUFFER_ONLY
      31             :     /* Callback pointer is not used in buffer-only configuration.
      32             :      * Having an int pointer here allows binary compatibility but
      33             :      * gives an error if someone tries to assign callback function.
      34             :      */
      35             :     int *callback;
      36             : #else
      37             :     bool (*callback)(pb_istream_t *stream, pb_byte_t *buf, size_t count);
      38             : #endif
      39             : 
      40             :     /* state is a free field for use of the callback function defined above.
      41             :      * Note that when pb_istream_from_buffer() is used, it reserves this field
      42             :      * for its own use.
      43             :      */
      44             :     void *state;
      45             : 
      46             :     /* Maximum number of bytes left in this stream. Callback can report
      47             :      * EOF before this limit is reached. Setting a limit is recommended
      48             :      * when decoding directly from file or network streams to avoid
      49             :      * denial-of-service by excessively long messages.
      50             :      */
      51             :     size_t bytes_left;
      52             :     
      53             : #ifndef PB_NO_ERRMSG
      54             :     /* Pointer to constant (ROM) string when decoding function returns error */
      55             :     const char *errmsg;
      56             : #endif
      57             : };
      58             : 
      59             : #ifndef PB_NO_ERRMSG
      60     2842107 : #define PB_ISTREAM_EMPTY {0,0,0,0}
      61             : #else
      62             : #define PB_ISTREAM_EMPTY {0,0,0}
      63             : #endif
      64             : 
      65             : /***************************
      66             :  * Main decoding functions *
      67             :  ***************************/
      68             :  
      69             : /* Decode a single protocol buffers message from input stream into a C structure.
      70             :  * Returns true on success, false on any failure.
      71             :  * The actual struct pointed to by dest must match the description in fields.
      72             :  * Callback fields of the destination structure must be initialized by caller.
      73             :  * All other fields will be initialized by this function.
      74             :  *
      75             :  * Example usage:
      76             :  *    MyMessage msg = {};
      77             :  *    uint8_t buffer[64];
      78             :  *    pb_istream_t stream;
      79             :  *    
      80             :  *    // ... read some data into buffer ...
      81             :  *
      82             :  *    stream = pb_istream_from_buffer(buffer, count);
      83             :  *    pb_decode(&stream, MyMessage_fields, &msg);
      84             :  */
      85             : bool pb_decode(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct);
      86             : 
      87             : /* Extended version of pb_decode, with several options to control
      88             :  * the decoding process:
      89             :  *
      90             :  * PB_DECODE_NOINIT:         Do not initialize the fields to default values.
      91             :  *                           This is slightly faster if you do not need the default
      92             :  *                           values and instead initialize the structure to 0 using
      93             :  *                           e.g. memset(). This can also be used for merging two
      94             :  *                           messages, i.e. combine already existing data with new
      95             :  *                           values.
      96             :  *
      97             :  * PB_DECODE_DELIMITED:      Input message starts with the message size as varint.
      98             :  *                           Corresponds to parseDelimitedFrom() in Google's
      99             :  *                           protobuf API.
     100             :  *
     101             :  * PB_DECODE_NULLTERMINATED: Stop reading when field tag is read as 0. This allows
     102             :  *                           reading null terminated messages.
     103             :  *                           NOTE: Until nanopb-0.4.0, pb_decode() also allows
     104             :  *                           null-termination. This behaviour is not supported in
     105             :  *                           most other protobuf implementations, so PB_DECODE_DELIMITED
     106             :  *                           is a better option for compatibility.
     107             :  *
     108             :  * Multiple flags can be combined with bitwise or (| operator)
     109             :  */
     110     7665576 : #define PB_DECODE_NOINIT          0x01U
     111      408450 : #define PB_DECODE_DELIMITED       0x02U
     112           0 : #define PB_DECODE_NULLTERMINATED  0x04U
     113             : bool pb_decode_ex(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct, unsigned int flags);
     114             : 
     115             : /* Defines for backwards compatibility with code written before nanopb-0.4.0 */
     116             : #define pb_decode_noinit(s,f,d) pb_decode_ex(s,f,d, PB_DECODE_NOINIT)
     117             : #define pb_decode_delimited(s,f,d) pb_decode_ex(s,f,d, PB_DECODE_DELIMITED)
     118             : #define pb_decode_delimited_noinit(s,f,d) pb_decode_ex(s,f,d, PB_DECODE_DELIMITED | PB_DECODE_NOINIT)
     119             : #define pb_decode_nullterminated(s,f,d) pb_decode_ex(s,f,d, PB_DECODE_NULLTERMINATED)
     120             : 
     121             : /* Release any allocated pointer fields. If you use dynamic allocation, you should
     122             :  * call this for any successfully decoded message when you are done with it. If
     123             :  * pb_decode() returns with an error, the message is already released.
     124             :  */
     125             : void pb_release(const pb_msgdesc_t *fields, void *dest_struct);
     126             : 
     127             : /**************************************
     128             :  * Functions for manipulating streams *
     129             :  **************************************/
     130             : 
     131             : /* Create an input stream for reading from a memory buffer.
     132             :  *
     133             :  * msglen should be the actual length of the message, not the full size of
     134             :  * allocated buffer.
     135             :  *
     136             :  * Alternatively, you can use a custom stream that reads directly from e.g.
     137             :  * a file or a network socket.
     138             :  */
     139             : pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t msglen);
     140             : 
     141             : /* Function to read from a pb_istream_t. You can use this if you need to
     142             :  * read some custom header data, or to read data in field callbacks.
     143             :  */
     144             : bool pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count);
     145             : 
     146             : 
     147             : /************************************************
     148             :  * Helper functions for writing field callbacks *
     149             :  ************************************************/
     150             : 
     151             : /* Decode the tag for the next field in the stream. Gives the wire type and
     152             :  * field tag. At end of the message, returns false and sets eof to true. */
     153             : bool pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof);
     154             : 
     155             : /* Skip the field payload data, given the wire type. */
     156             : bool pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type);
     157             : 
     158             : /* Decode an integer in the varint format. This works for enum, int32,
     159             :  * int64, uint32 and uint64 field types. */
     160             : #ifndef PB_WITHOUT_64BIT
     161             : bool pb_decode_varint(pb_istream_t *stream, uint64_t *dest);
     162             : #else
     163             : #define pb_decode_varint pb_decode_varint32
     164             : #endif
     165             : 
     166             : /* Decode an integer in the varint format. This works for enum, int32,
     167             :  * and uint32 field types. */
     168             : bool pb_decode_varint32(pb_istream_t *stream, uint32_t *dest);
     169             : 
     170             : /* Decode a bool value in varint format. */
     171             : bool pb_decode_bool(pb_istream_t *stream, bool *dest);
     172             : 
     173             : /* Decode an integer in the zig-zagged svarint format. This works for sint32
     174             :  * and sint64. */
     175             : #ifndef PB_WITHOUT_64BIT
     176             : bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest);
     177             : #else
     178             : bool pb_decode_svarint(pb_istream_t *stream, int32_t *dest);
     179             : #endif
     180             : 
     181             : /* Decode a fixed32, sfixed32 or float value. You need to pass a pointer to
     182             :  * a 4-byte wide C variable. */
     183             : bool pb_decode_fixed32(pb_istream_t *stream, void *dest);
     184             : 
     185             : #ifndef PB_WITHOUT_64BIT
     186             : /* Decode a fixed64, sfixed64 or double value. You need to pass a pointer to
     187             :  * a 8-byte wide C variable. */
     188             : bool pb_decode_fixed64(pb_istream_t *stream, void *dest);
     189             : #endif
     190             : 
     191             : #ifdef PB_CONVERT_DOUBLE_FLOAT
     192             : /* Decode a double value into float variable. */
     193             : bool pb_decode_double_as_float(pb_istream_t *stream, float *dest);
     194             : #endif
     195             : 
     196             : /* Make a limited-length substream for reading a PB_WT_STRING field. */
     197             : bool pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream);
     198             : bool pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream);
     199             : 
     200             : #ifdef __cplusplus
     201             : } /* extern "C" */
     202             : #endif
     203             : 
     204             : #endif

Generated by: LCOV version 1.14