le_pack.h

    1 /**
    2  * @page c_pack Low-level Pack/Unpack API
    3  *
    4  * @ref le_pack.h "API Reference"
    5  *
    6  * <HR>
    7  *
    8  * This low-level pack/unpack API is intended to support the higher level
    9  * IPC messaging system, specifically code generated by ifgen. But it
    10  * can also be used to hand-pack messages if using the @ref c_messaging
    11  * API directly.
    12  *
    13  * This low-level pack/unpack API supports:
    14  * - Packing basic types supported by the IPC system.
    15  * - Packing reference types
    16  * - Packing arrays of the above types
    17  * - Packing strings.
    18  * It also supports unpacking any of the above.
    19  */
    20 
    21 #ifndef LE_PACK_H_INCLUDE_GUARD
    22 #define LE_PACK_H_INCLUDE_GUARD
    23 
    24 
    25 // with ARM RVCT the max size of UINTPTR_MAX is signed.
    26 #if UINT32_MAX == UINTPTR_MAX || INT32_MAX == UINTPTR_MAX
    27 # define IFGEN_PTR32 1
    28 #elif UINT64_MAX == UINTPTR_MAX || INT64_MAX == UINTPTR_MAX
    29 # define IFGEN_PTR64 1
    30 #else
    31 # error "Unsupported pointer size -- only 32- and 64-bit are supported for local services."
    32 #endif
    33 
    34 //--------------------------------------------------------------------------------------------------
    35 /**
    36  * Pack Definitions and Types
    37  */
    38 //--------------------------------------------------------------------------------------------------
    39 
    40 //semantic tag type:
    41 typedef uint16_t le_pack_SemanticTag_t;
    42 
    43 // le_pack type:
    44 typedef enum le_pack_Type
    45 {
    46  LE_PACK_TYPE_POS_INTEGER = 0,
    47  LE_PACK_TYPE_NEG_INTEGER = 1,
    48  LE_PACK_TYPE_BYTE_STRING = 2,
    49  LE_PACK_TYPE_TEXT_STRING = 3,
    50  LE_PACK_TYPE_ITEM_ARRAY = 4,
    51  LE_PACK_TYPE_SEMANTIC_TAG = 5,
    52  LE_PACK_TYPE_BOOLEAN = 6,
    53  LE_PACK_TYPE_DOUBLE = 7,
    54  LE_PACK_TYPE_INDEF_END = 8,
    55  LE_PACK_TYPE_INVALID_TYPE = 9,
    56 } le_pack_Type_t;
    57 
    58 
    59 //--------------------------------------------------------------------------------------------------
    60 /**
    61  * The maximum size that a type would need when packed.
    62  */
    63 //--------------------------------------------------------------------------------------------------
    64 #ifdef LE_CONFIG_RPC
    65 #define LE_PACK_UINT8_MAX_SIZE (1 + sizeof(uint8_t))
    66 #define LE_PACK_UINT16_MAX_SIZE (1 + sizeof(uint16_t))
    67 #define LE_PACK_UINT32_MAX_SIZE (1 + sizeof(uint32_t))
    68 #define LE_PACK_UINT64_MAX_SIZE (1 + sizeof(uint64_t))
    69 #define LE_PACK_INT8_MAX_SIZE (1 + sizeof(int8_t))
    70 #define LE_PACK_INT16_MAX_SIZE (1 + sizeof(int16_t))
    71 #define LE_PACK_INT32_MAX_SIZE (1 + sizeof(int32_t))
    72 #define LE_PACK_INT64_MAX_SIZE (1 + sizeof(int64_t))
    73 #define LE_PACK_POS_INTEGER_MAX_SIZE (1 + sizeof(uint64_t))
    74 #define LE_PACK_NEG_INTEGER_MAX_SIZE (1 + sizeof(int64_t))
    75 #define LE_PACK_SEMANTIC_TAG_MAX_SIZE (1 + sizeof(le_pack_SemanticTag_t))
    76 #define LE_PACK_BOOL_MAX_SIZE (1)
    77 #define LE_PACK_DOUBLE_MAX_SIZE (9)
    78 #define LE_PACK_INDEF_END_MAX_SIZE (1)
    79 #define LE_PACK_STR_HEADER_MAX_SIZE (1 + sizeof(uint32_t))
    80 #define LE_PACK_ARRAY_HEADER_MAX_SIZE (1 + sizeof(uint32_t))
    81 #define LE_PACK_INDEF_ARRAY_HEADER_MAX_SIZE (1)
    82 #define LE_PACK_SIZE_POINTER_TUPLE_MAX_SIZE (1 + 1 + sizeof(size_t) + 1 + sizeof(intptr_t))
    83 
    84 #else // no rpc:
    85 #define LE_PACK_UINT8_MAX_SIZE (sizeof(uint8_t))
    86 #define LE_PACK_UINT16_MAX_SIZE (sizeof(uint16_t))
    87 #define LE_PACK_UINT32_MAX_SIZE (sizeof(uint32_t))
    88 #define LE_PACK_UINT64_MAX_SIZE (sizeof(uint64_t))
    89 #define LE_PACK_INT8_MAX_SIZE (sizeof(int8_t))
    90 #define LE_PACK_INT16_MAX_SIZE (sizeof(int16_t))
    91 #define LE_PACK_INT32_MAX_SIZE (sizeof(int32_t))
    92 #define LE_PACK_INT64_MAX_SIZE (sizeof(int64_t))
    93 #define LE_PACK_POS_INTEGER_MAX_SIZE (sizeof(uint64_t))
    94 #define LE_PACK_NEG_INTEGER_MAX_SIZE (sizeof(int64_t))
    95 #define LE_PACK_SEMANTIC_TAG_MAX_SIZE (0)
    96 #define LE_PACK_BOOL_MAX_SIZE (sizeof(bool))
    97 #define LE_PACK_DOUBLE_MAX_SIZE (sizeof(double))
    98 #define LE_PACK_INDEF_END_MAX_SIZE (0)
    99 #define LE_PACK_STR_HEADER_MAX_SIZE (sizeof(uint32_t))
    100 #define LE_PACK_ARRAY_HEADER_MAX_SIZE (sizeof(uint32_t))
    101 #define LE_PACK_INDEF_ARRAY_HEADER_MAX_SIZE (0)
    102 #define LE_PACK_SIZE_POINTER_TUPLE_MAX_SIZE (sizeof(size_t) + sizeof(intptr_t))
    103 #endif
    104 
    105 
    106 //--------------------------------------------------------------------------------------------------
    107 /**
    108  * Semantic Tags:
    109  */
    110 //--------------------------------------------------------------------------------------------------
    111 #define LE_PACK_REFERENCE (2001)
    112 
    113 #define LE_PACK_IN_STRING_POINTER (2002)
    114 #define LE_PACK_OUT_STRING_POINTER (2003)
    115 #define LE_PACK_IN_BYTE_STR_POINTER (2004)
    116 #define LE_PACK_OUT_BYTE_STR_POINTER (2005)
    117 
    118 #define LE_PACK_CONTEXT_PTR_REFERENCE (2006)
    119 #define LE_PACK_ASYNC_HANDLER_REFERENCE (2007)
    120 
    121 #define LE_PACK_FILESTREAM_ID (2008)
    122 #define LE_PACK_FILESTREAM_FLAG (2009)
    123 #define LE_PACK_FILESTREAM_REQUEST_SIZE (2010)
    124 
    125 #define LE_PACK_OUT_STRING_SIZE (2011)
    126 #define LE_PACK_OUT_BYTE_STR_SIZE (2012)
    127 
    128 #define LE_PACK_OUT_STRING_RESPONSE (2013)
    129 #define LE_PACK_OUT_BYTE_STR_RESPONSE (2014)
    130 
    131 
    132 //--------------------------------------------------------------------------------------------------
    133 /**
    134  * Internal macros:
    135  */
    136 //--------------------------------------------------------------------------------------------------
    137 #define _LE_PACK_CBOR_POS_INTEGER 0
    138 #define _LE_PACK_CBOR_NEG_INTEGER 1
    139 #define _LE_PACK_CBOR_BYTE_STRING 2
    140 #define _LE_PACK_CBOR_TEXT_STRING 3
    141 #define _LE_PACK_CBOR_ITEM_ARRAY 4
    142 #define _LE_PACK_CBOR_PAIR_MAP 5
    143 #define _LE_PACK_CBOR_SEMANTIC_TAG 6
    144 #define _LE_PACK_CBOR_PRIMITVE 7
    145 
    146 #define _LE_PACK_CBOR_COMPLEX_THRESHOLD 24
    147 
    148 #define _LE_PACK_CBOR_PRIMITIVE_FALSE 20
    149 #define _LE_PACK_CBOR_PRIMITIVE_TRUE 21
    150 #define _LE_PACK_CBOR_PRIMITIVE_DOUBLE 27
    151 #define _LE_PACK_CBOR_PRIMITIVE_BREAK 31
    152 #define _LE_PACK_CBOR_PRIMITIVE_INDEFINITE 31
    153 
    154 
    155 
    156 
    157 //--------------------------------------------------------------------------------------------------
    158 // Pack functions
    159 //--------------------------------------------------------------------------------------------------
    160 
    161 // Packing a simple value is basically the same regardless of type. But don't use this macro
    162 // directly to get better verification that we're only packing the types we expect
    163 #define LE_PACK_PACK_SIMPLE_VALUE(value) \
    164  do { \
    165  memcpy(*bufferPtr, &(value), sizeof(value)); \
    166  *bufferPtr = *bufferPtr + sizeof(value); \
    167  } while (0)
    168 
    169 
    170 //--------------------------------------------------------------------------------------------------
    171 /**
    172  * write bytes
    173  */
    174 //--------------------------------------------------------------------------------------------------
    175 #define LE_PACK_PACK_SIMPLE_BUFFER(desPtr, length) \
    176  do { \
    177  memcpy(*bufferPtr, desPtr, length); \
    178  *bufferPtr += length; \
    179  } while(0) \
    180 
    181 //--------------------------------------------------------------------------------------------------
    182 /**
    183  * pack tiny field
    184  */
    185 //--------------------------------------------------------------------------------------------------
    186 #define LE_PACK_PACK_TINY_ITEM(major, additional) \
    187  do { \
    188  *(*bufferPtr) = ((major & 0x7) << 5) | (additional); \
    189  *bufferPtr += 1; \
    190  } while(0) \
    191 
    192 //--------------------------------------------------------------------------------------------------
    193 /**
    194  * Pack an integer:
    195  */
    196 //--------------------------------------------------------------------------------------------------
    197 void _le_pack_packInteger
    198 (
    199  uint8_t **bufferPtr,
    200  uint64_t value,
    201  unsigned int major
    202 );
    203 
    204 //--------------------------------------------------------------------------------------------------
    205 /**
    206  * Pack a negative integer
    207  */
    208 //--------------------------------------------------------------------------------------------------
    209 void _le_pack_packNegativeInteger
    210 (
    211  uint8_t **bufferPtr,
    212  uint64_t value
    213 );
    214 
    215 //--------------------------------------------------------------------------------------------------
    216 /**
    217  * Pack a positive integer
    218  */
    219 //--------------------------------------------------------------------------------------------------
    220 void _le_pack_packPositiveInteger
    221 (
    222  uint8_t **bufferPtr,
    223  uint64_t value
    224 );
    225 
    226 //--------------------------------------------------------------------------------------------------
    227 /**
    228  * Pack a TagID into a buffer, incrementing the buffer pointer and decrementing the
    229  * available size, as appropriate.
    230  *
    231  * @note By making this an inline function, gcc can often optimize out the size check if the buffer
    232  * size is known at compile time.
    233  */
    234 //--------------------------------------------------------------------------------------------------
    235 #if LE_CONFIG_RPC
    236 bool le_pack_PackSemanticTag
    237 (
    238  uint8_t** bufferPtr,
    239  le_pack_SemanticTag_t value
    240 );
    241 #else
    242 LE_DECLARE_INLINE bool le_pack_PackSemanticTag
    243 (
    244  uint8_t **bufferPtr,
    245  le_pack_SemanticTag_t value
    246 )
    247 {
    248  LE_UNUSED(bufferPtr);
    249  LE_UNUSED(value);
    250 
    251  return true;
    252 }
    253 #endif
    254 
    255 
    256 #ifdef LE_CONFIG_RPC
    257 //--------------------------------------------------------------------------------------------------
    258 /**
    259  * prototype of Out-of-line functions containing rpc specific implementation:
    260  */
    261 //--------------------------------------------------------------------------------------------------
    262 bool le_pack_PackInt8_rpc(uint8_t** bufferPtr, int8_t value);
    263 bool le_pack_PackInt16_rpc(uint8_t** bufferPtr, int16_t value);
    264 bool le_pack_PackInt32_rpc(uint8_t** bufferPtr, int32_t value);
    265 bool le_pack_PackInt64_rpc(uint8_t** bufferPtr, int64_t value);
    266 bool le_pack_PackDouble_rpc(uint8_t** bufferPtr, double value);
    267 bool le_pack_PackResult_rpc(uint8_t** bufferPtr, le_result_t value);
    268 bool le_pack_PackTaggedSizeUint32Tuple_rpc(uint8_t** bufferPtr, size_t size, uint32_t value,
    269  le_pack_SemanticTag_t tagId);
    270 bool le_pack_PackTaggedSizeUint64Tuple_rpc(uint8_t** bufferPtr, size_t size, uint64_t value,
    271  le_pack_SemanticTag_t tagId);
    272 bool le_pack_PackString_rpc(uint8_t** bufferPtr, const char *stringPtr, uint32_t maxStringCount);
    273 bool le_pack_PackIndefArrayHeader_rpc(uint8_t** bufferPtr);
    274 bool le_pack_PackEndOfIndefArray_rpc(uint8_t** bufferPtr);
    275 bool le_pack_PackBool_rpc(uint8_t** bufferPtr, bool value);
    276 #endif
    277 
    278 //--------------------------------------------------------------------------------------------------
    279 /**
    280  * Pack a uint8_t into a buffer, incrementing the buffer pointer as appropriate.
    281  *
    282  * @note By making this an inline function, gcc can often optimize out the size check if the buffer
    283  * size is known at compile time.
    284  */
    285 //--------------------------------------------------------------------------------------------------
    286 LE_DECLARE_INLINE bool le_pack_PackUint8
    287 (
    288  uint8_t** bufferPtr,
    289  uint8_t value
    290 )
    291 {
    292 #ifdef LE_CONFIG_RPC
    293  _le_pack_packPositiveInteger(bufferPtr, value);
    294 #else
    295  LE_PACK_PACK_SIMPLE_VALUE(value);
    296 #endif
    297  return true;
    298 }
    299 
    300 //--------------------------------------------------------------------------------------------------
    301 /**
    302  * Pack a uint8_t into a buffer using the specified TagID, incrementing the buffer pointer
    303  * and decrementing the available size, as appropriate.
    304  *
    305  * @note By making this an inline function, gcc can often optimize out the size check if the buffer
    306  * size is known at compile time.
    307  */
    308 //--------------------------------------------------------------------------------------------------
    309 LE_DECLARE_INLINE bool le_pack_PackTaggedUint8
    310 (
    311  uint8_t** bufferPtr,
    312  uint8_t value,
    313  le_pack_SemanticTag_t tagId
    314 )
    315 {
    316 #ifdef LE_CONFIG_RPC
    317  le_pack_PackSemanticTag(bufferPtr, tagId);
    318 #else
    319  LE_UNUSED(tagId);
    320 #endif
    321  le_pack_PackUint8(bufferPtr, value);
    322  return true;
    323 }
    324 
    325 //--------------------------------------------------------------------------------------------------
    326 /**
    327  * Pack a uint16_t into a buffer, incrementing the buffer pointer as appropriate.
    328  */
    329 //--------------------------------------------------------------------------------------------------
    330 LE_DECLARE_INLINE bool le_pack_PackUint16
    331 (
    332  uint8_t** bufferPtr,
    333  uint16_t value
    334 )
    335 {
    336 #ifdef LE_CONFIG_RPC
    337  _le_pack_packPositiveInteger(bufferPtr, value);
    338 #else
    339  LE_PACK_PACK_SIMPLE_VALUE(value);
    340 #endif
    341  return true;
    342 }
    343 
    344 
    345 //--------------------------------------------------------------------------------------------------
    346 /**
    347  * Pack a uint16_t into a buffer using the specified TagID, incrementing the buffer pointer
    348  * and decrementing the available size, as appropriate.
    349  *
    350  * @note By making this an inline function, gcc can often optimize out the size check if the buffer
    351  * size is known at compile time.
    352  */
    353 //--------------------------------------------------------------------------------------------------
    354 LE_DECLARE_INLINE bool le_pack_PackTaggedUint16
    355 (
    356  uint8_t** bufferPtr,
    357  uint16_t value,
    358  le_pack_SemanticTag_t tagId
    359 )
    360 {
    361 #ifdef LE_CONFIG_RPC
    362  le_pack_PackSemanticTag(bufferPtr, tagId);
    363 #else
    364  LE_UNUSED(tagId);
    365 #endif
    366  le_pack_PackUint16(bufferPtr, value);
    367  return true;
    368 }
    369 
    370 //--------------------------------------------------------------------------------------------------
    371 /**
    372  * Pack a uint32_t into a buffer, incrementing the buffer pointer as appropriate.
    373  */
    374 //--------------------------------------------------------------------------------------------------
    375 LE_DECLARE_INLINE bool le_pack_PackUint32
    376 (
    377  uint8_t** bufferPtr,
    378  uint32_t value
    379 )
    380 {
    381 #ifdef LE_CONFIG_RPC
    382  _le_pack_packPositiveInteger(bufferPtr, value);
    383 #else
    384  LE_PACK_PACK_SIMPLE_VALUE(value);
    385 #endif
    386  return true;
    387 }
    388 
    389 
    390 //--------------------------------------------------------------------------------------------------
    391 /**
    392  * Pack a uint32_t into a buffer using the specified TagID, incrementing the buffer pointer
    393  * and decrementing the available size, as appropriate.
    394  *
    395  * @note By making this an inline function, gcc can often optimize out the size check if the buffer
    396  * size is known at compile time.
    397  */
    398 //--------------------------------------------------------------------------------------------------
    399 LE_DECLARE_INLINE bool le_pack_PackTaggedUint32
    400 (
    401  uint8_t** bufferPtr,
    402  uint32_t value,
    403  le_pack_SemanticTag_t tagId
    404 )
    405 {
    406 #ifdef LE_CONFIG_RPC
    407  le_pack_PackSemanticTag(bufferPtr, tagId);
    408 #else
    409  LE_UNUSED(tagId);
    410 #endif
    411  le_pack_PackUint32(bufferPtr, value);
    412  return true;
    413 }
    414 
    415 //--------------------------------------------------------------------------------------------------
    416 /**
    417  * Pack a uint64_t into a buffer, incrementing the buffer pointer as appropriate.
    418  */
    419 //--------------------------------------------------------------------------------------------------
    420 LE_DECLARE_INLINE bool le_pack_PackUint64
    421 (
    422  uint8_t** bufferPtr,
    423  uint64_t value
    424 )
    425 {
    426 #ifdef LE_CONFIG_RPC
    427  _le_pack_packPositiveInteger(bufferPtr, value);
    428 #else
    429  LE_PACK_PACK_SIMPLE_VALUE(value);
    430 #endif
    431  return true;
    432 }
    433 
    434 //--------------------------------------------------------------------------------------------------
    435 /**
    436  * Pack a uint64_t into a buffer using the specified TagID, incrementing the buffer pointer
    437  * and decrementing the available size, as appropriate.
    438  *
    439  * @note By making this an inline function, gcc can often optimize out the size check if the buffer
    440  * size is known at compile time.
    441  */
    442 //--------------------------------------------------------------------------------------------------
    443 LE_DECLARE_INLINE bool le_pack_PackTaggedUint64
    444 (
    445  uint8_t** bufferPtr,
    446  uint64_t value,
    447  le_pack_SemanticTag_t tagId
    448 )
    449 {
    450 #ifdef LE_CONFIG_RPC
    451  le_pack_PackSemanticTag(bufferPtr, tagId);
    452 #else
    453  LE_UNUSED(tagId);
    454 #endif
    455  le_pack_PackUint64(bufferPtr, value);
    456  return true;
    457 }
    458 
    459 //--------------------------------------------------------------------------------------------------
    460 /**
    461  * Pack a int8_t into a buffer, incrementing the buffer pointer as appropriate.
    462  */
    463 //--------------------------------------------------------------------------------------------------
    464 LE_DECLARE_INLINE bool le_pack_PackInt8
    465 (
    466  uint8_t** bufferPtr,
    467  int8_t value
    468 )
    469 {
    470 #ifdef LE_CONFIG_RPC
    471  return le_pack_PackInt8_rpc(bufferPtr, value);
    472 #else
    473  LE_PACK_PACK_SIMPLE_VALUE(value);
    474  return true;
    475 #endif
    476 }
    477 
    478 //--------------------------------------------------------------------------------------------------
    479 /**
    480  * Pack a int8_t into a buffer using the specified TagID, incrementing the buffer pointer
    481  * and decrementing the available size, as appropriate.
    482  *
    483  * @note By making this an inline function, gcc can often optimize out the size check if the buffer
    484  * size is known at compile time.
    485  */
    486 //--------------------------------------------------------------------------------------------------
    487 LE_DECLARE_INLINE bool le_pack_PackTaggedInt8
    488 (
    489  uint8_t** bufferPtr,
    490  int8_t value,
    491  le_pack_SemanticTag_t tagId
    492 )
    493 {
    494 #ifdef LE_CONFIG_RPC
    495  le_pack_PackSemanticTag(bufferPtr, tagId);
    496 #else
    497  LE_UNUSED(tagId);
    498 #endif
    499  le_pack_PackInt8(bufferPtr, value);
    500  return true;
    501 }
    502 
    503 //--------------------------------------------------------------------------------------------------
    504 /**
    505  * Pack a int16_t into a buffer, incrementing the buffer pointer as appropriate.
    506  */
    507 //--------------------------------------------------------------------------------------------------
    508 LE_DECLARE_INLINE bool le_pack_PackInt16
    509 (
    510  uint8_t** bufferPtr,
    511  int16_t value
    512 )
    513 {
    514 #ifdef LE_CONFIG_RPC
    515  return le_pack_PackInt16_rpc(bufferPtr, value);
    516 #else
    517  LE_PACK_PACK_SIMPLE_VALUE(value);
    518  return true;
    519 #endif
    520 }
    521 
    522 //--------------------------------------------------------------------------------------------------
    523 /**
    524  * Pack a int16_t into a buffer using the specified TagID, incrementing the buffer pointer
    525  * and decrementing the available size, as appropriate.
    526  *
    527  * @note By making this an inline function, gcc can often optimize out the size check if the buffer
    528  * size is known at compile time.
    529  */
    530 //--------------------------------------------------------------------------------------------------
    531 LE_DECLARE_INLINE bool le_pack_PackTaggedInt16
    532 (
    533  uint8_t** bufferPtr,
    534  int16_t value,
    535  le_pack_SemanticTag_t tagId
    536 )
    537 {
    538 #ifdef LE_CONFIG_RPC
    539  le_pack_PackSemanticTag(bufferPtr, tagId);
    540 #else
    541  LE_UNUSED(tagId);
    542 #endif
    543  le_pack_PackInt16(bufferPtr, value);
    544  return true;
    545 }
    546 
    547 //--------------------------------------------------------------------------------------------------
    548 /**
    549  * Pack a int32_t into a buffer, incrementing the buffer pointer as appropriate.
    550  */
    551 //--------------------------------------------------------------------------------------------------
    552 LE_DECLARE_INLINE bool le_pack_PackInt32
    553 (
    554  uint8_t** bufferPtr,
    555  int32_t value
    556 )
    557 {
    558 #ifdef LE_CONFIG_RPC
    559  return le_pack_PackInt32_rpc(bufferPtr, value);
    560 #else
    561  LE_PACK_PACK_SIMPLE_VALUE(value);
    562  return true;
    563 #endif
    564 }
    565 
    566 //--------------------------------------------------------------------------------------------------
    567 /**
    568  * Pack a int32_t into a buffer using the specified TagID, incrementing the buffer pointer
    569  * and decrementing the available size, as appropriate.
    570  *
    571  * @note By making this an inline function, gcc can often optimize out the size check if the buffer
    572  * size is known at compile time.
    573  */
    574 //--------------------------------------------------------------------------------------------------
    575 LE_DECLARE_INLINE bool le_pack_PackTaggedInt32
    576 (
    577  uint8_t** bufferPtr,
    578  int32_t value,
    579  le_pack_SemanticTag_t tagId
    580 )
    581 {
    582 #ifdef LE_CONFIG_RPC
    583  le_pack_PackSemanticTag(bufferPtr, tagId);
    584 #else
    585  LE_UNUSED(tagId);
    586 #endif
    587  le_pack_PackInt32(bufferPtr, value);
    588  return true;
    589 }
    590 
    591 //--------------------------------------------------------------------------------------------------
    592 /**
    593  * Pack a int64_t into a buffer, incrementing the buffer pointer as appropriate.
    594  */
    595 //--------------------------------------------------------------------------------------------------
    596 LE_DECLARE_INLINE bool le_pack_PackInt64
    597 (
    598  uint8_t** bufferPtr,
    599  int64_t value
    600 )
    601 {
    602 #ifdef LE_CONFIG_RPC
    603  return le_pack_PackInt64_rpc(bufferPtr, value);
    604 #else
    605  LE_PACK_PACK_SIMPLE_VALUE(value);
    606  return true;
    607 #endif
    608 }
    609 
    610 //--------------------------------------------------------------------------------------------------
    611 /**
    612  * Pack a int64_t into a buffer using the specified TagID, incrementing the buffer pointer
    613  * and decrementing the available size, as appropriate.
    614  *
    615  * @note By making this an inline function, gcc can often optimize out the size check if the buffer
    616  * size is known at compile time.
    617  */
    618 //--------------------------------------------------------------------------------------------------
    619 LE_DECLARE_INLINE bool le_pack_PackTaggedInt64
    620 (
    621  uint8_t** bufferPtr,
    622  int64_t value,
    623  le_pack_SemanticTag_t tagId
    624 )
    625 {
    626 #ifdef LE_CONFIG_RPC
    627  le_pack_PackSemanticTag(bufferPtr, tagId);
    628 #else
    629  LE_UNUSED(tagId);
    630 #endif
    631  le_pack_PackInt64(bufferPtr, value);
    632  return true;
    633 }
    634 
    635 //--------------------------------------------------------------------------------------------------
    636 /**
    637  * Pack a size_t into a buffer, incrementing the buffer pointer as appropriate.
    638  *
    639  * @note Packed sizes are limited to 2^32-1, regardless of platform
    640  */
    641 //--------------------------------------------------------------------------------------------------
    642 LE_DECLARE_INLINE bool le_pack_PackSize
    643 (
    644  uint8_t **bufferPtr,
    645  size_t value
    646 )
    647 {
    648 #ifdef LE_CONFIG_RPC
    649  _le_pack_packPositiveInteger(bufferPtr, value);
    650  return true;
    651 #else
    652  return le_pack_PackUint32(bufferPtr, value);
    653 #endif
    654 }
    655 
    656 //--------------------------------------------------------------------------------------------------
    657 /**
    658  * Pack size_t and 32-bit integer tuple into a buffer using the specified TagID,
    659  * incrementing the buffer pointer
    660  * and decrementing the available size, as appropriate.
    661  *
    662  * @note By making this an inline function, gcc can often optimize out the size check if the buffer
    663  * size is known at compile time.
    664  */
    665 //--------------------------------------------------------------------------------------------------
    666 LE_DECLARE_INLINE bool le_pack_PackTaggedSizeUint32Tuple
    667 (
    668  uint8_t** bufferPtr,
    669  size_t size,
    670  uint32_t value,
    671  le_pack_SemanticTag_t tagId
    672 )
    673 {
    674 #ifdef LE_CONFIG_RPC
    675  return le_pack_PackTaggedSizeUint32Tuple_rpc(bufferPtr, size, value, tagId);
    676 #else
    677  LE_UNUSED(tagId);
    678  bool result;
    679  result = le_pack_PackSize(bufferPtr, size);
    680  if (result)
    681  {
    682  result = le_pack_PackUint32(bufferPtr, value);
    683  }
    684  return result;
    685 #endif
    686 }
    687 
    688 //--------------------------------------------------------------------------------------------------
    689 /**
    690  * Pack size_t and 64-bit integer tuple into a buffer using the specified TagID,
    691  * incrementing the buffer pointer
    692  * and decrementing the available size, as appropriate.
    693  *
    694  * @note By making this an inline function, gcc can often optimize out the size check if the buffer
    695  * size is known at compile time.
    696  */
    697 //--------------------------------------------------------------------------------------------------
    698 LE_DECLARE_INLINE bool le_pack_PackTaggedSizeUint64Tuple
    699 (
    700  uint8_t** bufferPtr,
    701  size_t size,
    702  uint64_t value,
    703  le_pack_SemanticTag_t tagId
    704 )
    705 {
    706 #ifdef LE_CONFIG_RPC
    707  return le_pack_PackTaggedSizeUint64Tuple_rpc(bufferPtr, size, value, tagId);
    708 #else
    709  LE_UNUSED(tagId);
    710  bool result;
    711  result = le_pack_PackSize(bufferPtr, size);
    712  if (result)
    713  {
    714  result = le_pack_PackUint64(bufferPtr, value);
    715  }
    716  return result;
    717 #endif
    718 }
    719 
    720 //--------------------------------------------------------------------------------------------------
    721 /**
    722  * pack a tuple of size and pointer.
    723  */
    724 //--------------------------------------------------------------------------------------------------
    725 LE_DECLARE_INLINE bool le_pack_PackTaggedSizePointerTuple
    726 (
    727  uint8_t** bufferPtr,
    728  size_t size,
    729  void* value,
    730  le_pack_SemanticTag_t tagId
    731 )
    732 {
    733 #if IFGEN_PTR32
    734  uint32_t rawValue = (uint32_t)value;
    735  return le_pack_PackTaggedSizeUint32Tuple(bufferPtr, size, rawValue, tagId);
    736 #elif IFGEN_PTR64
    737  uint64_t rawValue = (uint64_t)value;
    738  return le_pack_PackTaggedSizeUint64Tuple(bufferPtr, size, rawValue, tagId);
    739 #else
    740 # error "Unsupported pointer size -- only 32- and 64-bit are supported for local services."
    741 #endif
    742 }
    743 
    744 //--------------------------------------------------------------------------------------------------
    745 /**
    746  * Pack a size_t into a buffer using the specified TagID, incrementing the buffer pointer
    747  * and decrementing the available size, as appropriate.
    748  *
    749  * @note Packed sizes are limited to 2^32-1, regardless of platform
    750  */
    751 //--------------------------------------------------------------------------------------------------
    752 LE_DECLARE_INLINE bool le_pack_PackTaggedSize
    753 (
    754  uint8_t **bufferPtr,
    755  size_t value,
    756  le_pack_SemanticTag_t tagId
    757 )
    758 {
    759  if (value > UINT32_MAX)
    760  {
    761  return false;
    762  }
    763 
    764  return le_pack_PackTaggedUint32(bufferPtr, value, tagId);
    765 }
    766 
    767 //--------------------------------------------------------------------------------------------------
    768 /**
    769  * Pack a bool into a buffer, incrementing the buffer pointer as appropriate.
    770  */
    771 //--------------------------------------------------------------------------------------------------
    772 LE_DECLARE_INLINE bool le_pack_PackBool
    773 (
    774  uint8_t** bufferPtr,
    775  bool value
    776 )
    777 {
    778 #ifdef LE_CONFIG_RPC
    779  return le_pack_PackBool_rpc(bufferPtr, value);
    780 #else
    781  // Force boolean to uint8_t 0 or 1 for packing, regarldess of underlying OS type.
    782  // Underlying type has been int on some platforms in the past.
    783  uint8_t simpleValue = ((value)?1:0);
    784  LE_PACK_PACK_SIMPLE_VALUE(simpleValue);
    785  return true;
    786 #endif
    787 }
    788 
    789 //--------------------------------------------------------------------------------------------------
    790 /**
    791  * Pack a bool into a buffer using the specified TagID, incrementing the buffer pointer
    792  * and decrementing the available size, as appropriate.
    793  *
    794  * @note By making this an inline function, gcc can often optimize out the size check if the buffer
    795  * size is known at compile time.
    796  */
    797 //--------------------------------------------------------------------------------------------------
    798 LE_DECLARE_INLINE bool le_pack_PackTaggedBool
    799 (
    800  uint8_t** bufferPtr,
    801  bool value,
    802  le_pack_SemanticTag_t tagId
    803 )
    804 {
    805 #ifdef LE_CONFIG_RPC
    806  le_pack_PackSemanticTag(bufferPtr, tagId);
    807 #else
    808  LE_UNUSED(tagId);
    809 #endif
    810  le_pack_PackBool(bufferPtr, value);
    811  return true;
    812 }
    813 
    814 //--------------------------------------------------------------------------------------------------
    815 /**
    816  * Pack a char into a buffer, incrementing the buffer pointer as appropriate.
    817  */
    818 //--------------------------------------------------------------------------------------------------
    819 LE_DECLARE_INLINE bool le_pack_PackChar
    820 (
    821  uint8_t** bufferPtr,
    822  char value
    823 )
    824 {
    825 #ifdef LE_CONFIG_RPC
    826  _le_pack_packPositiveInteger(bufferPtr, value);
    827 #else
    828  LE_PACK_PACK_SIMPLE_VALUE(value);
    829 #endif
    830  return true;
    831 }
    832 
    833 //--------------------------------------------------------------------------------------------------
    834 /**
    835  * Pack a char into a buffer using the specified TagID, incrementing the buffer pointer
    836  * and decrementing the available size, as appropriate.
    837  *
    838  * @note By making this an inline function, gcc can often optimize out the size check if the buffer
    839  * size is known at compile time.
    840  */
    841 //--------------------------------------------------------------------------------------------------
    842 LE_DECLARE_INLINE bool le_pack_PackTaggedChar
    843 (
    844  uint8_t** bufferPtr,
    845  char value,
    846  le_pack_SemanticTag_t tagId
    847 )
    848 {
    849 #ifdef LE_CONFIG_RPC
    850  le_pack_PackSemanticTag(bufferPtr, tagId);
    851 #else
    852  LE_UNUSED(tagId);
    853 #endif
    854  le_pack_PackChar(bufferPtr, value);
    855  return true;
    856 }
    857 
    858 //--------------------------------------------------------------------------------------------------
    859 /**
    860  * Pack a double into a buffer, incrementing the buffer pointer as appropriate.
    861  */
    862 //--------------------------------------------------------------------------------------------------
    863 LE_DECLARE_INLINE bool le_pack_PackDouble
    864 (
    865  uint8_t** bufferPtr,
    866  double value
    867 )
    868 {
    869 #ifdef LE_CONFIG_RPC
    870  return le_pack_PackDouble_rpc(bufferPtr, value);
    871 #else
    872  LE_PACK_PACK_SIMPLE_VALUE(value);
    873  return true;
    874 #endif
    875 }
    876 
    877 //--------------------------------------------------------------------------------------------------
    878 /**
    879  * Pack a double into a buffer using the specified TagID, incrementing the buffer pointer
    880  * and decrementing the available size, as appropriate.
    881  *
    882  * @note By making this an inline function, gcc can often optimize out the size check if the buffer
    883  * size is known at compile time.
    884  */
    885 //--------------------------------------------------------------------------------------------------
    886 LE_DECLARE_INLINE bool le_pack_PackTaggedDouble
    887 (
    888  uint8_t** bufferPtr,
    889  double value,
    890  le_pack_SemanticTag_t tagId
    891 )
    892 {
    893 #ifdef LE_CONFIG_RPC
    894  le_pack_PackSemanticTag(bufferPtr, tagId);
    895 #else
    896  LE_UNUSED(tagId);
    897 #endif
    898  le_pack_PackDouble(bufferPtr, value);
    899  return true;
    900 }
    901 
    902 //--------------------------------------------------------------------------------------------------
    903 /**
    904  * Pack a le_result_t into a buffer, incrementing the buffer pointer as appropriate.
    905  */
    906 //--------------------------------------------------------------------------------------------------
    907 LE_DECLARE_INLINE bool le_pack_PackResult
    908 (
    909  uint8_t** bufferPtr,
    910  le_result_t value
    911 )
    912 {
    913 #ifdef LE_CONFIG_RPC
    914  return le_pack_PackResult_rpc(bufferPtr, value);
    915 #else
    916  LE_PACK_PACK_SIMPLE_VALUE(value);
    917  return true;
    918 #endif
    919 }
    920 
    921 //--------------------------------------------------------------------------------------------------
    922 /**
    923  * Pack a le_result_t into a buffer using the specified TagID, incrementing the buffer pointer
    924  * and decrementing the available size, as appropriate.
    925  *
    926  * @note By making this an inline function, gcc can often optimize out the size check if the buffer
    927  * size is known at compile time.
    928  */
    929 //--------------------------------------------------------------------------------------------------
    930 LE_DECLARE_INLINE bool le_pack_PackTaggedResult
    931 (
    932  uint8_t** bufferPtr,
    933  le_result_t value,
    934  le_pack_SemanticTag_t tagId
    935 )
    936 {
    937 #ifdef LE_CONFIG_RPC
    938  le_pack_PackSemanticTag(bufferPtr, tagId);
    939 #else
    940  LE_UNUSED(tagId);
    941 #endif
    942  le_pack_PackResult(bufferPtr, value);
    943  return true;
    944 }
    945 
    946 //--------------------------------------------------------------------------------------------------
    947 /**
    948  * Pack le_onoff_t into a buffer, incrementing the buffer pointer as appropriate.
    949  */
    950 //--------------------------------------------------------------------------------------------------
    951 LE_DECLARE_INLINE bool le_pack_PackOnOff
    952 (
    953  uint8_t** bufferPtr,
    954  le_onoff_t value
    955 )
    956 {
    957 #ifdef LE_CONFIG_RPC
    958  le_pack_PackUint8(bufferPtr, value);
    959 #else
    960  LE_PACK_PACK_SIMPLE_VALUE(value);
    961 #endif
    962  return true;
    963 }
    964 
    965 //--------------------------------------------------------------------------------------------------
    966 /**
    967  * Pack le_onoff_t into a buffer using the specified TagID, incrementing the buffer pointer
    968  * and decrementing the available size, as appropriate.
    969  *
    970  * @note By making this an inline function, gcc can often optimize out the size check if the buffer
    971  * size is known at compile time.
    972  */
    973 //--------------------------------------------------------------------------------------------------
    974 LE_DECLARE_INLINE bool le_pack_PackTaggedOnOff
    975 (
    976  uint8_t** bufferPtr,
    977  le_onoff_t value,
    978  le_pack_SemanticTag_t tagId
    979 )
    980 {
    981 #ifdef LE_CONFIG_RPC
    982  le_pack_PackSemanticTag(bufferPtr, tagId);
    983 #else
    984  LE_UNUSED(tagId);
    985 #endif
    986  le_pack_PackOnOff(bufferPtr, value);
    987  return true;
    988 }
    989 
    990 #undef LE_PACK_PACK_SIMPLE_VALUE
    991 
    992 //--------------------------------------------------------------------------------------------------
    993 /**
    994  * Pack a reference into a buffer, incrementing the buffer pointer.
    995  */
    996 //--------------------------------------------------------------------------------------------------
    997 LE_DECLARE_INLINE bool le_pack_PackReference
    998 (
    999  uint8_t** bufferPtr,
    1000  const void* ref
    1001 )
    1002 {
    1003  size_t refAsInt = (size_t)ref;
    1004 
    1005  // All references passed through an API must be safe references (or NULL), so
    1006  // 0-bit will be set and reference will be <= UINT32_MAX. Size check
    1007  // is performed in pack function.
    1008  if ((refAsInt <= UINT32_MAX) &&
    1009  ((refAsInt & 0x01) ||
    1010  !refAsInt))
    1011  {
    1012 #ifdef LE_CONFIG_RPC
    1013  return le_pack_PackTaggedUint32(bufferPtr, (uint32_t)refAsInt, LE_PACK_REFERENCE);
    1014 #else
    1015  return le_pack_PackUint32(bufferPtr, (uint32_t)refAsInt);
    1016 #endif
    1017  }
    1018  else
    1019  {
    1020  return false;
    1021  }
    1022 }
    1023 
    1024 //--------------------------------------------------------------------------------------------------
    1025 /**
    1026  * Pack a reference into a buffer using the specified TagID, incrementing the buffer pointer
    1027  * and decrementing the available size.
    1028  */
    1029 //--------------------------------------------------------------------------------------------------
    1030 LE_DECLARE_INLINE bool le_pack_PackTaggedReference
    1031 (
    1032  uint8_t** bufferPtr,
    1033  const void* ref,
    1034  le_pack_SemanticTag_t tagId
    1035 )
    1036 {
    1037  size_t refAsInt = (size_t)ref;
    1038 
    1039  // All references passed through an API must be safe references (or NULL), so
    1040  // 0-bit will be set and reference will be <= UINT32_MAX. Size check
    1041  // is performed in pack function.
    1042  if ((refAsInt <= UINT32_MAX) &&
    1043  ((refAsInt & 0x01) ||
    1044  !refAsInt))
    1045  {
    1046  return le_pack_PackTaggedUint32(bufferPtr, (uint32_t)refAsInt, tagId);
    1047  }
    1048  else
    1049  {
    1050  return false;
    1051  }
    1052 }
    1053 
    1054 //--------------------------------------------------------------------------------------------------
    1055 /**
    1056  * Pack a string header
    1057  */
    1058 //--------------------------------------------------------------------------------------------------
    1059 LE_DECLARE_INLINE bool le_pack_PackStringHeader
    1060 (
    1061  uint8_t** bufferPtr,
    1062  size_t stringLen
    1063 )
    1064 {
    1065 #ifdef LE_CONFIG_RPC
    1066  _le_pack_packInteger(bufferPtr, stringLen, _LE_PACK_CBOR_TEXT_STRING);
    1067  return true;
    1068 #else
    1069  return le_pack_PackUint32(bufferPtr, stringLen);
    1070 #endif
    1071 }
    1072 
    1073 
    1074 //--------------------------------------------------------------------------------------------------
    1075 /**
    1076  * Pack a string into a buffer, incrementing the buffer pointer.
    1077  */
    1078 //--------------------------------------------------------------------------------------------------
    1079 LE_DECLARE_INLINE bool le_pack_PackString
    1080 (
    1081  uint8_t** bufferPtr,
    1082  const char *stringPtr,
    1083  uint32_t maxStringCount
    1084 )
    1085 {
    1086 #ifdef LE_CONFIG_RPC
    1087  return le_pack_PackString_rpc(bufferPtr, stringPtr, maxStringCount);
    1088 #else
    1089  if (!stringPtr)
    1090  {
    1091  return false;
    1092  }
    1093 
    1094  uint32_t stringLen = strnlen(stringPtr, maxStringCount);
    1095  // String was too long to fit in the buffer -- return false.
    1096  if (stringPtr[stringLen] != '\0')
    1097  {
    1098  return false;
    1099  }
    1100  le_pack_PackUint32(bufferPtr, stringLen);
    1101  LE_PACK_PACK_SIMPLE_BUFFER(stringPtr, stringLen);
    1102  return true;
    1103 #endif
    1104 }
    1105 
    1106 //--------------------------------------------------------------------------------------------------
    1107 /**
    1108  * Pack a string into a buffer using the specified TagID, incrementing the buffer pointer
    1109  * and decrementing the available size.
    1110  *
    1111  * @note Always decrements available size according to the max possible size used, not actual size
    1112  * used.
    1113  */
    1114 //--------------------------------------------------------------------------------------------------
    1115 LE_DECLARE_INLINE bool le_pack_PackTaggedString
    1116 (
    1117  uint8_t** bufferPtr,
    1118  const char *stringPtr,
    1119  uint32_t maxStringCount,
    1120  le_pack_SemanticTag_t tagId
    1121 )
    1122 {
    1123 #ifdef LE_CONFIG_RPC
    1124  le_pack_PackSemanticTag(bufferPtr, tagId);
    1125 #else
    1126  LE_UNUSED(tagId);
    1127 #endif
    1128  return le_pack_PackString(bufferPtr, stringPtr, maxStringCount);
    1129 }
    1130 
    1131 //--------------------------------------------------------------------------------------------------
    1132 /**
    1133  * Pack the size information for an array into a buffer, incrementing the buffer pointer.
    1134  *
    1135  * @note Users of this API should generally use LE_PACK_PACKARRAY macro instead which also
    1136  * packs the array data.
    1137  */
    1138 //--------------------------------------------------------------------------------------------------
    1139 LE_DECLARE_INLINE bool le_pack_PackArrayHeader
    1140 (
    1141  uint8_t **bufferPtr,
    1142  const void *arrayPtr,
    1143  size_t elementSize,
    1144  size_t arrayCount,
    1145  size_t arrayMaxCount
    1146 )
    1147 {
    1148  LE_UNUSED(arrayPtr);
    1149  LE_UNUSED(elementSize);
    1150 
    1151  if (arrayCount > arrayMaxCount)
    1152  {
    1153  return false;
    1154  }
    1155 
    1156 #ifdef LE_CONFIG_RPC
    1157  _le_pack_packInteger(bufferPtr, arrayCount, _LE_PACK_CBOR_ITEM_ARRAY);
    1158 #else
    1159  LE_ASSERT(le_pack_PackSize(bufferPtr, arrayCount));
    1160 #endif
    1161  return true;
    1162 }
    1163 
    1164 //--------------------------------------------------------------------------------------------------
    1165 /**
    1166  * Pack an array header with unknown number of elements (inifinite array)
    1167  */
    1168 //--------------------------------------------------------------------------------------------------
    1169 LE_DECLARE_INLINE bool le_pack_PackIndefArrayHeader
    1170 (
    1171  uint8_t** bufferPtr
    1172 )
    1173 {
    1174 #ifdef LE_CONFIG_RPC
    1175  return le_pack_PackIndefArrayHeader_rpc(bufferPtr);
    1176 #else
    1177  LE_UNUSED(bufferPtr);
    1178  return true;
    1179 #endif
    1180 }
    1181 
    1182 //--------------------------------------------------------------------------------------------------
    1183 /**
    1184  * Pack the end of an indefinite item array
    1185  */
    1186 //--------------------------------------------------------------------------------------------------
    1187 LE_DECLARE_INLINE bool le_pack_PackEndOfIndefArray
    1188 (
    1189  uint8_t** bufferPtr
    1190 )
    1191 {
    1192 #ifdef LE_CONFIG_RPC
    1193  return le_pack_PackEndOfIndefArray_rpc(bufferPtr);
    1194 #else
    1195  LE_UNUSED(bufferPtr);
    1196  return true;
    1197 #endif
    1198 }
    1199 
    1200 //--------------------------------------------------------------------------------------------------
    1201 /**
    1202  * Pack a string header
    1203  */
    1204 //--------------------------------------------------------------------------------------------------
    1205 LE_DECLARE_INLINE bool le_pack_PackByteStringHeader
    1206 (
    1207  uint8_t** bufferPtr,
    1208  size_t length
    1209 )
    1210 {
    1211 #ifdef LE_CONFIG_RPC
    1212  _le_pack_packInteger(bufferPtr, length, _LE_PACK_CBOR_BYTE_STRING);
    1213  return true;
    1214 #else
    1215  return le_pack_PackUint32(bufferPtr, length);
    1216 #endif
    1217 }
    1218 
    1219 //--------------------------------------------------------------------------------------------------
    1220 /**
    1221  * pack a byte string (Array of uint8, int8, or char)
    1222  */
    1223 //--------------------------------------------------------------------------------------------------
    1224 LE_DECLARE_INLINE bool le_pack_PackByteString
    1225 (
    1226  uint8_t** bufferPtr,
    1227  const void* byteStringPtr,
    1228  uint32_t byteStringCount
    1229 )
    1230 {
    1231 #ifdef LE_CONFIG_RPC
    1232  _le_pack_packInteger(bufferPtr, byteStringCount, _LE_PACK_CBOR_BYTE_STRING);
    1233 #else
    1234  le_pack_PackUint32(bufferPtr, byteStringCount);
    1235 #endif
    1236  LE_PACK_PACK_SIMPLE_BUFFER(byteStringPtr, byteStringCount);
    1237  return true;
    1238 }
    1239 
    1240 //--------------------------------------------------------------------------------------------------
    1241 /**
    1242  * Pack tagged inf array header
    1243  */
    1244 //--------------------------------------------------------------------------------------------------
    1245 LE_DECLARE_INLINE bool le_pack_PackTaggedIndefArrayHeader
    1246 (
    1247  uint8_t** bufferPtr,
    1248  le_pack_SemanticTag_t tagId
    1249 )
    1250 {
    1251 #ifdef LE_CONFIG_RPC
    1252  le_pack_PackSemanticTag(bufferPtr, tagId);
    1253 #else
    1254  LE_UNUSED(tagId);
    1255 #endif
    1256  return le_pack_PackIndefArrayHeader(bufferPtr);
    1257 }
    1258 
    1259 //--------------------------------------------------------------------------------------------------
    1260 /**
    1261  * Pack the size information for an array into a buffer using the specified TagID,
    1262  * incrementing the buffer pointer and decrementing the available size.
    1263  *
    1264  * @note Users of this API should generally use LE_PACK_PACKARRAY macro instead which also
    1265  * packs the array data.
    1266  */
    1267 //--------------------------------------------------------------------------------------------------
    1268 LE_DECLARE_INLINE bool le_pack_PackTaggedArrayHeader
    1269 (
    1270  uint8_t **bufferPtr,
    1271  const void *arrayPtr,
    1272  size_t elementSize,
    1273  size_t arrayCount,
    1274  size_t arrayMaxCount,
    1275  le_pack_SemanticTag_t tagId
    1276 )
    1277 {
    1278  LE_UNUSED(arrayPtr);
    1279  LE_UNUSED(elementSize);
    1280 
    1281  if (arrayCount > arrayMaxCount)
    1282  {
    1283  return false;
    1284  }
    1285 #ifdef LE_CONFIG_RPC
    1286  le_pack_PackSemanticTag(bufferPtr, tagId);
    1287 #else
    1288  LE_UNUSED(tagId);
    1289 #endif
    1290  LE_ASSERT(le_pack_PackArrayHeader(bufferPtr,arrayPtr, elementSize, arrayCount, arrayMaxCount));
    1291  return true;
    1292 }
    1293 
    1294 
    1295 //--------------------------------------------------------------------------------------------------
    1296 /**
    1297  * pack a byte string (Array of uint8, int8, or char)
    1298  */
    1299 //--------------------------------------------------------------------------------------------------
    1300 LE_DECLARE_INLINE bool le_pack_PackTaggedByteString
    1301 (
    1302  uint8_t** bufferPtr,
    1303  void* byteStringPtr,
    1304  uint32_t byteStringCount
    1305 )
    1306 {
    1307 #ifdef LE_CONFIG_RPC
    1308  _le_pack_packInteger(bufferPtr, byteStringCount, _LE_PACK_CBOR_BYTE_STRING);
    1309 #else
    1310  le_pack_PackUint32(bufferPtr, byteStringCount);
    1311 #endif
    1312  LE_PACK_PACK_SIMPLE_BUFFER(byteStringPtr, byteStringCount);
    1313  return true;
    1314 }
    1315 
    1316 //--------------------------------------------------------------------------------------------------
    1317 /**
    1318  * Pack an array into a buffer, incrementing the buffer pointer.
    1319  *
    1320  * @note Will assert if the resulted array exceeds the maximum size allowed.
    1321  */
    1322 //--------------------------------------------------------------------------------------------------
    1323 #define LE_PACK_PACKARRAY(bufferPtr, \
    1324  arrayPtr, \
    1325  arrayCount, \
    1326  arrayMaxCount, \
    1327  packFunc, \
    1328  resultPtr) \
    1329  do { \
    1330  *(resultPtr) = le_pack_PackArrayHeader((bufferPtr), \
    1331  (arrayPtr), sizeof((arrayPtr)[0]), \
    1332  (arrayCount), (arrayMaxCount)); \
    1333  if (*(resultPtr)) \
    1334  { \
    1335  uint32_t i; \
    1336  for (i = 0; i < (arrayCount); ++i) \
    1337  { \
    1338  LE_ASSERT(packFunc((bufferPtr), (arrayPtr)[i])); \
    1339  } \
    1340  *(resultPtr) = true; \
    1341  } \
    1342  } while (0)
    1343 
    1344 
    1345 //--------------------------------------------------------------------------------------------------
    1346 /**
    1347  * Pack an array into a buffer, incrementing the buffer pointer.
    1348  *
    1349  * @note Will assert if the resulted array exceeds the maximum size allowed.
    1350  */
    1351 //--------------------------------------------------------------------------------------------------
    1352 #define LE_PACK_PACKTAGGEDARRAY(bufferPtr, \
    1353  arrayPtr, \
    1354  arrayCount, \
    1355  arrayMaxCount, \
    1356  packFunc, \
    1357  tagId, \
    1358  resultPtr) \
    1359  do { \
    1360  *(resultPtr) = le_pack_PackTaggedArrayHeader((bufferPtr), \
    1361  (arrayPtr), sizeof((arrayPtr)[0]), \
    1362  (arrayCount), (arrayMaxCount), tagId); \
    1363  if (*(resultPtr)) \
    1364  { \
    1365  uint32_t i; \
    1366  for (i = 0; i < (arrayCount); ++i) \
    1367  { \
    1368  LE_ASSERT(packFunc((bufferPtr), (arrayPtr)[i])); \
    1369  } \
    1370  *(resultPtr) = true; \
    1371  } \
    1372  } while (0)
    1373 
    1374 //--------------------------------------------------------------------------------------------------
    1375 /**
    1376  * Pack an array of struct into a buffer, incrementing the buffer pointer.
    1377  *
    1378  * @note Will assert if the resulted array of struct exceeds the maximum size allowed.
    1379  */
    1380 //--------------------------------------------------------------------------------------------------
    1381 #define LE_PACK_PACKSTRUCTARRAY(bufferPtr, \
    1382  arrayPtr, \
    1383  arrayCount, \
    1384  arrayMaxCount, \
    1385  packFunc, \
    1386  resultPtr) \
    1387  do { \
    1388  *(resultPtr) = le_pack_PackArrayHeader((bufferPtr), \
    1389  (arrayPtr), sizeof((arrayPtr)[0]), \
    1390  (arrayCount), (arrayMaxCount)); \
    1391  if (*(resultPtr)) \
    1392  { \
    1393  uint32_t i; \
    1394  for (i = 0; i < (arrayCount); ++i) \
    1395  { \
    1396  LE_ASSERT(packFunc((bufferPtr), &((arrayPtr)[i]))); \
    1397  } \
    1398  *(resultPtr) = true; \
    1399  } \
    1400  } while (0)
    1401 
    1402 //--------------------------------------------------------------------------------------------------
    1403 // Unpack functions
    1404 //--------------------------------------------------------------------------------------------------
    1405 
    1406 #define LE_PACK_UNPACK_SIMPLE_VALUE(valuePtr) \
    1407  do { \
    1408  memcpy((valuePtr), *bufferPtr, sizeof(*(valuePtr))); \
    1409  *bufferPtr = (*bufferPtr) + sizeof(*(valuePtr)); \
    1410  } while (0)
    1411 
    1412 
    1413 //--------------------------------------------------------------------------------------------------
    1414 /**
    1415  * read bytes
    1416  */
    1417 //--------------------------------------------------------------------------------------------------
    1418 #define LE_PACK_UNPACK_SIMPLE_BUFFER(srcPtr, length) \
    1419  do { \
    1420  memcpy((void*)(srcPtr), *bufferPtr, length); \
    1421  *bufferPtr += length; \
    1422  } while(0) \
    1423 
    1424 //--------------------------------------------------------------------------------------------------
    1425 /**
    1426  * Get type.
    1427  *
    1428  * @return
    1429  * - an le_pack_Type_t enum.
    1430  */
    1431 //--------------------------------------------------------------------------------------------------
    1432 le_pack_Type_t le_pack_GetType
    1433 (
    1434  uint8_t* buffer, ///< [IN] buffer pointer
    1435  ssize_t* additionalBytes ///< [OUT] number of additional bytes
    1436 );
    1437 
    1438 //--------------------------------------------------------------------------------------------------
    1439 /**
    1440  * unpack tiny field
    1441  */
    1442 //--------------------------------------------------------------------------------------------------
    1443 #define LE_PACK_UNPACK_TINY_ITEM() \
    1444  do { \
    1445  uint8_t* buffer = *bufferPtr; \
    1446  major = (buffer[0] >> 5) & 0x7; \
    1447  additional = buffer[0] & 0x1F; \
    1448  *bufferPtr += 1; \
    1449  } while(0) \
    1450 
    1451 //--------------------------------------------------------------------------------------------------
    1452 /**
    1453  * unpack positive integer
    1454  */
    1455 //--------------------------------------------------------------------------------------------------
    1456 bool _le_pack_unpackPositiveInteger(
    1457  uint8_t** bufferPtr,
    1458  uint64_t* valuePtr,
    1459  unsigned int expectedMajor
    1460 );
    1461 
    1462 
    1463 //--------------------------------------------------------------------------------------------------
    1464 /**
    1465  * unpack integer(may be positive or negative)
    1466  */
    1467 //--------------------------------------------------------------------------------------------------
    1468 bool _le_pack_unpackInteger
    1469 (
    1470  uint8_t** bufferPtr,
    1471  int64_t* valuePtr
    1472 );
    1473 
    1474 #ifdef LE_CONFIG_RPC
    1475 //--------------------------------------------------------------------------------------------------
    1476 /**
    1477  * Protoype of out-of-line functions containing rpc specific implementations:
    1478  */
    1479 //--------------------------------------------------------------------------------------------------
    1480 bool le_pack_UnpackUint8_rpc(uint8_t** bufferPtr, uint8_t* valuePtr);
    1481 bool le_pack_UnpackUint16_rpc(uint8_t** bufferPtr, uint16_t* valuePtr);
    1482 bool le_pack_UnpackUint32_rpc(uint8_t** bufferPtr, uint32_t* valuePtr);
    1483 bool le_pack_UnpackUint64_rpc(uint8_t** bufferPtr, uint64_t* valuePtr);
    1484 bool le_pack_UnpackInt8_rpc(uint8_t** bufferPtr, int8_t* valuePtr);
    1485 bool le_pack_UnpackInt16_rpc(uint8_t** bufferPtr, int16_t* valuePtr);
    1486 bool le_pack_UnpackInt32_rpc(uint8_t** bufferPtr, int32_t* valuePtr);
    1487 bool le_pack_UnpackInt64_rpc(uint8_t** bufferPtr, int64_t* valuePtr);
    1488 bool le_pack_UnpackBool_rpc(uint8_t** bufferPtr, bool* valuePtr);
    1489 bool le_pack_UnpackChar_rpc(uint8_t** bufferPtr, char* valuePtr);
    1490 bool le_pack_UnpackDouble_rpc(uint8_t** bufferPtr, double* valuePtr);
    1491 bool le_pack_UnpackResult_rpc(uint8_t** bufferPtr, le_result_t* valuePtr);
    1492 bool le_pack_UnpackOnOff_rpc(uint8_t** bufferPtr, le_onoff_t* valuePtr);
    1493 bool le_pack_UnpackStringHeader_rpc(uint8_t** bufferPtr, size_t* stringSizePtr);
    1494 bool le_pack_UnpackIndefArrayHeader_rpc(uint8_t** bufferPtr);
    1495 bool le_pack_UnpackEndOfIndefArray_rpc(uint8_t** bufferPtr);
    1496 bool le_pack_UnpackByteStringHeader_rpc(uint8_t** bufferPtr, size_t* lengthPtr);
    1497 bool le_pack_UnpackSizeUint32Tuple_rpc(uint8_t** bufferPtr, size_t* sizePtr, uint32_t* valuePtr,
    1498  le_pack_SemanticTag_t* semanticTagPtr);
    1499 bool le_pack_UnpackSizeUint64Tuple_rpc(uint8_t** bufferPtr, size_t* sizePtr, uint64_t* valuePtr,
    1500  le_pack_SemanticTag_t* semanticTagPtr);
    1501 bool le_pack_UnpackReference_rpc(uint8_t** bufferPtr, void* refPtr,
    1502  le_pack_SemanticTag_t* semanticTagPtr);
    1503 bool le_pack_UnpackString_rpc(uint8_t** bufferPtr, char *stringPtr, uint32_t bufferSize,
    1504  uint32_t maxStringCount);
    1505 bool le_pack_UnpackStringHeader_rpc(uint8_t** bufferPtr, size_t* stringSizePtr);
    1506 bool le_pack_UnpackArrayHeader_rpc(uint8_t **bufferPtr, const void *arrayPtr, size_t elementSize,
    1507  size_t *arrayCountPtr, size_t arrayMaxCount);
    1508 bool le_pack_UnpackIndefArrayHeader_rpc(uint8_t** bufferPtr);
    1509 bool le_pack_UnpackEndOfIndefArray_rpc(uint8_t** bufferPtr);
    1510 bool le_pack_UnpackByteStringHeader_rpc(uint8_t** bufferPtr, size_t* lengthPtr);
    1511 bool le_pack_UnpackByteString_rpc(uint8_t** bufferPtr, void *arrayPtr, size_t *arrayCountPtr,
    1512  size_t arrayMaxCount);
    1513 #endif
    1514 
    1515 //--------------------------------------------------------------------------------------------------
    1516 /**
    1517  * Unpack a TagID from a buffer, incrementing the buffer pointer and decrementing the
    1518  * available size, as appropriate.
    1519  */
    1520 //--------------------------------------------------------------------------------------------------
    1521 #if LE_CONFIG_RPC
    1522 bool le_pack_UnpackSemanticTag
    1523 (
    1524  uint8_t** bufferPtr,
    1525  le_pack_SemanticTag_t* tagIdPtr
    1526 );
    1527 #else
    1528 LE_DECLARE_INLINE bool le_pack_UnpackSemanticTag
    1529 (
    1530  uint8_t** bufferPtr,
    1531  le_pack_SemanticTag_t *tagIdPtr
    1532 )
    1533 {
    1534  LE_UNUSED(bufferPtr);
    1535 
    1536  if (tagIdPtr)
    1537  {
    1538  *tagIdPtr = 0;
    1539  }
    1540 
    1541  return true;
    1542 }
    1543 #endif
    1544 
    1545 //--------------------------------------------------------------------------------------------------
    1546 /**
    1547  * Unpack a TagID from a buffer, incrementing the buffer pointer and decrementing the
    1548  * available size, as appropriate, then check the tag matches the expected tag
    1549  *
    1550  * @note By making this an inline function, gcc can often optimize out the size check if the buffer
    1551  * size is known at compile time.
    1552  */
    1553 //--------------------------------------------------------------------------------------------------
    1554 LE_DECLARE_INLINE bool le_pack_CheckSemanticTag
    1555 (
    1556  uint8_t** bufferPtr,
    1557  le_pack_SemanticTag_t expectedTagId
    1558 )
    1559 {
    1560 #if LE_CONFIG_RPC
    1561  le_pack_SemanticTag_t tagId;
    1562  return le_pack_UnpackSemanticTag(bufferPtr, &tagId) && (tagId == expectedTagId);
    1563 #else
    1564  // No tagging, assume tags always match
    1565  LE_UNUSED(bufferPtr);
    1566  LE_UNUSED(expectedTagId);
    1567  return true;
    1568 #endif
    1569 }
    1570 
    1571 
    1572 //--------------------------------------------------------------------------------------------------
    1573 /**
    1574  * Unpack a uint8_t from a buffer, incrementing the buffer pointer as appropriate.
    1575  */
    1576 //--------------------------------------------------------------------------------------------------
    1577 LE_DECLARE_INLINE bool le_pack_UnpackUint8
    1578 (
    1579  uint8_t** bufferPtr,
    1580  uint8_t* valuePtr
    1581 )
    1582 {
    1583 #ifdef LE_CONFIG_RPC
    1584  return le_pack_UnpackUint8_rpc(bufferPtr, valuePtr);
    1585 #else
    1586  LE_PACK_UNPACK_SIMPLE_VALUE(valuePtr);
    1587  return true;
    1588 #endif
    1589 }
    1590 
    1591 //--------------------------------------------------------------------------------------------------
    1592 /**
    1593  * Unpack a uint16_t from a buffer, incrementing the buffer pointer as appropriate.
    1594  */
    1595 //--------------------------------------------------------------------------------------------------
    1596 LE_DECLARE_INLINE bool le_pack_UnpackUint16
    1597 (
    1598  uint8_t** bufferPtr,
    1599  uint16_t* valuePtr
    1600 )
    1601 {
    1602 #ifdef LE_CONFIG_RPC
    1603  return le_pack_UnpackUint16_rpc(bufferPtr, valuePtr);
    1604 #else
    1605  LE_PACK_UNPACK_SIMPLE_VALUE(valuePtr);
    1606  return true;
    1607 #endif
    1608 }
    1609 
    1610 //--------------------------------------------------------------------------------------------------
    1611 /**
    1612  * Unpack a uint32_t from a buffer, incrementing the buffer pointer as appropriate.
    1613  */
    1614 //--------------------------------------------------------------------------------------------------
    1615 LE_DECLARE_INLINE bool le_pack_UnpackUint32
    1616 (
    1617  uint8_t** bufferPtr,
    1618  uint32_t* valuePtr
    1619 )
    1620 {
    1621 #ifdef LE_CONFIG_RPC
    1622  return le_pack_UnpackUint32_rpc(bufferPtr, valuePtr);
    1623 #else
    1624  LE_PACK_UNPACK_SIMPLE_VALUE(valuePtr);
    1625  return true;
    1626 #endif
    1627 }
    1628 
    1629 //--------------------------------------------------------------------------------------------------
    1630 /**
    1631  * Unpack a uint64_t from a buffer, incrementing the buffer pointer as appropriate.
    1632  */
    1633 //--------------------------------------------------------------------------------------------------
    1634 LE_DECLARE_INLINE bool le_pack_UnpackUint64
    1635 (
    1636  uint8_t** bufferPtr,
    1637  uint64_t* valuePtr
    1638 )
    1639 {
    1640 #ifdef LE_CONFIG_RPC
    1641  return le_pack_UnpackUint64_rpc(bufferPtr, valuePtr);
    1642 #else
    1643  LE_PACK_UNPACK_SIMPLE_VALUE(valuePtr);
    1644  return true;
    1645 #endif
    1646 }
    1647 
    1648 //--------------------------------------------------------------------------------------------------
    1649 /**
    1650  * Unpack a int8_t from a buffer, incrementing the buffer pointer as appropriate.
    1651  */
    1652 //--------------------------------------------------------------------------------------------------
    1653 LE_DECLARE_INLINE bool le_pack_UnpackInt8
    1654 (
    1655  uint8_t** bufferPtr,
    1656  int8_t* valuePtr
    1657 )
    1658 {
    1659 #ifdef LE_CONFIG_RPC
    1660  return le_pack_UnpackInt8_rpc(bufferPtr, valuePtr);
    1661 #else
    1662  LE_PACK_UNPACK_SIMPLE_VALUE(valuePtr);
    1663  return true;
    1664 #endif
    1665 }
    1666 
    1667 //--------------------------------------------------------------------------------------------------
    1668 /**
    1669  * Unpack a int16_t from a buffer, incrementing the buffer pointer as appropriate.
    1670  */
    1671 //--------------------------------------------------------------------------------------------------
    1672 LE_DECLARE_INLINE bool le_pack_UnpackInt16
    1673 (
    1674  uint8_t** bufferPtr,
    1675  int16_t* valuePtr
    1676 )
    1677 {
    1678 #ifdef LE_CONFIG_RPC
    1679  return le_pack_UnpackInt16_rpc(bufferPtr, valuePtr);
    1680 #else
    1681  LE_PACK_UNPACK_SIMPLE_VALUE(valuePtr);
    1682  return true;
    1683 #endif
    1684 }
    1685 
    1686 //--------------------------------------------------------------------------------------------------
    1687 /**
    1688  * Unpack a int32_t from a buffer, incrementing the buffer pointer as appropriate.
    1689  */
    1690 //--------------------------------------------------------------------------------------------------
    1691 LE_DECLARE_INLINE bool le_pack_UnpackInt32
    1692 (
    1693  uint8_t** bufferPtr,
    1694  int32_t* valuePtr
    1695 )
    1696 {
    1697 #ifdef LE_CONFIG_RPC
    1698  return le_pack_UnpackInt32_rpc(bufferPtr, valuePtr);
    1699 #else
    1700  LE_PACK_UNPACK_SIMPLE_VALUE(valuePtr);
    1701  return true;
    1702 #endif
    1703 }
    1704 
    1705 //--------------------------------------------------------------------------------------------------
    1706 /**
    1707  * Unpack a int64_t from a buffer, incrementing the buffer pointer as appropriate.
    1708  */
    1709 //--------------------------------------------------------------------------------------------------
    1710 LE_DECLARE_INLINE bool le_pack_UnpackInt64
    1711 (
    1712  uint8_t** bufferPtr,
    1713  int64_t* valuePtr
    1714 )
    1715 {
    1716 #ifdef LE_CONFIG_RPC
    1717  return le_pack_UnpackInt64_rpc(bufferPtr, valuePtr);
    1718 #else
    1719  LE_PACK_UNPACK_SIMPLE_VALUE(valuePtr);
    1720  return true;
    1721 #endif
    1722 }
    1723 
    1724 
    1725 //--------------------------------------------------------------------------------------------------
    1726 /**
    1727  * Pack a size_t into a buffer, incrementing the buffer pointer as appropriate.
    1728  *
    1729  * @note Packed sizes are limited to 2^32-1, regardless of platform
    1730  */
    1731 //--------------------------------------------------------------------------------------------------
    1732 LE_DECLARE_INLINE bool le_pack_UnpackSize
    1733 (
    1734  uint8_t **bufferPtr,
    1735  size_t *valuePtr
    1736 )
    1737 {
    1738  uint32_t rawValue;
    1739 
    1740  if (!le_pack_UnpackUint32(bufferPtr, &rawValue))
    1741  {
    1742  return false;
    1743  }
    1744 
    1745  *valuePtr = rawValue;
    1746 
    1747  return true;
    1748 }
    1749 
    1750 //--------------------------------------------------------------------------------------------------
    1751 /**
    1752  * Unpack a uint8_t from a buffer, checking if the tag matches the expected semantic tag
    1753  * and incrementing the buffer pointer as appropriate.
    1754  */
    1755 //--------------------------------------------------------------------------------------------------
    1756 LE_DECLARE_INLINE bool le_pack_UnpackTaggedUint8
    1757 (
    1758  uint8_t** bufferPtr,
    1759  uint8_t* valuePtr,
    1760  le_pack_SemanticTag_t tagId
    1761 )
    1762 {
    1763 #ifdef LE_CONFIG_RPC
    1764  if (!le_pack_CheckSemanticTag(bufferPtr, tagId))
    1765  {
    1766  return false;
    1767  }
    1768 
    1769  return le_pack_UnpackUint8_rpc(bufferPtr, valuePtr);
    1770 #else
    1771  LE_UNUSED(bufferPtr);
    1772  LE_UNUSED(tagId);
    1773  LE_PACK_UNPACK_SIMPLE_VALUE(valuePtr);
    1774  return true;
    1775 #endif
    1776 }
    1777 
    1778 //--------------------------------------------------------------------------------------------------
    1779 /**
    1780  * Unpack a uint16_t from a buffer, checking if the tag matches the expected semantic tag
    1781  * and incrementing the buffer pointer as appropriate.
    1782  */
    1783 //--------------------------------------------------------------------------------------------------
    1784 LE_DECLARE_INLINE bool le_pack_UnpackTaggedUint16
    1785 (
    1786  uint8_t** bufferPtr,
    1787  uint16_t* valuePtr,
    1788  le_pack_SemanticTag_t tagId
    1789 )
    1790 {
    1791 #ifdef LE_CONFIG_RPC
    1792  if (!le_pack_CheckSemanticTag(bufferPtr, tagId))
    1793  {
    1794  return false;
    1795  }
    1796 
    1797  return le_pack_UnpackUint16_rpc(bufferPtr, valuePtr);
    1798 #else
    1799  LE_UNUSED(bufferPtr);
    1800  LE_UNUSED(tagId);
    1801  LE_PACK_UNPACK_SIMPLE_VALUE(valuePtr);
    1802  return true;
    1803 #endif
    1804 }
    1805 
    1806 //--------------------------------------------------------------------------------------------------
    1807 /**
    1808  * Unpack a uint32_t from a buffer, checking if the tag matches the expected semantic tag
    1809  * and incrementing the buffer pointer as appropriate.
    1810  */
    1811 //--------------------------------------------------------------------------------------------------
    1812 LE_DECLARE_INLINE bool le_pack_UnpackTaggedUint32
    1813 (
    1814  uint8_t** bufferPtr,
    1815  uint32_t* valuePtr,
    1816  le_pack_SemanticTag_t tagId
    1817 )
    1818 {
    1819 #ifdef LE_CONFIG_RPC
    1820  if (!le_pack_CheckSemanticTag(bufferPtr, tagId))
    1821  {
    1822  return false;
    1823  }
    1824 
    1825  return le_pack_UnpackUint32_rpc(bufferPtr, valuePtr);
    1826 #else
    1827  LE_UNUSED(bufferPtr);
    1828  LE_UNUSED(tagId);
    1829  LE_PACK_UNPACK_SIMPLE_VALUE(valuePtr);
    1830  return true;
    1831 #endif
    1832 }
    1833 
    1834 //--------------------------------------------------------------------------------------------------
    1835 /**
    1836  * Unpack a uint64_t from a buffer, checking if the tag matches the expected semantic tag
    1837  * and incrementing the buffer pointer as appropriate.
    1838  */
    1839 //--------------------------------------------------------------------------------------------------
    1840 LE_DECLARE_INLINE bool le_pack_UnpackTaggedUint64
    1841 (
    1842  uint8_t** bufferPtr,
    1843  uint64_t* valuePtr,
    1844  le_pack_SemanticTag_t tagId
    1845 )
    1846 {
    1847 #ifdef LE_CONFIG_RPC
    1848  if (!le_pack_CheckSemanticTag(bufferPtr, tagId))
    1849  {
    1850  return false;
    1851  }
    1852 
    1853  return le_pack_UnpackUint64_rpc(bufferPtr, valuePtr);
    1854 #else
    1855  LE_UNUSED(bufferPtr);
    1856  LE_UNUSED(tagId);
    1857  LE_PACK_UNPACK_SIMPLE_VALUE(valuePtr);
    1858  return true;
    1859 #endif
    1860 }
    1861 
    1862 //--------------------------------------------------------------------------------------------------
    1863 /**
    1864  * Unpack a int8_t from a buffer, checking if the tag matches the expected semantic tag and
    1865  * incrementing the buffer pointer as appropriate.
    1866  */
    1867 //--------------------------------------------------------------------------------------------------
    1868 LE_DECLARE_INLINE bool le_pack_UnpackTaggedInt8
    1869 (
    1870  uint8_t** bufferPtr,
    1871  int8_t* valuePtr,
    1872  le_pack_SemanticTag_t tagId
    1873 )
    1874 {
    1875 #ifdef LE_CONFIG_RPC
    1876  if (!le_pack_CheckSemanticTag(bufferPtr, tagId))
    1877  {
    1878  return false;
    1879  }
    1880 
    1881  return le_pack_UnpackInt8_rpc(bufferPtr, valuePtr);
    1882 #else
    1883  LE_UNUSED(bufferPtr);
    1884  LE_UNUSED(tagId);
    1885  LE_PACK_UNPACK_SIMPLE_VALUE(valuePtr);
    1886  return true;
    1887 #endif
    1888 }
    1889 
    1890 //--------------------------------------------------------------------------------------------------
    1891 /**
    1892  * Unpack a int16_t from a buffer, checking if the tag matches the expected semantic tag
    1893  * and incrementing the buffer pointer as appropriate.
    1894  */
    1895 //--------------------------------------------------------------------------------------------------
    1896 LE_DECLARE_INLINE bool le_pack_UnpackTaggedInt16
    1897 (
    1898  uint8_t** bufferPtr,
    1899  int16_t* valuePtr,
    1900  le_pack_SemanticTag_t tagId
    1901 )
    1902 {
    1903 #ifdef LE_CONFIG_RPC
    1904  if (!le_pack_CheckSemanticTag(bufferPtr, tagId))
    1905  {
    1906  return false;
    1907  }
    1908 
    1909  return le_pack_UnpackInt16_rpc(bufferPtr, valuePtr);
    1910 #else
    1911  LE_UNUSED(bufferPtr);
    1912  LE_UNUSED(tagId);
    1913  LE_PACK_UNPACK_SIMPLE_VALUE(valuePtr);
    1914  return true;
    1915 #endif
    1916 }
    1917 
    1918 //--------------------------------------------------------------------------------------------------
    1919 /**
    1920  * Unpack a int32_t from a buffer, checking if the tag matches the expected semantic tag
    1921  * and incrementing the buffer pointer as appropriate.
    1922  */
    1923 //--------------------------------------------------------------------------------------------------
    1924 LE_DECLARE_INLINE bool le_pack_UnpackTaggedInt32
    1925 (
    1926  uint8_t** bufferPtr,
    1927  int32_t* valuePtr,
    1928  le_pack_SemanticTag_t tagId
    1929 )
    1930 {
    1931 #ifdef LE_CONFIG_RPC
    1932  if (!le_pack_CheckSemanticTag(bufferPtr, tagId))
    1933  {
    1934  return false;
    1935  }
    1936 
    1937  return le_pack_UnpackInt32_rpc(bufferPtr, valuePtr);
    1938 #else
    1939  LE_UNUSED(bufferPtr);
    1940  LE_UNUSED(tagId);
    1941  LE_PACK_UNPACK_SIMPLE_VALUE(valuePtr);
    1942  return true;
    1943 #endif
    1944 }
    1945 
    1946 //--------------------------------------------------------------------------------------------------
    1947 /**
    1948  * Unpack a int64_t from a buffer, checking if the tag matches the expected semantic tag
    1949  * and incrementing the buffer pointer as appropriate.
    1950  */
    1951 //--------------------------------------------------------------------------------------------------
    1952 LE_DECLARE_INLINE bool le_pack_UnpackTaggedInt64
    1953 (
    1954  uint8_t** bufferPtr,
    1955  int64_t* valuePtr,
    1956  le_pack_SemanticTag_t tagId
    1957 )
    1958 {
    1959 #ifdef LE_CONFIG_RPC
    1960  if (!le_pack_CheckSemanticTag(bufferPtr, tagId))
    1961  {
    1962  return false;
    1963  }
    1964 
    1965  return le_pack_UnpackInt64_rpc(bufferPtr, valuePtr);
    1966 #else
    1967  LE_UNUSED(bufferPtr);
    1968  LE_UNUSED(tagId);
    1969  LE_PACK_UNPACK_SIMPLE_VALUE(valuePtr);
    1970  return true;
    1971 #endif
    1972 }
    1973 
    1974 
    1975 //--------------------------------------------------------------------------------------------------
    1976 /**
    1977  * Pack a size_t into a buffer, checking if the tag matches the expected semantic tag
    1978  * and incrementing the buffer pointer as appropriate.
    1979  *
    1980  * @note Packed sizes are limited to 2^32-1, regardless of platform
    1981  */
    1982 //--------------------------------------------------------------------------------------------------
    1983 LE_DECLARE_INLINE bool le_pack_UnpackTaggedSize
    1984 (
    1985  uint8_t **bufferPtr,
    1986  size_t *valuePtr,
    1987  le_pack_SemanticTag_t tagId
    1988 )
    1989 {
    1990  uint32_t rawValue;
    1991 
    1992  if (!le_pack_CheckSemanticTag(bufferPtr, tagId))
    1993  {
    1994  return false;
    1995  }
    1996 
    1997  if (!le_pack_UnpackUint32(bufferPtr, &rawValue))
    1998  {
    1999  return false;
    2000  }
    2001 
    2002  *valuePtr = rawValue;
    2003 
    2004  return true;
    2005 }
    2006 
    2007 //--------------------------------------------------------------------------------------------------
    2008 /**
    2009  * Unpack a size_t and 32-bit integer tuple from the buffer,
    2010  * incrementing the buffer pointer as appropriate.
    2011  */
    2012 //--------------------------------------------------------------------------------------------------
    2013 LE_DECLARE_INLINE bool le_pack_UnpackSizeUint32Tuple
    2014 (
    2015  uint8_t** bufferPtr,
    2016  size_t* sizePtr,
    2017  uint32_t* valuePtr,
    2018  le_pack_SemanticTag_t* semanticTagPtr
    2019 )
    2020 {
    2021 #ifdef LE_CONFIG_RPC
    2022  return le_pack_UnpackSizeUint32Tuple_rpc(bufferPtr, sizePtr, valuePtr, semanticTagPtr);
    2023 #else
    2024  LE_UNUSED(semanticTagPtr);
    2025  bool result;
    2026  result = le_pack_UnpackSize(bufferPtr, sizePtr);
    2027  if (result)
    2028  {
    2029  result = le_pack_UnpackUint32(bufferPtr, valuePtr);
    2030  }
    2031  return result;
    2032 #endif
    2033 }
    2034 
    2035 
    2036 //--------------------------------------------------------------------------------------------------
    2037 /**
    2038  * Unpack a size_t and 64-bit integer tuple from the buffer,
    2039  * incrementing the buffer pointer as appropriate.
    2040  */
    2041 //--------------------------------------------------------------------------------------------------
    2042 LE_DECLARE_INLINE bool le_pack_UnpackSizeUint64Tuple
    2043 (
    2044  uint8_t** bufferPtr,
    2045  size_t* sizePtr,
    2046  uint64_t* valuePtr,
    2047  le_pack_SemanticTag_t* semanticTagPtr
    2048 )
    2049 {
    2050 #ifdef LE_CONFIG_RPC
    2051  return le_pack_UnpackSizeUint64Tuple_rpc(bufferPtr, sizePtr, valuePtr, semanticTagPtr);
    2052 #else
    2053  LE_UNUSED(semanticTagPtr);
    2054  bool result;
    2055  result = le_pack_UnpackSize(bufferPtr, sizePtr);
    2056  if (result)
    2057  {
    2058  result = le_pack_UnpackUint64(bufferPtr, valuePtr);
    2059  }
    2060  return result;
    2061 #endif
    2062 }
    2063 
    2064 //--------------------------------------------------------------------------------------------------
    2065 /**
    2066  * Unpack a size and pointer tuple from the buffer.
    2067  */
    2068 //--------------------------------------------------------------------------------------------------
    2069 LE_DECLARE_INLINE bool le_pack_UnpackSizePointerTuple
    2070 (
    2071  uint8_t** bufferPtr,
    2072  size_t* sizePtr,
    2073  void** valuePtr,
    2074  le_pack_SemanticTag_t* semanticTagPtr
    2075 )
    2076 {
    2077 #if IFGEN_PTR32
    2078  uint32_t* rawValuePtr = (uint32_t*)valuePtr;
    2079  return le_pack_UnpackSizeUint32Tuple(bufferPtr, sizePtr, rawValuePtr, semanticTagPtr);
    2080 #elif IFGEN_PTR64
    2081  uint64_t* rawValuePtr = (uint64_t*)valuePtr;
    2082  return le_pack_UnpackSizeUint64Tuple(bufferPtr, sizePtr, rawValuePtr, semanticTagPtr);
    2083 #else
    2084 # error "Unsupported pointer size -- only 32- and 64-bit are supported for local services."
    2085 #endif
    2086 }
    2087 
    2088 
    2089 
    2090 
    2091 //--------------------------------------------------------------------------------------------------
    2092 /**
    2093  * Unpack a bool from a buffer, incrementing the buffer pointer as appropriate.
    2094  */
    2095 //--------------------------------------------------------------------------------------------------
    2096 LE_DECLARE_INLINE bool le_pack_UnpackBool
    2097 (
    2098  uint8_t** bufferPtr,
    2099  bool* valuePtr
    2100 )
    2101 {
    2102 
    2103 #ifdef LE_CONFIG_RPC
    2104  return le_pack_UnpackBool_rpc(bufferPtr, valuePtr);
    2105 #else
    2106  // Treat boolean as uint8_t for packing, regardless of underlying OS type.
    2107  // Underlying type has been int on some platforms in the past.
    2108  uint8_t simpleValue;
    2109 
    2110  memcpy(&simpleValue, *bufferPtr, sizeof(simpleValue));
    2111 
    2112  *bufferPtr = ((uint8_t* )*bufferPtr) + sizeof(simpleValue);
    2113 
    2114  // force to true or false
    2115  *valuePtr = !!simpleValue;
    2116  return true;
    2117 #endif
    2118 }
    2119 
    2120 //--------------------------------------------------------------------------------------------------
    2121 /**
    2122  * Unpack a char from a buffer, incrementing the buffer pointer as appropriate.
    2123  */
    2124 //--------------------------------------------------------------------------------------------------
    2125 LE_DECLARE_INLINE bool le_pack_UnpackChar
    2126 (
    2127  uint8_t** bufferPtr,
    2128  char* valuePtr
    2129 )
    2130 {
    2131 #ifdef LE_CONFIG_RPC
    2132  return le_pack_UnpackChar_rpc(bufferPtr, valuePtr);
    2133 #else
    2134  LE_PACK_UNPACK_SIMPLE_VALUE(valuePtr);
    2135  return true;
    2136 #endif
    2137 }
    2138 
    2139 //--------------------------------------------------------------------------------------------------
    2140 /**
    2141  * Unpack a double from a buffer, incrementing the buffer pointer as appropriate.
    2142  */
    2143 //--------------------------------------------------------------------------------------------------
    2144 LE_DECLARE_INLINE bool le_pack_UnpackDouble
    2145 (
    2146  uint8_t** bufferPtr,
    2147  double* valuePtr
    2148 )
    2149 {
    2150 #ifdef LE_CONFIG_RPC
    2151  return le_pack_UnpackDouble_rpc(bufferPtr, valuePtr);
    2152 #else
    2153  LE_PACK_UNPACK_SIMPLE_VALUE(valuePtr);
    2154  return true;
    2155 #endif
    2156 }
    2157 
    2158 //--------------------------------------------------------------------------------------------------
    2159 /**
    2160  * Unpack a le_result_t from a buffer, incrementing the buffer pointer as appropriate.
    2161  */
    2162 //--------------------------------------------------------------------------------------------------
    2163 LE_DECLARE_INLINE bool le_pack_UnpackResult
    2164 (
    2165  uint8_t** bufferPtr,
    2166  le_result_t* valuePtr
    2167 )
    2168 {
    2169 #ifdef LE_CONFIG_RPC
    2170  return le_pack_UnpackResult_rpc(bufferPtr, valuePtr);
    2171 #else
    2172  LE_PACK_UNPACK_SIMPLE_VALUE(valuePtr);
    2173  return true;
    2174 #endif
    2175 }
    2176 
    2177 //--------------------------------------------------------------------------------------------------
    2178 /**
    2179  * Pack le_onoff_t into a buffer, incrementing the buffer pointer as appropriate.
    2180  */
    2181 //--------------------------------------------------------------------------------------------------
    2182 LE_DECLARE_INLINE bool le_pack_UnpackOnOff
    2183 (
    2184  uint8_t** bufferPtr,
    2185  le_onoff_t* valuePtr
    2186 )
    2187 {
    2188 #ifdef LE_CONFIG_RPC
    2189  return le_pack_UnpackOnOff_rpc(bufferPtr, valuePtr);
    2190 #else
    2191  LE_PACK_UNPACK_SIMPLE_VALUE(valuePtr);
    2192  return true;
    2193 #endif
    2194 }
    2195 
    2196 #undef LE_PACK_UNPACK_SIMPLE_VALUE
    2197 
    2198 //--------------------------------------------------------------------------------------------------
    2199 /**
    2200  * Unpack a reference from a buffer, incrementing the buffer pointer.
    2201  */
    2202 //--------------------------------------------------------------------------------------------------
    2203 LE_DECLARE_INLINE bool le_pack_UnpackReference
    2204 (
    2205  uint8_t** bufferPtr, ///< Pointer to the reference. Declared as void * to allow implicit
    2206  void* refPtr, ///< conversion from pointer to reference types.
    2207  le_pack_SemanticTag_t* semanticTagPtr ///< [out] semantic tag found before reference.
    2208 )
    2209 {
    2210 #ifdef LE_CONFIG_RPC
    2211  return le_pack_UnpackReference_rpc(bufferPtr, refPtr, semanticTagPtr);
    2212 #else
    2213  LE_UNUSED(semanticTagPtr);
    2214  uint32_t refAsInt;
    2215  if (!le_pack_UnpackUint32(bufferPtr, &refAsInt))
    2216  {
    2217  return false;
    2218  }
    2219 
    2220  // All references passed through an API must be safe references, so
    2221  // 0-bit will be set. Check that here to be safe.
    2222  if ((refAsInt & 0x01) ||
    2223  (!refAsInt))
    2224  {
    2225  // Double cast to avoid warnings.
    2226  *(void **)refPtr = (void *)(size_t)refAsInt;
    2227  return true;
    2228  }
    2229  else
    2230  {
    2231  return false;
    2232  }
    2233 #endif
    2234 }
    2235 
    2236 //--------------------------------------------------------------------------------------------------
    2237 /**
    2238  * Unpack a string header
    2239  */
    2240 //--------------------------------------------------------------------------------------------------
    2241 LE_DECLARE_INLINE bool le_pack_UnpackStringHeader
    2242 (
    2243  uint8_t** bufferPtr,
    2244  size_t* stringSizePtr
    2245 )
    2246 {
    2247 #ifdef LE_CONFIG_RPC
    2248  return le_pack_UnpackStringHeader_rpc(bufferPtr, stringSizePtr);
    2249 #else
    2250  if (!le_pack_UnpackSize(bufferPtr, stringSizePtr))
    2251  {
    2252  return false;
    2253  }
    2254  return true;
    2255 #endif
    2256 }
    2257 
    2258 //--------------------------------------------------------------------------------------------------
    2259 /**
    2260  * Unpack a string from a buffer, incrementing the buffer pointer.
    2261  */
    2262 //--------------------------------------------------------------------------------------------------
    2263 LE_DECLARE_INLINE bool le_pack_UnpackString
    2264 (
    2265  uint8_t** bufferPtr,
    2266  char *stringPtr,
    2267  uint32_t bufferSize,
    2268  uint32_t maxStringCount
    2269 )
    2270 {
    2271 #ifdef LE_CONFIG_RPC
    2272  return le_pack_UnpackString_rpc(bufferPtr, stringPtr, bufferSize, maxStringCount);
    2273 #else
    2274  // First get string size
    2275  uint32_t stringSize;
    2276  if (!le_pack_UnpackUint32(bufferPtr, &stringSize))
    2277  {
    2278  return false;
    2279  }
    2280  if ((stringSize > maxStringCount) ||
    2281  (stringSize > bufferSize))
    2282  {
    2283  return false;
    2284  }
    2285 
    2286  if (!stringPtr)
    2287  {
    2288  // Only allow unpacking into no output buffer if the string is zero sized.
    2289  // Otherwise an output buffer is required.
    2290  if (stringSize)
    2291  {
    2292  return false;
    2293  }
    2294  else
    2295  {
    2296  return true;
    2297  }
    2298  }
    2299 
    2300  memcpy(stringPtr, *bufferPtr, stringSize);
    2301  stringPtr[stringSize] = '\0';
    2302 
    2303  *bufferPtr = *bufferPtr + stringSize;
    2304 
    2305  return true;
    2306 #endif
    2307 }
    2308 
    2309 //--------------------------------------------------------------------------------------------------
    2310 /**
    2311  * Pack the size information for an array into a buffer, incrementing the buffer pointer.
    2312  *
    2313  * @note Users of this API should generally use LE_PACK_PACKARRAY macro instead which also
    2314  * packs the array data.
    2315  */
    2316 //--------------------------------------------------------------------------------------------------
    2317 LE_DECLARE_INLINE bool le_pack_UnpackArrayHeader
    2318 (
    2319  uint8_t **bufferPtr,
    2320  const void *arrayPtr,
    2321  size_t elementSize,
    2322  size_t *arrayCountPtr,
    2323  size_t arrayMaxCount
    2324 )
    2325 {
    2326 #ifdef LE_CONFIG_RPC
    2327  return le_pack_UnpackArrayHeader_rpc(bufferPtr, arrayPtr, elementSize, arrayCountPtr,
    2328  arrayMaxCount);
    2329 #else
    2330  LE_UNUSED(elementSize);
    2331  LE_ASSERT(le_pack_UnpackSize(bufferPtr, arrayCountPtr));
    2332  if (*arrayCountPtr > arrayMaxCount)
    2333  {
    2334  return false;
    2335  }
    2336  else if (!arrayPtr)
    2337  {
    2338  // Missing array pointer must match zero sized array.
    2339  return (*arrayCountPtr == 0);
    2340  }
    2341 
    2342  return true;
    2343 #endif
    2344 }
    2345 
    2346 //--------------------------------------------------------------------------------------------------
    2347 /**
    2348  * unpack infinite array header
    2349  */
    2350 //--------------------------------------------------------------------------------------------------
    2351 LE_DECLARE_INLINE bool le_pack_UnpackIndefArrayHeader
    2352 (
    2353  uint8_t** bufferPtr
    2354 )
    2355 {
    2356 #ifdef LE_CONFIG_RPC
    2357  return le_pack_UnpackIndefArrayHeader_rpc(bufferPtr);
    2358 #else
    2359  LE_UNUSED(bufferPtr);
    2360  return true;
    2361 #endif
    2362 }
    2363 
    2364 //--------------------------------------------------------------------------------------------------
    2365 /**
    2366  * unpack break
    2367  */
    2368 //--------------------------------------------------------------------------------------------------
    2369 LE_DECLARE_INLINE bool le_pack_UnpackEndOfIndefArray
    2370 (
    2371  uint8_t** bufferPtr
    2372 )
    2373 {
    2374 #ifdef LE_CONFIG_RPC
    2375  return le_pack_UnpackEndOfIndefArray_rpc(bufferPtr);
    2376 #else
    2377  LE_UNUSED(bufferPtr);
    2378  return true;
    2379 #endif
    2380 }
    2381 
    2382 //--------------------------------------------------------------------------------------------------
    2383 /**
    2384  * Unpack a string header
    2385  */
    2386 //--------------------------------------------------------------------------------------------------
    2387 LE_DECLARE_INLINE bool le_pack_UnpackByteStringHeader
    2388 (
    2389  uint8_t** bufferPtr,
    2390  size_t* lengthPtr
    2391 )
    2392 {
    2393 #ifdef LE_CONFIG_RPC
    2394  return le_pack_UnpackByteStringHeader_rpc(bufferPtr, lengthPtr);
    2395 #else
    2396  if (!le_pack_UnpackSize(bufferPtr, lengthPtr))
    2397  {
    2398  return false;
    2399  }
    2400  return true;
    2401 #endif
    2402 }
    2403 
    2404 //--------------------------------------------------------------------------------------------------
    2405 /**
    2406  * unpack a byte string (Array of uint8, int8, char)
    2407  */
    2408 //--------------------------------------------------------------------------------------------------
    2409 LE_DECLARE_INLINE bool le_pack_UnpackByteString
    2410 (
    2411  uint8_t** bufferPtr,
    2412  void *arrayPtr,
    2413  size_t *arrayCountPtr,
    2414  size_t arrayMaxCount
    2415 )
    2416 {
    2417 #ifdef LE_CONFIG_RPC
    2418  return le_pack_UnpackByteString_rpc(bufferPtr, arrayPtr, arrayCountPtr, arrayMaxCount);
    2419 #else
    2420  le_pack_UnpackSize(bufferPtr, arrayCountPtr);
    2421  if (*arrayCountPtr > arrayMaxCount)
    2422  {
    2423  return false;
    2424  }
    2425  else if (!arrayPtr)
    2426  {
    2427  // Missing array pointer must match zero sized array.
    2428  return (*arrayCountPtr == 0);
    2429  }
    2430  else
    2431  {
    2432  LE_PACK_UNPACK_SIMPLE_BUFFER(arrayPtr, *arrayCountPtr);
    2433  return true;
    2434  }
    2435 #endif
    2436 }
    2437 
    2438 //--------------------------------------------------------------------------------------------------
    2439 /**
    2440  * Unpack an array into from buffer, incrementing the buffer pointer and decrementing the available
    2441  * size.
    2442  *
    2443  * @note Always decrements available size according to the max possible size used, not actual size
    2444  * used. Will assert if the resulted array exceeds the maximum size allowed.
    2445  */
    2446 //--------------------------------------------------------------------------------------------------
    2447 #define LE_PACK_UNPACKARRAY(bufferPtr, \
    2448  arrayPtr, \
    2449  arrayCountPtr, \
    2450  arrayMaxCount, \
    2451  unpackFunc, \
    2452  resultPtr) \
    2453  do { \
    2454  if (!le_pack_UnpackArrayHeader((bufferPtr), \
    2455  (arrayPtr), sizeof((arrayPtr)[0]), \
    2456  (arrayCountPtr), (arrayMaxCount))) \
    2457  { \
    2458  *(resultPtr) = false; \
    2459  } \
    2460  else \
    2461  { \
    2462  uint32_t i; \
    2463  for (i = 0; i < *(arrayCountPtr); ++i) \
    2464  { \
    2465  LE_ASSERT(unpackFunc((bufferPtr), &(arrayPtr)[i])); \
    2466  } \
    2467  *(resultPtr) = true; \
    2468  } \
    2469  } while (0)
    2470 
    2471 
    2472 //--------------------------------------------------------------------------------------------------
    2473 /**
    2474  * Unpack an array of tagged items from buffer, incrementing the buffer pointer and decrementing the
    2475  * available size.
    2476  *
    2477  * @note Always decrements available size according to the max possible size used, not actual size
    2478  * used. Will assert if the resulted array exceeds the maximum size allowed.
    2479  */
    2480 //--------------------------------------------------------------------------------------------------
    2481 #define LE_PACK_UNPACKTAGGEDARRAY(bufferPtr, \
    2482  arrayPtr, \
    2483  arrayCountPtr, \
    2484  arrayMaxCount, \
    2485  unpackFunc, \
    2486  resultPtr) \
    2487  do { \
    2488  if (!le_pack_UnpackArrayHeader((bufferPtr), \
    2489  (arrayPtr), sizeof((arrayPtr)[0]), \
    2490  (arrayCountPtr), (arrayMaxCount))) \
    2491  { \
    2492  *(resultPtr) = false; \
    2493  } \
    2494  else \
    2495  { \
    2496  uint32_t i; \
    2497  for (i = 0; i < *(arrayCountPtr); ++i) \
    2498  { \
    2499  LE_ASSERT(unpackFunc((bufferPtr), &(arrayPtr)[i]), NULL); \
    2500  } \
    2501  *(resultPtr) = true; \
    2502  } \
    2503  } while (0)
    2504 
    2505 
    2506 //--------------------------------------------------------------------------------------------------
    2507 /**
    2508  * Unpack an array of struct from buffer. Since its logic is the same as that for unpacking an
    2509  * array, here it calls LE_PACK_UNPACKSTRUCTARRAY() to do the work.
    2510  */
    2511 //--------------------------------------------------------------------------------------------------
    2512 #define LE_PACK_UNPACKSTRUCTARRAY(bufferPtr, \
    2513  arrayPtr, \
    2514  arrayCountPtr, \
    2515  arrayMaxCount, \
    2516  unpackFunc, \
    2517  resultPtr) \
    2518  LE_PACK_UNPACKARRAY((bufferPtr), (arrayPtr), (arrayCountPtr), \
    2519  (arrayMaxCount), (unpackFunc), (resultPtr))
    2520 
    2521 #endif /* LE_PACK_H_INCLUDE_GUARD */
    le_result_t
    Definition: le_basics.h:46
    #define LE_UNUSED(v)
    Definition: le_basics.h:369
    #define LE_ASSERT(condition)
    Definition: le_log.h:991
    #define LE_DECLARE_INLINE
    Definition: le_basics.h:320
    le_onoff_t
    Definition: le_basics.h:85