Nanopb is a plain-C implementation of Google's Protocol Buffers data format. It is targeted at 32 bit microcontrollers, but is also fit for other embedded systems with tight (2-10 kB ROM, <1 kB RAM) memory constraints.

Dependents:   FBRLogger Dumb_box_rev2

Uploaded from http://koti.kapsi.fi/~jpa/nanopb/ Original licence included below.

Copyright (c) 2011 Petteri Aimonen <jpa at nanopb.mail.kapsi.fi>

This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.

  1. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
  2. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
  3. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. This notice may not be removed or altered from any source distribution.
Committer:
intrinseca
Date:
Fri Mar 01 12:41:26 2013 +0000
Revision:
1:e08406101222
Parent:
0:c7beea49fc91
fix bugs

Who changed what in which revision?

UserRevisionLine numberNew contents of line
intrinseca 0:c7beea49fc91 1 #ifndef _PB_H_
intrinseca 0:c7beea49fc91 2 #define _PB_H_
intrinseca 0:c7beea49fc91 3
intrinseca 0:c7beea49fc91 4 /* pb.h: Common parts for nanopb library.
intrinseca 0:c7beea49fc91 5 * Most of these are quite low-level stuff. For the high-level interface,
intrinseca 0:c7beea49fc91 6 * see pb_encode.h or pb_decode.h
intrinseca 0:c7beea49fc91 7 */
intrinseca 0:c7beea49fc91 8
intrinseca 0:c7beea49fc91 9 #define NANOPB_VERSION nanopb-0.1.9
intrinseca 0:c7beea49fc91 10
intrinseca 0:c7beea49fc91 11 #include <stdint.h>
intrinseca 0:c7beea49fc91 12 #include <stddef.h>
intrinseca 0:c7beea49fc91 13 #include <stdbool.h>
intrinseca 0:c7beea49fc91 14
intrinseca 0:c7beea49fc91 15 #ifdef __GNUC__
intrinseca 0:c7beea49fc91 16 /* This just reduces memory requirements, but is not required. */
intrinseca 0:c7beea49fc91 17 #define pb_packed __attribute__((packed))
intrinseca 0:c7beea49fc91 18 #else
intrinseca 0:c7beea49fc91 19 #define pb_packed
intrinseca 0:c7beea49fc91 20 #endif
intrinseca 0:c7beea49fc91 21
intrinseca 0:c7beea49fc91 22 /* Handly macro for suppressing unreferenced-parameter compiler warnings. */
intrinseca 0:c7beea49fc91 23 #ifndef UNUSED
intrinseca 0:c7beea49fc91 24 #define UNUSED(x) (void)(x)
intrinseca 0:c7beea49fc91 25 #endif
intrinseca 0:c7beea49fc91 26
intrinseca 0:c7beea49fc91 27 /* Compile-time assertion, used for checking compatible compilation options.
intrinseca 0:c7beea49fc91 28 * If this fails on your compiler for some reason, use #define STATIC_ASSERT
intrinseca 0:c7beea49fc91 29 * to disable it. */
intrinseca 0:c7beea49fc91 30 #ifndef STATIC_ASSERT
intrinseca 0:c7beea49fc91 31 #define STATIC_ASSERT(COND,MSG) typedef char STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND)?1:-1];
intrinseca 0:c7beea49fc91 32 #define STATIC_ASSERT_MSG(MSG, LINE, COUNTER) STATIC_ASSERT_MSG_(MSG, LINE, COUNTER)
intrinseca 0:c7beea49fc91 33 #define STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) static_assertion_##MSG##LINE##COUNTER
intrinseca 0:c7beea49fc91 34 #endif
intrinseca 0:c7beea49fc91 35
intrinseca 0:c7beea49fc91 36 /* Number of required fields to keep track of
intrinseca 0:c7beea49fc91 37 * (change here or on compiler command line). */
intrinseca 0:c7beea49fc91 38 #ifndef PB_MAX_REQUIRED_FIELDS
intrinseca 0:c7beea49fc91 39 #define PB_MAX_REQUIRED_FIELDS 64
intrinseca 0:c7beea49fc91 40 #endif
intrinseca 0:c7beea49fc91 41
intrinseca 0:c7beea49fc91 42 #if PB_MAX_REQUIRED_FIELDS < 64
intrinseca 0:c7beea49fc91 43 #error You should not lower PB_MAX_REQUIRED_FIELDS from the default value (64).
intrinseca 0:c7beea49fc91 44 #endif
intrinseca 0:c7beea49fc91 45
intrinseca 0:c7beea49fc91 46 /* List of possible field types. These are used in the autogenerated code.
intrinseca 0:c7beea49fc91 47 * Least-significant 4 bits tell the scalar type
intrinseca 0:c7beea49fc91 48 * Most-significant 4 bits specify repeated/required/packed etc.
intrinseca 0:c7beea49fc91 49 *
intrinseca 0:c7beea49fc91 50 * INT32 and UINT32 are treated the same, as are (U)INT64 and (S)FIXED*
intrinseca 0:c7beea49fc91 51 * These types are simply casted to correct field type when they are
intrinseca 0:c7beea49fc91 52 * assigned to the memory pointer.
intrinseca 0:c7beea49fc91 53 * SINT* is different, though, because it is zig-zag coded.
intrinseca 0:c7beea49fc91 54 */
intrinseca 0:c7beea49fc91 55
intrinseca 0:c7beea49fc91 56 typedef enum {
intrinseca 0:c7beea49fc91 57 /************************
intrinseca 0:c7beea49fc91 58 * Field contents types *
intrinseca 0:c7beea49fc91 59 ************************/
intrinseca 0:c7beea49fc91 60
intrinseca 0:c7beea49fc91 61 /* Numeric types */
intrinseca 0:c7beea49fc91 62 PB_LTYPE_VARINT = 0x00, /* int32, uint32, int64, uint64, bool, enum */
intrinseca 0:c7beea49fc91 63 PB_LTYPE_SVARINT = 0x01, /* sint32, sint64 */
intrinseca 0:c7beea49fc91 64 PB_LTYPE_FIXED32 = 0x02, /* fixed32, sfixed32, float */
intrinseca 0:c7beea49fc91 65 PB_LTYPE_FIXED64 = 0x03, /* fixed64, sfixed64, double */
intrinseca 0:c7beea49fc91 66
intrinseca 0:c7beea49fc91 67 /* Marker for last packable field type. */
intrinseca 0:c7beea49fc91 68 PB_LTYPE_LAST_PACKABLE = 0x03,
intrinseca 0:c7beea49fc91 69
intrinseca 0:c7beea49fc91 70 /* Byte array with pre-allocated buffer.
intrinseca 0:c7beea49fc91 71 * data_size is the length of the allocated PB_BYTES_ARRAY structure. */
intrinseca 0:c7beea49fc91 72 PB_LTYPE_BYTES = 0x04,
intrinseca 0:c7beea49fc91 73
intrinseca 0:c7beea49fc91 74 /* String with pre-allocated buffer.
intrinseca 0:c7beea49fc91 75 * data_size is the maximum length. */
intrinseca 0:c7beea49fc91 76 PB_LTYPE_STRING = 0x05,
intrinseca 0:c7beea49fc91 77
intrinseca 0:c7beea49fc91 78 /* Submessage
intrinseca 0:c7beea49fc91 79 * submsg_fields is pointer to field descriptions */
intrinseca 0:c7beea49fc91 80 PB_LTYPE_SUBMESSAGE = 0x06,
intrinseca 0:c7beea49fc91 81
intrinseca 0:c7beea49fc91 82 /* Number of declared LTYPES */
intrinseca 0:c7beea49fc91 83 PB_LTYPES_COUNT = 7,
intrinseca 0:c7beea49fc91 84 PB_LTYPE_MASK = 0x0F,
intrinseca 0:c7beea49fc91 85
intrinseca 0:c7beea49fc91 86 /******************
intrinseca 0:c7beea49fc91 87 * Modifier flags *
intrinseca 0:c7beea49fc91 88 ******************/
intrinseca 0:c7beea49fc91 89
intrinseca 0:c7beea49fc91 90 /* Just the basic, write data at data_offset */
intrinseca 0:c7beea49fc91 91 PB_HTYPE_REQUIRED = 0x00,
intrinseca 0:c7beea49fc91 92
intrinseca 0:c7beea49fc91 93 /* Write true at size_offset */
intrinseca 0:c7beea49fc91 94 PB_HTYPE_OPTIONAL = 0x10,
intrinseca 0:c7beea49fc91 95
intrinseca 0:c7beea49fc91 96 /* Read to pre-allocated array
intrinseca 0:c7beea49fc91 97 * Maximum number of entries is array_size,
intrinseca 0:c7beea49fc91 98 * actual number is stored at size_offset */
intrinseca 0:c7beea49fc91 99 PB_HTYPE_ARRAY = 0x20,
intrinseca 0:c7beea49fc91 100
intrinseca 0:c7beea49fc91 101 /* Works for all required/optional/repeated fields.
intrinseca 0:c7beea49fc91 102 * data_offset points to pb_callback_t structure.
intrinseca 0:c7beea49fc91 103 * LTYPE should be valid or 0 (it is ignored, but
intrinseca 0:c7beea49fc91 104 * sometimes used to speculatively index an array). */
intrinseca 0:c7beea49fc91 105 PB_HTYPE_CALLBACK = 0x30,
intrinseca 0:c7beea49fc91 106
intrinseca 0:c7beea49fc91 107 PB_HTYPE_MASK = 0xF0
intrinseca 0:c7beea49fc91 108 } pb_packed pb_type_t;
intrinseca 0:c7beea49fc91 109
intrinseca 0:c7beea49fc91 110 #define PB_HTYPE(x) ((x) & PB_HTYPE_MASK)
intrinseca 0:c7beea49fc91 111 #define PB_LTYPE(x) ((x) & PB_LTYPE_MASK)
intrinseca 0:c7beea49fc91 112
intrinseca 0:c7beea49fc91 113 /* This structure is used in auto-generated constants
intrinseca 0:c7beea49fc91 114 * to specify struct fields.
intrinseca 0:c7beea49fc91 115 * You can change field sizes if you need structures
intrinseca 0:c7beea49fc91 116 * larger than 256 bytes or field tags larger than 256.
intrinseca 0:c7beea49fc91 117 * The compiler should complain if your .proto has such
intrinseca 0:c7beea49fc91 118 * structures. Fix that by defining PB_FIELD_16BIT or
intrinseca 0:c7beea49fc91 119 * PB_FIELD_32BIT.
intrinseca 0:c7beea49fc91 120 */
intrinseca 0:c7beea49fc91 121 typedef struct _pb_field_t pb_field_t;
intrinseca 0:c7beea49fc91 122 struct _pb_field_t {
intrinseca 0:c7beea49fc91 123
intrinseca 0:c7beea49fc91 124 #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
intrinseca 0:c7beea49fc91 125 uint8_t tag;
intrinseca 0:c7beea49fc91 126 pb_type_t type;
intrinseca 0:c7beea49fc91 127 uint8_t data_offset; /* Offset of field data, relative to previous field. */
intrinseca 0:c7beea49fc91 128 int8_t size_offset; /* Offset of array size or has-boolean, relative to data */
intrinseca 0:c7beea49fc91 129 uint8_t data_size; /* Data size in bytes for a single item */
intrinseca 0:c7beea49fc91 130 uint8_t array_size; /* Maximum number of entries in array */
intrinseca 0:c7beea49fc91 131 #elif defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
intrinseca 0:c7beea49fc91 132 uint16_t tag;
intrinseca 0:c7beea49fc91 133 pb_type_t type;
intrinseca 0:c7beea49fc91 134 uint8_t data_offset;
intrinseca 0:c7beea49fc91 135 int8_t size_offset;
intrinseca 0:c7beea49fc91 136 uint16_t data_size;
intrinseca 0:c7beea49fc91 137 uint16_t array_size;
intrinseca 0:c7beea49fc91 138 #else
intrinseca 0:c7beea49fc91 139 uint32_t tag;
intrinseca 0:c7beea49fc91 140 pb_type_t type;
intrinseca 0:c7beea49fc91 141 uint8_t data_offset;
intrinseca 0:c7beea49fc91 142 int8_t size_offset;
intrinseca 0:c7beea49fc91 143 uint32_t data_size;
intrinseca 0:c7beea49fc91 144 uint32_t array_size;
intrinseca 0:c7beea49fc91 145 #endif
intrinseca 0:c7beea49fc91 146
intrinseca 0:c7beea49fc91 147 /* Field definitions for submessage
intrinseca 0:c7beea49fc91 148 * OR default value for all other non-array, non-callback types
intrinseca 0:c7beea49fc91 149 * If null, then field will zeroed. */
intrinseca 0:c7beea49fc91 150 const void *ptr;
intrinseca 0:c7beea49fc91 151 } pb_packed;
intrinseca 0:c7beea49fc91 152
intrinseca 0:c7beea49fc91 153 /* This structure is used for 'bytes' arrays.
intrinseca 0:c7beea49fc91 154 * It has the number of bytes in the beginning, and after that an array.
intrinseca 0:c7beea49fc91 155 * Note that actual structs used will have a different length of bytes array.
intrinseca 0:c7beea49fc91 156 */
intrinseca 0:c7beea49fc91 157 struct _pb_bytes_array_t {
intrinseca 0:c7beea49fc91 158 size_t size;
intrinseca 0:c7beea49fc91 159 uint8_t bytes[1];
intrinseca 0:c7beea49fc91 160 };
intrinseca 0:c7beea49fc91 161
intrinseca 0:c7beea49fc91 162 typedef struct _pb_bytes_array_t pb_bytes_array_t;
intrinseca 0:c7beea49fc91 163
intrinseca 0:c7beea49fc91 164 /* This structure is used for giving the callback function.
intrinseca 0:c7beea49fc91 165 * It is stored in the message structure and filled in by the method that
intrinseca 0:c7beea49fc91 166 * calls pb_decode.
intrinseca 0:c7beea49fc91 167 *
intrinseca 0:c7beea49fc91 168 * The decoding callback will be given a limited-length stream
intrinseca 0:c7beea49fc91 169 * If the wire type was string, the length is the length of the string.
intrinseca 0:c7beea49fc91 170 * If the wire type was a varint/fixed32/fixed64, the length is the length
intrinseca 0:c7beea49fc91 171 * of the actual value.
intrinseca 0:c7beea49fc91 172 * The function may be called multiple times (especially for repeated types,
intrinseca 0:c7beea49fc91 173 * but also otherwise if the message happens to contain the field multiple
intrinseca 0:c7beea49fc91 174 * times.)
intrinseca 0:c7beea49fc91 175 *
intrinseca 0:c7beea49fc91 176 * The encoding callback will receive the actual output stream.
intrinseca 0:c7beea49fc91 177 * It should write all the data in one call, including the field tag and
intrinseca 0:c7beea49fc91 178 * wire type. It can write multiple fields.
intrinseca 0:c7beea49fc91 179 *
intrinseca 0:c7beea49fc91 180 * The callback can be null if you want to skip a field.
intrinseca 0:c7beea49fc91 181 */
intrinseca 0:c7beea49fc91 182 typedef struct _pb_istream_t pb_istream_t;
intrinseca 0:c7beea49fc91 183 typedef struct _pb_ostream_t pb_ostream_t;
intrinseca 0:c7beea49fc91 184 typedef struct _pb_callback_t pb_callback_t;
intrinseca 0:c7beea49fc91 185 struct _pb_callback_t {
intrinseca 0:c7beea49fc91 186 union {
intrinseca 0:c7beea49fc91 187 bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void *arg);
intrinseca 0:c7beea49fc91 188 bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, const void *arg);
intrinseca 0:c7beea49fc91 189 } funcs;
intrinseca 0:c7beea49fc91 190
intrinseca 0:c7beea49fc91 191 /* Free arg for use by callback */
intrinseca 0:c7beea49fc91 192 void *arg;
intrinseca 0:c7beea49fc91 193 };
intrinseca 0:c7beea49fc91 194
intrinseca 0:c7beea49fc91 195 /* Wire types. Library user needs these only in encoder callbacks. */
intrinseca 0:c7beea49fc91 196 typedef enum {
intrinseca 0:c7beea49fc91 197 PB_WT_VARINT = 0,
intrinseca 0:c7beea49fc91 198 PB_WT_64BIT = 1,
intrinseca 0:c7beea49fc91 199 PB_WT_STRING = 2,
intrinseca 0:c7beea49fc91 200 PB_WT_32BIT = 5
intrinseca 0:c7beea49fc91 201 } pb_wire_type_t;
intrinseca 0:c7beea49fc91 202
intrinseca 0:c7beea49fc91 203 /* These macros are used to declare pb_field_t's in the constant array. */
intrinseca 0:c7beea49fc91 204 #define pb_membersize(st, m) (sizeof ((st*)0)->m)
intrinseca 0:c7beea49fc91 205 #define pb_arraysize(st, m) (pb_membersize(st, m) / pb_membersize(st, m[0]))
intrinseca 0:c7beea49fc91 206 #define pb_delta(st, m1, m2) ((int)offsetof(st, m1) - (int)offsetof(st, m2))
intrinseca 0:c7beea49fc91 207 #define pb_delta_end(st, m1, m2) (offsetof(st, m1) - offsetof(st, m2) - pb_membersize(st, m2))
intrinseca 0:c7beea49fc91 208 #define PB_LAST_FIELD {0,(pb_type_t) 0,0,0,0,0,0}
intrinseca 0:c7beea49fc91 209
intrinseca 0:c7beea49fc91 210 /* These macros are used for giving out error messages.
intrinseca 0:c7beea49fc91 211 * They are mostly a debugging aid; the main error information
intrinseca 0:c7beea49fc91 212 * is the true/false return value from functions.
intrinseca 0:c7beea49fc91 213 * Some code space can be saved by disabling the error
intrinseca 0:c7beea49fc91 214 * messages if not used.
intrinseca 0:c7beea49fc91 215 */
intrinseca 0:c7beea49fc91 216 #ifdef PB_NO_ERRMSG
intrinseca 0:c7beea49fc91 217 #define PB_RETURN_ERROR(stream,msg) return false
intrinseca 0:c7beea49fc91 218 #define PB_GET_ERROR(stream) "(errmsg disabled)"
intrinseca 0:c7beea49fc91 219 #else
intrinseca 0:c7beea49fc91 220 #define PB_RETURN_ERROR(stream,msg) \
intrinseca 0:c7beea49fc91 221 do {\
intrinseca 0:c7beea49fc91 222 if ((stream)->errmsg == NULL) \
intrinseca 0:c7beea49fc91 223 (stream)->errmsg = (msg); \
intrinseca 0:c7beea49fc91 224 return false; \
intrinseca 0:c7beea49fc91 225 } while(0)
intrinseca 0:c7beea49fc91 226 #define PB_GET_ERROR(stream) ((stream)->errmsg ? (stream)->errmsg : "(none)")
intrinseca 0:c7beea49fc91 227 #endif
intrinseca 0:c7beea49fc91 228
intrinseca 0:c7beea49fc91 229 #endif