All in one solution demonstrating how to use nanopb Protocol Buffers library from within mbed environment. Test case is very simple. It works.

Dependencies:   nanopb protocol

Original import was an all-in-one solution that only depends on mbed.

Current implementation extracted 2 librarires:

1) nanopb contains code required to use nanopb and Timestamp dependency. 2) protocol is a specific research protocol used by LCE at Itron at the moment of commit.

The application decodes Protocol Buffers message generated with GO application using the same 'protocol'. This test level application decodes message and validates that it matches expected.

It is simply a proof that nanopb library can be used.

Committer:
sgnezdov
Date:
Wed Jul 12 22:40:29 2017 +0000
Revision:
0:fbdd0d307c19
initial import demonstrates how to decode Sample protocol buffers message.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sgnezdov 0:fbdd0d307c19 1 /* Common parts of the nanopb library. Most of these are quite low-level
sgnezdov 0:fbdd0d307c19 2 * stuff. For the high-level interface, see pb_encode.h and pb_decode.h.
sgnezdov 0:fbdd0d307c19 3 */
sgnezdov 0:fbdd0d307c19 4
sgnezdov 0:fbdd0d307c19 5 #ifndef PB_H_INCLUDED
sgnezdov 0:fbdd0d307c19 6 #define PB_H_INCLUDED
sgnezdov 0:fbdd0d307c19 7
sgnezdov 0:fbdd0d307c19 8 /*****************************************************************
sgnezdov 0:fbdd0d307c19 9 * Nanopb compilation time options. You can change these here by *
sgnezdov 0:fbdd0d307c19 10 * uncommenting the lines, or on the compiler command line. *
sgnezdov 0:fbdd0d307c19 11 *****************************************************************/
sgnezdov 0:fbdd0d307c19 12
sgnezdov 0:fbdd0d307c19 13 /* Enable support for dynamically allocated fields */
sgnezdov 0:fbdd0d307c19 14 /* #define PB_ENABLE_MALLOC 1 */
sgnezdov 0:fbdd0d307c19 15
sgnezdov 0:fbdd0d307c19 16 /* Define this if your CPU / compiler combination does not support
sgnezdov 0:fbdd0d307c19 17 * unaligned memory access to packed structures. */
sgnezdov 0:fbdd0d307c19 18 /* #define PB_NO_PACKED_STRUCTS 1 */
sgnezdov 0:fbdd0d307c19 19
sgnezdov 0:fbdd0d307c19 20 /* Increase the number of required fields that are tracked.
sgnezdov 0:fbdd0d307c19 21 * A compiler warning will tell if you need this. */
sgnezdov 0:fbdd0d307c19 22 /* #define PB_MAX_REQUIRED_FIELDS 256 */
sgnezdov 0:fbdd0d307c19 23
sgnezdov 0:fbdd0d307c19 24 /* Add support for tag numbers > 255 and fields larger than 255 bytes. */
sgnezdov 0:fbdd0d307c19 25 /* #define PB_FIELD_16BIT 1 */
sgnezdov 0:fbdd0d307c19 26
sgnezdov 0:fbdd0d307c19 27 /* Add support for tag numbers > 65536 and fields larger than 65536 bytes. */
sgnezdov 0:fbdd0d307c19 28 /* #define PB_FIELD_32BIT 1 */
sgnezdov 0:fbdd0d307c19 29
sgnezdov 0:fbdd0d307c19 30 /* Disable support for error messages in order to save some code space. */
sgnezdov 0:fbdd0d307c19 31 /* #define PB_NO_ERRMSG 1 */
sgnezdov 0:fbdd0d307c19 32
sgnezdov 0:fbdd0d307c19 33 /* Disable support for custom streams (support only memory buffers). */
sgnezdov 0:fbdd0d307c19 34 /* #define PB_BUFFER_ONLY 1 */
sgnezdov 0:fbdd0d307c19 35
sgnezdov 0:fbdd0d307c19 36 /* Switch back to the old-style callback function signature.
sgnezdov 0:fbdd0d307c19 37 * This was the default until nanopb-0.2.1. */
sgnezdov 0:fbdd0d307c19 38 /* #define PB_OLD_CALLBACK_STYLE */
sgnezdov 0:fbdd0d307c19 39
sgnezdov 0:fbdd0d307c19 40
sgnezdov 0:fbdd0d307c19 41 /******************************************************************
sgnezdov 0:fbdd0d307c19 42 * You usually don't need to change anything below this line. *
sgnezdov 0:fbdd0d307c19 43 * Feel free to look around and use the defined macros, though. *
sgnezdov 0:fbdd0d307c19 44 ******************************************************************/
sgnezdov 0:fbdd0d307c19 45
sgnezdov 0:fbdd0d307c19 46
sgnezdov 0:fbdd0d307c19 47 /* Version of the nanopb library. Just in case you want to check it in
sgnezdov 0:fbdd0d307c19 48 * your own program. */
sgnezdov 0:fbdd0d307c19 49 #define NANOPB_VERSION nanopb-0.3.8
sgnezdov 0:fbdd0d307c19 50
sgnezdov 0:fbdd0d307c19 51 /* Include all the system headers needed by nanopb. You will need the
sgnezdov 0:fbdd0d307c19 52 * definitions of the following:
sgnezdov 0:fbdd0d307c19 53 * - strlen, memcpy, memset functions
sgnezdov 0:fbdd0d307c19 54 * - [u]int_least8_t, uint_fast8_t, [u]int_least16_t, [u]int32_t, [u]int64_t
sgnezdov 0:fbdd0d307c19 55 * - size_t
sgnezdov 0:fbdd0d307c19 56 * - bool
sgnezdov 0:fbdd0d307c19 57 *
sgnezdov 0:fbdd0d307c19 58 * If you don't have the standard header files, you can instead provide
sgnezdov 0:fbdd0d307c19 59 * a custom header that defines or includes all this. In that case,
sgnezdov 0:fbdd0d307c19 60 * define PB_SYSTEM_HEADER to the path of this file.
sgnezdov 0:fbdd0d307c19 61 */
sgnezdov 0:fbdd0d307c19 62 #ifdef PB_SYSTEM_HEADER
sgnezdov 0:fbdd0d307c19 63 #include PB_SYSTEM_HEADER
sgnezdov 0:fbdd0d307c19 64 #else
sgnezdov 0:fbdd0d307c19 65 #include <stdint.h>
sgnezdov 0:fbdd0d307c19 66 #include <stddef.h>
sgnezdov 0:fbdd0d307c19 67 #include <stdbool.h>
sgnezdov 0:fbdd0d307c19 68 #include <string.h>
sgnezdov 0:fbdd0d307c19 69
sgnezdov 0:fbdd0d307c19 70 #ifdef PB_ENABLE_MALLOC
sgnezdov 0:fbdd0d307c19 71 #include <stdlib.h>
sgnezdov 0:fbdd0d307c19 72 #endif
sgnezdov 0:fbdd0d307c19 73 #endif
sgnezdov 0:fbdd0d307c19 74
sgnezdov 0:fbdd0d307c19 75 /* Macro for defining packed structures (compiler dependent).
sgnezdov 0:fbdd0d307c19 76 * This just reduces memory requirements, but is not required.
sgnezdov 0:fbdd0d307c19 77 */
sgnezdov 0:fbdd0d307c19 78 #if defined(PB_NO_PACKED_STRUCTS)
sgnezdov 0:fbdd0d307c19 79 /* Disable struct packing */
sgnezdov 0:fbdd0d307c19 80 # define PB_PACKED_STRUCT_START
sgnezdov 0:fbdd0d307c19 81 # define PB_PACKED_STRUCT_END
sgnezdov 0:fbdd0d307c19 82 # define pb_packed
sgnezdov 0:fbdd0d307c19 83 #elif defined(__GNUC__) || defined(__clang__)
sgnezdov 0:fbdd0d307c19 84 /* For GCC and clang */
sgnezdov 0:fbdd0d307c19 85 # define PB_PACKED_STRUCT_START
sgnezdov 0:fbdd0d307c19 86 # define PB_PACKED_STRUCT_END
sgnezdov 0:fbdd0d307c19 87 # define pb_packed __attribute__((packed))
sgnezdov 0:fbdd0d307c19 88 #elif defined(__ICCARM__) || defined(__CC_ARM)
sgnezdov 0:fbdd0d307c19 89 /* For IAR ARM and Keil MDK-ARM compilers */
sgnezdov 0:fbdd0d307c19 90 # define PB_PACKED_STRUCT_START _Pragma("pack(push, 1)")
sgnezdov 0:fbdd0d307c19 91 # define PB_PACKED_STRUCT_END _Pragma("pack(pop)")
sgnezdov 0:fbdd0d307c19 92 # define pb_packed
sgnezdov 0:fbdd0d307c19 93 #elif defined(_MSC_VER) && (_MSC_VER >= 1500)
sgnezdov 0:fbdd0d307c19 94 /* For Microsoft Visual C++ */
sgnezdov 0:fbdd0d307c19 95 # define PB_PACKED_STRUCT_START __pragma(pack(push, 1))
sgnezdov 0:fbdd0d307c19 96 # define PB_PACKED_STRUCT_END __pragma(pack(pop))
sgnezdov 0:fbdd0d307c19 97 # define pb_packed
sgnezdov 0:fbdd0d307c19 98 #else
sgnezdov 0:fbdd0d307c19 99 /* Unknown compiler */
sgnezdov 0:fbdd0d307c19 100 # define PB_PACKED_STRUCT_START
sgnezdov 0:fbdd0d307c19 101 # define PB_PACKED_STRUCT_END
sgnezdov 0:fbdd0d307c19 102 # define pb_packed
sgnezdov 0:fbdd0d307c19 103 #endif
sgnezdov 0:fbdd0d307c19 104
sgnezdov 0:fbdd0d307c19 105 /* Handly macro for suppressing unreferenced-parameter compiler warnings. */
sgnezdov 0:fbdd0d307c19 106 #ifndef PB_UNUSED
sgnezdov 0:fbdd0d307c19 107 #define PB_UNUSED(x) (void)(x)
sgnezdov 0:fbdd0d307c19 108 #endif
sgnezdov 0:fbdd0d307c19 109
sgnezdov 0:fbdd0d307c19 110 /* Compile-time assertion, used for checking compatible compilation options.
sgnezdov 0:fbdd0d307c19 111 * If this does not work properly on your compiler, use
sgnezdov 0:fbdd0d307c19 112 * #define PB_NO_STATIC_ASSERT to disable it.
sgnezdov 0:fbdd0d307c19 113 *
sgnezdov 0:fbdd0d307c19 114 * But before doing that, check carefully the error message / place where it
sgnezdov 0:fbdd0d307c19 115 * comes from to see if the error has a real cause. Unfortunately the error
sgnezdov 0:fbdd0d307c19 116 * message is not always very clear to read, but you can see the reason better
sgnezdov 0:fbdd0d307c19 117 * in the place where the PB_STATIC_ASSERT macro was called.
sgnezdov 0:fbdd0d307c19 118 */
sgnezdov 0:fbdd0d307c19 119 #ifndef PB_NO_STATIC_ASSERT
sgnezdov 0:fbdd0d307c19 120 #ifndef PB_STATIC_ASSERT
sgnezdov 0:fbdd0d307c19 121 #define PB_STATIC_ASSERT(COND,MSG) typedef char PB_STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND)?1:-1];
sgnezdov 0:fbdd0d307c19 122 #define PB_STATIC_ASSERT_MSG(MSG, LINE, COUNTER) PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER)
sgnezdov 0:fbdd0d307c19 123 #define PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) pb_static_assertion_##MSG##LINE##COUNTER
sgnezdov 0:fbdd0d307c19 124 #endif
sgnezdov 0:fbdd0d307c19 125 #else
sgnezdov 0:fbdd0d307c19 126 #define PB_STATIC_ASSERT(COND,MSG)
sgnezdov 0:fbdd0d307c19 127 #endif
sgnezdov 0:fbdd0d307c19 128
sgnezdov 0:fbdd0d307c19 129 /* Number of required fields to keep track of. */
sgnezdov 0:fbdd0d307c19 130 #ifndef PB_MAX_REQUIRED_FIELDS
sgnezdov 0:fbdd0d307c19 131 #define PB_MAX_REQUIRED_FIELDS 64
sgnezdov 0:fbdd0d307c19 132 #endif
sgnezdov 0:fbdd0d307c19 133
sgnezdov 0:fbdd0d307c19 134 #if PB_MAX_REQUIRED_FIELDS < 64
sgnezdov 0:fbdd0d307c19 135 #error You should not lower PB_MAX_REQUIRED_FIELDS from the default value (64).
sgnezdov 0:fbdd0d307c19 136 #endif
sgnezdov 0:fbdd0d307c19 137
sgnezdov 0:fbdd0d307c19 138 /* List of possible field types. These are used in the autogenerated code.
sgnezdov 0:fbdd0d307c19 139 * Least-significant 4 bits tell the scalar type
sgnezdov 0:fbdd0d307c19 140 * Most-significant 4 bits specify repeated/required/packed etc.
sgnezdov 0:fbdd0d307c19 141 */
sgnezdov 0:fbdd0d307c19 142
sgnezdov 0:fbdd0d307c19 143 typedef uint_least8_t pb_type_t;
sgnezdov 0:fbdd0d307c19 144
sgnezdov 0:fbdd0d307c19 145 /**** Field data types ****/
sgnezdov 0:fbdd0d307c19 146
sgnezdov 0:fbdd0d307c19 147 /* Numeric types */
sgnezdov 0:fbdd0d307c19 148 #define PB_LTYPE_VARINT 0x00 /* int32, int64, enum, bool */
sgnezdov 0:fbdd0d307c19 149 #define PB_LTYPE_UVARINT 0x01 /* uint32, uint64 */
sgnezdov 0:fbdd0d307c19 150 #define PB_LTYPE_SVARINT 0x02 /* sint32, sint64 */
sgnezdov 0:fbdd0d307c19 151 #define PB_LTYPE_FIXED32 0x03 /* fixed32, sfixed32, float */
sgnezdov 0:fbdd0d307c19 152 #define PB_LTYPE_FIXED64 0x04 /* fixed64, sfixed64, double */
sgnezdov 0:fbdd0d307c19 153
sgnezdov 0:fbdd0d307c19 154 /* Marker for last packable field type. */
sgnezdov 0:fbdd0d307c19 155 #define PB_LTYPE_LAST_PACKABLE 0x04
sgnezdov 0:fbdd0d307c19 156
sgnezdov 0:fbdd0d307c19 157 /* Byte array with pre-allocated buffer.
sgnezdov 0:fbdd0d307c19 158 * data_size is the length of the allocated PB_BYTES_ARRAY structure. */
sgnezdov 0:fbdd0d307c19 159 #define PB_LTYPE_BYTES 0x05
sgnezdov 0:fbdd0d307c19 160
sgnezdov 0:fbdd0d307c19 161 /* String with pre-allocated buffer.
sgnezdov 0:fbdd0d307c19 162 * data_size is the maximum length. */
sgnezdov 0:fbdd0d307c19 163 #define PB_LTYPE_STRING 0x06
sgnezdov 0:fbdd0d307c19 164
sgnezdov 0:fbdd0d307c19 165 /* Submessage
sgnezdov 0:fbdd0d307c19 166 * submsg_fields is pointer to field descriptions */
sgnezdov 0:fbdd0d307c19 167 #define PB_LTYPE_SUBMESSAGE 0x07
sgnezdov 0:fbdd0d307c19 168
sgnezdov 0:fbdd0d307c19 169 /* Extension pseudo-field
sgnezdov 0:fbdd0d307c19 170 * The field contains a pointer to pb_extension_t */
sgnezdov 0:fbdd0d307c19 171 #define PB_LTYPE_EXTENSION 0x08
sgnezdov 0:fbdd0d307c19 172
sgnezdov 0:fbdd0d307c19 173 /* Byte array with inline, pre-allocated byffer.
sgnezdov 0:fbdd0d307c19 174 * data_size is the length of the inline, allocated buffer.
sgnezdov 0:fbdd0d307c19 175 * This differs from PB_LTYPE_BYTES by defining the element as
sgnezdov 0:fbdd0d307c19 176 * pb_byte_t[data_size] rather than pb_bytes_array_t. */
sgnezdov 0:fbdd0d307c19 177 #define PB_LTYPE_FIXED_LENGTH_BYTES 0x09
sgnezdov 0:fbdd0d307c19 178
sgnezdov 0:fbdd0d307c19 179 /* Number of declared LTYPES */
sgnezdov 0:fbdd0d307c19 180 #define PB_LTYPES_COUNT 0x0A
sgnezdov 0:fbdd0d307c19 181 #define PB_LTYPE_MASK 0x0F
sgnezdov 0:fbdd0d307c19 182
sgnezdov 0:fbdd0d307c19 183 /**** Field repetition rules ****/
sgnezdov 0:fbdd0d307c19 184
sgnezdov 0:fbdd0d307c19 185 #define PB_HTYPE_REQUIRED 0x00
sgnezdov 0:fbdd0d307c19 186 #define PB_HTYPE_OPTIONAL 0x10
sgnezdov 0:fbdd0d307c19 187 #define PB_HTYPE_REPEATED 0x20
sgnezdov 0:fbdd0d307c19 188 #define PB_HTYPE_ONEOF 0x30
sgnezdov 0:fbdd0d307c19 189 #define PB_HTYPE_MASK 0x30
sgnezdov 0:fbdd0d307c19 190
sgnezdov 0:fbdd0d307c19 191 /**** Field allocation types ****/
sgnezdov 0:fbdd0d307c19 192
sgnezdov 0:fbdd0d307c19 193 #define PB_ATYPE_STATIC 0x00
sgnezdov 0:fbdd0d307c19 194 #define PB_ATYPE_POINTER 0x80
sgnezdov 0:fbdd0d307c19 195 #define PB_ATYPE_CALLBACK 0x40
sgnezdov 0:fbdd0d307c19 196 #define PB_ATYPE_MASK 0xC0
sgnezdov 0:fbdd0d307c19 197
sgnezdov 0:fbdd0d307c19 198 #define PB_ATYPE(x) ((x) & PB_ATYPE_MASK)
sgnezdov 0:fbdd0d307c19 199 #define PB_HTYPE(x) ((x) & PB_HTYPE_MASK)
sgnezdov 0:fbdd0d307c19 200 #define PB_LTYPE(x) ((x) & PB_LTYPE_MASK)
sgnezdov 0:fbdd0d307c19 201
sgnezdov 0:fbdd0d307c19 202 /* Data type used for storing sizes of struct fields
sgnezdov 0:fbdd0d307c19 203 * and array counts.
sgnezdov 0:fbdd0d307c19 204 */
sgnezdov 0:fbdd0d307c19 205 #if defined(PB_FIELD_32BIT)
sgnezdov 0:fbdd0d307c19 206 typedef uint32_t pb_size_t;
sgnezdov 0:fbdd0d307c19 207 typedef int32_t pb_ssize_t;
sgnezdov 0:fbdd0d307c19 208 #elif defined(PB_FIELD_16BIT)
sgnezdov 0:fbdd0d307c19 209 typedef uint_least16_t pb_size_t;
sgnezdov 0:fbdd0d307c19 210 typedef int_least16_t pb_ssize_t;
sgnezdov 0:fbdd0d307c19 211 #else
sgnezdov 0:fbdd0d307c19 212 typedef uint_least8_t pb_size_t;
sgnezdov 0:fbdd0d307c19 213 typedef int_least8_t pb_ssize_t;
sgnezdov 0:fbdd0d307c19 214 #endif
sgnezdov 0:fbdd0d307c19 215 #define PB_SIZE_MAX ((pb_size_t)-1)
sgnezdov 0:fbdd0d307c19 216
sgnezdov 0:fbdd0d307c19 217 /* Data type for storing encoded data and other byte streams.
sgnezdov 0:fbdd0d307c19 218 * This typedef exists to support platforms where uint8_t does not exist.
sgnezdov 0:fbdd0d307c19 219 * You can regard it as equivalent on uint8_t on other platforms.
sgnezdov 0:fbdd0d307c19 220 */
sgnezdov 0:fbdd0d307c19 221 typedef uint_least8_t pb_byte_t;
sgnezdov 0:fbdd0d307c19 222
sgnezdov 0:fbdd0d307c19 223 /* This structure is used in auto-generated constants
sgnezdov 0:fbdd0d307c19 224 * to specify struct fields.
sgnezdov 0:fbdd0d307c19 225 * You can change field sizes if you need structures
sgnezdov 0:fbdd0d307c19 226 * larger than 256 bytes or field tags larger than 256.
sgnezdov 0:fbdd0d307c19 227 * The compiler should complain if your .proto has such
sgnezdov 0:fbdd0d307c19 228 * structures. Fix that by defining PB_FIELD_16BIT or
sgnezdov 0:fbdd0d307c19 229 * PB_FIELD_32BIT.
sgnezdov 0:fbdd0d307c19 230 */
sgnezdov 0:fbdd0d307c19 231 PB_PACKED_STRUCT_START
sgnezdov 0:fbdd0d307c19 232 typedef struct pb_field_s pb_field_t;
sgnezdov 0:fbdd0d307c19 233 struct pb_field_s {
sgnezdov 0:fbdd0d307c19 234 pb_size_t tag;
sgnezdov 0:fbdd0d307c19 235 pb_type_t type;
sgnezdov 0:fbdd0d307c19 236 pb_size_t data_offset; /* Offset of field data, relative to previous field. */
sgnezdov 0:fbdd0d307c19 237 pb_ssize_t size_offset; /* Offset of array size or has-boolean, relative to data */
sgnezdov 0:fbdd0d307c19 238 pb_size_t data_size; /* Data size in bytes for a single item */
sgnezdov 0:fbdd0d307c19 239 pb_size_t array_size; /* Maximum number of entries in array */
sgnezdov 0:fbdd0d307c19 240
sgnezdov 0:fbdd0d307c19 241 /* Field definitions for submessage
sgnezdov 0:fbdd0d307c19 242 * OR default value for all other non-array, non-callback types
sgnezdov 0:fbdd0d307c19 243 * If null, then field will zeroed. */
sgnezdov 0:fbdd0d307c19 244 const void *ptr;
sgnezdov 0:fbdd0d307c19 245 } pb_packed;
sgnezdov 0:fbdd0d307c19 246 PB_PACKED_STRUCT_END
sgnezdov 0:fbdd0d307c19 247
sgnezdov 0:fbdd0d307c19 248 /* Make sure that the standard integer types are of the expected sizes.
sgnezdov 0:fbdd0d307c19 249 * Otherwise fixed32/fixed64 fields can break.
sgnezdov 0:fbdd0d307c19 250 *
sgnezdov 0:fbdd0d307c19 251 * If you get errors here, it probably means that your stdint.h is not
sgnezdov 0:fbdd0d307c19 252 * correct for your platform.
sgnezdov 0:fbdd0d307c19 253 */
sgnezdov 0:fbdd0d307c19 254 PB_STATIC_ASSERT(sizeof(int64_t) == 2 * sizeof(int32_t), INT64_T_WRONG_SIZE)
sgnezdov 0:fbdd0d307c19 255 PB_STATIC_ASSERT(sizeof(uint64_t) == 2 * sizeof(uint32_t), UINT64_T_WRONG_SIZE)
sgnezdov 0:fbdd0d307c19 256
sgnezdov 0:fbdd0d307c19 257 /* This structure is used for 'bytes' arrays.
sgnezdov 0:fbdd0d307c19 258 * It has the number of bytes in the beginning, and after that an array.
sgnezdov 0:fbdd0d307c19 259 * Note that actual structs used will have a different length of bytes array.
sgnezdov 0:fbdd0d307c19 260 */
sgnezdov 0:fbdd0d307c19 261 #define PB_BYTES_ARRAY_T(n) struct { pb_size_t size; pb_byte_t bytes[n]; }
sgnezdov 0:fbdd0d307c19 262 #define PB_BYTES_ARRAY_T_ALLOCSIZE(n) ((size_t)n + offsetof(pb_bytes_array_t, bytes))
sgnezdov 0:fbdd0d307c19 263
sgnezdov 0:fbdd0d307c19 264 struct pb_bytes_array_s {
sgnezdov 0:fbdd0d307c19 265 pb_size_t size;
sgnezdov 0:fbdd0d307c19 266 pb_byte_t bytes[1];
sgnezdov 0:fbdd0d307c19 267 };
sgnezdov 0:fbdd0d307c19 268 typedef struct pb_bytes_array_s pb_bytes_array_t;
sgnezdov 0:fbdd0d307c19 269
sgnezdov 0:fbdd0d307c19 270 /* This structure is used for giving the callback function.
sgnezdov 0:fbdd0d307c19 271 * It is stored in the message structure and filled in by the method that
sgnezdov 0:fbdd0d307c19 272 * calls pb_decode.
sgnezdov 0:fbdd0d307c19 273 *
sgnezdov 0:fbdd0d307c19 274 * The decoding callback will be given a limited-length stream
sgnezdov 0:fbdd0d307c19 275 * If the wire type was string, the length is the length of the string.
sgnezdov 0:fbdd0d307c19 276 * If the wire type was a varint/fixed32/fixed64, the length is the length
sgnezdov 0:fbdd0d307c19 277 * of the actual value.
sgnezdov 0:fbdd0d307c19 278 * The function may be called multiple times (especially for repeated types,
sgnezdov 0:fbdd0d307c19 279 * but also otherwise if the message happens to contain the field multiple
sgnezdov 0:fbdd0d307c19 280 * times.)
sgnezdov 0:fbdd0d307c19 281 *
sgnezdov 0:fbdd0d307c19 282 * The encoding callback will receive the actual output stream.
sgnezdov 0:fbdd0d307c19 283 * It should write all the data in one call, including the field tag and
sgnezdov 0:fbdd0d307c19 284 * wire type. It can write multiple fields.
sgnezdov 0:fbdd0d307c19 285 *
sgnezdov 0:fbdd0d307c19 286 * The callback can be null if you want to skip a field.
sgnezdov 0:fbdd0d307c19 287 */
sgnezdov 0:fbdd0d307c19 288 typedef struct pb_istream_s pb_istream_t;
sgnezdov 0:fbdd0d307c19 289 typedef struct pb_ostream_s pb_ostream_t;
sgnezdov 0:fbdd0d307c19 290 typedef struct pb_callback_s pb_callback_t;
sgnezdov 0:fbdd0d307c19 291 struct pb_callback_s {
sgnezdov 0:fbdd0d307c19 292 #ifdef PB_OLD_CALLBACK_STYLE
sgnezdov 0:fbdd0d307c19 293 /* Deprecated since nanopb-0.2.1 */
sgnezdov 0:fbdd0d307c19 294 union {
sgnezdov 0:fbdd0d307c19 295 bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void *arg);
sgnezdov 0:fbdd0d307c19 296 bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, const void *arg);
sgnezdov 0:fbdd0d307c19 297 } funcs;
sgnezdov 0:fbdd0d307c19 298 #else
sgnezdov 0:fbdd0d307c19 299 /* New function signature, which allows modifying arg contents in callback. */
sgnezdov 0:fbdd0d307c19 300 union {
sgnezdov 0:fbdd0d307c19 301 bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void **arg);
sgnezdov 0:fbdd0d307c19 302 bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, void * const *arg);
sgnezdov 0:fbdd0d307c19 303 } funcs;
sgnezdov 0:fbdd0d307c19 304 #endif
sgnezdov 0:fbdd0d307c19 305
sgnezdov 0:fbdd0d307c19 306 /* Free arg for use by callback */
sgnezdov 0:fbdd0d307c19 307 void *arg;
sgnezdov 0:fbdd0d307c19 308 };
sgnezdov 0:fbdd0d307c19 309
sgnezdov 0:fbdd0d307c19 310 /* Wire types. Library user needs these only in encoder callbacks. */
sgnezdov 0:fbdd0d307c19 311 typedef enum {
sgnezdov 0:fbdd0d307c19 312 PB_WT_VARINT = 0,
sgnezdov 0:fbdd0d307c19 313 PB_WT_64BIT = 1,
sgnezdov 0:fbdd0d307c19 314 PB_WT_STRING = 2,
sgnezdov 0:fbdd0d307c19 315 PB_WT_32BIT = 5
sgnezdov 0:fbdd0d307c19 316 } pb_wire_type_t;
sgnezdov 0:fbdd0d307c19 317
sgnezdov 0:fbdd0d307c19 318 /* Structure for defining the handling of unknown/extension fields.
sgnezdov 0:fbdd0d307c19 319 * Usually the pb_extension_type_t structure is automatically generated,
sgnezdov 0:fbdd0d307c19 320 * while the pb_extension_t structure is created by the user. However,
sgnezdov 0:fbdd0d307c19 321 * if you want to catch all unknown fields, you can also create a custom
sgnezdov 0:fbdd0d307c19 322 * pb_extension_type_t with your own callback.
sgnezdov 0:fbdd0d307c19 323 */
sgnezdov 0:fbdd0d307c19 324 typedef struct pb_extension_type_s pb_extension_type_t;
sgnezdov 0:fbdd0d307c19 325 typedef struct pb_extension_s pb_extension_t;
sgnezdov 0:fbdd0d307c19 326 struct pb_extension_type_s {
sgnezdov 0:fbdd0d307c19 327 /* Called for each unknown field in the message.
sgnezdov 0:fbdd0d307c19 328 * If you handle the field, read off all of its data and return true.
sgnezdov 0:fbdd0d307c19 329 * If you do not handle the field, do not read anything and return true.
sgnezdov 0:fbdd0d307c19 330 * If you run into an error, return false.
sgnezdov 0:fbdd0d307c19 331 * Set to NULL for default handler.
sgnezdov 0:fbdd0d307c19 332 */
sgnezdov 0:fbdd0d307c19 333 bool (*decode)(pb_istream_t *stream, pb_extension_t *extension,
sgnezdov 0:fbdd0d307c19 334 uint32_t tag, pb_wire_type_t wire_type);
sgnezdov 0:fbdd0d307c19 335
sgnezdov 0:fbdd0d307c19 336 /* Called once after all regular fields have been encoded.
sgnezdov 0:fbdd0d307c19 337 * If you have something to write, do so and return true.
sgnezdov 0:fbdd0d307c19 338 * If you do not have anything to write, just return true.
sgnezdov 0:fbdd0d307c19 339 * If you run into an error, return false.
sgnezdov 0:fbdd0d307c19 340 * Set to NULL for default handler.
sgnezdov 0:fbdd0d307c19 341 */
sgnezdov 0:fbdd0d307c19 342 bool (*encode)(pb_ostream_t *stream, const pb_extension_t *extension);
sgnezdov 0:fbdd0d307c19 343
sgnezdov 0:fbdd0d307c19 344 /* Free field for use by the callback. */
sgnezdov 0:fbdd0d307c19 345 const void *arg;
sgnezdov 0:fbdd0d307c19 346 };
sgnezdov 0:fbdd0d307c19 347
sgnezdov 0:fbdd0d307c19 348 struct pb_extension_s {
sgnezdov 0:fbdd0d307c19 349 /* Type describing the extension field. Usually you'll initialize
sgnezdov 0:fbdd0d307c19 350 * this to a pointer to the automatically generated structure. */
sgnezdov 0:fbdd0d307c19 351 const pb_extension_type_t *type;
sgnezdov 0:fbdd0d307c19 352
sgnezdov 0:fbdd0d307c19 353 /* Destination for the decoded data. This must match the datatype
sgnezdov 0:fbdd0d307c19 354 * of the extension field. */
sgnezdov 0:fbdd0d307c19 355 void *dest;
sgnezdov 0:fbdd0d307c19 356
sgnezdov 0:fbdd0d307c19 357 /* Pointer to the next extension handler, or NULL.
sgnezdov 0:fbdd0d307c19 358 * If this extension does not match a field, the next handler is
sgnezdov 0:fbdd0d307c19 359 * automatically called. */
sgnezdov 0:fbdd0d307c19 360 pb_extension_t *next;
sgnezdov 0:fbdd0d307c19 361
sgnezdov 0:fbdd0d307c19 362 /* The decoder sets this to true if the extension was found.
sgnezdov 0:fbdd0d307c19 363 * Ignored for encoding. */
sgnezdov 0:fbdd0d307c19 364 bool found;
sgnezdov 0:fbdd0d307c19 365 };
sgnezdov 0:fbdd0d307c19 366
sgnezdov 0:fbdd0d307c19 367 /* Memory allocation functions to use. You can define pb_realloc and
sgnezdov 0:fbdd0d307c19 368 * pb_free to custom functions if you want. */
sgnezdov 0:fbdd0d307c19 369 #ifdef PB_ENABLE_MALLOC
sgnezdov 0:fbdd0d307c19 370 # ifndef pb_realloc
sgnezdov 0:fbdd0d307c19 371 # define pb_realloc(ptr, size) realloc(ptr, size)
sgnezdov 0:fbdd0d307c19 372 # endif
sgnezdov 0:fbdd0d307c19 373 # ifndef pb_free
sgnezdov 0:fbdd0d307c19 374 # define pb_free(ptr) free(ptr)
sgnezdov 0:fbdd0d307c19 375 # endif
sgnezdov 0:fbdd0d307c19 376 #endif
sgnezdov 0:fbdd0d307c19 377
sgnezdov 0:fbdd0d307c19 378 /* This is used to inform about need to regenerate .pb.h/.pb.c files. */
sgnezdov 0:fbdd0d307c19 379 #define PB_PROTO_HEADER_VERSION 30
sgnezdov 0:fbdd0d307c19 380
sgnezdov 0:fbdd0d307c19 381 /* These macros are used to declare pb_field_t's in the constant array. */
sgnezdov 0:fbdd0d307c19 382 /* Size of a structure member, in bytes. */
sgnezdov 0:fbdd0d307c19 383 #define pb_membersize(st, m) (sizeof ((st*)0)->m)
sgnezdov 0:fbdd0d307c19 384 /* Number of entries in an array. */
sgnezdov 0:fbdd0d307c19 385 #define pb_arraysize(st, m) (pb_membersize(st, m) / pb_membersize(st, m[0]))
sgnezdov 0:fbdd0d307c19 386 /* Delta from start of one member to the start of another member. */
sgnezdov 0:fbdd0d307c19 387 #define pb_delta(st, m1, m2) ((int)offsetof(st, m1) - (int)offsetof(st, m2))
sgnezdov 0:fbdd0d307c19 388 /* Marks the end of the field list */
sgnezdov 0:fbdd0d307c19 389 #define PB_LAST_FIELD {0,(pb_type_t) 0,0,0,0,0,0}
sgnezdov 0:fbdd0d307c19 390
sgnezdov 0:fbdd0d307c19 391 /* Macros for filling in the data_offset field */
sgnezdov 0:fbdd0d307c19 392 /* data_offset for first field in a message */
sgnezdov 0:fbdd0d307c19 393 #define PB_DATAOFFSET_FIRST(st, m1, m2) (offsetof(st, m1))
sgnezdov 0:fbdd0d307c19 394 /* data_offset for subsequent fields */
sgnezdov 0:fbdd0d307c19 395 #define PB_DATAOFFSET_OTHER(st, m1, m2) (offsetof(st, m1) - offsetof(st, m2) - pb_membersize(st, m2))
sgnezdov 0:fbdd0d307c19 396 /* data offset for subsequent fields inside an union (oneof) */
sgnezdov 0:fbdd0d307c19 397 #define PB_DATAOFFSET_UNION(st, m1, m2) (PB_SIZE_MAX)
sgnezdov 0:fbdd0d307c19 398 /* Choose first/other based on m1 == m2 (deprecated, remains for backwards compatibility) */
sgnezdov 0:fbdd0d307c19 399 #define PB_DATAOFFSET_CHOOSE(st, m1, m2) (int)(offsetof(st, m1) == offsetof(st, m2) \
sgnezdov 0:fbdd0d307c19 400 ? PB_DATAOFFSET_FIRST(st, m1, m2) \
sgnezdov 0:fbdd0d307c19 401 : PB_DATAOFFSET_OTHER(st, m1, m2))
sgnezdov 0:fbdd0d307c19 402
sgnezdov 0:fbdd0d307c19 403 /* Required fields are the simplest. They just have delta (padding) from
sgnezdov 0:fbdd0d307c19 404 * previous field end, and the size of the field. Pointer is used for
sgnezdov 0:fbdd0d307c19 405 * submessages and default values.
sgnezdov 0:fbdd0d307c19 406 */
sgnezdov 0:fbdd0d307c19 407 #define PB_REQUIRED_STATIC(tag, st, m, fd, ltype, ptr) \
sgnezdov 0:fbdd0d307c19 408 {tag, PB_ATYPE_STATIC | PB_HTYPE_REQUIRED | ltype, \
sgnezdov 0:fbdd0d307c19 409 fd, 0, pb_membersize(st, m), 0, ptr}
sgnezdov 0:fbdd0d307c19 410
sgnezdov 0:fbdd0d307c19 411 /* Optional fields add the delta to the has_ variable. */
sgnezdov 0:fbdd0d307c19 412 #define PB_OPTIONAL_STATIC(tag, st, m, fd, ltype, ptr) \
sgnezdov 0:fbdd0d307c19 413 {tag, PB_ATYPE_STATIC | PB_HTYPE_OPTIONAL | ltype, \
sgnezdov 0:fbdd0d307c19 414 fd, \
sgnezdov 0:fbdd0d307c19 415 pb_delta(st, has_ ## m, m), \
sgnezdov 0:fbdd0d307c19 416 pb_membersize(st, m), 0, ptr}
sgnezdov 0:fbdd0d307c19 417
sgnezdov 0:fbdd0d307c19 418 #define PB_SINGULAR_STATIC(tag, st, m, fd, ltype, ptr) \
sgnezdov 0:fbdd0d307c19 419 {tag, PB_ATYPE_STATIC | PB_HTYPE_OPTIONAL | ltype, \
sgnezdov 0:fbdd0d307c19 420 fd, 0, pb_membersize(st, m), 0, ptr}
sgnezdov 0:fbdd0d307c19 421
sgnezdov 0:fbdd0d307c19 422 /* Repeated fields have a _count field and also the maximum number of entries. */
sgnezdov 0:fbdd0d307c19 423 #define PB_REPEATED_STATIC(tag, st, m, fd, ltype, ptr) \
sgnezdov 0:fbdd0d307c19 424 {tag, PB_ATYPE_STATIC | PB_HTYPE_REPEATED | ltype, \
sgnezdov 0:fbdd0d307c19 425 fd, \
sgnezdov 0:fbdd0d307c19 426 pb_delta(st, m ## _count, m), \
sgnezdov 0:fbdd0d307c19 427 pb_membersize(st, m[0]), \
sgnezdov 0:fbdd0d307c19 428 pb_arraysize(st, m), ptr}
sgnezdov 0:fbdd0d307c19 429
sgnezdov 0:fbdd0d307c19 430 /* Allocated fields carry the size of the actual data, not the pointer */
sgnezdov 0:fbdd0d307c19 431 #define PB_REQUIRED_POINTER(tag, st, m, fd, ltype, ptr) \
sgnezdov 0:fbdd0d307c19 432 {tag, PB_ATYPE_POINTER | PB_HTYPE_REQUIRED | ltype, \
sgnezdov 0:fbdd0d307c19 433 fd, 0, pb_membersize(st, m[0]), 0, ptr}
sgnezdov 0:fbdd0d307c19 434
sgnezdov 0:fbdd0d307c19 435 /* Optional fields don't need a has_ variable, as information would be redundant */
sgnezdov 0:fbdd0d307c19 436 #define PB_OPTIONAL_POINTER(tag, st, m, fd, ltype, ptr) \
sgnezdov 0:fbdd0d307c19 437 {tag, PB_ATYPE_POINTER | PB_HTYPE_OPTIONAL | ltype, \
sgnezdov 0:fbdd0d307c19 438 fd, 0, pb_membersize(st, m[0]), 0, ptr}
sgnezdov 0:fbdd0d307c19 439
sgnezdov 0:fbdd0d307c19 440 /* Same as optional fields*/
sgnezdov 0:fbdd0d307c19 441 #define PB_SINGULAR_POINTER(tag, st, m, fd, ltype, ptr) \
sgnezdov 0:fbdd0d307c19 442 {tag, PB_ATYPE_POINTER | PB_HTYPE_OPTIONAL | ltype, \
sgnezdov 0:fbdd0d307c19 443 fd, 0, pb_membersize(st, m[0]), 0, ptr}
sgnezdov 0:fbdd0d307c19 444
sgnezdov 0:fbdd0d307c19 445 /* Repeated fields have a _count field and a pointer to array of pointers */
sgnezdov 0:fbdd0d307c19 446 #define PB_REPEATED_POINTER(tag, st, m, fd, ltype, ptr) \
sgnezdov 0:fbdd0d307c19 447 {tag, PB_ATYPE_POINTER | PB_HTYPE_REPEATED | ltype, \
sgnezdov 0:fbdd0d307c19 448 fd, pb_delta(st, m ## _count, m), \
sgnezdov 0:fbdd0d307c19 449 pb_membersize(st, m[0]), 0, ptr}
sgnezdov 0:fbdd0d307c19 450
sgnezdov 0:fbdd0d307c19 451 /* Callbacks are much like required fields except with special datatype. */
sgnezdov 0:fbdd0d307c19 452 #define PB_REQUIRED_CALLBACK(tag, st, m, fd, ltype, ptr) \
sgnezdov 0:fbdd0d307c19 453 {tag, PB_ATYPE_CALLBACK | PB_HTYPE_REQUIRED | ltype, \
sgnezdov 0:fbdd0d307c19 454 fd, 0, pb_membersize(st, m), 0, ptr}
sgnezdov 0:fbdd0d307c19 455
sgnezdov 0:fbdd0d307c19 456 #define PB_OPTIONAL_CALLBACK(tag, st, m, fd, ltype, ptr) \
sgnezdov 0:fbdd0d307c19 457 {tag, PB_ATYPE_CALLBACK | PB_HTYPE_OPTIONAL | ltype, \
sgnezdov 0:fbdd0d307c19 458 fd, 0, pb_membersize(st, m), 0, ptr}
sgnezdov 0:fbdd0d307c19 459
sgnezdov 0:fbdd0d307c19 460 #define PB_SINGULAR_CALLBACK(tag, st, m, fd, ltype, ptr) \
sgnezdov 0:fbdd0d307c19 461 {tag, PB_ATYPE_CALLBACK | PB_HTYPE_OPTIONAL | ltype, \
sgnezdov 0:fbdd0d307c19 462 fd, 0, pb_membersize(st, m), 0, ptr}
sgnezdov 0:fbdd0d307c19 463
sgnezdov 0:fbdd0d307c19 464 #define PB_REPEATED_CALLBACK(tag, st, m, fd, ltype, ptr) \
sgnezdov 0:fbdd0d307c19 465 {tag, PB_ATYPE_CALLBACK | PB_HTYPE_REPEATED | ltype, \
sgnezdov 0:fbdd0d307c19 466 fd, 0, pb_membersize(st, m), 0, ptr}
sgnezdov 0:fbdd0d307c19 467
sgnezdov 0:fbdd0d307c19 468 /* Optional extensions don't have the has_ field, as that would be redundant.
sgnezdov 0:fbdd0d307c19 469 * Furthermore, the combination of OPTIONAL without has_ field is used
sgnezdov 0:fbdd0d307c19 470 * for indicating proto3 style fields. Extensions exist in proto2 mode only,
sgnezdov 0:fbdd0d307c19 471 * so they should be encoded according to proto2 rules. To avoid the conflict,
sgnezdov 0:fbdd0d307c19 472 * extensions are marked as REQUIRED instead.
sgnezdov 0:fbdd0d307c19 473 */
sgnezdov 0:fbdd0d307c19 474 #define PB_OPTEXT_STATIC(tag, st, m, fd, ltype, ptr) \
sgnezdov 0:fbdd0d307c19 475 {tag, PB_ATYPE_STATIC | PB_HTYPE_REQUIRED | ltype, \
sgnezdov 0:fbdd0d307c19 476 0, \
sgnezdov 0:fbdd0d307c19 477 0, \
sgnezdov 0:fbdd0d307c19 478 pb_membersize(st, m), 0, ptr}
sgnezdov 0:fbdd0d307c19 479
sgnezdov 0:fbdd0d307c19 480 #define PB_OPTEXT_POINTER(tag, st, m, fd, ltype, ptr) \
sgnezdov 0:fbdd0d307c19 481 PB_OPTIONAL_POINTER(tag, st, m, fd, ltype, ptr)
sgnezdov 0:fbdd0d307c19 482
sgnezdov 0:fbdd0d307c19 483 #define PB_OPTEXT_CALLBACK(tag, st, m, fd, ltype, ptr) \
sgnezdov 0:fbdd0d307c19 484 PB_OPTIONAL_CALLBACK(tag, st, m, fd, ltype, ptr)
sgnezdov 0:fbdd0d307c19 485
sgnezdov 0:fbdd0d307c19 486 /* The mapping from protobuf types to LTYPEs is done using these macros. */
sgnezdov 0:fbdd0d307c19 487 #define PB_LTYPE_MAP_BOOL PB_LTYPE_VARINT
sgnezdov 0:fbdd0d307c19 488 #define PB_LTYPE_MAP_BYTES PB_LTYPE_BYTES
sgnezdov 0:fbdd0d307c19 489 #define PB_LTYPE_MAP_DOUBLE PB_LTYPE_FIXED64
sgnezdov 0:fbdd0d307c19 490 #define PB_LTYPE_MAP_ENUM PB_LTYPE_VARINT
sgnezdov 0:fbdd0d307c19 491 #define PB_LTYPE_MAP_UENUM PB_LTYPE_UVARINT
sgnezdov 0:fbdd0d307c19 492 #define PB_LTYPE_MAP_FIXED32 PB_LTYPE_FIXED32
sgnezdov 0:fbdd0d307c19 493 #define PB_LTYPE_MAP_FIXED64 PB_LTYPE_FIXED64
sgnezdov 0:fbdd0d307c19 494 #define PB_LTYPE_MAP_FLOAT PB_LTYPE_FIXED32
sgnezdov 0:fbdd0d307c19 495 #define PB_LTYPE_MAP_INT32 PB_LTYPE_VARINT
sgnezdov 0:fbdd0d307c19 496 #define PB_LTYPE_MAP_INT64 PB_LTYPE_VARINT
sgnezdov 0:fbdd0d307c19 497 #define PB_LTYPE_MAP_MESSAGE PB_LTYPE_SUBMESSAGE
sgnezdov 0:fbdd0d307c19 498 #define PB_LTYPE_MAP_SFIXED32 PB_LTYPE_FIXED32
sgnezdov 0:fbdd0d307c19 499 #define PB_LTYPE_MAP_SFIXED64 PB_LTYPE_FIXED64
sgnezdov 0:fbdd0d307c19 500 #define PB_LTYPE_MAP_SINT32 PB_LTYPE_SVARINT
sgnezdov 0:fbdd0d307c19 501 #define PB_LTYPE_MAP_SINT64 PB_LTYPE_SVARINT
sgnezdov 0:fbdd0d307c19 502 #define PB_LTYPE_MAP_STRING PB_LTYPE_STRING
sgnezdov 0:fbdd0d307c19 503 #define PB_LTYPE_MAP_UINT32 PB_LTYPE_UVARINT
sgnezdov 0:fbdd0d307c19 504 #define PB_LTYPE_MAP_UINT64 PB_LTYPE_UVARINT
sgnezdov 0:fbdd0d307c19 505 #define PB_LTYPE_MAP_EXTENSION PB_LTYPE_EXTENSION
sgnezdov 0:fbdd0d307c19 506 #define PB_LTYPE_MAP_FIXED_LENGTH_BYTES PB_LTYPE_FIXED_LENGTH_BYTES
sgnezdov 0:fbdd0d307c19 507
sgnezdov 0:fbdd0d307c19 508 /* This is the actual macro used in field descriptions.
sgnezdov 0:fbdd0d307c19 509 * It takes these arguments:
sgnezdov 0:fbdd0d307c19 510 * - Field tag number
sgnezdov 0:fbdd0d307c19 511 * - Field type: BOOL, BYTES, DOUBLE, ENUM, UENUM, FIXED32, FIXED64,
sgnezdov 0:fbdd0d307c19 512 * FLOAT, INT32, INT64, MESSAGE, SFIXED32, SFIXED64
sgnezdov 0:fbdd0d307c19 513 * SINT32, SINT64, STRING, UINT32, UINT64 or EXTENSION
sgnezdov 0:fbdd0d307c19 514 * - Field rules: REQUIRED, OPTIONAL or REPEATED
sgnezdov 0:fbdd0d307c19 515 * - Allocation: STATIC, CALLBACK or POINTER
sgnezdov 0:fbdd0d307c19 516 * - Placement: FIRST or OTHER, depending on if this is the first field in structure.
sgnezdov 0:fbdd0d307c19 517 * - Message name
sgnezdov 0:fbdd0d307c19 518 * - Field name
sgnezdov 0:fbdd0d307c19 519 * - Previous field name (or field name again for first field)
sgnezdov 0:fbdd0d307c19 520 * - Pointer to default value or submsg fields.
sgnezdov 0:fbdd0d307c19 521 */
sgnezdov 0:fbdd0d307c19 522
sgnezdov 0:fbdd0d307c19 523 #define PB_FIELD(tag, type, rules, allocation, placement, message, field, prevfield, ptr) \
sgnezdov 0:fbdd0d307c19 524 PB_ ## rules ## _ ## allocation(tag, message, field, \
sgnezdov 0:fbdd0d307c19 525 PB_DATAOFFSET_ ## placement(message, field, prevfield), \
sgnezdov 0:fbdd0d307c19 526 PB_LTYPE_MAP_ ## type, ptr)
sgnezdov 0:fbdd0d307c19 527
sgnezdov 0:fbdd0d307c19 528 /* Field description for oneof fields. This requires taking into account the
sgnezdov 0:fbdd0d307c19 529 * union name also, that's why a separate set of macros is needed.
sgnezdov 0:fbdd0d307c19 530 */
sgnezdov 0:fbdd0d307c19 531 #define PB_ONEOF_STATIC(u, tag, st, m, fd, ltype, ptr) \
sgnezdov 0:fbdd0d307c19 532 {tag, PB_ATYPE_STATIC | PB_HTYPE_ONEOF | ltype, \
sgnezdov 0:fbdd0d307c19 533 fd, pb_delta(st, which_ ## u, u.m), \
sgnezdov 0:fbdd0d307c19 534 pb_membersize(st, u.m), 0, ptr}
sgnezdov 0:fbdd0d307c19 535
sgnezdov 0:fbdd0d307c19 536 #define PB_ONEOF_POINTER(u, tag, st, m, fd, ltype, ptr) \
sgnezdov 0:fbdd0d307c19 537 {tag, PB_ATYPE_POINTER | PB_HTYPE_ONEOF | ltype, \
sgnezdov 0:fbdd0d307c19 538 fd, pb_delta(st, which_ ## u, u.m), \
sgnezdov 0:fbdd0d307c19 539 pb_membersize(st, u.m[0]), 0, ptr}
sgnezdov 0:fbdd0d307c19 540
sgnezdov 0:fbdd0d307c19 541 #define PB_ONEOF_FIELD(union_name, tag, type, rules, allocation, placement, message, field, prevfield, ptr) \
sgnezdov 0:fbdd0d307c19 542 PB_ONEOF_ ## allocation(union_name, tag, message, field, \
sgnezdov 0:fbdd0d307c19 543 PB_DATAOFFSET_ ## placement(message, union_name.field, prevfield), \
sgnezdov 0:fbdd0d307c19 544 PB_LTYPE_MAP_ ## type, ptr)
sgnezdov 0:fbdd0d307c19 545
sgnezdov 0:fbdd0d307c19 546 #define PB_ANONYMOUS_ONEOF_STATIC(u, tag, st, m, fd, ltype, ptr) \
sgnezdov 0:fbdd0d307c19 547 {tag, PB_ATYPE_STATIC | PB_HTYPE_ONEOF | ltype, \
sgnezdov 0:fbdd0d307c19 548 fd, pb_delta(st, which_ ## u, m), \
sgnezdov 0:fbdd0d307c19 549 pb_membersize(st, m), 0, ptr}
sgnezdov 0:fbdd0d307c19 550
sgnezdov 0:fbdd0d307c19 551 #define PB_ANONYMOUS_ONEOF_POINTER(u, tag, st, m, fd, ltype, ptr) \
sgnezdov 0:fbdd0d307c19 552 {tag, PB_ATYPE_POINTER | PB_HTYPE_ONEOF | ltype, \
sgnezdov 0:fbdd0d307c19 553 fd, pb_delta(st, which_ ## u, m), \
sgnezdov 0:fbdd0d307c19 554 pb_membersize(st, m[0]), 0, ptr}
sgnezdov 0:fbdd0d307c19 555
sgnezdov 0:fbdd0d307c19 556 #define PB_ANONYMOUS_ONEOF_FIELD(union_name, tag, type, rules, allocation, placement, message, field, prevfield, ptr) \
sgnezdov 0:fbdd0d307c19 557 PB_ANONYMOUS_ONEOF_ ## allocation(union_name, tag, message, field, \
sgnezdov 0:fbdd0d307c19 558 PB_DATAOFFSET_ ## placement(message, field, prevfield), \
sgnezdov 0:fbdd0d307c19 559 PB_LTYPE_MAP_ ## type, ptr)
sgnezdov 0:fbdd0d307c19 560
sgnezdov 0:fbdd0d307c19 561 /* These macros are used for giving out error messages.
sgnezdov 0:fbdd0d307c19 562 * They are mostly a debugging aid; the main error information
sgnezdov 0:fbdd0d307c19 563 * is the true/false return value from functions.
sgnezdov 0:fbdd0d307c19 564 * Some code space can be saved by disabling the error
sgnezdov 0:fbdd0d307c19 565 * messages if not used.
sgnezdov 0:fbdd0d307c19 566 *
sgnezdov 0:fbdd0d307c19 567 * PB_SET_ERROR() sets the error message if none has been set yet.
sgnezdov 0:fbdd0d307c19 568 * msg must be a constant string literal.
sgnezdov 0:fbdd0d307c19 569 * PB_GET_ERROR() always returns a pointer to a string.
sgnezdov 0:fbdd0d307c19 570 * PB_RETURN_ERROR() sets the error and returns false from current
sgnezdov 0:fbdd0d307c19 571 * function.
sgnezdov 0:fbdd0d307c19 572 */
sgnezdov 0:fbdd0d307c19 573 #ifdef PB_NO_ERRMSG
sgnezdov 0:fbdd0d307c19 574 #define PB_SET_ERROR(stream, msg) PB_UNUSED(stream)
sgnezdov 0:fbdd0d307c19 575 #define PB_GET_ERROR(stream) "(errmsg disabled)"
sgnezdov 0:fbdd0d307c19 576 #else
sgnezdov 0:fbdd0d307c19 577 #define PB_SET_ERROR(stream, msg) (stream->errmsg = (stream)->errmsg ? (stream)->errmsg : (msg))
sgnezdov 0:fbdd0d307c19 578 #define PB_GET_ERROR(stream) ((stream)->errmsg ? (stream)->errmsg : "(none)")
sgnezdov 0:fbdd0d307c19 579 #endif
sgnezdov 0:fbdd0d307c19 580
sgnezdov 0:fbdd0d307c19 581 #define PB_RETURN_ERROR(stream, msg) return PB_SET_ERROR(stream, msg), false
sgnezdov 0:fbdd0d307c19 582
sgnezdov 0:fbdd0d307c19 583 #endif