1*c8d645caSAndroid Build Coastguard Worker /* pb_decode.h: Functions to decode protocol buffers. Depends on pb_decode.c. 2*c8d645caSAndroid Build Coastguard Worker * The main function is pb_decode. You also need an input stream, and the 3*c8d645caSAndroid Build Coastguard Worker * field descriptions created by nanopb_generator.py. 4*c8d645caSAndroid Build Coastguard Worker */ 5*c8d645caSAndroid Build Coastguard Worker 6*c8d645caSAndroid Build Coastguard Worker #ifndef PB_DECODE_H_INCLUDED 7*c8d645caSAndroid Build Coastguard Worker #define PB_DECODE_H_INCLUDED 8*c8d645caSAndroid Build Coastguard Worker 9*c8d645caSAndroid Build Coastguard Worker #include "pb.h" 10*c8d645caSAndroid Build Coastguard Worker 11*c8d645caSAndroid Build Coastguard Worker #ifdef __cplusplus 12*c8d645caSAndroid Build Coastguard Worker extern "C" { 13*c8d645caSAndroid Build Coastguard Worker #endif 14*c8d645caSAndroid Build Coastguard Worker 15*c8d645caSAndroid Build Coastguard Worker /* Structure for defining custom input streams. You will need to provide 16*c8d645caSAndroid Build Coastguard Worker * a callback function to read the bytes from your storage, which can be 17*c8d645caSAndroid Build Coastguard Worker * for example a file or a network socket. 18*c8d645caSAndroid Build Coastguard Worker * 19*c8d645caSAndroid Build Coastguard Worker * The callback must conform to these rules: 20*c8d645caSAndroid Build Coastguard Worker * 21*c8d645caSAndroid Build Coastguard Worker * 1) Return false on IO errors. This will cause decoding to abort. 22*c8d645caSAndroid Build Coastguard Worker * 2) You can use state to store your own data (e.g. buffer pointer), 23*c8d645caSAndroid Build Coastguard Worker * and rely on pb_read to verify that no-body reads past bytes_left. 24*c8d645caSAndroid Build Coastguard Worker * 3) Your callback may be used with substreams, in which case bytes_left 25*c8d645caSAndroid Build Coastguard Worker * is different than from the main stream. Don't use bytes_left to compute 26*c8d645caSAndroid Build Coastguard Worker * any pointers. 27*c8d645caSAndroid Build Coastguard Worker */ 28*c8d645caSAndroid Build Coastguard Worker struct pb_istream_s 29*c8d645caSAndroid Build Coastguard Worker { 30*c8d645caSAndroid Build Coastguard Worker #ifdef PB_BUFFER_ONLY 31*c8d645caSAndroid Build Coastguard Worker /* Callback pointer is not used in buffer-only configuration. 32*c8d645caSAndroid Build Coastguard Worker * Having an int pointer here allows binary compatibility but 33*c8d645caSAndroid Build Coastguard Worker * gives an error if someone tries to assign callback function. 34*c8d645caSAndroid Build Coastguard Worker */ 35*c8d645caSAndroid Build Coastguard Worker int *callback; 36*c8d645caSAndroid Build Coastguard Worker #else 37*c8d645caSAndroid Build Coastguard Worker bool (*callback)(pb_istream_t *stream, pb_byte_t *buf, size_t count); 38*c8d645caSAndroid Build Coastguard Worker #endif 39*c8d645caSAndroid Build Coastguard Worker 40*c8d645caSAndroid Build Coastguard Worker void *state; /* Free field for use by callback implementation */ 41*c8d645caSAndroid Build Coastguard Worker size_t bytes_left; 42*c8d645caSAndroid Build Coastguard Worker 43*c8d645caSAndroid Build Coastguard Worker #ifndef PB_NO_ERRMSG 44*c8d645caSAndroid Build Coastguard Worker const char *errmsg; 45*c8d645caSAndroid Build Coastguard Worker #endif 46*c8d645caSAndroid Build Coastguard Worker }; 47*c8d645caSAndroid Build Coastguard Worker 48*c8d645caSAndroid Build Coastguard Worker /*************************** 49*c8d645caSAndroid Build Coastguard Worker * Main decoding functions * 50*c8d645caSAndroid Build Coastguard Worker ***************************/ 51*c8d645caSAndroid Build Coastguard Worker 52*c8d645caSAndroid Build Coastguard Worker /* Decode a single protocol buffers message from input stream into a C structure. 53*c8d645caSAndroid Build Coastguard Worker * Returns true on success, false on any failure. 54*c8d645caSAndroid Build Coastguard Worker * The actual struct pointed to by dest must match the description in fields. 55*c8d645caSAndroid Build Coastguard Worker * Callback fields of the destination structure must be initialized by caller. 56*c8d645caSAndroid Build Coastguard Worker * All other fields will be initialized by this function. 57*c8d645caSAndroid Build Coastguard Worker * 58*c8d645caSAndroid Build Coastguard Worker * Example usage: 59*c8d645caSAndroid Build Coastguard Worker * MyMessage msg = {}; 60*c8d645caSAndroid Build Coastguard Worker * uint8_t buffer[64]; 61*c8d645caSAndroid Build Coastguard Worker * pb_istream_t stream; 62*c8d645caSAndroid Build Coastguard Worker * 63*c8d645caSAndroid Build Coastguard Worker * // ... read some data into buffer ... 64*c8d645caSAndroid Build Coastguard Worker * 65*c8d645caSAndroid Build Coastguard Worker * stream = pb_istream_from_buffer(buffer, count); 66*c8d645caSAndroid Build Coastguard Worker * pb_decode(&stream, MyMessage_fields, &msg); 67*c8d645caSAndroid Build Coastguard Worker */ 68*c8d645caSAndroid Build Coastguard Worker bool pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); 69*c8d645caSAndroid Build Coastguard Worker 70*c8d645caSAndroid Build Coastguard Worker /* Same as pb_decode, except does not initialize the destination structure 71*c8d645caSAndroid Build Coastguard Worker * to default values. This is slightly faster if you need no default values 72*c8d645caSAndroid Build Coastguard Worker * and just do memset(struct, 0, sizeof(struct)) yourself. 73*c8d645caSAndroid Build Coastguard Worker * 74*c8d645caSAndroid Build Coastguard Worker * This can also be used for 'merging' two messages, i.e. update only the 75*c8d645caSAndroid Build Coastguard Worker * fields that exist in the new message. 76*c8d645caSAndroid Build Coastguard Worker * 77*c8d645caSAndroid Build Coastguard Worker * Note: If this function returns with an error, it will not release any 78*c8d645caSAndroid Build Coastguard Worker * dynamically allocated fields. You will need to call pb_release() yourself. 79*c8d645caSAndroid Build Coastguard Worker */ 80*c8d645caSAndroid Build Coastguard Worker bool pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); 81*c8d645caSAndroid Build Coastguard Worker 82*c8d645caSAndroid Build Coastguard Worker /* Same as pb_decode, except expects the stream to start with the message size 83*c8d645caSAndroid Build Coastguard Worker * encoded as varint. Corresponds to parseDelimitedFrom() in Google's 84*c8d645caSAndroid Build Coastguard Worker * protobuf API. 85*c8d645caSAndroid Build Coastguard Worker */ 86*c8d645caSAndroid Build Coastguard Worker bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); 87*c8d645caSAndroid Build Coastguard Worker 88*c8d645caSAndroid Build Coastguard Worker /* Same as pb_decode_delimited, except that it does not initialize the destination structure. 89*c8d645caSAndroid Build Coastguard Worker * See pb_decode_noinit 90*c8d645caSAndroid Build Coastguard Worker */ 91*c8d645caSAndroid Build Coastguard Worker bool pb_decode_delimited_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); 92*c8d645caSAndroid Build Coastguard Worker 93*c8d645caSAndroid Build Coastguard Worker /* Same as pb_decode, except allows the message to be terminated with a null byte. 94*c8d645caSAndroid Build Coastguard Worker * NOTE: Until nanopb-0.4.0, pb_decode() also allows null-termination. This behaviour 95*c8d645caSAndroid Build Coastguard Worker * is not supported in most other protobuf implementations, so pb_decode_delimited() 96*c8d645caSAndroid Build Coastguard Worker * is a better option for compatibility. 97*c8d645caSAndroid Build Coastguard Worker */ 98*c8d645caSAndroid Build Coastguard Worker bool pb_decode_nullterminated(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); 99*c8d645caSAndroid Build Coastguard Worker 100*c8d645caSAndroid Build Coastguard Worker #ifdef PB_ENABLE_MALLOC 101*c8d645caSAndroid Build Coastguard Worker /* Release any allocated pointer fields. If you use dynamic allocation, you should 102*c8d645caSAndroid Build Coastguard Worker * call this for any successfully decoded message when you are done with it. If 103*c8d645caSAndroid Build Coastguard Worker * pb_decode() returns with an error, the message is already released. 104*c8d645caSAndroid Build Coastguard Worker */ 105*c8d645caSAndroid Build Coastguard Worker void pb_release(const pb_field_t fields[], void *dest_struct); 106*c8d645caSAndroid Build Coastguard Worker #endif 107*c8d645caSAndroid Build Coastguard Worker 108*c8d645caSAndroid Build Coastguard Worker 109*c8d645caSAndroid Build Coastguard Worker /************************************** 110*c8d645caSAndroid Build Coastguard Worker * Functions for manipulating streams * 111*c8d645caSAndroid Build Coastguard Worker **************************************/ 112*c8d645caSAndroid Build Coastguard Worker 113*c8d645caSAndroid Build Coastguard Worker /* Create an input stream for reading from a memory buffer. 114*c8d645caSAndroid Build Coastguard Worker * 115*c8d645caSAndroid Build Coastguard Worker * Alternatively, you can use a custom stream that reads directly from e.g. 116*c8d645caSAndroid Build Coastguard Worker * a file or a network socket. 117*c8d645caSAndroid Build Coastguard Worker */ 118*c8d645caSAndroid Build Coastguard Worker pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t bufsize); 119*c8d645caSAndroid Build Coastguard Worker 120*c8d645caSAndroid Build Coastguard Worker /* Function to read from a pb_istream_t. You can use this if you need to 121*c8d645caSAndroid Build Coastguard Worker * read some custom header data, or to read data in field callbacks. 122*c8d645caSAndroid Build Coastguard Worker */ 123*c8d645caSAndroid Build Coastguard Worker bool pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count); 124*c8d645caSAndroid Build Coastguard Worker 125*c8d645caSAndroid Build Coastguard Worker 126*c8d645caSAndroid Build Coastguard Worker /************************************************ 127*c8d645caSAndroid Build Coastguard Worker * Helper functions for writing field callbacks * 128*c8d645caSAndroid Build Coastguard Worker ************************************************/ 129*c8d645caSAndroid Build Coastguard Worker 130*c8d645caSAndroid Build Coastguard Worker /* Decode the tag for the next field in the stream. Gives the wire type and 131*c8d645caSAndroid Build Coastguard Worker * field tag. At end of the message, returns false and sets eof to true. */ 132*c8d645caSAndroid Build Coastguard Worker bool pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof); 133*c8d645caSAndroid Build Coastguard Worker 134*c8d645caSAndroid Build Coastguard Worker /* Skip the field payload data, given the wire type. */ 135*c8d645caSAndroid Build Coastguard Worker bool pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type); 136*c8d645caSAndroid Build Coastguard Worker 137*c8d645caSAndroid Build Coastguard Worker /* Decode an integer in the varint format. This works for enum, int32, 138*c8d645caSAndroid Build Coastguard Worker * int64, uint32 and uint64 field types. */ 139*c8d645caSAndroid Build Coastguard Worker #ifndef PB_WITHOUT_64BIT 140*c8d645caSAndroid Build Coastguard Worker bool pb_decode_varint(pb_istream_t *stream, uint64_t *dest); 141*c8d645caSAndroid Build Coastguard Worker #else 142*c8d645caSAndroid Build Coastguard Worker #define pb_decode_varint pb_decode_varint32 143*c8d645caSAndroid Build Coastguard Worker #endif 144*c8d645caSAndroid Build Coastguard Worker 145*c8d645caSAndroid Build Coastguard Worker /* Decode an integer in the varint format. This works for enum, int32, 146*c8d645caSAndroid Build Coastguard Worker * and uint32 field types. */ 147*c8d645caSAndroid Build Coastguard Worker bool pb_decode_varint32(pb_istream_t *stream, uint32_t *dest); 148*c8d645caSAndroid Build Coastguard Worker 149*c8d645caSAndroid Build Coastguard Worker /* Decode a bool value in varint format. */ 150*c8d645caSAndroid Build Coastguard Worker bool pb_decode_bool(pb_istream_t *stream, bool *dest); 151*c8d645caSAndroid Build Coastguard Worker 152*c8d645caSAndroid Build Coastguard Worker /* Decode an integer in the zig-zagged svarint format. This works for sint32 153*c8d645caSAndroid Build Coastguard Worker * and sint64. */ 154*c8d645caSAndroid Build Coastguard Worker #ifndef PB_WITHOUT_64BIT 155*c8d645caSAndroid Build Coastguard Worker bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest); 156*c8d645caSAndroid Build Coastguard Worker #else 157*c8d645caSAndroid Build Coastguard Worker bool pb_decode_svarint(pb_istream_t *stream, int32_t *dest); 158*c8d645caSAndroid Build Coastguard Worker #endif 159*c8d645caSAndroid Build Coastguard Worker 160*c8d645caSAndroid Build Coastguard Worker /* Decode a fixed32, sfixed32 or float value. You need to pass a pointer to 161*c8d645caSAndroid Build Coastguard Worker * a 4-byte wide C variable. */ 162*c8d645caSAndroid Build Coastguard Worker bool pb_decode_fixed32(pb_istream_t *stream, void *dest); 163*c8d645caSAndroid Build Coastguard Worker 164*c8d645caSAndroid Build Coastguard Worker #ifndef PB_WITHOUT_64BIT 165*c8d645caSAndroid Build Coastguard Worker /* Decode a fixed64, sfixed64 or double value. You need to pass a pointer to 166*c8d645caSAndroid Build Coastguard Worker * a 8-byte wide C variable. */ 167*c8d645caSAndroid Build Coastguard Worker bool pb_decode_fixed64(pb_istream_t *stream, void *dest); 168*c8d645caSAndroid Build Coastguard Worker #endif 169*c8d645caSAndroid Build Coastguard Worker 170*c8d645caSAndroid Build Coastguard Worker /* Make a limited-length substream for reading a PB_WT_STRING field. */ 171*c8d645caSAndroid Build Coastguard Worker bool pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream); 172*c8d645caSAndroid Build Coastguard Worker bool pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream); 173*c8d645caSAndroid Build Coastguard Worker 174*c8d645caSAndroid Build Coastguard Worker #ifdef __cplusplus 175*c8d645caSAndroid Build Coastguard Worker } /* extern "C" */ 176*c8d645caSAndroid Build Coastguard Worker #endif 177*c8d645caSAndroid Build Coastguard Worker 178*c8d645caSAndroid Build Coastguard Worker #endif 179