Nanopb files

Dependents:   nanopb_V2 Message_generator LEX_Threaded_Programming_V3

Committer:
omatthews
Date:
Mon Aug 19 15:23:39 2019 +0000
Revision:
3:67ee10c4ae98
Parent:
2:d2c61a9be078
It works

Who changed what in which revision?

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