Petteri Aimonen | 0ed3158 | 2013-07-06 15:27:31 +0300 | [diff] [blame] | 1 | /* Common parts of the nanopb library. Most of these are quite low-level |
| 2 | * stuff. For the high-level interface, see pb_encode.h and pb_decode.h. |
| 3 | */ |
| 4 | |
Petteri Aimonen | be0b9e0 | 2014-08-18 21:11:10 +0300 | [diff] [blame] | 5 | #ifndef PB_H_INCLUDED |
| 6 | #define PB_H_INCLUDED |
Petteri Aimonen | 14bbe22 | 2011-07-25 20:42:48 +0000 | [diff] [blame] | 7 | |
Petteri Aimonen | 0ed3158 | 2013-07-06 15:27:31 +0300 | [diff] [blame] | 8 | /***************************************************************** |
| 9 | * Nanopb compilation time options. You can change these here by * |
| 10 | * uncommenting the lines, or on the compiler command line. * |
| 11 | *****************************************************************/ |
Petteri Aimonen | 842d526 | 2011-08-14 20:11:05 +0000 | [diff] [blame] | 12 | |
Petteri Aimonen | 607cb99 | 2014-03-17 17:25:58 +0200 | [diff] [blame] | 13 | /* Enable support for dynamically allocated fields */ |
| 14 | /* #define PB_ENABLE_MALLOC 1 */ |
| 15 | |
Petteri Aimonen | cfc517f | 2014-12-22 20:52:40 +0200 | [diff] [blame] | 16 | /* Define this if your CPU / compiler combination does not support |
Petteri Aimonen | fc9381c | 2021-08-18 20:35:21 +0300 | [diff] [blame] | 17 | * unaligned memory access to packed structures. Note that packed |
| 18 | * structures are only used when requested in .proto options. */ |
Petteri Aimonen | cfc517f | 2014-12-22 20:52:40 +0200 | [diff] [blame] | 19 | /* #define PB_NO_PACKED_STRUCTS 1 */ |
| 20 | |
Petteri Aimonen | 0ed3158 | 2013-07-06 15:27:31 +0300 | [diff] [blame] | 21 | /* Increase the number of required fields that are tracked. |
| 22 | * A compiler warning will tell if you need this. */ |
| 23 | /* #define PB_MAX_REQUIRED_FIELDS 256 */ |
| 24 | |
Petteri Aimonen | 0ed3158 | 2013-07-06 15:27:31 +0300 | [diff] [blame] | 25 | /* Add support for tag numbers > 65536 and fields larger than 65536 bytes. */ |
| 26 | /* #define PB_FIELD_32BIT 1 */ |
| 27 | |
| 28 | /* Disable support for error messages in order to save some code space. */ |
| 29 | /* #define PB_NO_ERRMSG 1 */ |
| 30 | |
| 31 | /* Disable support for custom streams (support only memory buffers). */ |
| 32 | /* #define PB_BUFFER_ONLY 1 */ |
| 33 | |
Petteri Aimonen | 96062cc | 2019-12-18 08:54:46 +0200 | [diff] [blame] | 34 | /* Disable support for 64-bit datatypes, for compilers without int64_t |
| 35 | or to save some code space. */ |
| 36 | /* #define PB_WITHOUT_64BIT 1 */ |
| 37 | |
Pavol Rusnak | 2e3d39d | 2019-08-27 13:01:03 +0200 | [diff] [blame] | 38 | /* Don't encode scalar arrays as packed. This is only to be used when |
| 39 | * the decoder on the receiving side cannot process packed scalar arrays. |
| 40 | * Such example is older protobuf.js. */ |
| 41 | /* #define PB_ENCODE_ARRAYS_UNPACKED 1 */ |
| 42 | |
Petteri Aimonen | 511b708 | 2019-12-16 12:14:16 +0200 | [diff] [blame] | 43 | /* Enable conversion of doubles to floats for platforms that do not |
| 44 | * support 64-bit doubles. Most commonly AVR. */ |
| 45 | /* #define PB_CONVERT_DOUBLE_FLOAT 1 */ |
| 46 | |
Pavol Rusnak | c00d4c1 | 2019-12-16 23:44:50 +0100 | [diff] [blame] | 47 | /* Check whether incoming strings are valid UTF-8 sequences. Slows down |
| 48 | * the string processing slightly and slightly increases code size. */ |
| 49 | /* #define PB_VALIDATE_UTF8 1 */ |
| 50 | |
Petteri Aimonen | fc9381c | 2021-08-18 20:35:21 +0300 | [diff] [blame] | 51 | /* This can be defined if the platform is little-endian and has 8-bit bytes. |
| 52 | * Normally it is automatically detected based on __BYTE_ORDER__ macro. */ |
| 53 | /* #define PB_LITTLE_ENDIAN_8BIT 1 */ |
| 54 | |
Petteri Aimonen | 940d9f0 | 2022-03-29 13:45:37 +0300 | [diff] [blame] | 55 | /* Configure static assert mechanism. Instead of changing these, set your |
| 56 | * compiler to C11 standard mode if possible. */ |
| 57 | /* #define PB_C99_STATIC_ASSERT 1 */ |
| 58 | /* #define PB_NO_STATIC_ASSERT 1 */ |
| 59 | |
Petteri Aimonen | 0ed3158 | 2013-07-06 15:27:31 +0300 | [diff] [blame] | 60 | /****************************************************************** |
| 61 | * You usually don't need to change anything below this line. * |
| 62 | * Feel free to look around and use the defined macros, though. * |
| 63 | ******************************************************************/ |
| 64 | |
| 65 | |
| 66 | /* Version of the nanopb library. Just in case you want to check it in |
| 67 | * your own program. */ |
Petteri Aimonen | da21b5e | 2022-05-30 20:30:35 +0300 | [diff] [blame] | 68 | #define NANOPB_VERSION "nanopb-0.4.6" |
Petteri Aimonen | 08391f3 | 2012-10-29 19:15:34 +0200 | [diff] [blame] | 69 | |
Petteri Aimonen | 0ed3158 | 2013-07-06 15:27:31 +0300 | [diff] [blame] | 70 | /* Include all the system headers needed by nanopb. You will need the |
| 71 | * definitions of the following: |
| 72 | * - strlen, memcpy, memset functions |
Petteri Aimonen | fa45589 | 2016-01-27 18:53:26 +0200 | [diff] [blame] | 73 | * - [u]int_least8_t, uint_fast8_t, [u]int_least16_t, [u]int32_t, [u]int64_t |
Petteri Aimonen | 0ed3158 | 2013-07-06 15:27:31 +0300 | [diff] [blame] | 74 | * - size_t |
| 75 | * - bool |
| 76 | * |
| 77 | * If you don't have the standard header files, you can instead provide |
| 78 | * a custom header that defines or includes all this. In that case, |
| 79 | * define PB_SYSTEM_HEADER to the path of this file. |
| 80 | */ |
Petteri Aimonen | 03e5393 | 2013-03-09 14:56:34 +0200 | [diff] [blame] | 81 | #ifdef PB_SYSTEM_HEADER |
| 82 | #include PB_SYSTEM_HEADER |
| 83 | #else |
Petteri Aimonen | 14bbe22 | 2011-07-25 20:42:48 +0000 | [diff] [blame] | 84 | #include <stdint.h> |
Petteri Aimonen | ead3b73 | 2011-07-27 19:57:43 +0000 | [diff] [blame] | 85 | #include <stddef.h> |
Petteri Aimonen | 84304b3 | 2011-07-27 19:22:11 +0000 | [diff] [blame] | 86 | #include <stdbool.h> |
Petteri Aimonen | 03e5393 | 2013-03-09 14:56:34 +0200 | [diff] [blame] | 87 | #include <string.h> |
Petteri Aimonen | 2ac6e97 | 2017-05-05 07:34:28 +0300 | [diff] [blame] | 88 | #include <limits.h> |
Petteri Aimonen | 011a30a | 2014-02-24 21:09:25 +0200 | [diff] [blame] | 89 | |
| 90 | #ifdef PB_ENABLE_MALLOC |
| 91 | #include <stdlib.h> |
| 92 | #endif |
Petteri Aimonen | 03e5393 | 2013-03-09 14:56:34 +0200 | [diff] [blame] | 93 | #endif |
Petteri Aimonen | 84304b3 | 2011-07-27 19:22:11 +0000 | [diff] [blame] | 94 | |
Petteri Aimonen | 87319f6 | 2018-12-09 17:26:13 +0200 | [diff] [blame] | 95 | #ifdef __cplusplus |
| 96 | extern "C" { |
| 97 | #endif |
| 98 | |
Petteri Aimonen | 1396dce | 2013-03-13 15:22:00 +0200 | [diff] [blame] | 99 | /* Macro for defining packed structures (compiler dependent). |
| 100 | * This just reduces memory requirements, but is not required. |
| 101 | */ |
Petteri Aimonen | cfc517f | 2014-12-22 20:52:40 +0200 | [diff] [blame] | 102 | #if defined(PB_NO_PACKED_STRUCTS) |
| 103 | /* Disable struct packing */ |
| 104 | # define PB_PACKED_STRUCT_START |
| 105 | # define PB_PACKED_STRUCT_END |
| 106 | # define pb_packed |
| 107 | #elif defined(__GNUC__) || defined(__clang__) |
Petteri Aimonen | 1396dce | 2013-03-13 15:22:00 +0200 | [diff] [blame] | 108 | /* For GCC and clang */ |
| 109 | # define PB_PACKED_STRUCT_START |
| 110 | # define PB_PACKED_STRUCT_END |
| 111 | # define pb_packed __attribute__((packed)) |
Petteri Aimonen | 8611958 | 2014-05-30 13:45:48 +0300 | [diff] [blame] | 112 | #elif defined(__ICCARM__) || defined(__CC_ARM) |
| 113 | /* For IAR ARM and Keil MDK-ARM compilers */ |
Petteri Aimonen | 1396dce | 2013-03-13 15:22:00 +0200 | [diff] [blame] | 114 | # define PB_PACKED_STRUCT_START _Pragma("pack(push, 1)") |
| 115 | # define PB_PACKED_STRUCT_END _Pragma("pack(pop)") |
| 116 | # define pb_packed |
dch | 710465a | 2013-04-07 15:28:05 +0100 | [diff] [blame] | 117 | #elif defined(_MSC_VER) && (_MSC_VER >= 1500) |
Petteri Aimonen | 1396dce | 2013-03-13 15:22:00 +0200 | [diff] [blame] | 118 | /* For Microsoft Visual C++ */ |
| 119 | # define PB_PACKED_STRUCT_START __pragma(pack(push, 1)) |
| 120 | # define PB_PACKED_STRUCT_END __pragma(pack(pop)) |
| 121 | # define pb_packed |
Petteri Aimonen | 84304b3 | 2011-07-27 19:22:11 +0000 | [diff] [blame] | 122 | #else |
Petteri Aimonen | 1396dce | 2013-03-13 15:22:00 +0200 | [diff] [blame] | 123 | /* Unknown compiler */ |
| 124 | # define PB_PACKED_STRUCT_START |
| 125 | # define PB_PACKED_STRUCT_END |
| 126 | # define pb_packed |
Petteri Aimonen | 84304b3 | 2011-07-27 19:22:11 +0000 | [diff] [blame] | 127 | #endif |
Petteri Aimonen | 14bbe22 | 2011-07-25 20:42:48 +0000 | [diff] [blame] | 128 | |
Slavey Karadzhov | b0ecac8 | 2021-12-09 11:30:02 +0100 | [diff] [blame] | 129 | /* Detect endianness */ |
Petteri Aimonen | fc9381c | 2021-08-18 20:35:21 +0300 | [diff] [blame] | 130 | #ifndef PB_LITTLE_ENDIAN_8BIT |
| 131 | #if ((defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN) || \ |
| 132 | (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \ |
| 133 | defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || \ |
| 134 | defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || \ |
| 135 | defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM)) \ |
| 136 | && CHAR_BIT == 8 |
| 137 | #define PB_LITTLE_ENDIAN_8BIT 1 |
| 138 | #endif |
| 139 | #endif |
| 140 | |
Petteri Aimonen | 0ed3158 | 2013-07-06 15:27:31 +0300 | [diff] [blame] | 141 | /* Handly macro for suppressing unreferenced-parameter compiler warnings. */ |
Petteri Aimonen | 62b4a8e | 2014-08-18 20:49:48 +0300 | [diff] [blame] | 142 | #ifndef PB_UNUSED |
| 143 | #define PB_UNUSED(x) (void)(x) |
Petteri Aimonen | d1ca88d | 2012-04-18 20:15:36 +0300 | [diff] [blame] | 144 | #endif |
| 145 | |
Petteri Aimonen | 1f97edf | 2019-12-18 19:35:12 +0200 | [diff] [blame] | 146 | /* Harvard-architecture processors may need special attributes for storing |
| 147 | * field information in program memory. */ |
| 148 | #ifndef PB_PROGMEM |
| 149 | #ifdef __AVR__ |
| 150 | #include <avr/pgmspace.h> |
| 151 | #define PB_PROGMEM PROGMEM |
| 152 | #define PB_PROGMEM_READU32(x) pgm_read_dword(&x) |
| 153 | #else |
| 154 | #define PB_PROGMEM |
| 155 | #define PB_PROGMEM_READU32(x) (x) |
| 156 | #endif |
| 157 | #endif |
| 158 | |
Petteri Aimonen | 59788e2 | 2012-11-16 09:33:11 +0200 | [diff] [blame] | 159 | /* Compile-time assertion, used for checking compatible compilation options. |
Petteri Aimonen | 62b4a8e | 2014-08-18 20:49:48 +0300 | [diff] [blame] | 160 | * If this does not work properly on your compiler, use |
| 161 | * #define PB_NO_STATIC_ASSERT to disable it. |
Petteri Aimonen | 879860b | 2014-02-04 20:34:57 +0200 | [diff] [blame] | 162 | * |
| 163 | * But before doing that, check carefully the error message / place where it |
| 164 | * comes from to see if the error has a real cause. Unfortunately the error |
| 165 | * message is not always very clear to read, but you can see the reason better |
Petteri Aimonen | 62b4a8e | 2014-08-18 20:49:48 +0300 | [diff] [blame] | 166 | * in the place where the PB_STATIC_ASSERT macro was called. |
Petteri Aimonen | 879860b | 2014-02-04 20:34:57 +0200 | [diff] [blame] | 167 | */ |
Petteri Aimonen | 62b4a8e | 2014-08-18 20:49:48 +0300 | [diff] [blame] | 168 | #ifndef PB_NO_STATIC_ASSERT |
Petteri Aimonen | 330a835 | 2018-12-02 16:06:31 +0200 | [diff] [blame] | 169 | # ifndef PB_STATIC_ASSERT |
ghseb | 9b773ef | 2021-06-15 14:02:47 +0200 | [diff] [blame] | 170 | # if defined(__ICCARM__) |
| 171 | /* IAR has static_assert keyword but no _Static_assert */ |
| 172 | # define PB_STATIC_ASSERT(COND,MSG) static_assert(COND,#MSG); |
Petteri Aimonen | d186833 | 2022-03-28 17:00:36 +0300 | [diff] [blame] | 173 | # elif defined(PB_C99_STATIC_ASSERT) |
Petteri Aimonen | 330a835 | 2018-12-02 16:06:31 +0200 | [diff] [blame] | 174 | /* Classic negative-size-array static assert mechanism */ |
| 175 | # define PB_STATIC_ASSERT(COND,MSG) typedef char PB_STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND)?1:-1]; |
| 176 | # define PB_STATIC_ASSERT_MSG(MSG, LINE, COUNTER) PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) |
| 177 | # define PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) pb_static_assertion_##MSG##_##LINE##_##COUNTER |
Petteri Aimonen | d186833 | 2022-03-28 17:00:36 +0300 | [diff] [blame] | 178 | # elif defined(__cplusplus) |
| 179 | /* C++11 standard static_assert mechanism */ |
| 180 | # define PB_STATIC_ASSERT(COND,MSG) static_assert(COND,#MSG); |
| 181 | # else |
| 182 | /* C11 standard _Static_assert mechanism */ |
| 183 | # define PB_STATIC_ASSERT(COND,MSG) _Static_assert(COND,#MSG); |
Petteri Aimonen | 330a835 | 2018-12-02 16:06:31 +0200 | [diff] [blame] | 184 | # endif |
| 185 | # endif |
Petteri Aimonen | 62b4a8e | 2014-08-18 20:49:48 +0300 | [diff] [blame] | 186 | #else |
Petteri Aimonen | 330a835 | 2018-12-02 16:06:31 +0200 | [diff] [blame] | 187 | /* Static asserts disabled by PB_NO_STATIC_ASSERT */ |
| 188 | # define PB_STATIC_ASSERT(COND,MSG) |
Petteri Aimonen | 78086cc | 2012-06-30 19:28:49 +0300 | [diff] [blame] | 189 | #endif |
| 190 | |
Petteri Aimonen | 940d9f0 | 2022-03-29 13:45:37 +0300 | [diff] [blame] | 191 | /* Test that PB_STATIC_ASSERT works |
| 192 | * If you get errors here, you may need to do one of these: |
| 193 | * - Enable C11 standard support in your compiler |
| 194 | * - Define PB_C99_STATIC_ASSERT to enable C99 standard support |
| 195 | * - Define PB_NO_STATIC_ASSERT to disable static asserts altogether |
| 196 | */ |
Petteri Aimonen | c3116cb | 2022-03-28 17:27:48 +0300 | [diff] [blame] | 197 | PB_STATIC_ASSERT(1, STATIC_ASSERT_IS_NOT_WORKING) |
| 198 | |
Petteri Aimonen | 0ed3158 | 2013-07-06 15:27:31 +0300 | [diff] [blame] | 199 | /* Number of required fields to keep track of. */ |
Petteri Aimonen | 95eb4a5 | 2012-06-30 18:10:08 +0300 | [diff] [blame] | 200 | #ifndef PB_MAX_REQUIRED_FIELDS |
| 201 | #define PB_MAX_REQUIRED_FIELDS 64 |
| 202 | #endif |
| 203 | |
Petteri Aimonen | 9b1e1b4 | 2012-07-01 10:15:37 +0300 | [diff] [blame] | 204 | #if PB_MAX_REQUIRED_FIELDS < 64 |
Petteri Aimonen | 72cca8d | 2012-07-05 18:19:38 +0300 | [diff] [blame] | 205 | #error You should not lower PB_MAX_REQUIRED_FIELDS from the default value (64). |
Petteri Aimonen | 9b1e1b4 | 2012-07-01 10:15:37 +0300 | [diff] [blame] | 206 | #endif |
| 207 | |
Petteri Aimonen | 96062cc | 2019-12-18 08:54:46 +0200 | [diff] [blame] | 208 | #ifdef PB_WITHOUT_64BIT |
| 209 | #ifdef PB_CONVERT_DOUBLE_FLOAT |
| 210 | /* Cannot use doubles without 64-bit types */ |
| 211 | #undef PB_CONVERT_DOUBLE_FLOAT |
| 212 | #endif |
| 213 | #endif |
| 214 | |
Petteri Aimonen | 842d526 | 2011-08-14 20:11:05 +0000 | [diff] [blame] | 215 | /* List of possible field types. These are used in the autogenerated code. |
Petteri Aimonen | 84304b3 | 2011-07-27 19:22:11 +0000 | [diff] [blame] | 216 | * Least-significant 4 bits tell the scalar type |
| 217 | * Most-significant 4 bits specify repeated/required/packed etc. |
Petteri Aimonen | 84304b3 | 2011-07-27 19:22:11 +0000 | [diff] [blame] | 218 | */ |
Petteri Aimonen | 14bbe22 | 2011-07-25 20:42:48 +0000 | [diff] [blame] | 219 | |
Petteri Aimonen | fa45589 | 2016-01-27 18:53:26 +0200 | [diff] [blame] | 220 | typedef uint_least8_t pb_type_t; |
Petteri Aimonen | ec4a7a0 | 2013-02-11 21:55:55 +0200 | [diff] [blame] | 221 | |
Petteri Aimonen | 0ed3158 | 2013-07-06 15:27:31 +0300 | [diff] [blame] | 222 | /**** Field data types ****/ |
Petteri Aimonen | ec4a7a0 | 2013-02-11 21:55:55 +0200 | [diff] [blame] | 223 | |
| 224 | /* Numeric types */ |
Torfinn Berset | df18328 | 2019-11-09 05:29:39 +0100 | [diff] [blame] | 225 | #define PB_LTYPE_BOOL 0x00U /* bool */ |
| 226 | #define PB_LTYPE_VARINT 0x01U /* int32, int64, enum, bool */ |
| 227 | #define PB_LTYPE_UVARINT 0x02U /* uint32, uint64 */ |
| 228 | #define PB_LTYPE_SVARINT 0x03U /* sint32, sint64 */ |
| 229 | #define PB_LTYPE_FIXED32 0x04U /* fixed32, sfixed32, float */ |
| 230 | #define PB_LTYPE_FIXED64 0x05U /* fixed64, sfixed64, double */ |
Petteri Aimonen | ec4a7a0 | 2013-02-11 21:55:55 +0200 | [diff] [blame] | 231 | |
| 232 | /* Marker for last packable field type. */ |
Torfinn Berset | df18328 | 2019-11-09 05:29:39 +0100 | [diff] [blame] | 233 | #define PB_LTYPE_LAST_PACKABLE 0x05U |
Petteri Aimonen | ec4a7a0 | 2013-02-11 21:55:55 +0200 | [diff] [blame] | 234 | |
| 235 | /* Byte array with pre-allocated buffer. |
| 236 | * data_size is the length of the allocated PB_BYTES_ARRAY structure. */ |
Torfinn Berset | df18328 | 2019-11-09 05:29:39 +0100 | [diff] [blame] | 237 | #define PB_LTYPE_BYTES 0x06U |
Petteri Aimonen | ec4a7a0 | 2013-02-11 21:55:55 +0200 | [diff] [blame] | 238 | |
| 239 | /* String with pre-allocated buffer. |
| 240 | * data_size is the maximum length. */ |
Torfinn Berset | df18328 | 2019-11-09 05:29:39 +0100 | [diff] [blame] | 241 | #define PB_LTYPE_STRING 0x07U |
Petteri Aimonen | ec4a7a0 | 2013-02-11 21:55:55 +0200 | [diff] [blame] | 242 | |
| 243 | /* Submessage |
| 244 | * submsg_fields is pointer to field descriptions */ |
Torfinn Berset | df18328 | 2019-11-09 05:29:39 +0100 | [diff] [blame] | 245 | #define PB_LTYPE_SUBMESSAGE 0x08U |
Petteri Aimonen | ec4a7a0 | 2013-02-11 21:55:55 +0200 | [diff] [blame] | 246 | |
Petteri Aimonen | b9c7bba | 2019-12-18 18:35:00 +0200 | [diff] [blame] | 247 | /* Submessage with pre-decoding callback |
| 248 | * The pre-decoding callback is stored as pb_callback_t right before pSize. |
| 249 | * submsg_fields is pointer to field descriptions */ |
| 250 | #define PB_LTYPE_SUBMSG_W_CB 0x09U |
| 251 | |
Petteri Aimonen | 7c5e184 | 2013-07-17 00:06:54 +0300 | [diff] [blame] | 252 | /* Extension pseudo-field |
| 253 | * The field contains a pointer to pb_extension_t */ |
Petteri Aimonen | b9c7bba | 2019-12-18 18:35:00 +0200 | [diff] [blame] | 254 | #define PB_LTYPE_EXTENSION 0x0AU |
Petteri Aimonen | 7c5e184 | 2013-07-17 00:06:54 +0300 | [diff] [blame] | 255 | |
Tom Roeder | 62afd54 | 2016-08-02 14:57:37 -0700 | [diff] [blame] | 256 | /* Byte array with inline, pre-allocated byffer. |
| 257 | * data_size is the length of the inline, allocated buffer. |
| 258 | * This differs from PB_LTYPE_BYTES by defining the element as |
| 259 | * pb_byte_t[data_size] rather than pb_bytes_array_t. */ |
Petteri Aimonen | b9c7bba | 2019-12-18 18:35:00 +0200 | [diff] [blame] | 260 | #define PB_LTYPE_FIXED_LENGTH_BYTES 0x0BU |
Tom Roeder | 62afd54 | 2016-08-02 14:57:37 -0700 | [diff] [blame] | 261 | |
Petteri Aimonen | ec4a7a0 | 2013-02-11 21:55:55 +0200 | [diff] [blame] | 262 | /* Number of declared LTYPES */ |
Petteri Aimonen | b9c7bba | 2019-12-18 18:35:00 +0200 | [diff] [blame] | 263 | #define PB_LTYPES_COUNT 0x0CU |
Torfinn Berset | df18328 | 2019-11-09 05:29:39 +0100 | [diff] [blame] | 264 | #define PB_LTYPE_MASK 0x0FU |
Petteri Aimonen | ec4a7a0 | 2013-02-11 21:55:55 +0200 | [diff] [blame] | 265 | |
Petteri Aimonen | 0ed3158 | 2013-07-06 15:27:31 +0300 | [diff] [blame] | 266 | /**** Field repetition rules ****/ |
Petteri Aimonen | ec4a7a0 | 2013-02-11 21:55:55 +0200 | [diff] [blame] | 267 | |
Torfinn Berset | df18328 | 2019-11-09 05:29:39 +0100 | [diff] [blame] | 268 | #define PB_HTYPE_REQUIRED 0x00U |
| 269 | #define PB_HTYPE_OPTIONAL 0x10U |
| 270 | #define PB_HTYPE_SINGULAR 0x10U |
| 271 | #define PB_HTYPE_REPEATED 0x20U |
| 272 | #define PB_HTYPE_FIXARRAY 0x20U |
| 273 | #define PB_HTYPE_ONEOF 0x30U |
| 274 | #define PB_HTYPE_MASK 0x30U |
Petteri Aimonen | ec4a7a0 | 2013-02-11 21:55:55 +0200 | [diff] [blame] | 275 | |
Petteri Aimonen | 0ed3158 | 2013-07-06 15:27:31 +0300 | [diff] [blame] | 276 | /**** Field allocation types ****/ |
David Sabatie | 81cae71 | 2021-07-23 18:04:47 +0200 | [diff] [blame] | 277 | |
Torfinn Berset | df18328 | 2019-11-09 05:29:39 +0100 | [diff] [blame] | 278 | #define PB_ATYPE_STATIC 0x00U |
| 279 | #define PB_ATYPE_POINTER 0x80U |
| 280 | #define PB_ATYPE_CALLBACK 0x40U |
| 281 | #define PB_ATYPE_MASK 0xC0U |
Petteri Aimonen | ec4a7a0 | 2013-02-11 21:55:55 +0200 | [diff] [blame] | 282 | |
Petteri Aimonen | 41f9834 | 2013-02-20 22:55:59 +0200 | [diff] [blame] | 283 | #define PB_ATYPE(x) ((x) & PB_ATYPE_MASK) |
Petteri Aimonen | b214de4 | 2012-09-03 17:35:14 +0300 | [diff] [blame] | 284 | #define PB_HTYPE(x) ((x) & PB_HTYPE_MASK) |
| 285 | #define PB_LTYPE(x) ((x) & PB_LTYPE_MASK) |
Petteri Aimonen | b9c7bba | 2019-12-18 18:35:00 +0200 | [diff] [blame] | 286 | #define PB_LTYPE_IS_SUBMSG(x) (PB_LTYPE(x) == PB_LTYPE_SUBMESSAGE || \ |
| 287 | PB_LTYPE(x) == PB_LTYPE_SUBMSG_W_CB) |
Petteri Aimonen | 84304b3 | 2011-07-27 19:22:11 +0000 | [diff] [blame] | 288 | |
Petteri Aimonen | 2bfd497 | 2013-10-20 21:49:55 +0300 | [diff] [blame] | 289 | /* Data type used for storing sizes of struct fields |
| 290 | * and array counts. |
| 291 | */ |
| 292 | #if defined(PB_FIELD_32BIT) |
| 293 | typedef uint32_t pb_size_t; |
| 294 | typedef int32_t pb_ssize_t; |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 295 | #else |
Petteri Aimonen | fa45589 | 2016-01-27 18:53:26 +0200 | [diff] [blame] | 296 | typedef uint_least16_t pb_size_t; |
| 297 | typedef int_least16_t pb_ssize_t; |
Petteri Aimonen | 2bfd497 | 2013-10-20 21:49:55 +0300 | [diff] [blame] | 298 | #endif |
Petteri Aimonen | fa45589 | 2016-01-27 18:53:26 +0200 | [diff] [blame] | 299 | #define PB_SIZE_MAX ((pb_size_t)-1) |
| 300 | |
| 301 | /* Data type for storing encoded data and other byte streams. |
| 302 | * This typedef exists to support platforms where uint8_t does not exist. |
| 303 | * You can regard it as equivalent on uint8_t on other platforms. |
| 304 | */ |
| 305 | typedef uint_least8_t pb_byte_t; |
Petteri Aimonen | 2bfd497 | 2013-10-20 21:49:55 +0300 | [diff] [blame] | 306 | |
Petteri Aimonen | e605e18 | 2018-12-06 21:33:21 +0200 | [diff] [blame] | 307 | /* Forward declaration of struct types */ |
| 308 | typedef struct pb_istream_s pb_istream_t; |
| 309 | typedef struct pb_ostream_s pb_ostream_t; |
| 310 | typedef struct pb_field_iter_s pb_field_iter_t; |
| 311 | |
Petteri Aimonen | 84304b3 | 2011-07-27 19:22:11 +0000 | [diff] [blame] | 312 | /* This structure is used in auto-generated constants |
| 313 | * to specify struct fields. |
Petteri Aimonen | 84304b3 | 2011-07-27 19:22:11 +0000 | [diff] [blame] | 314 | */ |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 315 | typedef struct pb_msgdesc_s pb_msgdesc_t; |
| 316 | struct pb_msgdesc_s { |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 317 | const uint32_t *field_info; |
Petteri Aimonen | 12a602f | 2019-12-15 18:47:12 +0200 | [diff] [blame] | 318 | const pb_msgdesc_t * const * submsg_info; |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 319 | const pb_byte_t *default_value; |
Petteri Aimonen | e605e18 | 2018-12-06 21:33:21 +0200 | [diff] [blame] | 320 | |
Petteri Aimonen | b71e4b7 | 2018-12-09 16:16:10 +0200 | [diff] [blame] | 321 | bool (*field_callback)(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_iter_t *field); |
Petteri Aimonen | afebd69 | 2020-06-24 13:46:47 +0300 | [diff] [blame] | 322 | |
| 323 | pb_size_t field_count; |
| 324 | pb_size_t required_field_count; |
| 325 | pb_size_t largest_tag; |
| 326 | }; |
Petteri Aimonen | 14bbe22 | 2011-07-25 20:42:48 +0000 | [diff] [blame] | 327 | |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 328 | /* Iterator for message descriptor */ |
| 329 | struct pb_field_iter_s { |
| 330 | const pb_msgdesc_t *descriptor; /* Pointer to message descriptor constant */ |
| 331 | void *message; /* Pointer to start of the structure */ |
| 332 | |
| 333 | pb_size_t index; /* Index of the field */ |
| 334 | pb_size_t field_info_index; /* Index to descriptor->field_info array */ |
| 335 | pb_size_t required_field_index; /* Index that counts only the required fields */ |
| 336 | pb_size_t submessage_index; /* Index that counts only submessages */ |
| 337 | |
| 338 | pb_size_t tag; /* Tag of current field */ |
| 339 | pb_size_t data_size; /* sizeof() of a single item */ |
| 340 | pb_size_t array_size; /* Number of array entries */ |
| 341 | pb_type_t type; /* Type of current field */ |
| 342 | |
| 343 | void *pField; /* Pointer to current field in struct */ |
| 344 | void *pData; /* Pointer to current data contents. Different than pField for arrays and pointers. */ |
| 345 | void *pSize; /* Pointer to count/has field */ |
| 346 | |
| 347 | const pb_msgdesc_t *submsg_desc; /* For submessage fields, pointer to field descriptor for the submessage. */ |
| 348 | }; |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 349 | |
| 350 | /* For compatibility with legacy code */ |
| 351 | typedef pb_field_iter_t pb_field_t; |
| 352 | |
Petteri Aimonen | e681dd0 | 2013-09-10 12:39:39 +0300 | [diff] [blame] | 353 | /* Make sure that the standard integer types are of the expected sizes. |
Petteri Aimonen | abdb594 | 2016-01-27 18:24:33 +0200 | [diff] [blame] | 354 | * Otherwise fixed32/fixed64 fields can break. |
Petteri Aimonen | 879860b | 2014-02-04 20:34:57 +0200 | [diff] [blame] | 355 | * |
| 356 | * If you get errors here, it probably means that your stdint.h is not |
| 357 | * correct for your platform. |
| 358 | */ |
Petteri Aimonen | c291fee | 2017-09-16 09:28:08 +0300 | [diff] [blame] | 359 | #ifndef PB_WITHOUT_64BIT |
Petteri Aimonen | abdb594 | 2016-01-27 18:24:33 +0200 | [diff] [blame] | 360 | PB_STATIC_ASSERT(sizeof(int64_t) == 2 * sizeof(int32_t), INT64_T_WRONG_SIZE) |
| 361 | PB_STATIC_ASSERT(sizeof(uint64_t) == 2 * sizeof(uint32_t), UINT64_T_WRONG_SIZE) |
Petteri Aimonen | c291fee | 2017-09-16 09:28:08 +0300 | [diff] [blame] | 362 | #endif |
Petteri Aimonen | e681dd0 | 2013-09-10 12:39:39 +0300 | [diff] [blame] | 363 | |
Petteri Aimonen | ead3b73 | 2011-07-27 19:57:43 +0000 | [diff] [blame] | 364 | /* This structure is used for 'bytes' arrays. |
Petteri Aimonen | a8d0172 | 2011-08-04 16:49:32 +0000 | [diff] [blame] | 365 | * It has the number of bytes in the beginning, and after that an array. |
| 366 | * Note that actual structs used will have a different length of bytes array. |
| 367 | */ |
Petteri Aimonen | fa45589 | 2016-01-27 18:53:26 +0200 | [diff] [blame] | 368 | #define PB_BYTES_ARRAY_T(n) struct { pb_size_t size; pb_byte_t bytes[n]; } |
Petteri Aimonen | 9be2cfe | 2014-03-15 08:45:58 +0200 | [diff] [blame] | 369 | #define PB_BYTES_ARRAY_T_ALLOCSIZE(n) ((size_t)n + offsetof(pb_bytes_array_t, bytes)) |
| 370 | |
Petteri Aimonen | be0b9e0 | 2014-08-18 21:11:10 +0300 | [diff] [blame] | 371 | struct pb_bytes_array_s { |
Petteri Aimonen | 1dd9f19 | 2014-08-18 20:09:52 +0300 | [diff] [blame] | 372 | pb_size_t size; |
Petteri Aimonen | fa45589 | 2016-01-27 18:53:26 +0200 | [diff] [blame] | 373 | pb_byte_t bytes[1]; |
Petteri Aimonen | c3fa362 | 2012-10-29 16:56:45 +0200 | [diff] [blame] | 374 | }; |
Petteri Aimonen | be0b9e0 | 2014-08-18 21:11:10 +0300 | [diff] [blame] | 375 | typedef struct pb_bytes_array_s pb_bytes_array_t; |
Petteri Aimonen | 14bbe22 | 2011-07-25 20:42:48 +0000 | [diff] [blame] | 376 | |
Petteri Aimonen | ead3b73 | 2011-07-27 19:57:43 +0000 | [diff] [blame] | 377 | /* This structure is used for giving the callback function. |
| 378 | * It is stored in the message structure and filled in by the method that |
| 379 | * calls pb_decode. |
| 380 | * |
| 381 | * The decoding callback will be given a limited-length stream |
| 382 | * If the wire type was string, the length is the length of the string. |
| 383 | * If the wire type was a varint/fixed32/fixed64, the length is the length |
| 384 | * of the actual value. |
| 385 | * The function may be called multiple times (especially for repeated types, |
| 386 | * but also otherwise if the message happens to contain the field multiple |
| 387 | * times.) |
| 388 | * |
| 389 | * The encoding callback will receive the actual output stream. |
| 390 | * It should write all the data in one call, including the field tag and |
| 391 | * wire type. It can write multiple fields. |
Petteri Aimonen | 7f53c3f | 2011-08-17 19:03:06 +0000 | [diff] [blame] | 392 | * |
| 393 | * The callback can be null if you want to skip a field. |
Petteri Aimonen | ead3b73 | 2011-07-27 19:57:43 +0000 | [diff] [blame] | 394 | */ |
Petteri Aimonen | be0b9e0 | 2014-08-18 21:11:10 +0300 | [diff] [blame] | 395 | typedef struct pb_callback_s pb_callback_t; |
| 396 | struct pb_callback_s { |
Petteri Aimonen | b9c7bba | 2019-12-18 18:35:00 +0200 | [diff] [blame] | 397 | /* Callback functions receive a pointer to the arg field. |
| 398 | * You can access the value of the field as *arg, and modify it if needed. |
| 399 | */ |
Petteri Aimonen | 214b0ea | 2013-04-02 19:55:21 +0300 | [diff] [blame] | 400 | union { |
| 401 | bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void **arg); |
| 402 | bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, void * const *arg); |
| 403 | } funcs; |
David Sabatie | 81cae71 | 2021-07-23 18:04:47 +0200 | [diff] [blame] | 404 | |
Petteri Aimonen | ead3b73 | 2011-07-27 19:57:43 +0000 | [diff] [blame] | 405 | /* Free arg for use by callback */ |
Petteri Aimonen | 14bbe22 | 2011-07-25 20:42:48 +0000 | [diff] [blame] | 406 | void *arg; |
| 407 | }; |
| 408 | |
Petteri Aimonen | b71e4b7 | 2018-12-09 16:16:10 +0200 | [diff] [blame] | 409 | extern bool pb_default_field_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_t *field); |
Petteri Aimonen | e605e18 | 2018-12-06 21:33:21 +0200 | [diff] [blame] | 410 | |
Petteri Aimonen | 842d526 | 2011-08-14 20:11:05 +0000 | [diff] [blame] | 411 | /* Wire types. Library user needs these only in encoder callbacks. */ |
| 412 | typedef enum { |
| 413 | PB_WT_VARINT = 0, |
| 414 | PB_WT_64BIT = 1, |
| 415 | PB_WT_STRING = 2, |
Petteri Aimonen | 27f252b | 2021-06-03 12:08:50 +0300 | [diff] [blame] | 416 | PB_WT_32BIT = 5, |
| 417 | PB_WT_PACKED = 255 /* PB_WT_PACKED is internal marker for packed arrays. */ |
Petteri Aimonen | 842d526 | 2011-08-14 20:11:05 +0000 | [diff] [blame] | 418 | } pb_wire_type_t; |
| 419 | |
Petteri Aimonen | 7c5e184 | 2013-07-17 00:06:54 +0300 | [diff] [blame] | 420 | /* Structure for defining the handling of unknown/extension fields. |
| 421 | * Usually the pb_extension_type_t structure is automatically generated, |
| 422 | * while the pb_extension_t structure is created by the user. However, |
| 423 | * if you want to catch all unknown fields, you can also create a custom |
| 424 | * pb_extension_type_t with your own callback. |
| 425 | */ |
Petteri Aimonen | be0b9e0 | 2014-08-18 21:11:10 +0300 | [diff] [blame] | 426 | typedef struct pb_extension_type_s pb_extension_type_t; |
| 427 | typedef struct pb_extension_s pb_extension_t; |
| 428 | struct pb_extension_type_s { |
Petteri Aimonen | 7c5e184 | 2013-07-17 00:06:54 +0300 | [diff] [blame] | 429 | /* Called for each unknown field in the message. |
| 430 | * If you handle the field, read off all of its data and return true. |
| 431 | * If you do not handle the field, do not read anything and return true. |
| 432 | * If you run into an error, return false. |
| 433 | * Set to NULL for default handler. |
| 434 | */ |
| 435 | bool (*decode)(pb_istream_t *stream, pb_extension_t *extension, |
| 436 | uint32_t tag, pb_wire_type_t wire_type); |
David Sabatie | 81cae71 | 2021-07-23 18:04:47 +0200 | [diff] [blame] | 437 | |
Petteri Aimonen | 7c5e184 | 2013-07-17 00:06:54 +0300 | [diff] [blame] | 438 | /* Called once after all regular fields have been encoded. |
| 439 | * If you have something to write, do so and return true. |
| 440 | * If you do not have anything to write, just return true. |
| 441 | * If you run into an error, return false. |
| 442 | * Set to NULL for default handler. |
| 443 | */ |
Petteri Aimonen | ebddda9 | 2013-07-17 19:23:19 +0300 | [diff] [blame] | 444 | bool (*encode)(pb_ostream_t *stream, const pb_extension_t *extension); |
David Sabatie | 81cae71 | 2021-07-23 18:04:47 +0200 | [diff] [blame] | 445 | |
Petteri Aimonen | 7c5e184 | 2013-07-17 00:06:54 +0300 | [diff] [blame] | 446 | /* Free field for use by the callback. */ |
| 447 | const void *arg; |
| 448 | }; |
| 449 | |
Petteri Aimonen | be0b9e0 | 2014-08-18 21:11:10 +0300 | [diff] [blame] | 450 | struct pb_extension_s { |
Petteri Aimonen | 7c5e184 | 2013-07-17 00:06:54 +0300 | [diff] [blame] | 451 | /* Type describing the extension field. Usually you'll initialize |
| 452 | * this to a pointer to the automatically generated structure. */ |
| 453 | const pb_extension_type_t *type; |
David Sabatie | 81cae71 | 2021-07-23 18:04:47 +0200 | [diff] [blame] | 454 | |
Petteri Aimonen | 7c5e184 | 2013-07-17 00:06:54 +0300 | [diff] [blame] | 455 | /* Destination for the decoded data. This must match the datatype |
| 456 | * of the extension field. */ |
| 457 | void *dest; |
David Sabatie | 81cae71 | 2021-07-23 18:04:47 +0200 | [diff] [blame] | 458 | |
Petteri Aimonen | 7c5e184 | 2013-07-17 00:06:54 +0300 | [diff] [blame] | 459 | /* Pointer to the next extension handler, or NULL. |
| 460 | * If this extension does not match a field, the next handler is |
| 461 | * automatically called. */ |
| 462 | pb_extension_t *next; |
Petteri Aimonen | e5b855f | 2014-04-05 11:11:05 +0300 | [diff] [blame] | 463 | |
| 464 | /* The decoder sets this to true if the extension was found. |
| 465 | * Ignored for encoding. */ |
| 466 | bool found; |
Petteri Aimonen | 7c5e184 | 2013-07-17 00:06:54 +0300 | [diff] [blame] | 467 | }; |
| 468 | |
Petteri Aimonen | 8d1dde5 | 2019-12-18 20:33:52 +0200 | [diff] [blame] | 469 | #define pb_extension_init_zero {NULL,NULL,NULL,false} |
| 470 | |
Petteri Aimonen | 607cb99 | 2014-03-17 17:25:58 +0200 | [diff] [blame] | 471 | /* Memory allocation functions to use. You can define pb_realloc and |
| 472 | * pb_free to custom functions if you want. */ |
| 473 | #ifdef PB_ENABLE_MALLOC |
| 474 | # ifndef pb_realloc |
| 475 | # define pb_realloc(ptr, size) realloc(ptr, size) |
| 476 | # endif |
| 477 | # ifndef pb_free |
| 478 | # define pb_free(ptr) free(ptr) |
| 479 | # endif |
| 480 | #endif |
| 481 | |
Petteri Aimonen | 3ed2193 | 2014-08-19 17:55:44 +0300 | [diff] [blame] | 482 | /* This is used to inform about need to regenerate .pb.h/.pb.c files. */ |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 483 | #define PB_PROTO_HEADER_VERSION 40 |
Petteri Aimonen | 3ed2193 | 2014-08-19 17:55:44 +0300 | [diff] [blame] | 484 | |
Petteri Aimonen | f836431 | 2011-07-30 09:59:08 +0000 | [diff] [blame] | 485 | /* These macros are used to declare pb_field_t's in the constant array. */ |
Petteri Aimonen | 840e213 | 2013-09-11 09:53:51 +0300 | [diff] [blame] | 486 | /* Size of a structure member, in bytes. */ |
Petteri Aimonen | f836431 | 2011-07-30 09:59:08 +0000 | [diff] [blame] | 487 | #define pb_membersize(st, m) (sizeof ((st*)0)->m) |
Petteri Aimonen | 840e213 | 2013-09-11 09:53:51 +0300 | [diff] [blame] | 488 | /* Number of entries in an array. */ |
Petteri Aimonen | f836431 | 2011-07-30 09:59:08 +0000 | [diff] [blame] | 489 | #define pb_arraysize(st, m) (pb_membersize(st, m) / pb_membersize(st, m[0])) |
Petteri Aimonen | 840e213 | 2013-09-11 09:53:51 +0300 | [diff] [blame] | 490 | /* Delta from start of one member to the start of another member. */ |
Petteri Aimonen | f836431 | 2011-07-30 09:59:08 +0000 | [diff] [blame] | 491 | #define pb_delta(st, m1, m2) ((int)offsetof(st, m1) - (int)offsetof(st, m2)) |
Petteri Aimonen | f836431 | 2011-07-30 09:59:08 +0000 | [diff] [blame] | 492 | |
Petteri Aimonen | 5acd377 | 2019-01-30 15:22:55 +0200 | [diff] [blame] | 493 | /* Force expansion of macro value */ |
| 494 | #define PB_EXPAND(x) x |
| 495 | |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 496 | /* Binding of a message field set into a specific structure */ |
| 497 | #define PB_BIND(msgname, structname, width) \ |
Petteri Aimonen | 1f97edf | 2019-12-18 19:35:12 +0200 | [diff] [blame] | 498 | const uint32_t structname ## _field_info[] PB_PROGMEM = \ |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 499 | { \ |
| 500 | msgname ## _FIELDLIST(PB_GEN_FIELD_INFO_ ## width, structname) \ |
| 501 | 0 \ |
| 502 | }; \ |
Petteri Aimonen | 12a602f | 2019-12-15 18:47:12 +0200 | [diff] [blame] | 503 | const pb_msgdesc_t* const structname ## _submsg_info[] = \ |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 504 | { \ |
| 505 | msgname ## _FIELDLIST(PB_GEN_SUBMSG_INFO, structname) \ |
| 506 | NULL \ |
| 507 | }; \ |
| 508 | const pb_msgdesc_t structname ## _msg = \ |
| 509 | { \ |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 510 | structname ## _field_info, \ |
| 511 | structname ## _submsg_info, \ |
Petteri Aimonen | b2d04df | 2019-01-25 18:42:58 +0200 | [diff] [blame] | 512 | msgname ## _DEFAULT, \ |
Petteri Aimonen | 87319f6 | 2018-12-09 17:26:13 +0200 | [diff] [blame] | 513 | msgname ## _CALLBACK, \ |
Petteri Aimonen | afebd69 | 2020-06-24 13:46:47 +0300 | [diff] [blame] | 514 | 0 msgname ## _FIELDLIST(PB_GEN_FIELD_COUNT, structname), \ |
| 515 | 0 msgname ## _FIELDLIST(PB_GEN_REQ_FIELD_COUNT, structname), \ |
| 516 | 0 msgname ## _FIELDLIST(PB_GEN_LARGEST_TAG, structname), \ |
Petteri Aimonen | 330a835 | 2018-12-02 16:06:31 +0200 | [diff] [blame] | 517 | }; \ |
| 518 | msgname ## _FIELDLIST(PB_GEN_FIELD_INFO_ASSERT_ ## width, structname) |
Petteri Aimonen | 9ada7e7 | 2013-09-13 11:30:58 +0300 | [diff] [blame] | 519 | |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 520 | #define PB_GEN_FIELD_COUNT(structname, atype, htype, ltype, fieldname, tag) +1 |
Petteri Aimonen | afebd69 | 2020-06-24 13:46:47 +0300 | [diff] [blame] | 521 | #define PB_GEN_REQ_FIELD_COUNT(structname, atype, htype, ltype, fieldname, tag) \ |
| 522 | + (PB_HTYPE_ ## htype == PB_HTYPE_REQUIRED) |
| 523 | #define PB_GEN_LARGEST_TAG(structname, atype, htype, ltype, fieldname, tag) \ |
| 524 | * 0 + tag |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 525 | |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 526 | /* X-macro for generating the entries in struct_field_info[] array. */ |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 527 | #define PB_GEN_FIELD_INFO_1(structname, atype, htype, ltype, fieldname, tag) \ |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 528 | PB_FIELDINFO_1(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ |
| 529 | PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 530 | PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 531 | PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 532 | PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 533 | |
| 534 | #define PB_GEN_FIELD_INFO_2(structname, atype, htype, ltype, fieldname, tag) \ |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 535 | PB_FIELDINFO_2(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ |
| 536 | PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 537 | PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 538 | PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 539 | PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 540 | |
| 541 | #define PB_GEN_FIELD_INFO_4(structname, atype, htype, ltype, fieldname, tag) \ |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 542 | PB_FIELDINFO_4(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ |
| 543 | PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 544 | PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 545 | PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 546 | PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 547 | |
| 548 | #define PB_GEN_FIELD_INFO_8(structname, atype, htype, ltype, fieldname, tag) \ |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 549 | PB_FIELDINFO_8(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ |
| 550 | PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 551 | PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 552 | PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 553 | PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 554 | |
| 555 | #define PB_GEN_FIELD_INFO_AUTO(structname, atype, htype, ltype, fieldname, tag) \ |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 556 | PB_FIELDINFO_AUTO2(PB_FIELDINFO_WIDTH_AUTO(_PB_ATYPE_ ## atype, _PB_HTYPE_ ## htype, _PB_LTYPE_ ## ltype), \ |
| 557 | tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ |
| 558 | PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 559 | PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 560 | PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 561 | PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 562 | |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 563 | #define PB_FIELDINFO_AUTO2(width, tag, type, data_offset, data_size, size_offset, array_size) \ |
| 564 | PB_FIELDINFO_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 565 | |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 566 | #define PB_FIELDINFO_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) \ |
| 567 | PB_FIELDINFO_ ## width(tag, type, data_offset, data_size, size_offset, array_size) |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 568 | |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 569 | /* X-macro for generating asserts that entries fit in struct_field_info[] array. |
| 570 | * The structure of macros here must match the structure above in PB_GEN_FIELD_INFO_x(), |
| 571 | * but it is not easily reused because of how macro substitutions work. */ |
Petteri Aimonen | 330a835 | 2018-12-02 16:06:31 +0200 | [diff] [blame] | 572 | #define PB_GEN_FIELD_INFO_ASSERT_1(structname, atype, htype, ltype, fieldname, tag) \ |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 573 | PB_FIELDINFO_ASSERT_1(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ |
| 574 | PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 575 | PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 576 | PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 577 | PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) |
Petteri Aimonen | 330a835 | 2018-12-02 16:06:31 +0200 | [diff] [blame] | 578 | |
| 579 | #define PB_GEN_FIELD_INFO_ASSERT_2(structname, atype, htype, ltype, fieldname, tag) \ |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 580 | PB_FIELDINFO_ASSERT_2(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ |
| 581 | PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 582 | PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 583 | PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 584 | PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) |
Petteri Aimonen | 330a835 | 2018-12-02 16:06:31 +0200 | [diff] [blame] | 585 | |
| 586 | #define PB_GEN_FIELD_INFO_ASSERT_4(structname, atype, htype, ltype, fieldname, tag) \ |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 587 | PB_FIELDINFO_ASSERT_4(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ |
| 588 | PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 589 | PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 590 | PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 591 | PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) |
Petteri Aimonen | 330a835 | 2018-12-02 16:06:31 +0200 | [diff] [blame] | 592 | |
| 593 | #define PB_GEN_FIELD_INFO_ASSERT_8(structname, atype, htype, ltype, fieldname, tag) \ |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 594 | PB_FIELDINFO_ASSERT_8(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ |
| 595 | PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 596 | PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 597 | PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 598 | PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) |
Petteri Aimonen | 330a835 | 2018-12-02 16:06:31 +0200 | [diff] [blame] | 599 | |
| 600 | #define PB_GEN_FIELD_INFO_ASSERT_AUTO(structname, atype, htype, ltype, fieldname, tag) \ |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 601 | PB_FIELDINFO_ASSERT_AUTO2(PB_FIELDINFO_WIDTH_AUTO(_PB_ATYPE_ ## atype, _PB_HTYPE_ ## htype, _PB_LTYPE_ ## ltype), \ |
| 602 | tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ |
| 603 | PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 604 | PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 605 | PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ |
| 606 | PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) |
Petteri Aimonen | 330a835 | 2018-12-02 16:06:31 +0200 | [diff] [blame] | 607 | |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 608 | #define PB_FIELDINFO_ASSERT_AUTO2(width, tag, type, data_offset, data_size, size_offset, array_size) \ |
| 609 | PB_FIELDINFO_ASSERT_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) |
Petteri Aimonen | 330a835 | 2018-12-02 16:06:31 +0200 | [diff] [blame] | 610 | |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 611 | #define PB_FIELDINFO_ASSERT_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) \ |
| 612 | PB_FIELDINFO_ASSERT_ ## width(tag, type, data_offset, data_size, size_offset, array_size) |
Petteri Aimonen | 330a835 | 2018-12-02 16:06:31 +0200 | [diff] [blame] | 613 | |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 614 | #define PB_DATA_OFFSET_STATIC(htype, structname, fieldname) PB_DO ## htype(structname, fieldname) |
| 615 | #define PB_DATA_OFFSET_POINTER(htype, structname, fieldname) PB_DO ## htype(structname, fieldname) |
| 616 | #define PB_DATA_OFFSET_CALLBACK(htype, structname, fieldname) PB_DO ## htype(structname, fieldname) |
| 617 | #define PB_DO_PB_HTYPE_REQUIRED(structname, fieldname) offsetof(structname, fieldname) |
| 618 | #define PB_DO_PB_HTYPE_SINGULAR(structname, fieldname) offsetof(structname, fieldname) |
| 619 | #define PB_DO_PB_HTYPE_ONEOF(structname, fieldname) offsetof(structname, PB_ONEOF_NAME(FULL, fieldname)) |
| 620 | #define PB_DO_PB_HTYPE_OPTIONAL(structname, fieldname) offsetof(structname, fieldname) |
| 621 | #define PB_DO_PB_HTYPE_REPEATED(structname, fieldname) offsetof(structname, fieldname) |
| 622 | #define PB_DO_PB_HTYPE_FIXARRAY(structname, fieldname) offsetof(structname, fieldname) |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 623 | |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 624 | #define PB_SIZE_OFFSET_STATIC(htype, structname, fieldname) PB_SO ## htype(structname, fieldname) |
| 625 | #define PB_SIZE_OFFSET_POINTER(htype, structname, fieldname) PB_SO_PTR ## htype(structname, fieldname) |
| 626 | #define PB_SIZE_OFFSET_CALLBACK(htype, structname, fieldname) PB_SO_CB ## htype(structname, fieldname) |
| 627 | #define PB_SO_PB_HTYPE_REQUIRED(structname, fieldname) 0 |
| 628 | #define PB_SO_PB_HTYPE_SINGULAR(structname, fieldname) 0 |
| 629 | #define PB_SO_PB_HTYPE_ONEOF(structname, fieldname) PB_SO_PB_HTYPE_ONEOF2(structname, PB_ONEOF_NAME(FULL, fieldname), PB_ONEOF_NAME(UNION, fieldname)) |
| 630 | #define PB_SO_PB_HTYPE_ONEOF2(structname, fullname, unionname) PB_SO_PB_HTYPE_ONEOF3(structname, fullname, unionname) |
| 631 | #define PB_SO_PB_HTYPE_ONEOF3(structname, fullname, unionname) pb_delta(structname, fullname, which_ ## unionname) |
| 632 | #define PB_SO_PB_HTYPE_OPTIONAL(structname, fieldname) pb_delta(structname, fieldname, has_ ## fieldname) |
| 633 | #define PB_SO_PB_HTYPE_REPEATED(structname, fieldname) pb_delta(structname, fieldname, fieldname ## _count) |
| 634 | #define PB_SO_PB_HTYPE_FIXARRAY(structname, fieldname) 0 |
| 635 | #define PB_SO_PTR_PB_HTYPE_REQUIRED(structname, fieldname) 0 |
| 636 | #define PB_SO_PTR_PB_HTYPE_SINGULAR(structname, fieldname) 0 |
| 637 | #define PB_SO_PTR_PB_HTYPE_ONEOF(structname, fieldname) PB_SO_PB_HTYPE_ONEOF(structname, fieldname) |
| 638 | #define PB_SO_PTR_PB_HTYPE_OPTIONAL(structname, fieldname) 0 |
| 639 | #define PB_SO_PTR_PB_HTYPE_REPEATED(structname, fieldname) PB_SO_PB_HTYPE_REPEATED(structname, fieldname) |
| 640 | #define PB_SO_PTR_PB_HTYPE_FIXARRAY(structname, fieldname) 0 |
| 641 | #define PB_SO_CB_PB_HTYPE_REQUIRED(structname, fieldname) 0 |
| 642 | #define PB_SO_CB_PB_HTYPE_SINGULAR(structname, fieldname) 0 |
| 643 | #define PB_SO_CB_PB_HTYPE_ONEOF(structname, fieldname) PB_SO_PB_HTYPE_ONEOF(structname, fieldname) |
| 644 | #define PB_SO_CB_PB_HTYPE_OPTIONAL(structname, fieldname) 0 |
| 645 | #define PB_SO_CB_PB_HTYPE_REPEATED(structname, fieldname) 0 |
| 646 | #define PB_SO_CB_PB_HTYPE_FIXARRAY(structname, fieldname) 0 |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 647 | |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 648 | #define PB_ARRAY_SIZE_STATIC(htype, structname, fieldname) PB_AS ## htype(structname, fieldname) |
| 649 | #define PB_ARRAY_SIZE_POINTER(htype, structname, fieldname) PB_AS_PTR ## htype(structname, fieldname) |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 650 | #define PB_ARRAY_SIZE_CALLBACK(htype, structname, fieldname) 1 |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 651 | #define PB_AS_PB_HTYPE_REQUIRED(structname, fieldname) 1 |
| 652 | #define PB_AS_PB_HTYPE_SINGULAR(structname, fieldname) 1 |
| 653 | #define PB_AS_PB_HTYPE_OPTIONAL(structname, fieldname) 1 |
| 654 | #define PB_AS_PB_HTYPE_ONEOF(structname, fieldname) 1 |
| 655 | #define PB_AS_PB_HTYPE_REPEATED(structname, fieldname) pb_arraysize(structname, fieldname) |
| 656 | #define PB_AS_PB_HTYPE_FIXARRAY(structname, fieldname) pb_arraysize(structname, fieldname) |
| 657 | #define PB_AS_PTR_PB_HTYPE_REQUIRED(structname, fieldname) 1 |
| 658 | #define PB_AS_PTR_PB_HTYPE_SINGULAR(structname, fieldname) 1 |
| 659 | #define PB_AS_PTR_PB_HTYPE_OPTIONAL(structname, fieldname) 1 |
| 660 | #define PB_AS_PTR_PB_HTYPE_ONEOF(structname, fieldname) 1 |
| 661 | #define PB_AS_PTR_PB_HTYPE_REPEATED(structname, fieldname) 1 |
| 662 | #define PB_AS_PTR_PB_HTYPE_FIXARRAY(structname, fieldname) pb_arraysize(structname, fieldname[0]) |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 663 | |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 664 | #define PB_DATA_SIZE_STATIC(htype, structname, fieldname) PB_DS ## htype(structname, fieldname) |
| 665 | #define PB_DATA_SIZE_POINTER(htype, structname, fieldname) PB_DS_PTR ## htype(structname, fieldname) |
| 666 | #define PB_DATA_SIZE_CALLBACK(htype, structname, fieldname) PB_DS_CB ## htype(structname, fieldname) |
| 667 | #define PB_DS_PB_HTYPE_REQUIRED(structname, fieldname) pb_membersize(structname, fieldname) |
| 668 | #define PB_DS_PB_HTYPE_SINGULAR(structname, fieldname) pb_membersize(structname, fieldname) |
| 669 | #define PB_DS_PB_HTYPE_OPTIONAL(structname, fieldname) pb_membersize(structname, fieldname) |
| 670 | #define PB_DS_PB_HTYPE_ONEOF(structname, fieldname) pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname)) |
| 671 | #define PB_DS_PB_HTYPE_REPEATED(structname, fieldname) pb_membersize(structname, fieldname[0]) |
| 672 | #define PB_DS_PB_HTYPE_FIXARRAY(structname, fieldname) pb_membersize(structname, fieldname[0]) |
| 673 | #define PB_DS_PTR_PB_HTYPE_REQUIRED(structname, fieldname) pb_membersize(structname, fieldname[0]) |
| 674 | #define PB_DS_PTR_PB_HTYPE_SINGULAR(structname, fieldname) pb_membersize(structname, fieldname[0]) |
| 675 | #define PB_DS_PTR_PB_HTYPE_OPTIONAL(structname, fieldname) pb_membersize(structname, fieldname[0]) |
| 676 | #define PB_DS_PTR_PB_HTYPE_ONEOF(structname, fieldname) pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname)[0]) |
| 677 | #define PB_DS_PTR_PB_HTYPE_REPEATED(structname, fieldname) pb_membersize(structname, fieldname[0]) |
| 678 | #define PB_DS_PTR_PB_HTYPE_FIXARRAY(structname, fieldname) pb_membersize(structname, fieldname[0][0]) |
| 679 | #define PB_DS_CB_PB_HTYPE_REQUIRED(structname, fieldname) pb_membersize(structname, fieldname) |
| 680 | #define PB_DS_CB_PB_HTYPE_SINGULAR(structname, fieldname) pb_membersize(structname, fieldname) |
| 681 | #define PB_DS_CB_PB_HTYPE_OPTIONAL(structname, fieldname) pb_membersize(structname, fieldname) |
| 682 | #define PB_DS_CB_PB_HTYPE_ONEOF(structname, fieldname) pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname)) |
| 683 | #define PB_DS_CB_PB_HTYPE_REPEATED(structname, fieldname) pb_membersize(structname, fieldname) |
| 684 | #define PB_DS_CB_PB_HTYPE_FIXARRAY(structname, fieldname) pb_membersize(structname, fieldname) |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 685 | |
Petteri Aimonen | 5acd377 | 2019-01-30 15:22:55 +0200 | [diff] [blame] | 686 | #define PB_ONEOF_NAME(type, tuple) PB_EXPAND(PB_ONEOF_NAME_ ## type tuple) |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 687 | #define PB_ONEOF_NAME_UNION(unionname,membername,fullname) unionname |
| 688 | #define PB_ONEOF_NAME_MEMBER(unionname,membername,fullname) membername |
| 689 | #define PB_ONEOF_NAME_FULL(unionname,membername,fullname) fullname |
| 690 | |
| 691 | #define PB_GEN_SUBMSG_INFO(structname, atype, htype, ltype, fieldname, tag) \ |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 692 | PB_SUBMSG_INFO_ ## htype(_PB_LTYPE_ ## ltype, structname, fieldname) |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 693 | |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 694 | #define PB_SUBMSG_INFO_REQUIRED(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) |
| 695 | #define PB_SUBMSG_INFO_SINGULAR(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) |
| 696 | #define PB_SUBMSG_INFO_OPTIONAL(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 697 | #define PB_SUBMSG_INFO_ONEOF(ltype, structname, fieldname) PB_SUBMSG_INFO_ONEOF2(ltype, structname, PB_ONEOF_NAME(UNION, fieldname), PB_ONEOF_NAME(MEMBER, fieldname)) |
| 698 | #define PB_SUBMSG_INFO_ONEOF2(ltype, structname, unionname, membername) PB_SUBMSG_INFO_ONEOF3(ltype, structname, unionname, membername) |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 699 | #define PB_SUBMSG_INFO_ONEOF3(ltype, structname, unionname, membername) PB_SI ## ltype(structname ## _ ## unionname ## _ ## membername ## _MSGTYPE) |
| 700 | #define PB_SUBMSG_INFO_REPEATED(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) |
| 701 | #define PB_SUBMSG_INFO_FIXARRAY(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) |
| 702 | #define PB_SI_PB_LTYPE_BOOL(t) |
| 703 | #define PB_SI_PB_LTYPE_BYTES(t) |
| 704 | #define PB_SI_PB_LTYPE_DOUBLE(t) |
| 705 | #define PB_SI_PB_LTYPE_ENUM(t) |
| 706 | #define PB_SI_PB_LTYPE_UENUM(t) |
| 707 | #define PB_SI_PB_LTYPE_FIXED32(t) |
| 708 | #define PB_SI_PB_LTYPE_FIXED64(t) |
| 709 | #define PB_SI_PB_LTYPE_FLOAT(t) |
| 710 | #define PB_SI_PB_LTYPE_INT32(t) |
| 711 | #define PB_SI_PB_LTYPE_INT64(t) |
| 712 | #define PB_SI_PB_LTYPE_MESSAGE(t) PB_SUBMSG_DESCRIPTOR(t) |
| 713 | #define PB_SI_PB_LTYPE_MSG_W_CB(t) PB_SUBMSG_DESCRIPTOR(t) |
| 714 | #define PB_SI_PB_LTYPE_SFIXED32(t) |
| 715 | #define PB_SI_PB_LTYPE_SFIXED64(t) |
| 716 | #define PB_SI_PB_LTYPE_SINT32(t) |
| 717 | #define PB_SI_PB_LTYPE_SINT64(t) |
| 718 | #define PB_SI_PB_LTYPE_STRING(t) |
| 719 | #define PB_SI_PB_LTYPE_UINT32(t) |
| 720 | #define PB_SI_PB_LTYPE_UINT64(t) |
| 721 | #define PB_SI_PB_LTYPE_EXTENSION(t) |
| 722 | #define PB_SI_PB_LTYPE_FIXED_LENGTH_BYTES(t) |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 723 | #define PB_SUBMSG_DESCRIPTOR(t) &(t ## _msg), |
| 724 | |
| 725 | /* The field descriptors use a variable width format, with width of either |
| 726 | * 1, 2, 4 or 8 of 32-bit words. The two lowest bytes of the first byte always |
| 727 | * encode the descriptor size, 6 lowest bits of field tag number, and 8 bits |
| 728 | * of the field type. |
| 729 | * |
| 730 | * Descriptor size is encoded as 0 = 1 word, 1 = 2 words, 2 = 4 words, 3 = 8 words. |
| 731 | * |
| 732 | * Formats, listed starting with the least significant bit of the first word. |
| 733 | * 1 word: [2-bit len] [6-bit tag] [8-bit type] [8-bit data_offset] [4-bit size_offset] [4-bit data_size] |
| 734 | * |
| 735 | * 2 words: [2-bit len] [6-bit tag] [8-bit type] [12-bit array_size] [4-bit size_offset] |
| 736 | * [16-bit data_offset] [12-bit data_size] [4-bit tag>>6] |
| 737 | * |
| 738 | * 4 words: [2-bit len] [6-bit tag] [8-bit type] [16-bit array_size] |
| 739 | * [8-bit size_offset] [24-bit tag>>6] |
| 740 | * [32-bit data_offset] |
| 741 | * [32-bit data_size] |
| 742 | * |
| 743 | * 8 words: [2-bit len] [6-bit tag] [8-bit type] [16-bit reserved] |
| 744 | * [8-bit size_offset] [24-bit tag>>6] |
| 745 | * [32-bit data_offset] |
| 746 | * [32-bit data_size] |
| 747 | * [32-bit array_size] |
| 748 | * [32-bit reserved] |
| 749 | * [32-bit reserved] |
| 750 | * [32-bit reserved] |
Petteri Aimonen | 258ba83 | 2013-02-17 00:10:47 +0200 | [diff] [blame] | 751 | */ |
Petteri Aimonen | 258ba83 | 2013-02-17 00:10:47 +0200 | [diff] [blame] | 752 | |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 753 | #define PB_FIELDINFO_1(tag, type, data_offset, data_size, size_offset, array_size) \ |
| 754 | (0 | (((tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(data_offset) & 0xFF) << 16) | \ |
Petteri Aimonen | 72f4594 | 2019-03-22 07:46:50 +0200 | [diff] [blame] | 755 | (((uint32_t)(size_offset) & 0x0F) << 24) | (((uint32_t)(data_size) & 0x0F) << 28)), |
Petteri Aimonen | 258ba83 | 2013-02-17 00:10:47 +0200 | [diff] [blame] | 756 | |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 757 | #define PB_FIELDINFO_2(tag, type, data_offset, data_size, size_offset, array_size) \ |
Petteri Aimonen | 72f4594 | 2019-03-22 07:46:50 +0200 | [diff] [blame] | 758 | (1 | (((tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(array_size) & 0xFFF) << 16) | (((uint32_t)(size_offset) & 0x0F) << 28)), \ |
Petteri Aimonen | 7c90bee | 2019-12-29 15:56:50 +0200 | [diff] [blame] | 759 | (((uint32_t)(data_offset) & 0xFFFF) | (((uint32_t)(data_size) & 0xFFF) << 16) | (((uint32_t)(tag) & 0x3c0) << 22)), |
Bernhard Krämer | ba97926 | 2016-10-09 20:26:28 +0200 | [diff] [blame] | 760 | |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 761 | #define PB_FIELDINFO_4(tag, type, data_offset, data_size, size_offset, array_size) \ |
| 762 | (2 | (((tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(array_size) & 0xFFFF) << 16)), \ |
Petteri Aimonen | f131926 | 2020-01-29 18:59:36 +0200 | [diff] [blame] | 763 | ((uint32_t)(int_least8_t)(size_offset) | (((uint32_t)(tag) << 2) & 0xFFFFFF00)), \ |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 764 | (data_offset), (data_size), |
Petteri Aimonen | 258ba83 | 2013-02-17 00:10:47 +0200 | [diff] [blame] | 765 | |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 766 | #define PB_FIELDINFO_8(tag, type, data_offset, data_size, size_offset, array_size) \ |
| 767 | (3 | (((tag) << 2) & 0xFF) | ((type) << 8)), \ |
Petteri Aimonen | f131926 | 2020-01-29 18:59:36 +0200 | [diff] [blame] | 768 | ((uint32_t)(int_least8_t)(size_offset) | (((uint32_t)(tag) << 2) & 0xFFFFFF00)), \ |
Petteri Aimonen | 2198604 | 2020-01-02 11:47:44 +0200 | [diff] [blame] | 769 | (data_offset), (data_size), (array_size), 0, 0, 0, |
Martin Donath | 4ae3b2e | 2013-12-08 23:25:32 +0100 | [diff] [blame] | 770 | |
Petteri Aimonen | 330a835 | 2018-12-02 16:06:31 +0200 | [diff] [blame] | 771 | /* These assertions verify that the field information fits in the allocated space. |
Petteri Aimonen | 1d43638 | 2018-12-10 16:42:21 +0200 | [diff] [blame] | 772 | * The generator tries to automatically determine the correct width that can fit all |
| 773 | * data associated with a message. These asserts will fail only if there has been a |
| 774 | * problem in the automatic logic - this may be worth reporting as a bug. As a workaround, |
| 775 | * you can increase the descriptor width by defining PB_FIELDINFO_WIDTH or by setting |
| 776 | * descriptorsize option in .options file. |
Petteri Aimonen | 330a835 | 2018-12-02 16:06:31 +0200 | [diff] [blame] | 777 | */ |
| 778 | #define PB_FITS(value,bits) ((uint32_t)(value) < ((uint32_t)1<<bits)) |
| 779 | #define PB_FIELDINFO_ASSERT_1(tag, type, data_offset, data_size, size_offset, array_size) \ |
| 780 | PB_STATIC_ASSERT(PB_FITS(tag,6) && PB_FITS(data_offset,8) && PB_FITS(size_offset,4) && PB_FITS(data_size,4) && PB_FITS(array_size,1), FIELDINFO_DOES_NOT_FIT_width1_field ## tag) |
| 781 | |
| 782 | #define PB_FIELDINFO_ASSERT_2(tag, type, data_offset, data_size, size_offset, array_size) \ |
| 783 | PB_STATIC_ASSERT(PB_FITS(tag,10) && PB_FITS(data_offset,16) && PB_FITS(size_offset,4) && PB_FITS(data_size,12) && PB_FITS(array_size,12), FIELDINFO_DOES_NOT_FIT_width2_field ## tag) |
| 784 | |
| 785 | #ifndef PB_FIELD_32BIT |
| 786 | /* Maximum field sizes are still 16-bit if pb_size_t is 16-bit */ |
| 787 | #define PB_FIELDINFO_ASSERT_4(tag, type, data_offset, data_size, size_offset, array_size) \ |
Petteri Aimonen | f131926 | 2020-01-29 18:59:36 +0200 | [diff] [blame] | 788 | PB_STATIC_ASSERT(PB_FITS(tag,16) && PB_FITS(data_offset,16) && PB_FITS((int_least8_t)size_offset,8) && PB_FITS(data_size,16) && PB_FITS(array_size,16), FIELDINFO_DOES_NOT_FIT_width4_field ## tag) |
Petteri Aimonen | 330a835 | 2018-12-02 16:06:31 +0200 | [diff] [blame] | 789 | |
| 790 | #define PB_FIELDINFO_ASSERT_8(tag, type, data_offset, data_size, size_offset, array_size) \ |
Petteri Aimonen | f131926 | 2020-01-29 18:59:36 +0200 | [diff] [blame] | 791 | PB_STATIC_ASSERT(PB_FITS(tag,16) && PB_FITS(data_offset,16) && PB_FITS((int_least8_t)size_offset,8) && PB_FITS(data_size,16) && PB_FITS(array_size,16), FIELDINFO_DOES_NOT_FIT_width8_field ## tag) |
Petteri Aimonen | 330a835 | 2018-12-02 16:06:31 +0200 | [diff] [blame] | 792 | #else |
| 793 | /* Up to 32-bit fields supported. |
| 794 | * Note that the checks are against 31 bits to avoid compiler warnings about shift wider than type in the test. |
| 795 | * I expect that there is no reasonable use for >2GB messages with nanopb anyway. |
| 796 | */ |
| 797 | #define PB_FIELDINFO_ASSERT_4(tag, type, data_offset, data_size, size_offset, array_size) \ |
Petteri Aimonen | f131926 | 2020-01-29 18:59:36 +0200 | [diff] [blame] | 798 | PB_STATIC_ASSERT(PB_FITS(tag,30) && PB_FITS(data_offset,31) && PB_FITS(size_offset,8) && PB_FITS(data_size,31) && PB_FITS(array_size,16), FIELDINFO_DOES_NOT_FIT_width4_field ## tag) |
Petteri Aimonen | 330a835 | 2018-12-02 16:06:31 +0200 | [diff] [blame] | 799 | |
| 800 | #define PB_FIELDINFO_ASSERT_8(tag, type, data_offset, data_size, size_offset, array_size) \ |
Petteri Aimonen | f131926 | 2020-01-29 18:59:36 +0200 | [diff] [blame] | 801 | PB_STATIC_ASSERT(PB_FITS(tag,30) && PB_FITS(data_offset,31) && PB_FITS(size_offset,8) && PB_FITS(data_size,31) && PB_FITS(array_size,31), FIELDINFO_DOES_NOT_FIT_width8_field ## tag) |
Petteri Aimonen | 330a835 | 2018-12-02 16:06:31 +0200 | [diff] [blame] | 802 | #endif |
| 803 | |
| 804 | |
Petteri Aimonen | 6a59527 | 2018-12-01 18:17:07 +0200 | [diff] [blame] | 805 | /* Automatic picking of FIELDINFO width: |
| 806 | * Uses width 1 when possible, otherwise resorts to width 2. |
Petteri Aimonen | 974daf2 | 2020-01-31 20:36:12 +0200 | [diff] [blame] | 807 | * This is used when PB_BIND() is called with "AUTO" as the argument. |
| 808 | * The generator will give explicit size argument when it knows that a message |
| 809 | * structure grows beyond 1-word format limits. |
Petteri Aimonen | 2467922 | 2017-02-12 10:48:51 +0200 | [diff] [blame] | 810 | */ |
Petteri Aimonen | 44b5256 | 2020-06-22 09:48:21 +0300 | [diff] [blame] | 811 | #define PB_FIELDINFO_WIDTH_AUTO(atype, htype, ltype) PB_FI_WIDTH ## atype(htype, ltype) |
| 812 | #define PB_FI_WIDTH_PB_ATYPE_STATIC(htype, ltype) PB_FI_WIDTH ## htype(ltype) |
| 813 | #define PB_FI_WIDTH_PB_ATYPE_POINTER(htype, ltype) PB_FI_WIDTH ## htype(ltype) |
| 814 | #define PB_FI_WIDTH_PB_ATYPE_CALLBACK(htype, ltype) 2 |
| 815 | #define PB_FI_WIDTH_PB_HTYPE_REQUIRED(ltype) PB_FI_WIDTH ## ltype |
| 816 | #define PB_FI_WIDTH_PB_HTYPE_SINGULAR(ltype) PB_FI_WIDTH ## ltype |
| 817 | #define PB_FI_WIDTH_PB_HTYPE_OPTIONAL(ltype) PB_FI_WIDTH ## ltype |
| 818 | #define PB_FI_WIDTH_PB_HTYPE_ONEOF(ltype) PB_FI_WIDTH ## ltype |
| 819 | #define PB_FI_WIDTH_PB_HTYPE_REPEATED(ltype) 2 |
| 820 | #define PB_FI_WIDTH_PB_HTYPE_FIXARRAY(ltype) 2 |
| 821 | #define PB_FI_WIDTH_PB_LTYPE_BOOL 1 |
| 822 | #define PB_FI_WIDTH_PB_LTYPE_BYTES 2 |
| 823 | #define PB_FI_WIDTH_PB_LTYPE_DOUBLE 1 |
| 824 | #define PB_FI_WIDTH_PB_LTYPE_ENUM 1 |
| 825 | #define PB_FI_WIDTH_PB_LTYPE_UENUM 1 |
| 826 | #define PB_FI_WIDTH_PB_LTYPE_FIXED32 1 |
| 827 | #define PB_FI_WIDTH_PB_LTYPE_FIXED64 1 |
| 828 | #define PB_FI_WIDTH_PB_LTYPE_FLOAT 1 |
| 829 | #define PB_FI_WIDTH_PB_LTYPE_INT32 1 |
| 830 | #define PB_FI_WIDTH_PB_LTYPE_INT64 1 |
| 831 | #define PB_FI_WIDTH_PB_LTYPE_MESSAGE 2 |
| 832 | #define PB_FI_WIDTH_PB_LTYPE_MSG_W_CB 2 |
| 833 | #define PB_FI_WIDTH_PB_LTYPE_SFIXED32 1 |
| 834 | #define PB_FI_WIDTH_PB_LTYPE_SFIXED64 1 |
| 835 | #define PB_FI_WIDTH_PB_LTYPE_SINT32 1 |
| 836 | #define PB_FI_WIDTH_PB_LTYPE_SINT64 1 |
| 837 | #define PB_FI_WIDTH_PB_LTYPE_STRING 2 |
| 838 | #define PB_FI_WIDTH_PB_LTYPE_UINT32 1 |
| 839 | #define PB_FI_WIDTH_PB_LTYPE_UINT64 1 |
| 840 | #define PB_FI_WIDTH_PB_LTYPE_EXTENSION 1 |
| 841 | #define PB_FI_WIDTH_PB_LTYPE_FIXED_LENGTH_BYTES 2 |
Petteri Aimonen | 1f13e8c | 2013-07-22 18:59:15 +0300 | [diff] [blame] | 842 | |
Petteri Aimonen | 258ba83 | 2013-02-17 00:10:47 +0200 | [diff] [blame] | 843 | /* The mapping from protobuf types to LTYPEs is done using these macros. */ |
Petteri Aimonen | eab98eb | 2019-10-02 10:56:49 +0300 | [diff] [blame] | 844 | #define PB_LTYPE_MAP_BOOL PB_LTYPE_BOOL |
Petteri Aimonen | 07375a1 | 2017-02-22 21:06:32 +0200 | [diff] [blame] | 845 | #define PB_LTYPE_MAP_BYTES PB_LTYPE_BYTES |
| 846 | #define PB_LTYPE_MAP_DOUBLE PB_LTYPE_FIXED64 |
| 847 | #define PB_LTYPE_MAP_ENUM PB_LTYPE_VARINT |
| 848 | #define PB_LTYPE_MAP_UENUM PB_LTYPE_UVARINT |
| 849 | #define PB_LTYPE_MAP_FIXED32 PB_LTYPE_FIXED32 |
| 850 | #define PB_LTYPE_MAP_FIXED64 PB_LTYPE_FIXED64 |
| 851 | #define PB_LTYPE_MAP_FLOAT PB_LTYPE_FIXED32 |
| 852 | #define PB_LTYPE_MAP_INT32 PB_LTYPE_VARINT |
| 853 | #define PB_LTYPE_MAP_INT64 PB_LTYPE_VARINT |
| 854 | #define PB_LTYPE_MAP_MESSAGE PB_LTYPE_SUBMESSAGE |
Petteri Aimonen | b9c7bba | 2019-12-18 18:35:00 +0200 | [diff] [blame] | 855 | #define PB_LTYPE_MAP_MSG_W_CB PB_LTYPE_SUBMSG_W_CB |
Petteri Aimonen | 07375a1 | 2017-02-22 21:06:32 +0200 | [diff] [blame] | 856 | #define PB_LTYPE_MAP_SFIXED32 PB_LTYPE_FIXED32 |
| 857 | #define PB_LTYPE_MAP_SFIXED64 PB_LTYPE_FIXED64 |
| 858 | #define PB_LTYPE_MAP_SINT32 PB_LTYPE_SVARINT |
| 859 | #define PB_LTYPE_MAP_SINT64 PB_LTYPE_SVARINT |
| 860 | #define PB_LTYPE_MAP_STRING PB_LTYPE_STRING |
| 861 | #define PB_LTYPE_MAP_UINT32 PB_LTYPE_UVARINT |
| 862 | #define PB_LTYPE_MAP_UINT64 PB_LTYPE_UVARINT |
| 863 | #define PB_LTYPE_MAP_EXTENSION PB_LTYPE_EXTENSION |
| 864 | #define PB_LTYPE_MAP_FIXED_LENGTH_BYTES PB_LTYPE_FIXED_LENGTH_BYTES |
Petteri Aimonen | 258ba83 | 2013-02-17 00:10:47 +0200 | [diff] [blame] | 865 | |
Petteri Aimonen | 0fb5e5e | 2012-08-24 21:22:20 +0300 | [diff] [blame] | 866 | /* These macros are used for giving out error messages. |
| 867 | * They are mostly a debugging aid; the main error information |
| 868 | * is the true/false return value from functions. |
| 869 | * Some code space can be saved by disabling the error |
| 870 | * messages if not used. |
Petteri Aimonen | b0d3146 | 2015-01-03 10:59:19 +0200 | [diff] [blame] | 871 | * |
| 872 | * PB_SET_ERROR() sets the error message if none has been set yet. |
| 873 | * msg must be a constant string literal. |
| 874 | * PB_GET_ERROR() always returns a pointer to a string. |
| 875 | * PB_RETURN_ERROR() sets the error and returns false from current |
| 876 | * function. |
Petteri Aimonen | 0fb5e5e | 2012-08-24 21:22:20 +0300 | [diff] [blame] | 877 | */ |
| 878 | #ifdef PB_NO_ERRMSG |
Petteri Aimonen | b0d3146 | 2015-01-03 10:59:19 +0200 | [diff] [blame] | 879 | #define PB_SET_ERROR(stream, msg) PB_UNUSED(stream) |
Petteri Aimonen | 0fb5e5e | 2012-08-24 21:22:20 +0300 | [diff] [blame] | 880 | #define PB_GET_ERROR(stream) "(errmsg disabled)" |
| 881 | #else |
Petteri Aimonen | b0d3146 | 2015-01-03 10:59:19 +0200 | [diff] [blame] | 882 | #define PB_SET_ERROR(stream, msg) (stream->errmsg = (stream)->errmsg ? (stream)->errmsg : (msg)) |
Petteri Aimonen | 0fb5e5e | 2012-08-24 21:22:20 +0300 | [diff] [blame] | 883 | #define PB_GET_ERROR(stream) ((stream)->errmsg ? (stream)->errmsg : "(none)") |
| 884 | #endif |
Petteri Aimonen | f836431 | 2011-07-30 09:59:08 +0000 | [diff] [blame] | 885 | |
Petteri Aimonen | b0d3146 | 2015-01-03 10:59:19 +0200 | [diff] [blame] | 886 | #define PB_RETURN_ERROR(stream, msg) return PB_SET_ERROR(stream, msg), false |
| 887 | |
Petteri Aimonen | 87319f6 | 2018-12-09 17:26:13 +0200 | [diff] [blame] | 888 | #ifdef __cplusplus |
| 889 | } /* extern "C" */ |
Petteri Aimonen | 2a80ff2 | 2011-11-30 15:03:23 +0000 | [diff] [blame] | 890 | #endif |
Petteri Aimonen | 87319f6 | 2018-12-09 17:26:13 +0200 | [diff] [blame] | 891 | |
Vitali Lovich | 4b869d7 | 2019-03-01 11:16:53 -0800 | [diff] [blame] | 892 | #ifdef __cplusplus |
| 893 | #if __cplusplus >= 201103L |
| 894 | #define PB_CONSTEXPR constexpr |
| 895 | #else // __cplusplus >= 201103L |
| 896 | #define PB_CONSTEXPR |
| 897 | #endif // __cplusplus >= 201103L |
| 898 | |
| 899 | #if __cplusplus >= 201703L |
| 900 | #define PB_INLINE_CONSTEXPR inline constexpr |
| 901 | #else // __cplusplus >= 201703L |
| 902 | #define PB_INLINE_CONSTEXPR PB_CONSTEXPR |
| 903 | #endif // __cplusplus >= 201703L |
| 904 | |
| 905 | namespace nanopb { |
| 906 | // Each type will be partially specialized by the generator. |
| 907 | template <typename GenMessageT> struct MessageDescriptor; |
| 908 | } // namespace nanopb |
| 909 | #endif /* __cplusplus */ |
| 910 | |
Petteri Aimonen | 87319f6 | 2018-12-09 17:26:13 +0200 | [diff] [blame] | 911 | #endif |