The open source OpenXR runtime

external: Add NanoPB

authored by

Jakob Bornecrantz and committed by
Moses Turner
58186cc6 d0c6cfae

+4604 -1
+5
.reuse/dep5
··· 109 109 License: MIT 110 110 Comment: SPDX-License-Identifier missing. 111 111 112 + Files: src/external/nanopb/* 113 + Copyright: 2011-2022, Petteri Aimonen 114 + License: Zlib 115 + Comment: License information global from repository. 116 + 112 117 Files: src/external/tracy/* 113 118 Copyright: 2017-2022, Bartosz Taudul 114 119 License: BSD-3-Clause
+14 -1
src/external/CMakeLists.txt
··· 1 - # Copyright 2020, Collabora, Ltd. 1 + # Copyright 2020-2022, Collabora, Ltd. 2 2 # SPDX-License-Identifier: BSL-1.0 3 3 4 4 # Catch2 ··· 50 50 ) 51 51 target_link_libraries(xrt-external-jni-wrap PUBLIC xrt-external-jnipp) 52 52 endif() 53 + 54 + # Nano Protobuf 55 + add_library( 56 + xrt-external-nanopb STATIC 57 + nanopb/pb.h 58 + nanopb/pb_common.c 59 + nanopb/pb_common.h 60 + nanopb/pb_decode.c 61 + nanopb/pb_decode.h 62 + nanopb/pb_encode.c 63 + nanopb/pb_encode.h 64 + ) 65 + target_include_directories(xrt-external-nanopb PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/nanopb) 53 66 54 67 # OpenXR 55 68 add_library(xrt-external-openxr INTERFACE)
+116
src/external/nanopb/AUTHORS.txt
··· 1 + Petteri Aimonen <jpa@npb.mail.kapsi.fi> 2 + Michael Poole <mdpoole@troilus.org> 3 + Daniel Kan <extremeblue99@gmail.com> 4 + Stan Hu <stanhu@aclimalabs.com> 5 + David Hotham <david.hotham@blueyonder.co.uk> 6 + Steffen Siering <steffen siering gmail com> 7 + Jens Steinhauser <jens.steinhauser@gmail.com> 8 + Pavel Ilin <ilin.pa@gmail.com> 9 + Kent Ryhorchuk <kryhorchuk@xeralux.com> 10 + Martin Donath <scifish@gmail.com> 11 + Oliver Lee <oliverzlee@gmail.com> 12 + Michael Haberler <git@mah.priv.at> 13 + Nicolas Colomer <ncolomer@viadeoteam.com> 14 + Ivan Kravets <me@ikravets.com> 15 + Kyle Manna <kyle@kylemanna.com> 16 + Benjamin Kamath <ben.kamath@synapse.com> 17 + Andrew Ruder <andrew.ruder@elecsyscorp.com> 18 + Kenshi Kawaguchi <kenshi@recurse.ca> 19 + isotes <isotes@gmail.com> 20 + Maxim Khitrov <max@mxcrypt.com> 21 + Yaniv Mordekhay <yanivmo@users.noreply.github.com> 22 + Ming Zhao <mzhao@luminatewireless.com> 23 + Google, Inc. 24 + Tom Roeder <tmroeder@google.com> 25 + Piotr Sikora <piotrsikora@google.com> 26 + Bernhard Krämer <bdkrae@gmail.com> 27 + Konstantin Podsvirov <konstantin@podsvirov.pro> 28 + William A. Kennington III <wak@google.com> 29 + Guillaume Lager <g.lager@innoseis.com> 30 + Tobias Haegermarck <tobias.haegermarck@gmail.com> 31 + Justin DeMartino <jdemarti@gmail.com> 32 + Constantine Grantcharov <cgrantcharov@trustpointinnovation.com> 33 + Nick Ewalt <nicholasewalt@google.com> 34 + Harald Fernengel <harryf@gmx.com> 35 + Alice Wang <aw@squareup.com> 36 + Kevin Fitch <kfitch42@gmail.com> 37 + Kamal Marhubi <kamal@marhubi.com> 38 + Elco Jacobs <elco@brewpi.com> 39 + Sébastien Morin <sebastien.morin@primerogames.com> 40 + Dave Flogeras <dflogeras2@gmail.com> 41 + Edward Z. Yang <ezyang@mit.edu> 42 + Robbie Shade <rjshade@google.com> 43 + Andrew Ballinger <andrewballinger@stratisopt.com> 44 + Hamina, Juha-Pekka <Juha-Pekka.Hamina@nordicsemi.no> 45 + Jason Bishop <jason.bishop@bigassfans.com> 46 + matejcik <ja@matejcik.cz> 47 + Tobias Müller <Tobias_Mueller@twam.info> 48 + Jari Vetoniemi <mailroxas@gmail.com> 49 + Gabriel Staples <ercaguy@gmail.com> 50 + Amarnath <amarnath.h.96@gmail.com> 51 + Michal Rostecki <mrostecki@suse.de> 52 + Pei Wang <wangpei10@baidu.com> 53 + Noah Pendleton <2538614+noahp@users.noreply.github.com> 54 + Pavol Rusnak <pavol@rusnak.io> 55 + der-imp <falkjan@msn.com> 56 + Mark Hill <markleehill@gmail.com> 57 + Torfinn Berset <torfinn@bloom-life.com> 58 + Bo Langgaard Lind <bo.langgaard.lind@gmail.com> 59 + Stephane Dorre <stephane.dorre@cobi.bike> 60 + Phillip Cao <Phillip.Cao@fphcare.co.nz> 61 + Melvin Wang <melvin.mc.wang@gmail.com> 62 + Joshua Salzedo <thHunkn0WNd@gmail.com> 63 + Adam Klama <klama.adam@gmail.com> 64 + Anton Matosov <amatosov@roblox.com> 65 + berni155 <bdkrae@gmail.com> 66 + bolind <bolind@users.noreply.github.com> 67 + David Lin <dtwlin@google.com> 68 + dch <david.hotham@blueyonder.co.uk> 69 + devjoa <devjoa@gmail.com> 70 + Evan Fisher <schleb@gmail.com> 71 + Fay <fay2003hiend@gmail.com> 72 + Florian Märkl <info@florianmaerkl.de> 73 + Franck <franck.sehedic@ledger.fr> 74 + Ilya Averyanov <i.averyanov@geoscan.aero> 75 + John Ullman <jrullman@google.com> 76 + Ket3r <peter.kempter@gmail.com> 77 + maciej <maciej.matuszak@gmail.com> 78 + Marek Zukal <marek.zukal@gmail.com> 79 + Paul Beusterien <paulbeusterien@google.com> 80 + Rogers Guedes <rogers.guedes@smdautomacao.com> 81 + Stefan R. Filipek <srfilipek@gmail.com> 82 + T. Carl Beery <beeryt@users.noreply.github.com> 83 + Vitali Lovich <vlovich@google.com> 84 + Vojtěch Boček <vbocek@gmail.com> 85 + Wael Nasreddine <wael.nasreddine@gmail.com> 86 + wangli28 <wangli28@beyondsoft.com> 87 + Zukaitis <gediminas.zukaitis@office.auriga.msk> 88 + Alex Pacini <alexpacini90@gmail.com> 89 + Cong <congusbongus@gmail.com> 90 + kurddt <kurddt@users.noreply.github.com> 91 + otopetrik <oto.petrik@gmail.com> 92 + Psy-Kai <psykai1993@googlemail.com> 93 + a1lu <a1lu@users.noreply.github.com> 94 + L <46594312+WakandaO2@users.noreply.github.com> 95 + Melvin Wang <mwang@sibros.tech> 96 + Tim Gates <tim.gates@iress.com> 97 + leabut <leabut@users.noreply.github.com> 98 + Angel ILIEV <a.v.iliev13@gmail.com> 99 + Jakub Tymejczyk <jakub@tymejczyk.pl> 100 + Matthew Simmons <simmonmt@acm.org> 101 + Anthony Pesch <inolen@gmail.com> 102 + Avik De <avikde@gmail.com> 103 + ConradWood <github@conradwood.net> 104 + David Sabatie <david.sabatie@notrenet.com> 105 + Sebastian Stockhammer <sebastian.stockhammer@rosenberger.de> 106 + Gil Shapira <gil.shapira@intusurg.com> 107 + Ian Frosst <ianjfrosst@gmail.com> 108 + Ingo Kresse <ingo.kresse@kuka.com> 109 + Ivan Zrno <ivan.zrno2@gmail.com> 110 + Jonathan Seilkopf <j.seilkopf@isatech.de> 111 + Karl Ljungkvist <k.ljungkvist@gmail.com> 112 + Mathis Logemann <mathisloge@gmail.com> 113 + Oleg Dolgy <60554929+odolgy@users.noreply.github.com> 114 + Pavel Sokolov <pavel@sokolov.me> 115 + Slavey Karadzhov <slav@attachix.com> 116 + Tobias Nießen <tniessen@tnie.de>
+1
src/external/nanopb/COMMIT.txt
··· 1 + nanopb-0.4.6-20-g23993cf
+20
src/external/nanopb/LICENSE.txt
··· 1 + Copyright (c) 2011 Petteri Aimonen <jpa at nanopb.mail.kapsi.fi> 2 + 3 + This software is provided 'as-is', without any express or 4 + implied warranty. In no event will the authors be held liable 5 + for any damages arising from the use of this software. 6 + 7 + Permission is granted to anyone to use this software for any 8 + purpose, including commercial applications, and to alter it and 9 + redistribute it freely, subject to the following restrictions: 10 + 11 + 1. The origin of this software must not be misrepresented; you 12 + must not claim that you wrote the original software. If you use 13 + this software in a product, an acknowledgment in the product 14 + documentation would be appreciated but is not required. 15 + 16 + 2. Altered source versions must be plainly marked as such, and 17 + must not be misrepresented as being the original software. 18 + 19 + 3. This notice may not be removed or altered from any source 20 + distribution.
+911
src/external/nanopb/pb.h
··· 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 + 5 + #ifndef PB_H_INCLUDED 6 + #define PB_H_INCLUDED 7 + 8 + /***************************************************************** 9 + * Nanopb compilation time options. You can change these here by * 10 + * uncommenting the lines, or on the compiler command line. * 11 + *****************************************************************/ 12 + 13 + /* Enable support for dynamically allocated fields */ 14 + /* #define PB_ENABLE_MALLOC 1 */ 15 + 16 + /* Define this if your CPU / compiler combination does not support 17 + * unaligned memory access to packed structures. Note that packed 18 + * structures are only used when requested in .proto options. */ 19 + /* #define PB_NO_PACKED_STRUCTS 1 */ 20 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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. */ 68 + #define NANOPB_VERSION "nanopb-0.4.7-dev" 69 + 70 + /* Include all the system headers needed by nanopb. You will need the 71 + * definitions of the following: 72 + * - strlen, memcpy, memset functions 73 + * - [u]int_least8_t, uint_fast8_t, [u]int_least16_t, [u]int32_t, [u]int64_t 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 + */ 81 + #ifdef PB_SYSTEM_HEADER 82 + #include PB_SYSTEM_HEADER 83 + #else 84 + #include <stdint.h> 85 + #include <stddef.h> 86 + #include <stdbool.h> 87 + #include <string.h> 88 + #include <limits.h> 89 + 90 + #ifdef PB_ENABLE_MALLOC 91 + #include <stdlib.h> 92 + #endif 93 + #endif 94 + 95 + #ifdef __cplusplus 96 + extern "C" { 97 + #endif 98 + 99 + /* Macro for defining packed structures (compiler dependent). 100 + * This just reduces memory requirements, but is not required. 101 + */ 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__) 108 + /* For GCC and clang */ 109 + # define PB_PACKED_STRUCT_START 110 + # define PB_PACKED_STRUCT_END 111 + # define pb_packed __attribute__((packed)) 112 + #elif defined(__ICCARM__) || defined(__CC_ARM) 113 + /* For IAR ARM and Keil MDK-ARM compilers */ 114 + # define PB_PACKED_STRUCT_START _Pragma("pack(push, 1)") 115 + # define PB_PACKED_STRUCT_END _Pragma("pack(pop)") 116 + # define pb_packed 117 + #elif defined(_MSC_VER) && (_MSC_VER >= 1500) 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 122 + #else 123 + /* Unknown compiler */ 124 + # define PB_PACKED_STRUCT_START 125 + # define PB_PACKED_STRUCT_END 126 + # define pb_packed 127 + #endif 128 + 129 + /* Detect endianness */ 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 + 141 + /* Handly macro for suppressing unreferenced-parameter compiler warnings. */ 142 + #ifndef PB_UNUSED 143 + #define PB_UNUSED(x) (void)(x) 144 + #endif 145 + 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 + 159 + /* Compile-time assertion, used for checking compatible compilation options. 160 + * If this does not work properly on your compiler, use 161 + * #define PB_NO_STATIC_ASSERT to disable it. 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 166 + * in the place where the PB_STATIC_ASSERT macro was called. 167 + */ 168 + #ifndef PB_NO_STATIC_ASSERT 169 + # ifndef PB_STATIC_ASSERT 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); 173 + # elif defined(PB_C99_STATIC_ASSERT) 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 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); 184 + # endif 185 + # endif 186 + #else 187 + /* Static asserts disabled by PB_NO_STATIC_ASSERT */ 188 + # define PB_STATIC_ASSERT(COND,MSG) 189 + #endif 190 + 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 + */ 197 + PB_STATIC_ASSERT(1, STATIC_ASSERT_IS_NOT_WORKING) 198 + 199 + /* Number of required fields to keep track of. */ 200 + #ifndef PB_MAX_REQUIRED_FIELDS 201 + #define PB_MAX_REQUIRED_FIELDS 64 202 + #endif 203 + 204 + #if PB_MAX_REQUIRED_FIELDS < 64 205 + #error You should not lower PB_MAX_REQUIRED_FIELDS from the default value (64). 206 + #endif 207 + 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 + 215 + /* List of possible field types. These are used in the autogenerated code. 216 + * Least-significant 4 bits tell the scalar type 217 + * Most-significant 4 bits specify repeated/required/packed etc. 218 + */ 219 + 220 + typedef uint_least8_t pb_type_t; 221 + 222 + /**** Field data types ****/ 223 + 224 + /* Numeric types */ 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 */ 231 + 232 + /* Marker for last packable field type. */ 233 + #define PB_LTYPE_LAST_PACKABLE 0x05U 234 + 235 + /* Byte array with pre-allocated buffer. 236 + * data_size is the length of the allocated PB_BYTES_ARRAY structure. */ 237 + #define PB_LTYPE_BYTES 0x06U 238 + 239 + /* String with pre-allocated buffer. 240 + * data_size is the maximum length. */ 241 + #define PB_LTYPE_STRING 0x07U 242 + 243 + /* Submessage 244 + * submsg_fields is pointer to field descriptions */ 245 + #define PB_LTYPE_SUBMESSAGE 0x08U 246 + 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 + 252 + /* Extension pseudo-field 253 + * The field contains a pointer to pb_extension_t */ 254 + #define PB_LTYPE_EXTENSION 0x0AU 255 + 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. */ 260 + #define PB_LTYPE_FIXED_LENGTH_BYTES 0x0BU 261 + 262 + /* Number of declared LTYPES */ 263 + #define PB_LTYPES_COUNT 0x0CU 264 + #define PB_LTYPE_MASK 0x0FU 265 + 266 + /**** Field repetition rules ****/ 267 + 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 275 + 276 + /**** Field allocation types ****/ 277 + 278 + #define PB_ATYPE_STATIC 0x00U 279 + #define PB_ATYPE_POINTER 0x80U 280 + #define PB_ATYPE_CALLBACK 0x40U 281 + #define PB_ATYPE_MASK 0xC0U 282 + 283 + #define PB_ATYPE(x) ((x) & PB_ATYPE_MASK) 284 + #define PB_HTYPE(x) ((x) & PB_HTYPE_MASK) 285 + #define PB_LTYPE(x) ((x) & PB_LTYPE_MASK) 286 + #define PB_LTYPE_IS_SUBMSG(x) (PB_LTYPE(x) == PB_LTYPE_SUBMESSAGE || \ 287 + PB_LTYPE(x) == PB_LTYPE_SUBMSG_W_CB) 288 + 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; 295 + #else 296 + typedef uint_least16_t pb_size_t; 297 + typedef int_least16_t pb_ssize_t; 298 + #endif 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; 306 + 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 + 312 + /* This structure is used in auto-generated constants 313 + * to specify struct fields. 314 + */ 315 + typedef struct pb_msgdesc_s pb_msgdesc_t; 316 + struct pb_msgdesc_s { 317 + const uint32_t *field_info; 318 + const pb_msgdesc_t * const * submsg_info; 319 + const pb_byte_t *default_value; 320 + 321 + bool (*field_callback)(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_iter_t *field); 322 + 323 + pb_size_t field_count; 324 + pb_size_t required_field_count; 325 + pb_size_t largest_tag; 326 + }; 327 + 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 + }; 349 + 350 + /* For compatibility with legacy code */ 351 + typedef pb_field_iter_t pb_field_t; 352 + 353 + /* Make sure that the standard integer types are of the expected sizes. 354 + * Otherwise fixed32/fixed64 fields can break. 355 + * 356 + * If you get errors here, it probably means that your stdint.h is not 357 + * correct for your platform. 358 + */ 359 + #ifndef PB_WITHOUT_64BIT 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) 362 + #endif 363 + 364 + /* This structure is used for 'bytes' arrays. 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 + */ 368 + #define PB_BYTES_ARRAY_T(n) struct { pb_size_t size; pb_byte_t bytes[n]; } 369 + #define PB_BYTES_ARRAY_T_ALLOCSIZE(n) ((size_t)n + offsetof(pb_bytes_array_t, bytes)) 370 + 371 + struct pb_bytes_array_s { 372 + pb_size_t size; 373 + pb_byte_t bytes[1]; 374 + }; 375 + typedef struct pb_bytes_array_s pb_bytes_array_t; 376 + 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. 392 + * 393 + * The callback can be null if you want to skip a field. 394 + */ 395 + typedef struct pb_callback_s pb_callback_t; 396 + struct pb_callback_s { 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 + */ 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; 404 + 405 + /* Free arg for use by callback */ 406 + void *arg; 407 + }; 408 + 409 + extern bool pb_default_field_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_t *field); 410 + 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, 416 + PB_WT_32BIT = 5, 417 + PB_WT_PACKED = 255 /* PB_WT_PACKED is internal marker for packed arrays. */ 418 + } pb_wire_type_t; 419 + 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 + */ 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 { 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); 437 + 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 + */ 444 + bool (*encode)(pb_ostream_t *stream, const pb_extension_t *extension); 445 + 446 + /* Free field for use by the callback. */ 447 + const void *arg; 448 + }; 449 + 450 + struct pb_extension_s { 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; 454 + 455 + /* Destination for the decoded data. This must match the datatype 456 + * of the extension field. */ 457 + void *dest; 458 + 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; 463 + 464 + /* The decoder sets this to true if the extension was found. 465 + * Ignored for encoding. */ 466 + bool found; 467 + }; 468 + 469 + #define pb_extension_init_zero {NULL,NULL,NULL,false} 470 + 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 + 482 + /* This is used to inform about need to regenerate .pb.h/.pb.c files. */ 483 + #define PB_PROTO_HEADER_VERSION 40 484 + 485 + /* These macros are used to declare pb_field_t's in the constant array. */ 486 + /* Size of a structure member, in bytes. */ 487 + #define pb_membersize(st, m) (sizeof ((st*)0)->m) 488 + /* Number of entries in an array. */ 489 + #define pb_arraysize(st, m) (pb_membersize(st, m) / pb_membersize(st, m[0])) 490 + /* Delta from start of one member to the start of another member. */ 491 + #define pb_delta(st, m1, m2) ((int)offsetof(st, m1) - (int)offsetof(st, m2)) 492 + 493 + /* Force expansion of macro value */ 494 + #define PB_EXPAND(x) x 495 + 496 + /* Binding of a message field set into a specific structure */ 497 + #define PB_BIND(msgname, structname, width) \ 498 + const uint32_t structname ## _field_info[] PB_PROGMEM = \ 499 + { \ 500 + msgname ## _FIELDLIST(PB_GEN_FIELD_INFO_ ## width, structname) \ 501 + 0 \ 502 + }; \ 503 + const pb_msgdesc_t* const structname ## _submsg_info[] = \ 504 + { \ 505 + msgname ## _FIELDLIST(PB_GEN_SUBMSG_INFO, structname) \ 506 + NULL \ 507 + }; \ 508 + const pb_msgdesc_t structname ## _msg = \ 509 + { \ 510 + structname ## _field_info, \ 511 + structname ## _submsg_info, \ 512 + msgname ## _DEFAULT, \ 513 + msgname ## _CALLBACK, \ 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), \ 517 + }; \ 518 + msgname ## _FIELDLIST(PB_GEN_FIELD_INFO_ASSERT_ ## width, structname) 519 + 520 + #define PB_GEN_FIELD_COUNT(structname, atype, htype, ltype, fieldname, tag) +1 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 525 + 526 + /* X-macro for generating the entries in struct_field_info[] array. */ 527 + #define PB_GEN_FIELD_INFO_1(structname, atype, htype, ltype, fieldname, tag) \ 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)) 533 + 534 + #define PB_GEN_FIELD_INFO_2(structname, atype, htype, ltype, fieldname, tag) \ 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)) 540 + 541 + #define PB_GEN_FIELD_INFO_4(structname, atype, htype, ltype, fieldname, tag) \ 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)) 547 + 548 + #define PB_GEN_FIELD_INFO_8(structname, atype, htype, ltype, fieldname, tag) \ 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)) 554 + 555 + #define PB_GEN_FIELD_INFO_AUTO(structname, atype, htype, ltype, fieldname, tag) \ 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)) 562 + 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) 565 + 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) 568 + 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. */ 572 + #define PB_GEN_FIELD_INFO_ASSERT_1(structname, atype, htype, ltype, fieldname, tag) \ 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)) 578 + 579 + #define PB_GEN_FIELD_INFO_ASSERT_2(structname, atype, htype, ltype, fieldname, tag) \ 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)) 585 + 586 + #define PB_GEN_FIELD_INFO_ASSERT_4(structname, atype, htype, ltype, fieldname, tag) \ 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)) 592 + 593 + #define PB_GEN_FIELD_INFO_ASSERT_8(structname, atype, htype, ltype, fieldname, tag) \ 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)) 599 + 600 + #define PB_GEN_FIELD_INFO_ASSERT_AUTO(structname, atype, htype, ltype, fieldname, tag) \ 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)) 607 + 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) 610 + 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) 613 + 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) 623 + 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 647 + 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) 650 + #define PB_ARRAY_SIZE_CALLBACK(htype, structname, fieldname) 1 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]) 663 + 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) 685 + 686 + #define PB_ONEOF_NAME(type, tuple) PB_EXPAND(PB_ONEOF_NAME_ ## type tuple) 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) \ 692 + PB_SUBMSG_INFO_ ## htype(_PB_LTYPE_ ## ltype, structname, fieldname) 693 + 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) 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) 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) 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] 751 + */ 752 + 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) | \ 755 + (((uint32_t)(size_offset) & 0x0F) << 24) | (((uint32_t)(data_size) & 0x0F) << 28)), 756 + 757 + #define PB_FIELDINFO_2(tag, type, data_offset, data_size, size_offset, array_size) \ 758 + (1 | (((tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(array_size) & 0xFFF) << 16) | (((uint32_t)(size_offset) & 0x0F) << 28)), \ 759 + (((uint32_t)(data_offset) & 0xFFFF) | (((uint32_t)(data_size) & 0xFFF) << 16) | (((uint32_t)(tag) & 0x3c0) << 22)), 760 + 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)), \ 763 + ((uint32_t)(int_least8_t)(size_offset) | (((uint32_t)(tag) << 2) & 0xFFFFFF00)), \ 764 + (data_offset), (data_size), 765 + 766 + #define PB_FIELDINFO_8(tag, type, data_offset, data_size, size_offset, array_size) \ 767 + (3 | (((tag) << 2) & 0xFF) | ((type) << 8)), \ 768 + ((uint32_t)(int_least8_t)(size_offset) | (((uint32_t)(tag) << 2) & 0xFFFFFF00)), \ 769 + (data_offset), (data_size), (array_size), 0, 0, 0, 770 + 771 + /* These assertions verify that the field information fits in the allocated space. 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. 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) \ 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) 789 + 790 + #define PB_FIELDINFO_ASSERT_8(tag, type, data_offset, data_size, size_offset, array_size) \ 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) 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) \ 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) 799 + 800 + #define PB_FIELDINFO_ASSERT_8(tag, type, data_offset, data_size, size_offset, array_size) \ 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) 802 + #endif 803 + 804 + 805 + /* Automatic picking of FIELDINFO width: 806 + * Uses width 1 when possible, otherwise resorts to width 2. 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. 810 + */ 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 842 + 843 + /* The mapping from protobuf types to LTYPEs is done using these macros. */ 844 + #define PB_LTYPE_MAP_BOOL PB_LTYPE_BOOL 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 855 + #define PB_LTYPE_MAP_MSG_W_CB PB_LTYPE_SUBMSG_W_CB 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 865 + 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. 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. 877 + */ 878 + #ifdef PB_NO_ERRMSG 879 + #define PB_SET_ERROR(stream, msg) PB_UNUSED(stream) 880 + #define PB_GET_ERROR(stream) "(errmsg disabled)" 881 + #else 882 + #define PB_SET_ERROR(stream, msg) (stream->errmsg = (stream)->errmsg ? (stream)->errmsg : (msg)) 883 + #define PB_GET_ERROR(stream) ((stream)->errmsg ? (stream)->errmsg : "(none)") 884 + #endif 885 + 886 + #define PB_RETURN_ERROR(stream, msg) return PB_SET_ERROR(stream, msg), false 887 + 888 + #ifdef __cplusplus 889 + } /* extern "C" */ 890 + #endif 891 + 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 + 911 + #endif
+388
src/external/nanopb/pb_common.c
··· 1 + /* pb_common.c: Common support functions for pb_encode.c and pb_decode.c. 2 + * 3 + * 2014 Petteri Aimonen <jpa@kapsi.fi> 4 + */ 5 + 6 + #include "pb_common.h" 7 + 8 + static bool load_descriptor_values(pb_field_iter_t *iter) 9 + { 10 + uint32_t word0; 11 + uint32_t data_offset; 12 + int_least8_t size_offset; 13 + 14 + if (iter->index >= iter->descriptor->field_count) 15 + return false; 16 + 17 + word0 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index]); 18 + iter->type = (pb_type_t)((word0 >> 8) & 0xFF); 19 + 20 + switch(word0 & 3) 21 + { 22 + case 0: { 23 + /* 1-word format */ 24 + iter->array_size = 1; 25 + iter->tag = (pb_size_t)((word0 >> 2) & 0x3F); 26 + size_offset = (int_least8_t)((word0 >> 24) & 0x0F); 27 + data_offset = (word0 >> 16) & 0xFF; 28 + iter->data_size = (pb_size_t)((word0 >> 28) & 0x0F); 29 + break; 30 + } 31 + 32 + case 1: { 33 + /* 2-word format */ 34 + uint32_t word1 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 1]); 35 + 36 + iter->array_size = (pb_size_t)((word0 >> 16) & 0x0FFF); 37 + iter->tag = (pb_size_t)(((word0 >> 2) & 0x3F) | ((word1 >> 28) << 6)); 38 + size_offset = (int_least8_t)((word0 >> 28) & 0x0F); 39 + data_offset = word1 & 0xFFFF; 40 + iter->data_size = (pb_size_t)((word1 >> 16) & 0x0FFF); 41 + break; 42 + } 43 + 44 + case 2: { 45 + /* 4-word format */ 46 + uint32_t word1 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 1]); 47 + uint32_t word2 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 2]); 48 + uint32_t word3 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 3]); 49 + 50 + iter->array_size = (pb_size_t)(word0 >> 16); 51 + iter->tag = (pb_size_t)(((word0 >> 2) & 0x3F) | ((word1 >> 8) << 6)); 52 + size_offset = (int_least8_t)(word1 & 0xFF); 53 + data_offset = word2; 54 + iter->data_size = (pb_size_t)word3; 55 + break; 56 + } 57 + 58 + default: { 59 + /* 8-word format */ 60 + uint32_t word1 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 1]); 61 + uint32_t word2 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 2]); 62 + uint32_t word3 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 3]); 63 + uint32_t word4 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 4]); 64 + 65 + iter->array_size = (pb_size_t)word4; 66 + iter->tag = (pb_size_t)(((word0 >> 2) & 0x3F) | ((word1 >> 8) << 6)); 67 + size_offset = (int_least8_t)(word1 & 0xFF); 68 + data_offset = word2; 69 + iter->data_size = (pb_size_t)word3; 70 + break; 71 + } 72 + } 73 + 74 + if (!iter->message) 75 + { 76 + /* Avoid doing arithmetic on null pointers, it is undefined */ 77 + iter->pField = NULL; 78 + iter->pSize = NULL; 79 + } 80 + else 81 + { 82 + iter->pField = (char*)iter->message + data_offset; 83 + 84 + if (size_offset) 85 + { 86 + iter->pSize = (char*)iter->pField - size_offset; 87 + } 88 + else if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED && 89 + (PB_ATYPE(iter->type) == PB_ATYPE_STATIC || 90 + PB_ATYPE(iter->type) == PB_ATYPE_POINTER)) 91 + { 92 + /* Fixed count array */ 93 + iter->pSize = &iter->array_size; 94 + } 95 + else 96 + { 97 + iter->pSize = NULL; 98 + } 99 + 100 + if (PB_ATYPE(iter->type) == PB_ATYPE_POINTER && iter->pField != NULL) 101 + { 102 + iter->pData = *(void**)iter->pField; 103 + } 104 + else 105 + { 106 + iter->pData = iter->pField; 107 + } 108 + } 109 + 110 + if (PB_LTYPE_IS_SUBMSG(iter->type)) 111 + { 112 + iter->submsg_desc = iter->descriptor->submsg_info[iter->submessage_index]; 113 + } 114 + else 115 + { 116 + iter->submsg_desc = NULL; 117 + } 118 + 119 + return true; 120 + } 121 + 122 + static void advance_iterator(pb_field_iter_t *iter) 123 + { 124 + iter->index++; 125 + 126 + if (iter->index >= iter->descriptor->field_count) 127 + { 128 + /* Restart */ 129 + iter->index = 0; 130 + iter->field_info_index = 0; 131 + iter->submessage_index = 0; 132 + iter->required_field_index = 0; 133 + } 134 + else 135 + { 136 + /* Increment indexes based on previous field type. 137 + * All field info formats have the following fields: 138 + * - lowest 2 bits tell the amount of words in the descriptor (2^n words) 139 + * - bits 2..7 give the lowest bits of tag number. 140 + * - bits 8..15 give the field type. 141 + */ 142 + uint32_t prev_descriptor = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index]); 143 + pb_type_t prev_type = (prev_descriptor >> 8) & 0xFF; 144 + pb_size_t descriptor_len = (pb_size_t)(1 << (prev_descriptor & 3)); 145 + 146 + /* Add to fields. 147 + * The cast to pb_size_t is needed to avoid -Wconversion warning. 148 + * Because the data is is constants from generator, there is no danger of overflow. 149 + */ 150 + iter->field_info_index = (pb_size_t)(iter->field_info_index + descriptor_len); 151 + iter->required_field_index = (pb_size_t)(iter->required_field_index + (PB_HTYPE(prev_type) == PB_HTYPE_REQUIRED)); 152 + iter->submessage_index = (pb_size_t)(iter->submessage_index + PB_LTYPE_IS_SUBMSG(prev_type)); 153 + } 154 + } 155 + 156 + bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_msgdesc_t *desc, void *message) 157 + { 158 + memset(iter, 0, sizeof(*iter)); 159 + 160 + iter->descriptor = desc; 161 + iter->message = message; 162 + 163 + return load_descriptor_values(iter); 164 + } 165 + 166 + bool pb_field_iter_begin_extension(pb_field_iter_t *iter, pb_extension_t *extension) 167 + { 168 + const pb_msgdesc_t *msg = (const pb_msgdesc_t*)extension->type->arg; 169 + bool status; 170 + 171 + uint32_t word0 = PB_PROGMEM_READU32(msg->field_info[0]); 172 + if (PB_ATYPE(word0 >> 8) == PB_ATYPE_POINTER) 173 + { 174 + /* For pointer extensions, the pointer is stored directly 175 + * in the extension structure. This avoids having an extra 176 + * indirection. */ 177 + status = pb_field_iter_begin(iter, msg, &extension->dest); 178 + } 179 + else 180 + { 181 + status = pb_field_iter_begin(iter, msg, extension->dest); 182 + } 183 + 184 + iter->pSize = &extension->found; 185 + return status; 186 + } 187 + 188 + bool pb_field_iter_next(pb_field_iter_t *iter) 189 + { 190 + advance_iterator(iter); 191 + (void)load_descriptor_values(iter); 192 + return iter->index != 0; 193 + } 194 + 195 + bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag) 196 + { 197 + if (iter->tag == tag) 198 + { 199 + return true; /* Nothing to do, correct field already. */ 200 + } 201 + else if (tag > iter->descriptor->largest_tag) 202 + { 203 + return false; 204 + } 205 + else 206 + { 207 + pb_size_t start = iter->index; 208 + uint32_t fieldinfo; 209 + 210 + if (tag < iter->tag) 211 + { 212 + /* Fields are in tag number order, so we know that tag is between 213 + * 0 and our start position. Setting index to end forces 214 + * advance_iterator() call below to restart from beginning. */ 215 + iter->index = iter->descriptor->field_count; 216 + } 217 + 218 + do 219 + { 220 + /* Advance iterator but don't load values yet */ 221 + advance_iterator(iter); 222 + 223 + /* Do fast check for tag number match */ 224 + fieldinfo = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index]); 225 + 226 + if (((fieldinfo >> 2) & 0x3F) == (tag & 0x3F)) 227 + { 228 + /* Good candidate, check further */ 229 + (void)load_descriptor_values(iter); 230 + 231 + if (iter->tag == tag && 232 + PB_LTYPE(iter->type) != PB_LTYPE_EXTENSION) 233 + { 234 + /* Found it */ 235 + return true; 236 + } 237 + } 238 + } while (iter->index != start); 239 + 240 + /* Searched all the way back to start, and found nothing. */ 241 + (void)load_descriptor_values(iter); 242 + return false; 243 + } 244 + } 245 + 246 + bool pb_field_iter_find_extension(pb_field_iter_t *iter) 247 + { 248 + if (PB_LTYPE(iter->type) == PB_LTYPE_EXTENSION) 249 + { 250 + return true; 251 + } 252 + else 253 + { 254 + pb_size_t start = iter->index; 255 + uint32_t fieldinfo; 256 + 257 + do 258 + { 259 + /* Advance iterator but don't load values yet */ 260 + advance_iterator(iter); 261 + 262 + /* Do fast check for field type */ 263 + fieldinfo = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index]); 264 + 265 + if (PB_LTYPE((fieldinfo >> 8) & 0xFF) == PB_LTYPE_EXTENSION) 266 + { 267 + return load_descriptor_values(iter); 268 + } 269 + } while (iter->index != start); 270 + 271 + /* Searched all the way back to start, and found nothing. */ 272 + (void)load_descriptor_values(iter); 273 + return false; 274 + } 275 + } 276 + 277 + static void *pb_const_cast(const void *p) 278 + { 279 + /* Note: this casts away const, in order to use the common field iterator 280 + * logic for both encoding and decoding. The cast is done using union 281 + * to avoid spurious compiler warnings. */ 282 + union { 283 + void *p1; 284 + const void *p2; 285 + } t; 286 + t.p2 = p; 287 + return t.p1; 288 + } 289 + 290 + bool pb_field_iter_begin_const(pb_field_iter_t *iter, const pb_msgdesc_t *desc, const void *message) 291 + { 292 + return pb_field_iter_begin(iter, desc, pb_const_cast(message)); 293 + } 294 + 295 + bool pb_field_iter_begin_extension_const(pb_field_iter_t *iter, const pb_extension_t *extension) 296 + { 297 + return pb_field_iter_begin_extension(iter, (pb_extension_t*)pb_const_cast(extension)); 298 + } 299 + 300 + bool pb_default_field_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_t *field) 301 + { 302 + if (field->data_size == sizeof(pb_callback_t)) 303 + { 304 + pb_callback_t *pCallback = (pb_callback_t*)field->pData; 305 + 306 + if (pCallback != NULL) 307 + { 308 + if (istream != NULL && pCallback->funcs.decode != NULL) 309 + { 310 + return pCallback->funcs.decode(istream, field, &pCallback->arg); 311 + } 312 + 313 + if (ostream != NULL && pCallback->funcs.encode != NULL) 314 + { 315 + return pCallback->funcs.encode(ostream, field, &pCallback->arg); 316 + } 317 + } 318 + } 319 + 320 + return true; /* Success, but didn't do anything */ 321 + 322 + } 323 + 324 + #ifdef PB_VALIDATE_UTF8 325 + 326 + /* This function checks whether a string is valid UTF-8 text. 327 + * 328 + * Algorithm is adapted from https://www.cl.cam.ac.uk/~mgk25/ucs/utf8_check.c 329 + * Original copyright: Markus Kuhn <http://www.cl.cam.ac.uk/~mgk25/> 2005-03-30 330 + * Licensed under "Short code license", which allows use under MIT license or 331 + * any compatible with it. 332 + */ 333 + 334 + bool pb_validate_utf8(const char *str) 335 + { 336 + const pb_byte_t *s = (const pb_byte_t*)str; 337 + while (*s) 338 + { 339 + if (*s < 0x80) 340 + { 341 + /* 0xxxxxxx */ 342 + s++; 343 + } 344 + else if ((s[0] & 0xe0) == 0xc0) 345 + { 346 + /* 110XXXXx 10xxxxxx */ 347 + if ((s[1] & 0xc0) != 0x80 || 348 + (s[0] & 0xfe) == 0xc0) /* overlong? */ 349 + return false; 350 + else 351 + s += 2; 352 + } 353 + else if ((s[0] & 0xf0) == 0xe0) 354 + { 355 + /* 1110XXXX 10Xxxxxx 10xxxxxx */ 356 + if ((s[1] & 0xc0) != 0x80 || 357 + (s[2] & 0xc0) != 0x80 || 358 + (s[0] == 0xe0 && (s[1] & 0xe0) == 0x80) || /* overlong? */ 359 + (s[0] == 0xed && (s[1] & 0xe0) == 0xa0) || /* surrogate? */ 360 + (s[0] == 0xef && s[1] == 0xbf && 361 + (s[2] & 0xfe) == 0xbe)) /* U+FFFE or U+FFFF? */ 362 + return false; 363 + else 364 + s += 3; 365 + } 366 + else if ((s[0] & 0xf8) == 0xf0) 367 + { 368 + /* 11110XXX 10XXxxxx 10xxxxxx 10xxxxxx */ 369 + if ((s[1] & 0xc0) != 0x80 || 370 + (s[2] & 0xc0) != 0x80 || 371 + (s[3] & 0xc0) != 0x80 || 372 + (s[0] == 0xf0 && (s[1] & 0xf0) == 0x80) || /* overlong? */ 373 + (s[0] == 0xf4 && s[1] > 0x8f) || s[0] > 0xf4) /* > U+10FFFF? */ 374 + return false; 375 + else 376 + s += 4; 377 + } 378 + else 379 + { 380 + return false; 381 + } 382 + } 383 + 384 + return true; 385 + } 386 + 387 + #endif 388 +
+49
src/external/nanopb/pb_common.h
··· 1 + /* pb_common.h: Common support functions for pb_encode.c and pb_decode.c. 2 + * These functions are rarely needed by applications directly. 3 + */ 4 + 5 + #ifndef PB_COMMON_H_INCLUDED 6 + #define PB_COMMON_H_INCLUDED 7 + 8 + #include "pb.h" 9 + 10 + #ifdef __cplusplus 11 + extern "C" { 12 + #endif 13 + 14 + /* Initialize the field iterator structure to beginning. 15 + * Returns false if the message type is empty. */ 16 + bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_msgdesc_t *desc, void *message); 17 + 18 + /* Get a field iterator for extension field. */ 19 + bool pb_field_iter_begin_extension(pb_field_iter_t *iter, pb_extension_t *extension); 20 + 21 + /* Same as pb_field_iter_begin(), but for const message pointer. 22 + * Note that the pointers in pb_field_iter_t will be non-const but shouldn't 23 + * be written to when using these functions. */ 24 + bool pb_field_iter_begin_const(pb_field_iter_t *iter, const pb_msgdesc_t *desc, const void *message); 25 + bool pb_field_iter_begin_extension_const(pb_field_iter_t *iter, const pb_extension_t *extension); 26 + 27 + /* Advance the iterator to the next field. 28 + * Returns false when the iterator wraps back to the first field. */ 29 + bool pb_field_iter_next(pb_field_iter_t *iter); 30 + 31 + /* Advance the iterator until it points at a field with the given tag. 32 + * Returns false if no such field exists. */ 33 + bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag); 34 + 35 + /* Find a field with type PB_LTYPE_EXTENSION, or return false if not found. 36 + * There can be only one extension range field per message. */ 37 + bool pb_field_iter_find_extension(pb_field_iter_t *iter); 38 + 39 + #ifdef PB_VALIDATE_UTF8 40 + /* Validate UTF-8 text string */ 41 + bool pb_validate_utf8(const char *s); 42 + #endif 43 + 44 + #ifdef __cplusplus 45 + } /* extern "C" */ 46 + #endif 47 + 48 + #endif 49 +
+1716
src/external/nanopb/pb_decode.c
··· 1 + /* pb_decode.c -- decode a protobuf using minimal resources 2 + * 3 + * 2011 Petteri Aimonen <jpa@kapsi.fi> 4 + */ 5 + 6 + /* Use the GCC warn_unused_result attribute to check that all return values 7 + * are propagated correctly. On other compilers and gcc before 3.4.0 just 8 + * ignore the annotation. 9 + */ 10 + #if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) 11 + #define checkreturn 12 + #else 13 + #define checkreturn __attribute__((warn_unused_result)) 14 + #endif 15 + 16 + #include "pb.h" 17 + #include "pb_decode.h" 18 + #include "pb_common.h" 19 + 20 + /************************************** 21 + * Declarations internal to this file * 22 + **************************************/ 23 + 24 + static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count); 25 + static bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, uint32_t *dest, bool *eof); 26 + static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size); 27 + static bool checkreturn decode_basic_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field); 28 + static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field); 29 + static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field); 30 + static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field); 31 + static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field); 32 + static bool checkreturn default_extension_decoder(pb_istream_t *stream, pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type); 33 + static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, pb_wire_type_t wire_type, pb_extension_t *extension); 34 + static bool pb_field_set_to_default(pb_field_iter_t *field); 35 + static bool pb_message_set_to_defaults(pb_field_iter_t *iter); 36 + static bool checkreturn pb_dec_bool(pb_istream_t *stream, const pb_field_iter_t *field); 37 + static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_iter_t *field); 38 + static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_iter_t *field); 39 + static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_iter_t *field); 40 + static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_iter_t *field); 41 + static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_iter_t *field); 42 + static bool checkreturn pb_skip_varint(pb_istream_t *stream); 43 + static bool checkreturn pb_skip_string(pb_istream_t *stream); 44 + 45 + #ifdef PB_ENABLE_MALLOC 46 + static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size); 47 + static void initialize_pointer_field(void *pItem, pb_field_iter_t *field); 48 + static bool checkreturn pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *field); 49 + static void pb_release_single_field(pb_field_iter_t *field); 50 + #endif 51 + 52 + #ifdef PB_WITHOUT_64BIT 53 + #define pb_int64_t int32_t 54 + #define pb_uint64_t uint32_t 55 + #else 56 + #define pb_int64_t int64_t 57 + #define pb_uint64_t uint64_t 58 + #endif 59 + 60 + typedef struct { 61 + uint32_t bitfield[(PB_MAX_REQUIRED_FIELDS + 31) / 32]; 62 + } pb_fields_seen_t; 63 + 64 + /******************************* 65 + * pb_istream_t implementation * 66 + *******************************/ 67 + 68 + static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count) 69 + { 70 + const pb_byte_t *source = (const pb_byte_t*)stream->state; 71 + stream->state = (pb_byte_t*)stream->state + count; 72 + 73 + if (buf != NULL) 74 + { 75 + memcpy(buf, source, count * sizeof(pb_byte_t)); 76 + } 77 + 78 + return true; 79 + } 80 + 81 + bool checkreturn pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count) 82 + { 83 + if (count == 0) 84 + return true; 85 + 86 + #ifndef PB_BUFFER_ONLY 87 + if (buf == NULL && stream->callback != buf_read) 88 + { 89 + /* Skip input bytes */ 90 + pb_byte_t tmp[16]; 91 + while (count > 16) 92 + { 93 + if (!pb_read(stream, tmp, 16)) 94 + return false; 95 + 96 + count -= 16; 97 + } 98 + 99 + return pb_read(stream, tmp, count); 100 + } 101 + #endif 102 + 103 + if (stream->bytes_left < count) 104 + PB_RETURN_ERROR(stream, "end-of-stream"); 105 + 106 + #ifndef PB_BUFFER_ONLY 107 + if (!stream->callback(stream, buf, count)) 108 + PB_RETURN_ERROR(stream, "io error"); 109 + #else 110 + if (!buf_read(stream, buf, count)) 111 + return false; 112 + #endif 113 + 114 + stream->bytes_left -= count; 115 + return true; 116 + } 117 + 118 + /* Read a single byte from input stream. buf may not be NULL. 119 + * This is an optimization for the varint decoding. */ 120 + static bool checkreturn pb_readbyte(pb_istream_t *stream, pb_byte_t *buf) 121 + { 122 + if (stream->bytes_left == 0) 123 + PB_RETURN_ERROR(stream, "end-of-stream"); 124 + 125 + #ifndef PB_BUFFER_ONLY 126 + if (!stream->callback(stream, buf, 1)) 127 + PB_RETURN_ERROR(stream, "io error"); 128 + #else 129 + *buf = *(const pb_byte_t*)stream->state; 130 + stream->state = (pb_byte_t*)stream->state + 1; 131 + #endif 132 + 133 + stream->bytes_left--; 134 + 135 + return true; 136 + } 137 + 138 + pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t msglen) 139 + { 140 + pb_istream_t stream; 141 + /* Cast away the const from buf without a compiler error. We are 142 + * careful to use it only in a const manner in the callbacks. 143 + */ 144 + union { 145 + void *state; 146 + const void *c_state; 147 + } state; 148 + #ifdef PB_BUFFER_ONLY 149 + stream.callback = NULL; 150 + #else 151 + stream.callback = &buf_read; 152 + #endif 153 + state.c_state = buf; 154 + stream.state = state.state; 155 + stream.bytes_left = msglen; 156 + #ifndef PB_NO_ERRMSG 157 + stream.errmsg = NULL; 158 + #endif 159 + return stream; 160 + } 161 + 162 + /******************** 163 + * Helper functions * 164 + ********************/ 165 + 166 + static bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, uint32_t *dest, bool *eof) 167 + { 168 + pb_byte_t byte; 169 + uint32_t result; 170 + 171 + if (!pb_readbyte(stream, &byte)) 172 + { 173 + if (stream->bytes_left == 0) 174 + { 175 + if (eof) 176 + { 177 + *eof = true; 178 + } 179 + } 180 + 181 + return false; 182 + } 183 + 184 + if ((byte & 0x80) == 0) 185 + { 186 + /* Quick case, 1 byte value */ 187 + result = byte; 188 + } 189 + else 190 + { 191 + /* Multibyte case */ 192 + uint_fast8_t bitpos = 7; 193 + result = byte & 0x7F; 194 + 195 + do 196 + { 197 + if (!pb_readbyte(stream, &byte)) 198 + return false; 199 + 200 + if (bitpos >= 32) 201 + { 202 + /* Note: The varint could have trailing 0x80 bytes, or 0xFF for negative. */ 203 + pb_byte_t sign_extension = (bitpos < 63) ? 0xFF : 0x01; 204 + bool valid_extension = ((byte & 0x7F) == 0x00 || 205 + ((result >> 31) != 0 && byte == sign_extension)); 206 + 207 + if (bitpos >= 64 || !valid_extension) 208 + { 209 + PB_RETURN_ERROR(stream, "varint overflow"); 210 + } 211 + } 212 + else if (bitpos == 28) 213 + { 214 + if ((byte & 0x70) != 0 && (byte & 0x78) != 0x78) 215 + { 216 + PB_RETURN_ERROR(stream, "varint overflow"); 217 + } 218 + result |= (uint32_t)(byte & 0x0F) << bitpos; 219 + } 220 + else 221 + { 222 + result |= (uint32_t)(byte & 0x7F) << bitpos; 223 + } 224 + bitpos = (uint_fast8_t)(bitpos + 7); 225 + } while (byte & 0x80); 226 + } 227 + 228 + *dest = result; 229 + return true; 230 + } 231 + 232 + bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest) 233 + { 234 + return pb_decode_varint32_eof(stream, dest, NULL); 235 + } 236 + 237 + #ifndef PB_WITHOUT_64BIT 238 + bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest) 239 + { 240 + pb_byte_t byte; 241 + uint_fast8_t bitpos = 0; 242 + uint64_t result = 0; 243 + 244 + do 245 + { 246 + if (!pb_readbyte(stream, &byte)) 247 + return false; 248 + 249 + if (bitpos >= 63 && (byte & 0xFE) != 0) 250 + PB_RETURN_ERROR(stream, "varint overflow"); 251 + 252 + result |= (uint64_t)(byte & 0x7F) << bitpos; 253 + bitpos = (uint_fast8_t)(bitpos + 7); 254 + } while (byte & 0x80); 255 + 256 + *dest = result; 257 + return true; 258 + } 259 + #endif 260 + 261 + bool checkreturn pb_skip_varint(pb_istream_t *stream) 262 + { 263 + pb_byte_t byte; 264 + do 265 + { 266 + if (!pb_read(stream, &byte, 1)) 267 + return false; 268 + } while (byte & 0x80); 269 + return true; 270 + } 271 + 272 + bool checkreturn pb_skip_string(pb_istream_t *stream) 273 + { 274 + uint32_t length; 275 + if (!pb_decode_varint32(stream, &length)) 276 + return false; 277 + 278 + if ((size_t)length != length) 279 + { 280 + PB_RETURN_ERROR(stream, "size too large"); 281 + } 282 + 283 + return pb_read(stream, NULL, (size_t)length); 284 + } 285 + 286 + bool checkreturn pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof) 287 + { 288 + uint32_t temp; 289 + *eof = false; 290 + *wire_type = (pb_wire_type_t) 0; 291 + *tag = 0; 292 + 293 + if (!pb_decode_varint32_eof(stream, &temp, eof)) 294 + { 295 + return false; 296 + } 297 + 298 + *tag = temp >> 3; 299 + *wire_type = (pb_wire_type_t)(temp & 7); 300 + return true; 301 + } 302 + 303 + bool checkreturn pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type) 304 + { 305 + switch (wire_type) 306 + { 307 + case PB_WT_VARINT: return pb_skip_varint(stream); 308 + case PB_WT_64BIT: return pb_read(stream, NULL, 8); 309 + case PB_WT_STRING: return pb_skip_string(stream); 310 + case PB_WT_32BIT: return pb_read(stream, NULL, 4); 311 + default: PB_RETURN_ERROR(stream, "invalid wire_type"); 312 + } 313 + } 314 + 315 + /* Read a raw value to buffer, for the purpose of passing it to callback as 316 + * a substream. Size is maximum size on call, and actual size on return. 317 + */ 318 + static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size) 319 + { 320 + size_t max_size = *size; 321 + switch (wire_type) 322 + { 323 + case PB_WT_VARINT: 324 + *size = 0; 325 + do 326 + { 327 + (*size)++; 328 + if (*size > max_size) 329 + PB_RETURN_ERROR(stream, "varint overflow"); 330 + 331 + if (!pb_read(stream, buf, 1)) 332 + return false; 333 + } while (*buf++ & 0x80); 334 + return true; 335 + 336 + case PB_WT_64BIT: 337 + *size = 8; 338 + return pb_read(stream, buf, 8); 339 + 340 + case PB_WT_32BIT: 341 + *size = 4; 342 + return pb_read(stream, buf, 4); 343 + 344 + case PB_WT_STRING: 345 + /* Calling read_raw_value with a PB_WT_STRING is an error. 346 + * Explicitly handle this case and fallthrough to default to avoid 347 + * compiler warnings. 348 + */ 349 + 350 + default: PB_RETURN_ERROR(stream, "invalid wire_type"); 351 + } 352 + } 353 + 354 + /* Decode string length from stream and return a substream with limited length. 355 + * Remember to close the substream using pb_close_string_substream(). 356 + */ 357 + bool checkreturn pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream) 358 + { 359 + uint32_t size; 360 + if (!pb_decode_varint32(stream, &size)) 361 + return false; 362 + 363 + *substream = *stream; 364 + if (substream->bytes_left < size) 365 + PB_RETURN_ERROR(stream, "parent stream too short"); 366 + 367 + substream->bytes_left = (size_t)size; 368 + stream->bytes_left -= (size_t)size; 369 + return true; 370 + } 371 + 372 + bool checkreturn pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream) 373 + { 374 + if (substream->bytes_left) { 375 + if (!pb_read(substream, NULL, substream->bytes_left)) 376 + return false; 377 + } 378 + 379 + stream->state = substream->state; 380 + 381 + #ifndef PB_NO_ERRMSG 382 + stream->errmsg = substream->errmsg; 383 + #endif 384 + return true; 385 + } 386 + 387 + /************************* 388 + * Decode a single field * 389 + *************************/ 390 + 391 + static bool checkreturn decode_basic_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) 392 + { 393 + switch (PB_LTYPE(field->type)) 394 + { 395 + case PB_LTYPE_BOOL: 396 + if (wire_type != PB_WT_VARINT && wire_type != PB_WT_PACKED) 397 + PB_RETURN_ERROR(stream, "wrong wire type"); 398 + 399 + return pb_dec_bool(stream, field); 400 + 401 + case PB_LTYPE_VARINT: 402 + case PB_LTYPE_UVARINT: 403 + case PB_LTYPE_SVARINT: 404 + if (wire_type != PB_WT_VARINT && wire_type != PB_WT_PACKED) 405 + PB_RETURN_ERROR(stream, "wrong wire type"); 406 + 407 + return pb_dec_varint(stream, field); 408 + 409 + case PB_LTYPE_FIXED32: 410 + if (wire_type != PB_WT_32BIT && wire_type != PB_WT_PACKED) 411 + PB_RETURN_ERROR(stream, "wrong wire type"); 412 + 413 + return pb_decode_fixed32(stream, field->pData); 414 + 415 + case PB_LTYPE_FIXED64: 416 + if (wire_type != PB_WT_64BIT && wire_type != PB_WT_PACKED) 417 + PB_RETURN_ERROR(stream, "wrong wire type"); 418 + 419 + #ifdef PB_CONVERT_DOUBLE_FLOAT 420 + if (field->data_size == sizeof(float)) 421 + { 422 + return pb_decode_double_as_float(stream, (float*)field->pData); 423 + } 424 + #endif 425 + 426 + #ifdef PB_WITHOUT_64BIT 427 + PB_RETURN_ERROR(stream, "invalid data_size"); 428 + #else 429 + return pb_decode_fixed64(stream, field->pData); 430 + #endif 431 + 432 + case PB_LTYPE_BYTES: 433 + if (wire_type != PB_WT_STRING) 434 + PB_RETURN_ERROR(stream, "wrong wire type"); 435 + 436 + return pb_dec_bytes(stream, field); 437 + 438 + case PB_LTYPE_STRING: 439 + if (wire_type != PB_WT_STRING) 440 + PB_RETURN_ERROR(stream, "wrong wire type"); 441 + 442 + return pb_dec_string(stream, field); 443 + 444 + case PB_LTYPE_SUBMESSAGE: 445 + case PB_LTYPE_SUBMSG_W_CB: 446 + if (wire_type != PB_WT_STRING) 447 + PB_RETURN_ERROR(stream, "wrong wire type"); 448 + 449 + return pb_dec_submessage(stream, field); 450 + 451 + case PB_LTYPE_FIXED_LENGTH_BYTES: 452 + if (wire_type != PB_WT_STRING) 453 + PB_RETURN_ERROR(stream, "wrong wire type"); 454 + 455 + return pb_dec_fixed_length_bytes(stream, field); 456 + 457 + default: 458 + PB_RETURN_ERROR(stream, "invalid field type"); 459 + } 460 + } 461 + 462 + static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) 463 + { 464 + switch (PB_HTYPE(field->type)) 465 + { 466 + case PB_HTYPE_REQUIRED: 467 + return decode_basic_field(stream, wire_type, field); 468 + 469 + case PB_HTYPE_OPTIONAL: 470 + if (field->pSize != NULL) 471 + *(bool*)field->pSize = true; 472 + return decode_basic_field(stream, wire_type, field); 473 + 474 + case PB_HTYPE_REPEATED: 475 + if (wire_type == PB_WT_STRING 476 + && PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) 477 + { 478 + /* Packed array */ 479 + bool status = true; 480 + pb_istream_t substream; 481 + pb_size_t *size = (pb_size_t*)field->pSize; 482 + field->pData = (char*)field->pField + field->data_size * (*size); 483 + 484 + if (!pb_make_string_substream(stream, &substream)) 485 + return false; 486 + 487 + while (substream.bytes_left > 0 && *size < field->array_size) 488 + { 489 + if (!decode_basic_field(&substream, PB_WT_PACKED, field)) 490 + { 491 + status = false; 492 + break; 493 + } 494 + (*size)++; 495 + field->pData = (char*)field->pData + field->data_size; 496 + } 497 + 498 + if (substream.bytes_left != 0) 499 + PB_RETURN_ERROR(stream, "array overflow"); 500 + if (!pb_close_string_substream(stream, &substream)) 501 + return false; 502 + 503 + return status; 504 + } 505 + else 506 + { 507 + /* Repeated field */ 508 + pb_size_t *size = (pb_size_t*)field->pSize; 509 + field->pData = (char*)field->pField + field->data_size * (*size); 510 + 511 + if ((*size)++ >= field->array_size) 512 + PB_RETURN_ERROR(stream, "array overflow"); 513 + 514 + return decode_basic_field(stream, wire_type, field); 515 + } 516 + 517 + case PB_HTYPE_ONEOF: 518 + if (PB_LTYPE_IS_SUBMSG(field->type) && 519 + *(pb_size_t*)field->pSize != field->tag) 520 + { 521 + /* We memset to zero so that any callbacks are set to NULL. 522 + * This is because the callbacks might otherwise have values 523 + * from some other union field. 524 + * If callbacks are needed inside oneof field, use .proto 525 + * option submsg_callback to have a separate callback function 526 + * that can set the fields before submessage is decoded. 527 + * pb_dec_submessage() will set any default values. */ 528 + memset(field->pData, 0, (size_t)field->data_size); 529 + 530 + /* Set default values for the submessage fields. */ 531 + if (field->submsg_desc->default_value != NULL || 532 + field->submsg_desc->field_callback != NULL || 533 + field->submsg_desc->submsg_info[0] != NULL) 534 + { 535 + pb_field_iter_t submsg_iter; 536 + if (pb_field_iter_begin(&submsg_iter, field->submsg_desc, field->pData)) 537 + { 538 + if (!pb_message_set_to_defaults(&submsg_iter)) 539 + PB_RETURN_ERROR(stream, "failed to set defaults"); 540 + } 541 + } 542 + } 543 + *(pb_size_t*)field->pSize = field->tag; 544 + 545 + return decode_basic_field(stream, wire_type, field); 546 + 547 + default: 548 + PB_RETURN_ERROR(stream, "invalid field type"); 549 + } 550 + } 551 + 552 + #ifdef PB_ENABLE_MALLOC 553 + /* Allocate storage for the field and store the pointer at iter->pData. 554 + * array_size is the number of entries to reserve in an array. 555 + * Zero size is not allowed, use pb_free() for releasing. 556 + */ 557 + static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size) 558 + { 559 + void *ptr = *(void**)pData; 560 + 561 + if (data_size == 0 || array_size == 0) 562 + PB_RETURN_ERROR(stream, "invalid size"); 563 + 564 + #ifdef __AVR__ 565 + /* Workaround for AVR libc bug 53284: http://savannah.nongnu.org/bugs/?53284 566 + * Realloc to size of 1 byte can cause corruption of the malloc structures. 567 + */ 568 + if (data_size == 1 && array_size == 1) 569 + { 570 + data_size = 2; 571 + } 572 + #endif 573 + 574 + /* Check for multiplication overflows. 575 + * This code avoids the costly division if the sizes are small enough. 576 + * Multiplication is safe as long as only half of bits are set 577 + * in either multiplicand. 578 + */ 579 + { 580 + const size_t check_limit = (size_t)1 << (sizeof(size_t) * 4); 581 + if (data_size >= check_limit || array_size >= check_limit) 582 + { 583 + const size_t size_max = (size_t)-1; 584 + if (size_max / array_size < data_size) 585 + { 586 + PB_RETURN_ERROR(stream, "size too large"); 587 + } 588 + } 589 + } 590 + 591 + /* Allocate new or expand previous allocation */ 592 + /* Note: on failure the old pointer will remain in the structure, 593 + * the message must be freed by caller also on error return. */ 594 + ptr = pb_realloc(ptr, array_size * data_size); 595 + if (ptr == NULL) 596 + PB_RETURN_ERROR(stream, "realloc failed"); 597 + 598 + *(void**)pData = ptr; 599 + return true; 600 + } 601 + 602 + /* Clear a newly allocated item in case it contains a pointer, or is a submessage. */ 603 + static void initialize_pointer_field(void *pItem, pb_field_iter_t *field) 604 + { 605 + if (PB_LTYPE(field->type) == PB_LTYPE_STRING || 606 + PB_LTYPE(field->type) == PB_LTYPE_BYTES) 607 + { 608 + *(void**)pItem = NULL; 609 + } 610 + else if (PB_LTYPE_IS_SUBMSG(field->type)) 611 + { 612 + /* We memset to zero so that any callbacks are set to NULL. 613 + * Default values will be set by pb_dec_submessage(). */ 614 + memset(pItem, 0, field->data_size); 615 + } 616 + } 617 + #endif 618 + 619 + static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) 620 + { 621 + #ifndef PB_ENABLE_MALLOC 622 + PB_UNUSED(wire_type); 623 + PB_UNUSED(field); 624 + PB_RETURN_ERROR(stream, "no malloc support"); 625 + #else 626 + switch (PB_HTYPE(field->type)) 627 + { 628 + case PB_HTYPE_REQUIRED: 629 + case PB_HTYPE_OPTIONAL: 630 + case PB_HTYPE_ONEOF: 631 + if (PB_LTYPE_IS_SUBMSG(field->type) && *(void**)field->pField != NULL) 632 + { 633 + /* Duplicate field, have to release the old allocation first. */ 634 + /* FIXME: Does this work correctly for oneofs? */ 635 + pb_release_single_field(field); 636 + } 637 + 638 + if (PB_HTYPE(field->type) == PB_HTYPE_ONEOF) 639 + { 640 + *(pb_size_t*)field->pSize = field->tag; 641 + } 642 + 643 + if (PB_LTYPE(field->type) == PB_LTYPE_STRING || 644 + PB_LTYPE(field->type) == PB_LTYPE_BYTES) 645 + { 646 + /* pb_dec_string and pb_dec_bytes handle allocation themselves */ 647 + field->pData = field->pField; 648 + return decode_basic_field(stream, wire_type, field); 649 + } 650 + else 651 + { 652 + if (!allocate_field(stream, field->pField, field->data_size, 1)) 653 + return false; 654 + 655 + field->pData = *(void**)field->pField; 656 + initialize_pointer_field(field->pData, field); 657 + return decode_basic_field(stream, wire_type, field); 658 + } 659 + 660 + case PB_HTYPE_REPEATED: 661 + if (wire_type == PB_WT_STRING 662 + && PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) 663 + { 664 + /* Packed array, multiple items come in at once. */ 665 + bool status = true; 666 + pb_size_t *size = (pb_size_t*)field->pSize; 667 + size_t allocated_size = *size; 668 + pb_istream_t substream; 669 + 670 + if (!pb_make_string_substream(stream, &substream)) 671 + return false; 672 + 673 + while (substream.bytes_left) 674 + { 675 + if (*size == PB_SIZE_MAX) 676 + { 677 + #ifndef PB_NO_ERRMSG 678 + stream->errmsg = "too many array entries"; 679 + #endif 680 + status = false; 681 + break; 682 + } 683 + 684 + if ((size_t)*size + 1 > allocated_size) 685 + { 686 + /* Allocate more storage. This tries to guess the 687 + * number of remaining entries. Round the division 688 + * upwards. */ 689 + size_t remain = (substream.bytes_left - 1) / field->data_size + 1; 690 + if (remain < PB_SIZE_MAX - allocated_size) 691 + allocated_size += remain; 692 + else 693 + allocated_size += 1; 694 + 695 + if (!allocate_field(&substream, field->pField, field->data_size, allocated_size)) 696 + { 697 + status = false; 698 + break; 699 + } 700 + } 701 + 702 + /* Decode the array entry */ 703 + field->pData = *(char**)field->pField + field->data_size * (*size); 704 + if (field->pData == NULL) 705 + { 706 + /* Shouldn't happen, but satisfies static analyzers */ 707 + status = false; 708 + break; 709 + } 710 + initialize_pointer_field(field->pData, field); 711 + if (!decode_basic_field(&substream, PB_WT_PACKED, field)) 712 + { 713 + status = false; 714 + break; 715 + } 716 + 717 + (*size)++; 718 + } 719 + if (!pb_close_string_substream(stream, &substream)) 720 + return false; 721 + 722 + return status; 723 + } 724 + else 725 + { 726 + /* Normal repeated field, i.e. only one item at a time. */ 727 + pb_size_t *size = (pb_size_t*)field->pSize; 728 + 729 + if (*size == PB_SIZE_MAX) 730 + PB_RETURN_ERROR(stream, "too many array entries"); 731 + 732 + if (!allocate_field(stream, field->pField, field->data_size, (size_t)(*size + 1))) 733 + return false; 734 + 735 + field->pData = *(char**)field->pField + field->data_size * (*size); 736 + (*size)++; 737 + initialize_pointer_field(field->pData, field); 738 + return decode_basic_field(stream, wire_type, field); 739 + } 740 + 741 + default: 742 + PB_RETURN_ERROR(stream, "invalid field type"); 743 + } 744 + #endif 745 + } 746 + 747 + static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) 748 + { 749 + if (!field->descriptor->field_callback) 750 + return pb_skip_field(stream, wire_type); 751 + 752 + if (wire_type == PB_WT_STRING) 753 + { 754 + pb_istream_t substream; 755 + size_t prev_bytes_left; 756 + 757 + if (!pb_make_string_substream(stream, &substream)) 758 + return false; 759 + 760 + do 761 + { 762 + prev_bytes_left = substream.bytes_left; 763 + if (!field->descriptor->field_callback(&substream, NULL, field)) 764 + { 765 + PB_SET_ERROR(stream, substream.errmsg ? substream.errmsg : "callback failed"); 766 + return false; 767 + } 768 + } while (substream.bytes_left > 0 && substream.bytes_left < prev_bytes_left); 769 + 770 + if (!pb_close_string_substream(stream, &substream)) 771 + return false; 772 + 773 + return true; 774 + } 775 + else 776 + { 777 + /* Copy the single scalar value to stack. 778 + * This is required so that we can limit the stream length, 779 + * which in turn allows to use same callback for packed and 780 + * not-packed fields. */ 781 + pb_istream_t substream; 782 + pb_byte_t buffer[10]; 783 + size_t size = sizeof(buffer); 784 + 785 + if (!read_raw_value(stream, wire_type, buffer, &size)) 786 + return false; 787 + substream = pb_istream_from_buffer(buffer, size); 788 + 789 + return field->descriptor->field_callback(&substream, NULL, field); 790 + } 791 + } 792 + 793 + static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) 794 + { 795 + #ifdef PB_ENABLE_MALLOC 796 + /* When decoding an oneof field, check if there is old data that must be 797 + * released first. */ 798 + if (PB_HTYPE(field->type) == PB_HTYPE_ONEOF) 799 + { 800 + if (!pb_release_union_field(stream, field)) 801 + return false; 802 + } 803 + #endif 804 + 805 + switch (PB_ATYPE(field->type)) 806 + { 807 + case PB_ATYPE_STATIC: 808 + return decode_static_field(stream, wire_type, field); 809 + 810 + case PB_ATYPE_POINTER: 811 + return decode_pointer_field(stream, wire_type, field); 812 + 813 + case PB_ATYPE_CALLBACK: 814 + return decode_callback_field(stream, wire_type, field); 815 + 816 + default: 817 + PB_RETURN_ERROR(stream, "invalid field type"); 818 + } 819 + } 820 + 821 + /* Default handler for extension fields. Expects to have a pb_msgdesc_t 822 + * pointer in the extension->type->arg field, pointing to a message with 823 + * only one field in it. */ 824 + static bool checkreturn default_extension_decoder(pb_istream_t *stream, 825 + pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type) 826 + { 827 + pb_field_iter_t iter; 828 + 829 + if (!pb_field_iter_begin_extension(&iter, extension)) 830 + PB_RETURN_ERROR(stream, "invalid extension"); 831 + 832 + if (iter.tag != tag || !iter.message) 833 + return true; 834 + 835 + extension->found = true; 836 + return decode_field(stream, wire_type, &iter); 837 + } 838 + 839 + /* Try to decode an unknown field as an extension field. Tries each extension 840 + * decoder in turn, until one of them handles the field or loop ends. */ 841 + static bool checkreturn decode_extension(pb_istream_t *stream, 842 + uint32_t tag, pb_wire_type_t wire_type, pb_extension_t *extension) 843 + { 844 + size_t pos = stream->bytes_left; 845 + 846 + while (extension != NULL && pos == stream->bytes_left) 847 + { 848 + bool status; 849 + if (extension->type->decode) 850 + status = extension->type->decode(stream, extension, tag, wire_type); 851 + else 852 + status = default_extension_decoder(stream, extension, tag, wire_type); 853 + 854 + if (!status) 855 + return false; 856 + 857 + extension = extension->next; 858 + } 859 + 860 + return true; 861 + } 862 + 863 + /* Initialize message fields to default values, recursively */ 864 + static bool pb_field_set_to_default(pb_field_iter_t *field) 865 + { 866 + pb_type_t type; 867 + type = field->type; 868 + 869 + if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) 870 + { 871 + pb_extension_t *ext = *(pb_extension_t* const *)field->pData; 872 + while (ext != NULL) 873 + { 874 + pb_field_iter_t ext_iter; 875 + if (pb_field_iter_begin_extension(&ext_iter, ext)) 876 + { 877 + ext->found = false; 878 + if (!pb_message_set_to_defaults(&ext_iter)) 879 + return false; 880 + } 881 + ext = ext->next; 882 + } 883 + } 884 + else if (PB_ATYPE(type) == PB_ATYPE_STATIC) 885 + { 886 + bool init_data = true; 887 + if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL && field->pSize != NULL) 888 + { 889 + /* Set has_field to false. Still initialize the optional field 890 + * itself also. */ 891 + *(bool*)field->pSize = false; 892 + } 893 + else if (PB_HTYPE(type) == PB_HTYPE_REPEATED || 894 + PB_HTYPE(type) == PB_HTYPE_ONEOF) 895 + { 896 + /* REPEATED: Set array count to 0, no need to initialize contents. 897 + ONEOF: Set which_field to 0. */ 898 + *(pb_size_t*)field->pSize = 0; 899 + init_data = false; 900 + } 901 + 902 + if (init_data) 903 + { 904 + if (PB_LTYPE_IS_SUBMSG(field->type) && 905 + (field->submsg_desc->default_value != NULL || 906 + field->submsg_desc->field_callback != NULL || 907 + field->submsg_desc->submsg_info[0] != NULL)) 908 + { 909 + /* Initialize submessage to defaults. 910 + * Only needed if it has default values 911 + * or callback/submessage fields. */ 912 + pb_field_iter_t submsg_iter; 913 + if (pb_field_iter_begin(&submsg_iter, field->submsg_desc, field->pData)) 914 + { 915 + if (!pb_message_set_to_defaults(&submsg_iter)) 916 + return false; 917 + } 918 + } 919 + else 920 + { 921 + /* Initialize to zeros */ 922 + memset(field->pData, 0, (size_t)field->data_size); 923 + } 924 + } 925 + } 926 + else if (PB_ATYPE(type) == PB_ATYPE_POINTER) 927 + { 928 + /* Initialize the pointer to NULL. */ 929 + *(void**)field->pField = NULL; 930 + 931 + /* Initialize array count to 0. */ 932 + if (PB_HTYPE(type) == PB_HTYPE_REPEATED || 933 + PB_HTYPE(type) == PB_HTYPE_ONEOF) 934 + { 935 + *(pb_size_t*)field->pSize = 0; 936 + } 937 + } 938 + else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK) 939 + { 940 + /* Don't overwrite callback */ 941 + } 942 + 943 + return true; 944 + } 945 + 946 + static bool pb_message_set_to_defaults(pb_field_iter_t *iter) 947 + { 948 + pb_istream_t defstream = PB_ISTREAM_EMPTY; 949 + uint32_t tag = 0; 950 + pb_wire_type_t wire_type = PB_WT_VARINT; 951 + bool eof; 952 + 953 + if (iter->descriptor->default_value) 954 + { 955 + defstream = pb_istream_from_buffer(iter->descriptor->default_value, (size_t)-1); 956 + if (!pb_decode_tag(&defstream, &wire_type, &tag, &eof)) 957 + return false; 958 + } 959 + 960 + do 961 + { 962 + if (!pb_field_set_to_default(iter)) 963 + return false; 964 + 965 + if (tag != 0 && iter->tag == tag) 966 + { 967 + /* We have a default value for this field in the defstream */ 968 + if (!decode_field(&defstream, wire_type, iter)) 969 + return false; 970 + if (!pb_decode_tag(&defstream, &wire_type, &tag, &eof)) 971 + return false; 972 + 973 + if (iter->pSize) 974 + *(bool*)iter->pSize = false; 975 + } 976 + } while (pb_field_iter_next(iter)); 977 + 978 + return true; 979 + } 980 + 981 + /********************* 982 + * Decode all fields * 983 + *********************/ 984 + 985 + static bool checkreturn pb_decode_inner(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct, unsigned int flags) 986 + { 987 + uint32_t extension_range_start = 0; 988 + pb_extension_t *extensions = NULL; 989 + 990 + /* 'fixed_count_field' and 'fixed_count_size' track position of a repeated fixed 991 + * count field. This can only handle _one_ repeated fixed count field that 992 + * is unpacked and unordered among other (non repeated fixed count) fields. 993 + */ 994 + pb_size_t fixed_count_field = PB_SIZE_MAX; 995 + pb_size_t fixed_count_size = 0; 996 + pb_size_t fixed_count_total_size = 0; 997 + 998 + pb_fields_seen_t fields_seen = {{0, 0}}; 999 + const uint32_t allbits = ~(uint32_t)0; 1000 + pb_field_iter_t iter; 1001 + 1002 + if (pb_field_iter_begin(&iter, fields, dest_struct)) 1003 + { 1004 + if ((flags & PB_DECODE_NOINIT) == 0) 1005 + { 1006 + if (!pb_message_set_to_defaults(&iter)) 1007 + PB_RETURN_ERROR(stream, "failed to set defaults"); 1008 + } 1009 + } 1010 + 1011 + while (stream->bytes_left) 1012 + { 1013 + uint32_t tag; 1014 + pb_wire_type_t wire_type; 1015 + bool eof; 1016 + 1017 + if (!pb_decode_tag(stream, &wire_type, &tag, &eof)) 1018 + { 1019 + if (eof) 1020 + break; 1021 + else 1022 + return false; 1023 + } 1024 + 1025 + if (tag == 0) 1026 + { 1027 + if (flags & PB_DECODE_NULLTERMINATED) 1028 + { 1029 + break; 1030 + } 1031 + else 1032 + { 1033 + PB_RETURN_ERROR(stream, "zero tag"); 1034 + } 1035 + } 1036 + 1037 + if (!pb_field_iter_find(&iter, tag) || PB_LTYPE(iter.type) == PB_LTYPE_EXTENSION) 1038 + { 1039 + /* No match found, check if it matches an extension. */ 1040 + if (extension_range_start == 0) 1041 + { 1042 + if (pb_field_iter_find_extension(&iter)) 1043 + { 1044 + extensions = *(pb_extension_t* const *)iter.pData; 1045 + extension_range_start = iter.tag; 1046 + } 1047 + 1048 + if (!extensions) 1049 + { 1050 + extension_range_start = (uint32_t)-1; 1051 + } 1052 + } 1053 + 1054 + if (tag >= extension_range_start) 1055 + { 1056 + size_t pos = stream->bytes_left; 1057 + 1058 + if (!decode_extension(stream, tag, wire_type, extensions)) 1059 + return false; 1060 + 1061 + if (pos != stream->bytes_left) 1062 + { 1063 + /* The field was handled */ 1064 + continue; 1065 + } 1066 + } 1067 + 1068 + /* No match found, skip data */ 1069 + if (!pb_skip_field(stream, wire_type)) 1070 + return false; 1071 + continue; 1072 + } 1073 + 1074 + /* If a repeated fixed count field was found, get size from 1075 + * 'fixed_count_field' as there is no counter contained in the struct. 1076 + */ 1077 + if (PB_HTYPE(iter.type) == PB_HTYPE_REPEATED && iter.pSize == &iter.array_size) 1078 + { 1079 + if (fixed_count_field != iter.index) { 1080 + /* If the new fixed count field does not match the previous one, 1081 + * check that the previous one is NULL or that it finished 1082 + * receiving all the expected data. 1083 + */ 1084 + if (fixed_count_field != PB_SIZE_MAX && 1085 + fixed_count_size != fixed_count_total_size) 1086 + { 1087 + PB_RETURN_ERROR(stream, "wrong size for fixed count field"); 1088 + } 1089 + 1090 + fixed_count_field = iter.index; 1091 + fixed_count_size = 0; 1092 + fixed_count_total_size = iter.array_size; 1093 + } 1094 + 1095 + iter.pSize = &fixed_count_size; 1096 + } 1097 + 1098 + if (PB_HTYPE(iter.type) == PB_HTYPE_REQUIRED 1099 + && iter.required_field_index < PB_MAX_REQUIRED_FIELDS) 1100 + { 1101 + uint32_t tmp = ((uint32_t)1 << (iter.required_field_index & 31)); 1102 + fields_seen.bitfield[iter.required_field_index >> 5] |= tmp; 1103 + } 1104 + 1105 + if (!decode_field(stream, wire_type, &iter)) 1106 + return false; 1107 + } 1108 + 1109 + /* Check that all elements of the last decoded fixed count field were present. */ 1110 + if (fixed_count_field != PB_SIZE_MAX && 1111 + fixed_count_size != fixed_count_total_size) 1112 + { 1113 + PB_RETURN_ERROR(stream, "wrong size for fixed count field"); 1114 + } 1115 + 1116 + /* Check that all required fields were present. */ 1117 + { 1118 + pb_size_t req_field_count = iter.descriptor->required_field_count; 1119 + 1120 + if (req_field_count > 0) 1121 + { 1122 + pb_size_t i; 1123 + 1124 + if (req_field_count > PB_MAX_REQUIRED_FIELDS) 1125 + req_field_count = PB_MAX_REQUIRED_FIELDS; 1126 + 1127 + /* Check the whole words */ 1128 + for (i = 0; i < (req_field_count >> 5); i++) 1129 + { 1130 + if (fields_seen.bitfield[i] != allbits) 1131 + PB_RETURN_ERROR(stream, "missing required field"); 1132 + } 1133 + 1134 + /* Check the remaining bits (if any) */ 1135 + if ((req_field_count & 31) != 0) 1136 + { 1137 + if (fields_seen.bitfield[req_field_count >> 5] != 1138 + (allbits >> (uint_least8_t)(32 - (req_field_count & 31)))) 1139 + { 1140 + PB_RETURN_ERROR(stream, "missing required field"); 1141 + } 1142 + } 1143 + } 1144 + } 1145 + 1146 + return true; 1147 + } 1148 + 1149 + bool checkreturn pb_decode_ex(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct, unsigned int flags) 1150 + { 1151 + bool status; 1152 + 1153 + if ((flags & PB_DECODE_DELIMITED) == 0) 1154 + { 1155 + status = pb_decode_inner(stream, fields, dest_struct, flags); 1156 + } 1157 + else 1158 + { 1159 + pb_istream_t substream; 1160 + if (!pb_make_string_substream(stream, &substream)) 1161 + return false; 1162 + 1163 + status = pb_decode_inner(&substream, fields, dest_struct, flags); 1164 + 1165 + if (!pb_close_string_substream(stream, &substream)) 1166 + return false; 1167 + } 1168 + 1169 + #ifdef PB_ENABLE_MALLOC 1170 + if (!status) 1171 + pb_release(fields, dest_struct); 1172 + #endif 1173 + 1174 + return status; 1175 + } 1176 + 1177 + bool checkreturn pb_decode(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct) 1178 + { 1179 + bool status; 1180 + 1181 + status = pb_decode_inner(stream, fields, dest_struct, 0); 1182 + 1183 + #ifdef PB_ENABLE_MALLOC 1184 + if (!status) 1185 + pb_release(fields, dest_struct); 1186 + #endif 1187 + 1188 + return status; 1189 + } 1190 + 1191 + #ifdef PB_ENABLE_MALLOC 1192 + /* Given an oneof field, if there has already been a field inside this oneof, 1193 + * release it before overwriting with a different one. */ 1194 + static bool pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *field) 1195 + { 1196 + pb_field_iter_t old_field = *field; 1197 + pb_size_t old_tag = *(pb_size_t*)field->pSize; /* Previous which_ value */ 1198 + pb_size_t new_tag = field->tag; /* New which_ value */ 1199 + 1200 + if (old_tag == 0) 1201 + return true; /* Ok, no old data in union */ 1202 + 1203 + if (old_tag == new_tag) 1204 + return true; /* Ok, old data is of same type => merge */ 1205 + 1206 + /* Release old data. The find can fail if the message struct contains 1207 + * invalid data. */ 1208 + if (!pb_field_iter_find(&old_field, old_tag)) 1209 + PB_RETURN_ERROR(stream, "invalid union tag"); 1210 + 1211 + pb_release_single_field(&old_field); 1212 + 1213 + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) 1214 + { 1215 + /* Initialize the pointer to NULL to make sure it is valid 1216 + * even in case of error return. */ 1217 + *(void**)field->pField = NULL; 1218 + field->pData = NULL; 1219 + } 1220 + 1221 + return true; 1222 + } 1223 + 1224 + static void pb_release_single_field(pb_field_iter_t *field) 1225 + { 1226 + pb_type_t type; 1227 + type = field->type; 1228 + 1229 + if (PB_HTYPE(type) == PB_HTYPE_ONEOF) 1230 + { 1231 + if (*(pb_size_t*)field->pSize != field->tag) 1232 + return; /* This is not the current field in the union */ 1233 + } 1234 + 1235 + /* Release anything contained inside an extension or submsg. 1236 + * This has to be done even if the submsg itself is statically 1237 + * allocated. */ 1238 + if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) 1239 + { 1240 + /* Release fields from all extensions in the linked list */ 1241 + pb_extension_t *ext = *(pb_extension_t**)field->pData; 1242 + while (ext != NULL) 1243 + { 1244 + pb_field_iter_t ext_iter; 1245 + if (pb_field_iter_begin_extension(&ext_iter, ext)) 1246 + { 1247 + pb_release_single_field(&ext_iter); 1248 + } 1249 + ext = ext->next; 1250 + } 1251 + } 1252 + else if (PB_LTYPE_IS_SUBMSG(type) && PB_ATYPE(type) != PB_ATYPE_CALLBACK) 1253 + { 1254 + /* Release fields in submessage or submsg array */ 1255 + pb_size_t count = 1; 1256 + 1257 + if (PB_ATYPE(type) == PB_ATYPE_POINTER) 1258 + { 1259 + field->pData = *(void**)field->pField; 1260 + } 1261 + else 1262 + { 1263 + field->pData = field->pField; 1264 + } 1265 + 1266 + if (PB_HTYPE(type) == PB_HTYPE_REPEATED) 1267 + { 1268 + count = *(pb_size_t*)field->pSize; 1269 + 1270 + if (PB_ATYPE(type) == PB_ATYPE_STATIC && count > field->array_size) 1271 + { 1272 + /* Protect against corrupted _count fields */ 1273 + count = field->array_size; 1274 + } 1275 + } 1276 + 1277 + if (field->pData) 1278 + { 1279 + for (; count > 0; count--) 1280 + { 1281 + pb_release(field->submsg_desc, field->pData); 1282 + field->pData = (char*)field->pData + field->data_size; 1283 + } 1284 + } 1285 + } 1286 + 1287 + if (PB_ATYPE(type) == PB_ATYPE_POINTER) 1288 + { 1289 + if (PB_HTYPE(type) == PB_HTYPE_REPEATED && 1290 + (PB_LTYPE(type) == PB_LTYPE_STRING || 1291 + PB_LTYPE(type) == PB_LTYPE_BYTES)) 1292 + { 1293 + /* Release entries in repeated string or bytes array */ 1294 + void **pItem = *(void***)field->pField; 1295 + pb_size_t count = *(pb_size_t*)field->pSize; 1296 + for (; count > 0; count--) 1297 + { 1298 + pb_free(*pItem); 1299 + *pItem++ = NULL; 1300 + } 1301 + } 1302 + 1303 + if (PB_HTYPE(type) == PB_HTYPE_REPEATED) 1304 + { 1305 + /* We are going to release the array, so set the size to 0 */ 1306 + *(pb_size_t*)field->pSize = 0; 1307 + } 1308 + 1309 + /* Release main pointer */ 1310 + pb_free(*(void**)field->pField); 1311 + *(void**)field->pField = NULL; 1312 + } 1313 + } 1314 + 1315 + void pb_release(const pb_msgdesc_t *fields, void *dest_struct) 1316 + { 1317 + pb_field_iter_t iter; 1318 + 1319 + if (!dest_struct) 1320 + return; /* Ignore NULL pointers, similar to free() */ 1321 + 1322 + if (!pb_field_iter_begin(&iter, fields, dest_struct)) 1323 + return; /* Empty message type */ 1324 + 1325 + do 1326 + { 1327 + pb_release_single_field(&iter); 1328 + } while (pb_field_iter_next(&iter)); 1329 + } 1330 + #endif 1331 + 1332 + /* Field decoders */ 1333 + 1334 + bool pb_decode_bool(pb_istream_t *stream, bool *dest) 1335 + { 1336 + uint32_t value; 1337 + if (!pb_decode_varint32(stream, &value)) 1338 + return false; 1339 + 1340 + *(bool*)dest = (value != 0); 1341 + return true; 1342 + } 1343 + 1344 + bool pb_decode_svarint(pb_istream_t *stream, pb_int64_t *dest) 1345 + { 1346 + pb_uint64_t value; 1347 + if (!pb_decode_varint(stream, &value)) 1348 + return false; 1349 + 1350 + if (value & 1) 1351 + *dest = (pb_int64_t)(~(value >> 1)); 1352 + else 1353 + *dest = (pb_int64_t)(value >> 1); 1354 + 1355 + return true; 1356 + } 1357 + 1358 + bool pb_decode_fixed32(pb_istream_t *stream, void *dest) 1359 + { 1360 + union { 1361 + uint32_t fixed32; 1362 + pb_byte_t bytes[4]; 1363 + } u; 1364 + 1365 + if (!pb_read(stream, u.bytes, 4)) 1366 + return false; 1367 + 1368 + #if defined(PB_LITTLE_ENDIAN_8BIT) && PB_LITTLE_ENDIAN_8BIT == 1 1369 + /* fast path - if we know that we're on little endian, assign directly */ 1370 + *(uint32_t*)dest = u.fixed32; 1371 + #else 1372 + *(uint32_t*)dest = ((uint32_t)u.bytes[0] << 0) | 1373 + ((uint32_t)u.bytes[1] << 8) | 1374 + ((uint32_t)u.bytes[2] << 16) | 1375 + ((uint32_t)u.bytes[3] << 24); 1376 + #endif 1377 + return true; 1378 + } 1379 + 1380 + #ifndef PB_WITHOUT_64BIT 1381 + bool pb_decode_fixed64(pb_istream_t *stream, void *dest) 1382 + { 1383 + union { 1384 + uint64_t fixed64; 1385 + pb_byte_t bytes[8]; 1386 + } u; 1387 + 1388 + if (!pb_read(stream, u.bytes, 8)) 1389 + return false; 1390 + 1391 + #if defined(PB_LITTLE_ENDIAN_8BIT) && PB_LITTLE_ENDIAN_8BIT == 1 1392 + /* fast path - if we know that we're on little endian, assign directly */ 1393 + *(uint64_t*)dest = u.fixed64; 1394 + #else 1395 + *(uint64_t*)dest = ((uint64_t)u.bytes[0] << 0) | 1396 + ((uint64_t)u.bytes[1] << 8) | 1397 + ((uint64_t)u.bytes[2] << 16) | 1398 + ((uint64_t)u.bytes[3] << 24) | 1399 + ((uint64_t)u.bytes[4] << 32) | 1400 + ((uint64_t)u.bytes[5] << 40) | 1401 + ((uint64_t)u.bytes[6] << 48) | 1402 + ((uint64_t)u.bytes[7] << 56); 1403 + #endif 1404 + return true; 1405 + } 1406 + #endif 1407 + 1408 + static bool checkreturn pb_dec_bool(pb_istream_t *stream, const pb_field_iter_t *field) 1409 + { 1410 + return pb_decode_bool(stream, (bool*)field->pData); 1411 + } 1412 + 1413 + static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_iter_t *field) 1414 + { 1415 + if (PB_LTYPE(field->type) == PB_LTYPE_UVARINT) 1416 + { 1417 + pb_uint64_t value, clamped; 1418 + if (!pb_decode_varint(stream, &value)) 1419 + return false; 1420 + 1421 + /* Cast to the proper field size, while checking for overflows */ 1422 + if (field->data_size == sizeof(pb_uint64_t)) 1423 + clamped = *(pb_uint64_t*)field->pData = value; 1424 + else if (field->data_size == sizeof(uint32_t)) 1425 + clamped = *(uint32_t*)field->pData = (uint32_t)value; 1426 + else if (field->data_size == sizeof(uint_least16_t)) 1427 + clamped = *(uint_least16_t*)field->pData = (uint_least16_t)value; 1428 + else if (field->data_size == sizeof(uint_least8_t)) 1429 + clamped = *(uint_least8_t*)field->pData = (uint_least8_t)value; 1430 + else 1431 + PB_RETURN_ERROR(stream, "invalid data_size"); 1432 + 1433 + if (clamped != value) 1434 + PB_RETURN_ERROR(stream, "integer too large"); 1435 + 1436 + return true; 1437 + } 1438 + else 1439 + { 1440 + pb_uint64_t value; 1441 + pb_int64_t svalue; 1442 + pb_int64_t clamped; 1443 + 1444 + if (PB_LTYPE(field->type) == PB_LTYPE_SVARINT) 1445 + { 1446 + if (!pb_decode_svarint(stream, &svalue)) 1447 + return false; 1448 + } 1449 + else 1450 + { 1451 + if (!pb_decode_varint(stream, &value)) 1452 + return false; 1453 + 1454 + /* See issue 97: Google's C++ protobuf allows negative varint values to 1455 + * be cast as int32_t, instead of the int64_t that should be used when 1456 + * encoding. Nanopb versions before 0.2.5 had a bug in encoding. In order to 1457 + * not break decoding of such messages, we cast <=32 bit fields to 1458 + * int32_t first to get the sign correct. 1459 + */ 1460 + if (field->data_size == sizeof(pb_int64_t)) 1461 + svalue = (pb_int64_t)value; 1462 + else 1463 + svalue = (int32_t)value; 1464 + } 1465 + 1466 + /* Cast to the proper field size, while checking for overflows */ 1467 + if (field->data_size == sizeof(pb_int64_t)) 1468 + clamped = *(pb_int64_t*)field->pData = svalue; 1469 + else if (field->data_size == sizeof(int32_t)) 1470 + clamped = *(int32_t*)field->pData = (int32_t)svalue; 1471 + else if (field->data_size == sizeof(int_least16_t)) 1472 + clamped = *(int_least16_t*)field->pData = (int_least16_t)svalue; 1473 + else if (field->data_size == sizeof(int_least8_t)) 1474 + clamped = *(int_least8_t*)field->pData = (int_least8_t)svalue; 1475 + else 1476 + PB_RETURN_ERROR(stream, "invalid data_size"); 1477 + 1478 + if (clamped != svalue) 1479 + PB_RETURN_ERROR(stream, "integer too large"); 1480 + 1481 + return true; 1482 + } 1483 + } 1484 + 1485 + static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_iter_t *field) 1486 + { 1487 + uint32_t size; 1488 + size_t alloc_size; 1489 + pb_bytes_array_t *dest; 1490 + 1491 + if (!pb_decode_varint32(stream, &size)) 1492 + return false; 1493 + 1494 + if (size > PB_SIZE_MAX) 1495 + PB_RETURN_ERROR(stream, "bytes overflow"); 1496 + 1497 + alloc_size = PB_BYTES_ARRAY_T_ALLOCSIZE(size); 1498 + if (size > alloc_size) 1499 + PB_RETURN_ERROR(stream, "size too large"); 1500 + 1501 + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) 1502 + { 1503 + #ifndef PB_ENABLE_MALLOC 1504 + PB_RETURN_ERROR(stream, "no malloc support"); 1505 + #else 1506 + if (stream->bytes_left < size) 1507 + PB_RETURN_ERROR(stream, "end-of-stream"); 1508 + 1509 + if (!allocate_field(stream, field->pData, alloc_size, 1)) 1510 + return false; 1511 + dest = *(pb_bytes_array_t**)field->pData; 1512 + #endif 1513 + } 1514 + else 1515 + { 1516 + if (alloc_size > field->data_size) 1517 + PB_RETURN_ERROR(stream, "bytes overflow"); 1518 + dest = (pb_bytes_array_t*)field->pData; 1519 + } 1520 + 1521 + dest->size = (pb_size_t)size; 1522 + return pb_read(stream, dest->bytes, (size_t)size); 1523 + } 1524 + 1525 + static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_iter_t *field) 1526 + { 1527 + uint32_t size; 1528 + size_t alloc_size; 1529 + pb_byte_t *dest = (pb_byte_t*)field->pData; 1530 + 1531 + if (!pb_decode_varint32(stream, &size)) 1532 + return false; 1533 + 1534 + if (size == (uint32_t)-1) 1535 + PB_RETURN_ERROR(stream, "size too large"); 1536 + 1537 + /* Space for null terminator */ 1538 + alloc_size = (size_t)(size + 1); 1539 + 1540 + if (alloc_size < size) 1541 + PB_RETURN_ERROR(stream, "size too large"); 1542 + 1543 + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) 1544 + { 1545 + #ifndef PB_ENABLE_MALLOC 1546 + PB_RETURN_ERROR(stream, "no malloc support"); 1547 + #else 1548 + if (stream->bytes_left < size) 1549 + PB_RETURN_ERROR(stream, "end-of-stream"); 1550 + 1551 + if (!allocate_field(stream, field->pData, alloc_size, 1)) 1552 + return false; 1553 + dest = *(pb_byte_t**)field->pData; 1554 + #endif 1555 + } 1556 + else 1557 + { 1558 + if (alloc_size > field->data_size) 1559 + PB_RETURN_ERROR(stream, "string overflow"); 1560 + } 1561 + 1562 + dest[size] = 0; 1563 + 1564 + if (!pb_read(stream, dest, (size_t)size)) 1565 + return false; 1566 + 1567 + #ifdef PB_VALIDATE_UTF8 1568 + if (!pb_validate_utf8((const char*)dest)) 1569 + PB_RETURN_ERROR(stream, "invalid utf8"); 1570 + #endif 1571 + 1572 + return true; 1573 + } 1574 + 1575 + static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_iter_t *field) 1576 + { 1577 + bool status = true; 1578 + bool submsg_consumed = false; 1579 + pb_istream_t substream; 1580 + 1581 + if (!pb_make_string_substream(stream, &substream)) 1582 + return false; 1583 + 1584 + if (field->submsg_desc == NULL) 1585 + PB_RETURN_ERROR(stream, "invalid field descriptor"); 1586 + 1587 + /* Submessages can have a separate message-level callback that is called 1588 + * before decoding the message. Typically it is used to set callback fields 1589 + * inside oneofs. */ 1590 + if (PB_LTYPE(field->type) == PB_LTYPE_SUBMSG_W_CB && field->pSize != NULL) 1591 + { 1592 + /* Message callback is stored right before pSize. */ 1593 + pb_callback_t *callback = (pb_callback_t*)field->pSize - 1; 1594 + if (callback->funcs.decode) 1595 + { 1596 + status = callback->funcs.decode(&substream, field, &callback->arg); 1597 + 1598 + if (substream.bytes_left == 0) 1599 + { 1600 + submsg_consumed = true; 1601 + } 1602 + } 1603 + } 1604 + 1605 + /* Now decode the submessage contents */ 1606 + if (status && !submsg_consumed) 1607 + { 1608 + unsigned int flags = 0; 1609 + 1610 + /* Static required/optional fields are already initialized by top-level 1611 + * pb_decode(), no need to initialize them again. */ 1612 + if (PB_ATYPE(field->type) == PB_ATYPE_STATIC && 1613 + PB_HTYPE(field->type) != PB_HTYPE_REPEATED) 1614 + { 1615 + flags = PB_DECODE_NOINIT; 1616 + } 1617 + 1618 + status = pb_decode_inner(&substream, field->submsg_desc, field->pData, flags); 1619 + } 1620 + 1621 + if (!pb_close_string_substream(stream, &substream)) 1622 + return false; 1623 + 1624 + return status; 1625 + } 1626 + 1627 + static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_iter_t *field) 1628 + { 1629 + uint32_t size; 1630 + 1631 + if (!pb_decode_varint32(stream, &size)) 1632 + return false; 1633 + 1634 + if (size > PB_SIZE_MAX) 1635 + PB_RETURN_ERROR(stream, "bytes overflow"); 1636 + 1637 + if (size == 0) 1638 + { 1639 + /* As a special case, treat empty bytes string as all zeros for fixed_length_bytes. */ 1640 + memset(field->pData, 0, (size_t)field->data_size); 1641 + return true; 1642 + } 1643 + 1644 + if (size != field->data_size) 1645 + PB_RETURN_ERROR(stream, "incorrect fixed length bytes size"); 1646 + 1647 + return pb_read(stream, (pb_byte_t*)field->pData, (size_t)field->data_size); 1648 + } 1649 + 1650 + #ifdef PB_CONVERT_DOUBLE_FLOAT 1651 + bool pb_decode_double_as_float(pb_istream_t *stream, float *dest) 1652 + { 1653 + uint_least8_t sign; 1654 + int exponent; 1655 + uint32_t mantissa; 1656 + uint64_t value; 1657 + union { float f; uint32_t i; } out; 1658 + 1659 + if (!pb_decode_fixed64(stream, &value)) 1660 + return false; 1661 + 1662 + /* Decompose input value */ 1663 + sign = (uint_least8_t)((value >> 63) & 1); 1664 + exponent = (int)((value >> 52) & 0x7FF) - 1023; 1665 + mantissa = (value >> 28) & 0xFFFFFF; /* Highest 24 bits */ 1666 + 1667 + /* Figure if value is in range representable by floats. */ 1668 + if (exponent == 1024) 1669 + { 1670 + /* Special value */ 1671 + exponent = 128; 1672 + mantissa >>= 1; 1673 + } 1674 + else 1675 + { 1676 + if (exponent > 127) 1677 + { 1678 + /* Too large, convert to infinity */ 1679 + exponent = 128; 1680 + mantissa = 0; 1681 + } 1682 + else if (exponent < -150) 1683 + { 1684 + /* Too small, convert to zero */ 1685 + exponent = -127; 1686 + mantissa = 0; 1687 + } 1688 + else if (exponent < -126) 1689 + { 1690 + /* Denormalized */ 1691 + mantissa |= 0x1000000; 1692 + mantissa >>= (-126 - exponent); 1693 + exponent = -127; 1694 + } 1695 + 1696 + /* Round off mantissa */ 1697 + mantissa = (mantissa + 1) >> 1; 1698 + 1699 + /* Check if mantissa went over 2.0 */ 1700 + if (mantissa & 0x800000) 1701 + { 1702 + exponent += 1; 1703 + mantissa &= 0x7FFFFF; 1704 + mantissa >>= 1; 1705 + } 1706 + } 1707 + 1708 + /* Combine fields */ 1709 + out.i = mantissa; 1710 + out.i |= (uint32_t)(exponent + 127) << 23; 1711 + out.i |= (uint32_t)sign << 31; 1712 + 1713 + *dest = out.f; 1714 + return true; 1715 + } 1716 + #endif
+199
src/external/nanopb/pb_decode.h
··· 1 + /* pb_decode.h: Functions to decode protocol buffers. Depends on pb_decode.c. 2 + * The main function is pb_decode. You also need an input stream, and the 3 + * field descriptions created by nanopb_generator.py. 4 + */ 5 + 6 + #ifndef PB_DECODE_H_INCLUDED 7 + #define PB_DECODE_H_INCLUDED 8 + 9 + #include "pb.h" 10 + 11 + #ifdef __cplusplus 12 + extern "C" { 13 + #endif 14 + 15 + /* Structure for defining custom input streams. You will need to provide 16 + * a callback function to read the bytes from your storage, which can be 17 + * for example a file or a network socket. 18 + * 19 + * The callback must conform to these rules: 20 + * 21 + * 1) Return false on IO errors. This will cause decoding to abort. 22 + * 2) You can use state to store your own data (e.g. buffer pointer), 23 + * and rely on pb_read to verify that no-body reads past bytes_left. 24 + * 3) Your callback may be used with substreams, in which case bytes_left 25 + * is different than from the main stream. Don't use bytes_left to compute 26 + * any pointers. 27 + */ 28 + struct pb_istream_s 29 + { 30 + #ifdef PB_BUFFER_ONLY 31 + /* Callback pointer is not used in buffer-only configuration. 32 + * Having an int pointer here allows binary compatibility but 33 + * gives an error if someone tries to assign callback function. 34 + */ 35 + int *callback; 36 + #else 37 + bool (*callback)(pb_istream_t *stream, pb_byte_t *buf, size_t count); 38 + #endif 39 + 40 + void *state; /* Free field for use by callback implementation */ 41 + size_t bytes_left; 42 + 43 + #ifndef PB_NO_ERRMSG 44 + const char *errmsg; 45 + #endif 46 + }; 47 + 48 + #ifndef PB_NO_ERRMSG 49 + #define PB_ISTREAM_EMPTY {0,0,0,0} 50 + #else 51 + #define PB_ISTREAM_EMPTY {0,0,0} 52 + #endif 53 + 54 + /*************************** 55 + * Main decoding functions * 56 + ***************************/ 57 + 58 + /* Decode a single protocol buffers message from input stream into a C structure. 59 + * Returns true on success, false on any failure. 60 + * The actual struct pointed to by dest must match the description in fields. 61 + * Callback fields of the destination structure must be initialized by caller. 62 + * All other fields will be initialized by this function. 63 + * 64 + * Example usage: 65 + * MyMessage msg = {}; 66 + * uint8_t buffer[64]; 67 + * pb_istream_t stream; 68 + * 69 + * // ... read some data into buffer ... 70 + * 71 + * stream = pb_istream_from_buffer(buffer, count); 72 + * pb_decode(&stream, MyMessage_fields, &msg); 73 + */ 74 + bool pb_decode(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct); 75 + 76 + /* Extended version of pb_decode, with several options to control 77 + * the decoding process: 78 + * 79 + * PB_DECODE_NOINIT: Do not initialize the fields to default values. 80 + * This is slightly faster if you do not need the default 81 + * values and instead initialize the structure to 0 using 82 + * e.g. memset(). This can also be used for merging two 83 + * messages, i.e. combine already existing data with new 84 + * values. 85 + * 86 + * PB_DECODE_DELIMITED: Input message starts with the message size as varint. 87 + * Corresponds to parseDelimitedFrom() in Google's 88 + * protobuf API. 89 + * 90 + * PB_DECODE_NULLTERMINATED: Stop reading when field tag is read as 0. This allows 91 + * reading null terminated messages. 92 + * NOTE: Until nanopb-0.4.0, pb_decode() also allows 93 + * null-termination. This behaviour is not supported in 94 + * most other protobuf implementations, so PB_DECODE_DELIMITED 95 + * is a better option for compatibility. 96 + * 97 + * Multiple flags can be combined with bitwise or (| operator) 98 + */ 99 + #define PB_DECODE_NOINIT 0x01U 100 + #define PB_DECODE_DELIMITED 0x02U 101 + #define PB_DECODE_NULLTERMINATED 0x04U 102 + bool pb_decode_ex(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct, unsigned int flags); 103 + 104 + /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ 105 + #define pb_decode_noinit(s,f,d) pb_decode_ex(s,f,d, PB_DECODE_NOINIT) 106 + #define pb_decode_delimited(s,f,d) pb_decode_ex(s,f,d, PB_DECODE_DELIMITED) 107 + #define pb_decode_delimited_noinit(s,f,d) pb_decode_ex(s,f,d, PB_DECODE_DELIMITED | PB_DECODE_NOINIT) 108 + #define pb_decode_nullterminated(s,f,d) pb_decode_ex(s,f,d, PB_DECODE_NULLTERMINATED) 109 + 110 + #ifdef PB_ENABLE_MALLOC 111 + /* Release any allocated pointer fields. If you use dynamic allocation, you should 112 + * call this for any successfully decoded message when you are done with it. If 113 + * pb_decode() returns with an error, the message is already released. 114 + */ 115 + void pb_release(const pb_msgdesc_t *fields, void *dest_struct); 116 + #else 117 + /* Allocation is not supported, so release is no-op */ 118 + #define pb_release(fields, dest_struct) PB_UNUSED(fields); PB_UNUSED(dest_struct); 119 + #endif 120 + 121 + 122 + /************************************** 123 + * Functions for manipulating streams * 124 + **************************************/ 125 + 126 + /* Create an input stream for reading from a memory buffer. 127 + * 128 + * msglen should be the actual length of the message, not the full size of 129 + * allocated buffer. 130 + * 131 + * Alternatively, you can use a custom stream that reads directly from e.g. 132 + * a file or a network socket. 133 + */ 134 + pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t msglen); 135 + 136 + /* Function to read from a pb_istream_t. You can use this if you need to 137 + * read some custom header data, or to read data in field callbacks. 138 + */ 139 + bool pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count); 140 + 141 + 142 + /************************************************ 143 + * Helper functions for writing field callbacks * 144 + ************************************************/ 145 + 146 + /* Decode the tag for the next field in the stream. Gives the wire type and 147 + * field tag. At end of the message, returns false and sets eof to true. */ 148 + bool pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof); 149 + 150 + /* Skip the field payload data, given the wire type. */ 151 + bool pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type); 152 + 153 + /* Decode an integer in the varint format. This works for enum, int32, 154 + * int64, uint32 and uint64 field types. */ 155 + #ifndef PB_WITHOUT_64BIT 156 + bool pb_decode_varint(pb_istream_t *stream, uint64_t *dest); 157 + #else 158 + #define pb_decode_varint pb_decode_varint32 159 + #endif 160 + 161 + /* Decode an integer in the varint format. This works for enum, int32, 162 + * and uint32 field types. */ 163 + bool pb_decode_varint32(pb_istream_t *stream, uint32_t *dest); 164 + 165 + /* Decode a bool value in varint format. */ 166 + bool pb_decode_bool(pb_istream_t *stream, bool *dest); 167 + 168 + /* Decode an integer in the zig-zagged svarint format. This works for sint32 169 + * and sint64. */ 170 + #ifndef PB_WITHOUT_64BIT 171 + bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest); 172 + #else 173 + bool pb_decode_svarint(pb_istream_t *stream, int32_t *dest); 174 + #endif 175 + 176 + /* Decode a fixed32, sfixed32 or float value. You need to pass a pointer to 177 + * a 4-byte wide C variable. */ 178 + bool pb_decode_fixed32(pb_istream_t *stream, void *dest); 179 + 180 + #ifndef PB_WITHOUT_64BIT 181 + /* Decode a fixed64, sfixed64 or double value. You need to pass a pointer to 182 + * a 8-byte wide C variable. */ 183 + bool pb_decode_fixed64(pb_istream_t *stream, void *dest); 184 + #endif 185 + 186 + #ifdef PB_CONVERT_DOUBLE_FLOAT 187 + /* Decode a double value into float variable. */ 188 + bool pb_decode_double_as_float(pb_istream_t *stream, float *dest); 189 + #endif 190 + 191 + /* Make a limited-length substream for reading a PB_WT_STRING field. */ 192 + bool pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream); 193 + bool pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream); 194 + 195 + #ifdef __cplusplus 196 + } /* extern "C" */ 197 + #endif 198 + 199 + #endif
+1000
src/external/nanopb/pb_encode.c
··· 1 + /* pb_encode.c -- encode a protobuf using minimal resources 2 + * 3 + * 2011 Petteri Aimonen <jpa@kapsi.fi> 4 + */ 5 + 6 + #include "pb.h" 7 + #include "pb_encode.h" 8 + #include "pb_common.h" 9 + 10 + /* Use the GCC warn_unused_result attribute to check that all return values 11 + * are propagated correctly. On other compilers and gcc before 3.4.0 just 12 + * ignore the annotation. 13 + */ 14 + #if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) 15 + #define checkreturn 16 + #else 17 + #define checkreturn __attribute__((warn_unused_result)) 18 + #endif 19 + 20 + /************************************** 21 + * Declarations internal to this file * 22 + **************************************/ 23 + static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); 24 + static bool checkreturn encode_array(pb_ostream_t *stream, pb_field_iter_t *field); 25 + static bool checkreturn pb_check_proto3_default_value(const pb_field_iter_t *field); 26 + static bool checkreturn encode_basic_field(pb_ostream_t *stream, const pb_field_iter_t *field); 27 + static bool checkreturn encode_callback_field(pb_ostream_t *stream, const pb_field_iter_t *field); 28 + static bool checkreturn encode_field(pb_ostream_t *stream, pb_field_iter_t *field); 29 + static bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_iter_t *field); 30 + static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb_extension_t *extension); 31 + static bool checkreturn pb_encode_varint_32(pb_ostream_t *stream, uint32_t low, uint32_t high); 32 + static bool checkreturn pb_enc_bool(pb_ostream_t *stream, const pb_field_iter_t *field); 33 + static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_iter_t *field); 34 + static bool checkreturn pb_enc_fixed(pb_ostream_t *stream, const pb_field_iter_t *field); 35 + static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_iter_t *field); 36 + static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_iter_t *field); 37 + static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_iter_t *field); 38 + static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_iter_t *field); 39 + 40 + #ifdef PB_WITHOUT_64BIT 41 + #define pb_int64_t int32_t 42 + #define pb_uint64_t uint32_t 43 + #else 44 + #define pb_int64_t int64_t 45 + #define pb_uint64_t uint64_t 46 + #endif 47 + 48 + /******************************* 49 + * pb_ostream_t implementation * 50 + *******************************/ 51 + 52 + static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count) 53 + { 54 + pb_byte_t *dest = (pb_byte_t*)stream->state; 55 + stream->state = dest + count; 56 + 57 + memcpy(dest, buf, count * sizeof(pb_byte_t)); 58 + 59 + return true; 60 + } 61 + 62 + pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize) 63 + { 64 + pb_ostream_t stream; 65 + #ifdef PB_BUFFER_ONLY 66 + /* In PB_BUFFER_ONLY configuration the callback pointer is just int*. 67 + * NULL pointer marks a sizing field, so put a non-NULL value to mark a buffer stream. 68 + */ 69 + static const int marker = 0; 70 + stream.callback = &marker; 71 + #else 72 + stream.callback = &buf_write; 73 + #endif 74 + stream.state = buf; 75 + stream.max_size = bufsize; 76 + stream.bytes_written = 0; 77 + #ifndef PB_NO_ERRMSG 78 + stream.errmsg = NULL; 79 + #endif 80 + return stream; 81 + } 82 + 83 + bool checkreturn pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count) 84 + { 85 + if (count > 0 && stream->callback != NULL) 86 + { 87 + if (stream->bytes_written + count < stream->bytes_written || 88 + stream->bytes_written + count > stream->max_size) 89 + { 90 + PB_RETURN_ERROR(stream, "stream full"); 91 + } 92 + 93 + #ifdef PB_BUFFER_ONLY 94 + if (!buf_write(stream, buf, count)) 95 + PB_RETURN_ERROR(stream, "io error"); 96 + #else 97 + if (!stream->callback(stream, buf, count)) 98 + PB_RETURN_ERROR(stream, "io error"); 99 + #endif 100 + } 101 + 102 + stream->bytes_written += count; 103 + return true; 104 + } 105 + 106 + /************************* 107 + * Encode a single field * 108 + *************************/ 109 + 110 + /* Read a bool value without causing undefined behavior even if the value 111 + * is invalid. See issue #434 and 112 + * https://stackoverflow.com/questions/27661768/weird-results-for-conditional 113 + */ 114 + static bool safe_read_bool(const void *pSize) 115 + { 116 + const char *p = (const char *)pSize; 117 + size_t i; 118 + for (i = 0; i < sizeof(bool); i++) 119 + { 120 + if (p[i] != 0) 121 + return true; 122 + } 123 + return false; 124 + } 125 + 126 + /* Encode a static array. Handles the size calculations and possible packing. */ 127 + static bool checkreturn encode_array(pb_ostream_t *stream, pb_field_iter_t *field) 128 + { 129 + pb_size_t i; 130 + pb_size_t count; 131 + #ifndef PB_ENCODE_ARRAYS_UNPACKED 132 + size_t size; 133 + #endif 134 + 135 + count = *(pb_size_t*)field->pSize; 136 + 137 + if (count == 0) 138 + return true; 139 + 140 + if (PB_ATYPE(field->type) != PB_ATYPE_POINTER && count > field->array_size) 141 + PB_RETURN_ERROR(stream, "array max size exceeded"); 142 + 143 + #ifndef PB_ENCODE_ARRAYS_UNPACKED 144 + /* We always pack arrays if the datatype allows it. */ 145 + if (PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) 146 + { 147 + if (!pb_encode_tag(stream, PB_WT_STRING, field->tag)) 148 + return false; 149 + 150 + /* Determine the total size of packed array. */ 151 + if (PB_LTYPE(field->type) == PB_LTYPE_FIXED32) 152 + { 153 + size = 4 * (size_t)count; 154 + } 155 + else if (PB_LTYPE(field->type) == PB_LTYPE_FIXED64) 156 + { 157 + size = 8 * (size_t)count; 158 + } 159 + else 160 + { 161 + pb_ostream_t sizestream = PB_OSTREAM_SIZING; 162 + void *pData_orig = field->pData; 163 + for (i = 0; i < count; i++) 164 + { 165 + if (!pb_enc_varint(&sizestream, field)) 166 + PB_RETURN_ERROR(stream, PB_GET_ERROR(&sizestream)); 167 + field->pData = (char*)field->pData + field->data_size; 168 + } 169 + field->pData = pData_orig; 170 + size = sizestream.bytes_written; 171 + } 172 + 173 + if (!pb_encode_varint(stream, (pb_uint64_t)size)) 174 + return false; 175 + 176 + if (stream->callback == NULL) 177 + return pb_write(stream, NULL, size); /* Just sizing.. */ 178 + 179 + /* Write the data */ 180 + for (i = 0; i < count; i++) 181 + { 182 + if (PB_LTYPE(field->type) == PB_LTYPE_FIXED32 || PB_LTYPE(field->type) == PB_LTYPE_FIXED64) 183 + { 184 + if (!pb_enc_fixed(stream, field)) 185 + return false; 186 + } 187 + else 188 + { 189 + if (!pb_enc_varint(stream, field)) 190 + return false; 191 + } 192 + 193 + field->pData = (char*)field->pData + field->data_size; 194 + } 195 + } 196 + else /* Unpacked fields */ 197 + #endif 198 + { 199 + for (i = 0; i < count; i++) 200 + { 201 + /* Normally the data is stored directly in the array entries, but 202 + * for pointer-type string and bytes fields, the array entries are 203 + * actually pointers themselves also. So we have to dereference once 204 + * more to get to the actual data. */ 205 + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER && 206 + (PB_LTYPE(field->type) == PB_LTYPE_STRING || 207 + PB_LTYPE(field->type) == PB_LTYPE_BYTES)) 208 + { 209 + bool status; 210 + void *pData_orig = field->pData; 211 + field->pData = *(void* const*)field->pData; 212 + 213 + if (!field->pData) 214 + { 215 + /* Null pointer in array is treated as empty string / bytes */ 216 + status = pb_encode_tag_for_field(stream, field) && 217 + pb_encode_varint(stream, 0); 218 + } 219 + else 220 + { 221 + status = encode_basic_field(stream, field); 222 + } 223 + 224 + field->pData = pData_orig; 225 + 226 + if (!status) 227 + return false; 228 + } 229 + else 230 + { 231 + if (!encode_basic_field(stream, field)) 232 + return false; 233 + } 234 + field->pData = (char*)field->pData + field->data_size; 235 + } 236 + } 237 + 238 + return true; 239 + } 240 + 241 + /* In proto3, all fields are optional and are only encoded if their value is "non-zero". 242 + * This function implements the check for the zero value. */ 243 + static bool checkreturn pb_check_proto3_default_value(const pb_field_iter_t *field) 244 + { 245 + pb_type_t type = field->type; 246 + 247 + if (PB_ATYPE(type) == PB_ATYPE_STATIC) 248 + { 249 + if (PB_HTYPE(type) == PB_HTYPE_REQUIRED) 250 + { 251 + /* Required proto2 fields inside proto3 submessage, pretty rare case */ 252 + return false; 253 + } 254 + else if (PB_HTYPE(type) == PB_HTYPE_REPEATED) 255 + { 256 + /* Repeated fields inside proto3 submessage: present if count != 0 */ 257 + return *(const pb_size_t*)field->pSize == 0; 258 + } 259 + else if (PB_HTYPE(type) == PB_HTYPE_ONEOF) 260 + { 261 + /* Oneof fields */ 262 + return *(const pb_size_t*)field->pSize == 0; 263 + } 264 + else if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL && field->pSize != NULL) 265 + { 266 + /* Proto2 optional fields inside proto3 message, or proto3 267 + * submessage fields. */ 268 + return safe_read_bool(field->pSize) == false; 269 + } 270 + else if (field->descriptor->default_value) 271 + { 272 + /* Proto3 messages do not have default values, but proto2 messages 273 + * can contain optional fields without has_fields (generator option 'proto3'). 274 + * In this case they must always be encoded, to make sure that the 275 + * non-zero default value is overwritten. 276 + */ 277 + return false; 278 + } 279 + 280 + /* Rest is proto3 singular fields */ 281 + if (PB_LTYPE(type) <= PB_LTYPE_LAST_PACKABLE) 282 + { 283 + /* Simple integer / float fields */ 284 + pb_size_t i; 285 + const char *p = (const char*)field->pData; 286 + for (i = 0; i < field->data_size; i++) 287 + { 288 + if (p[i] != 0) 289 + { 290 + return false; 291 + } 292 + } 293 + 294 + return true; 295 + } 296 + else if (PB_LTYPE(type) == PB_LTYPE_BYTES) 297 + { 298 + const pb_bytes_array_t *bytes = (const pb_bytes_array_t*)field->pData; 299 + return bytes->size == 0; 300 + } 301 + else if (PB_LTYPE(type) == PB_LTYPE_STRING) 302 + { 303 + return *(const char*)field->pData == '\0'; 304 + } 305 + else if (PB_LTYPE(type) == PB_LTYPE_FIXED_LENGTH_BYTES) 306 + { 307 + /* Fixed length bytes is only empty if its length is fixed 308 + * as 0. Which would be pretty strange, but we can check 309 + * it anyway. */ 310 + return field->data_size == 0; 311 + } 312 + else if (PB_LTYPE_IS_SUBMSG(type)) 313 + { 314 + /* Check all fields in the submessage to find if any of them 315 + * are non-zero. The comparison cannot be done byte-per-byte 316 + * because the C struct may contain padding bytes that must 317 + * be skipped. Note that usually proto3 submessages have 318 + * a separate has_field that is checked earlier in this if. 319 + */ 320 + pb_field_iter_t iter; 321 + if (pb_field_iter_begin(&iter, field->submsg_desc, field->pData)) 322 + { 323 + do 324 + { 325 + if (!pb_check_proto3_default_value(&iter)) 326 + { 327 + return false; 328 + } 329 + } while (pb_field_iter_next(&iter)); 330 + } 331 + return true; 332 + } 333 + } 334 + else if (PB_ATYPE(type) == PB_ATYPE_POINTER) 335 + { 336 + return field->pData == NULL; 337 + } 338 + else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK) 339 + { 340 + if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) 341 + { 342 + const pb_extension_t *extension = *(const pb_extension_t* const *)field->pData; 343 + return extension == NULL; 344 + } 345 + else if (field->descriptor->field_callback == pb_default_field_callback) 346 + { 347 + pb_callback_t *pCallback = (pb_callback_t*)field->pData; 348 + return pCallback->funcs.encode == NULL; 349 + } 350 + else 351 + { 352 + return field->descriptor->field_callback == NULL; 353 + } 354 + } 355 + 356 + return false; /* Not typically reached, safe default for weird special cases. */ 357 + } 358 + 359 + /* Encode a field with static or pointer allocation, i.e. one whose data 360 + * is available to the encoder directly. */ 361 + static bool checkreturn encode_basic_field(pb_ostream_t *stream, const pb_field_iter_t *field) 362 + { 363 + if (!field->pData) 364 + { 365 + /* Missing pointer field */ 366 + return true; 367 + } 368 + 369 + if (!pb_encode_tag_for_field(stream, field)) 370 + return false; 371 + 372 + switch (PB_LTYPE(field->type)) 373 + { 374 + case PB_LTYPE_BOOL: 375 + return pb_enc_bool(stream, field); 376 + 377 + case PB_LTYPE_VARINT: 378 + case PB_LTYPE_UVARINT: 379 + case PB_LTYPE_SVARINT: 380 + return pb_enc_varint(stream, field); 381 + 382 + case PB_LTYPE_FIXED32: 383 + case PB_LTYPE_FIXED64: 384 + return pb_enc_fixed(stream, field); 385 + 386 + case PB_LTYPE_BYTES: 387 + return pb_enc_bytes(stream, field); 388 + 389 + case PB_LTYPE_STRING: 390 + return pb_enc_string(stream, field); 391 + 392 + case PB_LTYPE_SUBMESSAGE: 393 + case PB_LTYPE_SUBMSG_W_CB: 394 + return pb_enc_submessage(stream, field); 395 + 396 + case PB_LTYPE_FIXED_LENGTH_BYTES: 397 + return pb_enc_fixed_length_bytes(stream, field); 398 + 399 + default: 400 + PB_RETURN_ERROR(stream, "invalid field type"); 401 + } 402 + } 403 + 404 + /* Encode a field with callback semantics. This means that a user function is 405 + * called to provide and encode the actual data. */ 406 + static bool checkreturn encode_callback_field(pb_ostream_t *stream, const pb_field_iter_t *field) 407 + { 408 + if (field->descriptor->field_callback != NULL) 409 + { 410 + if (!field->descriptor->field_callback(NULL, stream, field)) 411 + PB_RETURN_ERROR(stream, "callback error"); 412 + } 413 + return true; 414 + } 415 + 416 + /* Encode a single field of any callback, pointer or static type. */ 417 + static bool checkreturn encode_field(pb_ostream_t *stream, pb_field_iter_t *field) 418 + { 419 + /* Check field presence */ 420 + if (PB_HTYPE(field->type) == PB_HTYPE_ONEOF) 421 + { 422 + if (*(const pb_size_t*)field->pSize != field->tag) 423 + { 424 + /* Different type oneof field */ 425 + return true; 426 + } 427 + } 428 + else if (PB_HTYPE(field->type) == PB_HTYPE_OPTIONAL) 429 + { 430 + if (field->pSize) 431 + { 432 + if (safe_read_bool(field->pSize) == false) 433 + { 434 + /* Missing optional field */ 435 + return true; 436 + } 437 + } 438 + else if (PB_ATYPE(field->type) == PB_ATYPE_STATIC) 439 + { 440 + /* Proto3 singular field */ 441 + if (pb_check_proto3_default_value(field)) 442 + return true; 443 + } 444 + } 445 + 446 + if (!field->pData) 447 + { 448 + if (PB_HTYPE(field->type) == PB_HTYPE_REQUIRED) 449 + PB_RETURN_ERROR(stream, "missing required field"); 450 + 451 + /* Pointer field set to NULL */ 452 + return true; 453 + } 454 + 455 + /* Then encode field contents */ 456 + if (PB_ATYPE(field->type) == PB_ATYPE_CALLBACK) 457 + { 458 + return encode_callback_field(stream, field); 459 + } 460 + else if (PB_HTYPE(field->type) == PB_HTYPE_REPEATED) 461 + { 462 + return encode_array(stream, field); 463 + } 464 + else 465 + { 466 + return encode_basic_field(stream, field); 467 + } 468 + } 469 + 470 + /* Default handler for extension fields. Expects to have a pb_msgdesc_t 471 + * pointer in the extension->type->arg field, pointing to a message with 472 + * only one field in it. */ 473 + static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb_extension_t *extension) 474 + { 475 + pb_field_iter_t iter; 476 + 477 + if (!pb_field_iter_begin_extension_const(&iter, extension)) 478 + PB_RETURN_ERROR(stream, "invalid extension"); 479 + 480 + return encode_field(stream, &iter); 481 + } 482 + 483 + 484 + /* Walk through all the registered extensions and give them a chance 485 + * to encode themselves. */ 486 + static bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_iter_t *field) 487 + { 488 + const pb_extension_t *extension = *(const pb_extension_t* const *)field->pData; 489 + 490 + while (extension) 491 + { 492 + bool status; 493 + if (extension->type->encode) 494 + status = extension->type->encode(stream, extension); 495 + else 496 + status = default_extension_encoder(stream, extension); 497 + 498 + if (!status) 499 + return false; 500 + 501 + extension = extension->next; 502 + } 503 + 504 + return true; 505 + } 506 + 507 + /********************* 508 + * Encode all fields * 509 + *********************/ 510 + 511 + bool checkreturn pb_encode(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct) 512 + { 513 + pb_field_iter_t iter; 514 + if (!pb_field_iter_begin_const(&iter, fields, src_struct)) 515 + return true; /* Empty message type */ 516 + 517 + do { 518 + if (PB_LTYPE(iter.type) == PB_LTYPE_EXTENSION) 519 + { 520 + /* Special case for the extension field placeholder */ 521 + if (!encode_extension_field(stream, &iter)) 522 + return false; 523 + } 524 + else 525 + { 526 + /* Regular field */ 527 + if (!encode_field(stream, &iter)) 528 + return false; 529 + } 530 + } while (pb_field_iter_next(&iter)); 531 + 532 + return true; 533 + } 534 + 535 + bool checkreturn pb_encode_ex(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct, unsigned int flags) 536 + { 537 + if ((flags & PB_ENCODE_DELIMITED) != 0) 538 + { 539 + return pb_encode_submessage(stream, fields, src_struct); 540 + } 541 + else if ((flags & PB_ENCODE_NULLTERMINATED) != 0) 542 + { 543 + const pb_byte_t zero = 0; 544 + 545 + if (!pb_encode(stream, fields, src_struct)) 546 + return false; 547 + 548 + return pb_write(stream, &zero, 1); 549 + } 550 + else 551 + { 552 + return pb_encode(stream, fields, src_struct); 553 + } 554 + } 555 + 556 + bool pb_get_encoded_size(size_t *size, const pb_msgdesc_t *fields, const void *src_struct) 557 + { 558 + pb_ostream_t stream = PB_OSTREAM_SIZING; 559 + 560 + if (!pb_encode(&stream, fields, src_struct)) 561 + return false; 562 + 563 + *size = stream.bytes_written; 564 + return true; 565 + } 566 + 567 + /******************** 568 + * Helper functions * 569 + ********************/ 570 + 571 + /* This function avoids 64-bit shifts as they are quite slow on many platforms. */ 572 + static bool checkreturn pb_encode_varint_32(pb_ostream_t *stream, uint32_t low, uint32_t high) 573 + { 574 + size_t i = 0; 575 + pb_byte_t buffer[10]; 576 + pb_byte_t byte = (pb_byte_t)(low & 0x7F); 577 + low >>= 7; 578 + 579 + while (i < 4 && (low != 0 || high != 0)) 580 + { 581 + byte |= 0x80; 582 + buffer[i++] = byte; 583 + byte = (pb_byte_t)(low & 0x7F); 584 + low >>= 7; 585 + } 586 + 587 + if (high) 588 + { 589 + byte = (pb_byte_t)(byte | ((high & 0x07) << 4)); 590 + high >>= 3; 591 + 592 + while (high) 593 + { 594 + byte |= 0x80; 595 + buffer[i++] = byte; 596 + byte = (pb_byte_t)(high & 0x7F); 597 + high >>= 7; 598 + } 599 + } 600 + 601 + buffer[i++] = byte; 602 + 603 + return pb_write(stream, buffer, i); 604 + } 605 + 606 + bool checkreturn pb_encode_varint(pb_ostream_t *stream, pb_uint64_t value) 607 + { 608 + if (value <= 0x7F) 609 + { 610 + /* Fast path: single byte */ 611 + pb_byte_t byte = (pb_byte_t)value; 612 + return pb_write(stream, &byte, 1); 613 + } 614 + else 615 + { 616 + #ifdef PB_WITHOUT_64BIT 617 + return pb_encode_varint_32(stream, value, 0); 618 + #else 619 + return pb_encode_varint_32(stream, (uint32_t)value, (uint32_t)(value >> 32)); 620 + #endif 621 + } 622 + } 623 + 624 + bool checkreturn pb_encode_svarint(pb_ostream_t *stream, pb_int64_t value) 625 + { 626 + pb_uint64_t zigzagged; 627 + pb_uint64_t mask = ((pb_uint64_t)-1) >> 1; /* Satisfy clang -fsanitize=integer */ 628 + if (value < 0) 629 + zigzagged = ~(((pb_uint64_t)value & mask) << 1); 630 + else 631 + zigzagged = (pb_uint64_t)value << 1; 632 + 633 + return pb_encode_varint(stream, zigzagged); 634 + } 635 + 636 + bool checkreturn pb_encode_fixed32(pb_ostream_t *stream, const void *value) 637 + { 638 + #if defined(PB_LITTLE_ENDIAN_8BIT) && PB_LITTLE_ENDIAN_8BIT == 1 639 + /* Fast path if we know that we're on little endian */ 640 + return pb_write(stream, (const pb_byte_t*)value, 4); 641 + #else 642 + uint32_t val = *(const uint32_t*)value; 643 + pb_byte_t bytes[4]; 644 + bytes[0] = (pb_byte_t)(val & 0xFF); 645 + bytes[1] = (pb_byte_t)((val >> 8) & 0xFF); 646 + bytes[2] = (pb_byte_t)((val >> 16) & 0xFF); 647 + bytes[3] = (pb_byte_t)((val >> 24) & 0xFF); 648 + return pb_write(stream, bytes, 4); 649 + #endif 650 + } 651 + 652 + #ifndef PB_WITHOUT_64BIT 653 + bool checkreturn pb_encode_fixed64(pb_ostream_t *stream, const void *value) 654 + { 655 + #if defined(PB_LITTLE_ENDIAN_8BIT) && PB_LITTLE_ENDIAN_8BIT == 1 656 + /* Fast path if we know that we're on little endian */ 657 + return pb_write(stream, (const pb_byte_t*)value, 8); 658 + #else 659 + uint64_t val = *(const uint64_t*)value; 660 + pb_byte_t bytes[8]; 661 + bytes[0] = (pb_byte_t)(val & 0xFF); 662 + bytes[1] = (pb_byte_t)((val >> 8) & 0xFF); 663 + bytes[2] = (pb_byte_t)((val >> 16) & 0xFF); 664 + bytes[3] = (pb_byte_t)((val >> 24) & 0xFF); 665 + bytes[4] = (pb_byte_t)((val >> 32) & 0xFF); 666 + bytes[5] = (pb_byte_t)((val >> 40) & 0xFF); 667 + bytes[6] = (pb_byte_t)((val >> 48) & 0xFF); 668 + bytes[7] = (pb_byte_t)((val >> 56) & 0xFF); 669 + return pb_write(stream, bytes, 8); 670 + #endif 671 + } 672 + #endif 673 + 674 + bool checkreturn pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number) 675 + { 676 + pb_uint64_t tag = ((pb_uint64_t)field_number << 3) | wiretype; 677 + return pb_encode_varint(stream, tag); 678 + } 679 + 680 + bool pb_encode_tag_for_field ( pb_ostream_t* stream, const pb_field_iter_t* field ) 681 + { 682 + pb_wire_type_t wiretype; 683 + switch (PB_LTYPE(field->type)) 684 + { 685 + case PB_LTYPE_BOOL: 686 + case PB_LTYPE_VARINT: 687 + case PB_LTYPE_UVARINT: 688 + case PB_LTYPE_SVARINT: 689 + wiretype = PB_WT_VARINT; 690 + break; 691 + 692 + case PB_LTYPE_FIXED32: 693 + wiretype = PB_WT_32BIT; 694 + break; 695 + 696 + case PB_LTYPE_FIXED64: 697 + wiretype = PB_WT_64BIT; 698 + break; 699 + 700 + case PB_LTYPE_BYTES: 701 + case PB_LTYPE_STRING: 702 + case PB_LTYPE_SUBMESSAGE: 703 + case PB_LTYPE_SUBMSG_W_CB: 704 + case PB_LTYPE_FIXED_LENGTH_BYTES: 705 + wiretype = PB_WT_STRING; 706 + break; 707 + 708 + default: 709 + PB_RETURN_ERROR(stream, "invalid field type"); 710 + } 711 + 712 + return pb_encode_tag(stream, wiretype, field->tag); 713 + } 714 + 715 + bool checkreturn pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size) 716 + { 717 + if (!pb_encode_varint(stream, (pb_uint64_t)size)) 718 + return false; 719 + 720 + return pb_write(stream, buffer, size); 721 + } 722 + 723 + bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct) 724 + { 725 + /* First calculate the message size using a non-writing substream. */ 726 + pb_ostream_t substream = PB_OSTREAM_SIZING; 727 + size_t size; 728 + bool status; 729 + 730 + if (!pb_encode(&substream, fields, src_struct)) 731 + { 732 + #ifndef PB_NO_ERRMSG 733 + stream->errmsg = substream.errmsg; 734 + #endif 735 + return false; 736 + } 737 + 738 + size = substream.bytes_written; 739 + 740 + if (!pb_encode_varint(stream, (pb_uint64_t)size)) 741 + return false; 742 + 743 + if (stream->callback == NULL) 744 + return pb_write(stream, NULL, size); /* Just sizing */ 745 + 746 + if (stream->bytes_written + size > stream->max_size) 747 + PB_RETURN_ERROR(stream, "stream full"); 748 + 749 + /* Use a substream to verify that a callback doesn't write more than 750 + * what it did the first time. */ 751 + substream.callback = stream->callback; 752 + substream.state = stream->state; 753 + substream.max_size = size; 754 + substream.bytes_written = 0; 755 + #ifndef PB_NO_ERRMSG 756 + substream.errmsg = NULL; 757 + #endif 758 + 759 + status = pb_encode(&substream, fields, src_struct); 760 + 761 + stream->bytes_written += substream.bytes_written; 762 + stream->state = substream.state; 763 + #ifndef PB_NO_ERRMSG 764 + stream->errmsg = substream.errmsg; 765 + #endif 766 + 767 + if (substream.bytes_written != size) 768 + PB_RETURN_ERROR(stream, "submsg size changed"); 769 + 770 + return status; 771 + } 772 + 773 + /* Field encoders */ 774 + 775 + static bool checkreturn pb_enc_bool(pb_ostream_t *stream, const pb_field_iter_t *field) 776 + { 777 + uint32_t value = safe_read_bool(field->pData) ? 1 : 0; 778 + PB_UNUSED(field); 779 + return pb_encode_varint(stream, value); 780 + } 781 + 782 + static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_iter_t *field) 783 + { 784 + if (PB_LTYPE(field->type) == PB_LTYPE_UVARINT) 785 + { 786 + /* Perform unsigned integer extension */ 787 + pb_uint64_t value = 0; 788 + 789 + if (field->data_size == sizeof(uint_least8_t)) 790 + value = *(const uint_least8_t*)field->pData; 791 + else if (field->data_size == sizeof(uint_least16_t)) 792 + value = *(const uint_least16_t*)field->pData; 793 + else if (field->data_size == sizeof(uint32_t)) 794 + value = *(const uint32_t*)field->pData; 795 + else if (field->data_size == sizeof(pb_uint64_t)) 796 + value = *(const pb_uint64_t*)field->pData; 797 + else 798 + PB_RETURN_ERROR(stream, "invalid data_size"); 799 + 800 + return pb_encode_varint(stream, value); 801 + } 802 + else 803 + { 804 + /* Perform signed integer extension */ 805 + pb_int64_t value = 0; 806 + 807 + if (field->data_size == sizeof(int_least8_t)) 808 + value = *(const int_least8_t*)field->pData; 809 + else if (field->data_size == sizeof(int_least16_t)) 810 + value = *(const int_least16_t*)field->pData; 811 + else if (field->data_size == sizeof(int32_t)) 812 + value = *(const int32_t*)field->pData; 813 + else if (field->data_size == sizeof(pb_int64_t)) 814 + value = *(const pb_int64_t*)field->pData; 815 + else 816 + PB_RETURN_ERROR(stream, "invalid data_size"); 817 + 818 + if (PB_LTYPE(field->type) == PB_LTYPE_SVARINT) 819 + return pb_encode_svarint(stream, value); 820 + #ifdef PB_WITHOUT_64BIT 821 + else if (value < 0) 822 + return pb_encode_varint_32(stream, (uint32_t)value, (uint32_t)-1); 823 + #endif 824 + else 825 + return pb_encode_varint(stream, (pb_uint64_t)value); 826 + 827 + } 828 + } 829 + 830 + static bool checkreturn pb_enc_fixed(pb_ostream_t *stream, const pb_field_iter_t *field) 831 + { 832 + #ifdef PB_CONVERT_DOUBLE_FLOAT 833 + if (field->data_size == sizeof(float) && PB_LTYPE(field->type) == PB_LTYPE_FIXED64) 834 + { 835 + return pb_encode_float_as_double(stream, *(float*)field->pData); 836 + } 837 + #endif 838 + 839 + if (field->data_size == sizeof(uint32_t)) 840 + { 841 + return pb_encode_fixed32(stream, field->pData); 842 + } 843 + #ifndef PB_WITHOUT_64BIT 844 + else if (field->data_size == sizeof(uint64_t)) 845 + { 846 + return pb_encode_fixed64(stream, field->pData); 847 + } 848 + #endif 849 + else 850 + { 851 + PB_RETURN_ERROR(stream, "invalid data_size"); 852 + } 853 + } 854 + 855 + static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_iter_t *field) 856 + { 857 + const pb_bytes_array_t *bytes = NULL; 858 + 859 + bytes = (const pb_bytes_array_t*)field->pData; 860 + 861 + if (bytes == NULL) 862 + { 863 + /* Treat null pointer as an empty bytes field */ 864 + return pb_encode_string(stream, NULL, 0); 865 + } 866 + 867 + if (PB_ATYPE(field->type) == PB_ATYPE_STATIC && 868 + bytes->size > field->data_size - offsetof(pb_bytes_array_t, bytes)) 869 + { 870 + PB_RETURN_ERROR(stream, "bytes size exceeded"); 871 + } 872 + 873 + return pb_encode_string(stream, bytes->bytes, (size_t)bytes->size); 874 + } 875 + 876 + static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_iter_t *field) 877 + { 878 + size_t size = 0; 879 + size_t max_size = (size_t)field->data_size; 880 + const char *str = (const char*)field->pData; 881 + 882 + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) 883 + { 884 + max_size = (size_t)-1; 885 + } 886 + else 887 + { 888 + /* pb_dec_string() assumes string fields end with a null 889 + * terminator when the type isn't PB_ATYPE_POINTER, so we 890 + * shouldn't allow more than max-1 bytes to be written to 891 + * allow space for the null terminator. 892 + */ 893 + if (max_size == 0) 894 + PB_RETURN_ERROR(stream, "zero-length string"); 895 + 896 + max_size -= 1; 897 + } 898 + 899 + 900 + if (str == NULL) 901 + { 902 + size = 0; /* Treat null pointer as an empty string */ 903 + } 904 + else 905 + { 906 + const char *p = str; 907 + 908 + /* strnlen() is not always available, so just use a loop */ 909 + while (size < max_size && *p != '\0') 910 + { 911 + size++; 912 + p++; 913 + } 914 + 915 + if (*p != '\0') 916 + { 917 + PB_RETURN_ERROR(stream, "unterminated string"); 918 + } 919 + } 920 + 921 + #ifdef PB_VALIDATE_UTF8 922 + if (!pb_validate_utf8(str)) 923 + PB_RETURN_ERROR(stream, "invalid utf8"); 924 + #endif 925 + 926 + return pb_encode_string(stream, (const pb_byte_t*)str, size); 927 + } 928 + 929 + static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_iter_t *field) 930 + { 931 + if (field->submsg_desc == NULL) 932 + PB_RETURN_ERROR(stream, "invalid field descriptor"); 933 + 934 + if (PB_LTYPE(field->type) == PB_LTYPE_SUBMSG_W_CB && field->pSize != NULL) 935 + { 936 + /* Message callback is stored right before pSize. */ 937 + pb_callback_t *callback = (pb_callback_t*)field->pSize - 1; 938 + if (callback->funcs.encode) 939 + { 940 + if (!callback->funcs.encode(stream, field, &callback->arg)) 941 + return false; 942 + } 943 + } 944 + 945 + return pb_encode_submessage(stream, field->submsg_desc, field->pData); 946 + } 947 + 948 + static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_iter_t *field) 949 + { 950 + return pb_encode_string(stream, (const pb_byte_t*)field->pData, (size_t)field->data_size); 951 + } 952 + 953 + #ifdef PB_CONVERT_DOUBLE_FLOAT 954 + bool pb_encode_float_as_double(pb_ostream_t *stream, float value) 955 + { 956 + union { float f; uint32_t i; } in; 957 + uint_least8_t sign; 958 + int exponent; 959 + uint64_t mantissa; 960 + 961 + in.f = value; 962 + 963 + /* Decompose input value */ 964 + sign = (uint_least8_t)((in.i >> 31) & 1); 965 + exponent = (int)((in.i >> 23) & 0xFF) - 127; 966 + mantissa = in.i & 0x7FFFFF; 967 + 968 + if (exponent == 128) 969 + { 970 + /* Special value (NaN etc.) */ 971 + exponent = 1024; 972 + } 973 + else if (exponent == -127) 974 + { 975 + if (!mantissa) 976 + { 977 + /* Zero */ 978 + exponent = -1023; 979 + } 980 + else 981 + { 982 + /* Denormalized */ 983 + mantissa <<= 1; 984 + while (!(mantissa & 0x800000)) 985 + { 986 + mantissa <<= 1; 987 + exponent--; 988 + } 989 + mantissa &= 0x7FFFFF; 990 + } 991 + } 992 + 993 + /* Combine fields */ 994 + mantissa <<= 29; 995 + mantissa |= (uint64_t)(exponent + 1023) << 52; 996 + mantissa |= (uint64_t)sign << 63; 997 + 998 + return pb_encode_fixed64(stream, &mantissa); 999 + } 1000 + #endif
+185
src/external/nanopb/pb_encode.h
··· 1 + /* pb_encode.h: Functions to encode protocol buffers. Depends on pb_encode.c. 2 + * The main function is pb_encode. You also need an output stream, and the 3 + * field descriptions created by nanopb_generator.py. 4 + */ 5 + 6 + #ifndef PB_ENCODE_H_INCLUDED 7 + #define PB_ENCODE_H_INCLUDED 8 + 9 + #include "pb.h" 10 + 11 + #ifdef __cplusplus 12 + extern "C" { 13 + #endif 14 + 15 + /* Structure for defining custom output streams. You will need to provide 16 + * a callback function to write the bytes to your storage, which can be 17 + * for example a file or a network socket. 18 + * 19 + * The callback must conform to these rules: 20 + * 21 + * 1) Return false on IO errors. This will cause encoding to abort. 22 + * 2) You can use state to store your own data (e.g. buffer pointer). 23 + * 3) pb_write will update bytes_written after your callback runs. 24 + * 4) Substreams will modify max_size and bytes_written. Don't use them 25 + * to calculate any pointers. 26 + */ 27 + struct pb_ostream_s 28 + { 29 + #ifdef PB_BUFFER_ONLY 30 + /* Callback pointer is not used in buffer-only configuration. 31 + * Having an int pointer here allows binary compatibility but 32 + * gives an error if someone tries to assign callback function. 33 + * Also, NULL pointer marks a 'sizing stream' that does not 34 + * write anything. 35 + */ 36 + const int *callback; 37 + #else 38 + bool (*callback)(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); 39 + #endif 40 + void *state; /* Free field for use by callback implementation. */ 41 + size_t max_size; /* Limit number of output bytes written (or use SIZE_MAX). */ 42 + size_t bytes_written; /* Number of bytes written so far. */ 43 + 44 + #ifndef PB_NO_ERRMSG 45 + const char *errmsg; 46 + #endif 47 + }; 48 + 49 + /*************************** 50 + * Main encoding functions * 51 + ***************************/ 52 + 53 + /* Encode a single protocol buffers message from C structure into a stream. 54 + * Returns true on success, false on any failure. 55 + * The actual struct pointed to by src_struct must match the description in fields. 56 + * All required fields in the struct are assumed to have been filled in. 57 + * 58 + * Example usage: 59 + * MyMessage msg = {}; 60 + * uint8_t buffer[64]; 61 + * pb_ostream_t stream; 62 + * 63 + * msg.field1 = 42; 64 + * stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); 65 + * pb_encode(&stream, MyMessage_fields, &msg); 66 + */ 67 + bool pb_encode(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct); 68 + 69 + /* Extended version of pb_encode, with several options to control the 70 + * encoding process: 71 + * 72 + * PB_ENCODE_DELIMITED: Prepend the length of message as a varint. 73 + * Corresponds to writeDelimitedTo() in Google's 74 + * protobuf API. 75 + * 76 + * PB_ENCODE_NULLTERMINATED: Append a null byte to the message for termination. 77 + * NOTE: This behaviour is not supported in most other 78 + * protobuf implementations, so PB_ENCODE_DELIMITED 79 + * is a better option for compatibility. 80 + */ 81 + #define PB_ENCODE_DELIMITED 0x02U 82 + #define PB_ENCODE_NULLTERMINATED 0x04U 83 + bool pb_encode_ex(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct, unsigned int flags); 84 + 85 + /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ 86 + #define pb_encode_delimited(s,f,d) pb_encode_ex(s,f,d, PB_ENCODE_DELIMITED) 87 + #define pb_encode_nullterminated(s,f,d) pb_encode_ex(s,f,d, PB_ENCODE_NULLTERMINATED) 88 + 89 + /* Encode the message to get the size of the encoded data, but do not store 90 + * the data. */ 91 + bool pb_get_encoded_size(size_t *size, const pb_msgdesc_t *fields, const void *src_struct); 92 + 93 + /************************************** 94 + * Functions for manipulating streams * 95 + **************************************/ 96 + 97 + /* Create an output stream for writing into a memory buffer. 98 + * The number of bytes written can be found in stream.bytes_written after 99 + * encoding the message. 100 + * 101 + * Alternatively, you can use a custom stream that writes directly to e.g. 102 + * a file or a network socket. 103 + */ 104 + pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize); 105 + 106 + /* Pseudo-stream for measuring the size of a message without actually storing 107 + * the encoded data. 108 + * 109 + * Example usage: 110 + * MyMessage msg = {}; 111 + * pb_ostream_t stream = PB_OSTREAM_SIZING; 112 + * pb_encode(&stream, MyMessage_fields, &msg); 113 + * printf("Message size is %d\n", stream.bytes_written); 114 + */ 115 + #ifndef PB_NO_ERRMSG 116 + #define PB_OSTREAM_SIZING {0,0,0,0,0} 117 + #else 118 + #define PB_OSTREAM_SIZING {0,0,0,0} 119 + #endif 120 + 121 + /* Function to write into a pb_ostream_t stream. You can use this if you need 122 + * to append or prepend some custom headers to the message. 123 + */ 124 + bool pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); 125 + 126 + 127 + /************************************************ 128 + * Helper functions for writing field callbacks * 129 + ************************************************/ 130 + 131 + /* Encode field header based on type and field number defined in the field 132 + * structure. Call this from the callback before writing out field contents. */ 133 + bool pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_iter_t *field); 134 + 135 + /* Encode field header by manually specifying wire type. You need to use this 136 + * if you want to write out packed arrays from a callback field. */ 137 + bool pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number); 138 + 139 + /* Encode an integer in the varint format. 140 + * This works for bool, enum, int32, int64, uint32 and uint64 field types. */ 141 + #ifndef PB_WITHOUT_64BIT 142 + bool pb_encode_varint(pb_ostream_t *stream, uint64_t value); 143 + #else 144 + bool pb_encode_varint(pb_ostream_t *stream, uint32_t value); 145 + #endif 146 + 147 + /* Encode an integer in the zig-zagged svarint format. 148 + * This works for sint32 and sint64. */ 149 + #ifndef PB_WITHOUT_64BIT 150 + bool pb_encode_svarint(pb_ostream_t *stream, int64_t value); 151 + #else 152 + bool pb_encode_svarint(pb_ostream_t *stream, int32_t value); 153 + #endif 154 + 155 + /* Encode a string or bytes type field. For strings, pass strlen(s) as size. */ 156 + bool pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size); 157 + 158 + /* Encode a fixed32, sfixed32 or float value. 159 + * You need to pass a pointer to a 4-byte wide C variable. */ 160 + bool pb_encode_fixed32(pb_ostream_t *stream, const void *value); 161 + 162 + #ifndef PB_WITHOUT_64BIT 163 + /* Encode a fixed64, sfixed64 or double value. 164 + * You need to pass a pointer to a 8-byte wide C variable. */ 165 + bool pb_encode_fixed64(pb_ostream_t *stream, const void *value); 166 + #endif 167 + 168 + #ifdef PB_CONVERT_DOUBLE_FLOAT 169 + /* Encode a float value so that it appears like a double in the encoded 170 + * message. */ 171 + bool pb_encode_float_as_double(pb_ostream_t *stream, float value); 172 + #endif 173 + 174 + /* Encode a submessage field. 175 + * You need to pass the pb_field_t array and pointer to struct, just like 176 + * with pb_encode(). This internally encodes the submessage twice, first to 177 + * calculate message size and then to actually write it out. 178 + */ 179 + bool pb_encode_submessage(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct); 180 + 181 + #ifdef __cplusplus 182 + } /* extern "C" */ 183 + #endif 184 + 185 + #endif