pb_util.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /* Copyright (C) 2018 RDA Technologies Limited and/or its affiliates("RDA").
  2. * All rights reserved.
  3. *
  4. * This software is supplied "AS IS" without any warranties.
  5. * RDA assumes no responsibility or liability for the use of the software,
  6. * conveys no license or title under any patent, copyright, or mask work
  7. * right to the product. RDA reserves the right to make changes in the
  8. * software without notification. RDA also make no representation or
  9. * warranty that such application will be suitable for the specified use
  10. * without further testing or modification.
  11. */
  12. #ifndef _PB_UTIL_H_
  13. #define _PB_UTIL_H_
  14. #include <pb.h>
  15. #include "pb_decode.h"
  16. #include "pb_encode.h"
  17. #ifdef __cplusplus
  18. extern "C" {
  19. #endif
  20. /**
  21. * The pointer variable name of PB struct
  22. */
  23. #ifndef PB_VAR_NAME
  24. #define PB_VAR_NAME pbs
  25. #endif
  26. /**
  27. * For plain and necessary variables
  28. */
  29. #define PB_DEC_ASSIGN(var, field) \
  30. var = PB_VAR_NAME->field;
  31. #define PB_ENC_ASSIGN(var, field) \
  32. PB_VAR_NAME->field = var;
  33. /**
  34. * For plain and optional variables
  35. */
  36. #define PB_OPT_DEC_ASSIGN(var, field) \
  37. if (PB_VAR_NAME->has_##field) \
  38. var = PB_VAR_NAME->field;
  39. #define PB_OPT_ENC_ASSIGN(var, field) \
  40. PB_VAR_NAME->has_##field = true; \
  41. PB_VAR_NAME->field = var;
  42. /**
  43. * For decode/encode with provided callback, usually for sub-message.
  44. */
  45. #define PB_DEC_CB(field, cb, param) \
  46. PB_VAR_NAME->field.funcs.decode = cb; \
  47. PB_VAR_NAME->field.arg = param;
  48. #define PB_ENC_CB(field, cb, param) \
  49. PB_VAR_NAME->field.funcs.encode = cb; \
  50. PB_VAR_NAME->field.arg = param;
  51. /**
  52. * For decode/encode string, with provided size.
  53. */
  54. #define PB_DEC_VARSTRING(var, field, size) \
  55. pbStringDecodeParam_t field##__LINE__ = {.data = var, .cnt = size}; \
  56. PB_VAR_NAME->field.funcs.decode = pbDecStringCallback; \
  57. PB_VAR_NAME->field.arg = &field##__LINE__;
  58. #define PB_ENC_VARSTRING(var, field, size) \
  59. pbStringEncodeParam_t field = {.data = var, .cnt = size}; \
  60. PB_VAR_NAME->field.funcs.encode = pbEncStringCallback; \
  61. PB_VAR_NAME->field.arg = &field;
  62. /**
  63. * For decode/encode string, size if from sizeof(var).
  64. */
  65. #define PB_DEC_STRING(var, field) \
  66. pbStringDecodeParam_t field##__LINE__ = {var, sizeof(var)}; \
  67. PB_VAR_NAME->field.funcs.decode = pbDecStringCallback; \
  68. PB_VAR_NAME->field.arg = &field##__LINE__;
  69. #define PB_ENC_STRING(var, field) \
  70. pbStringEncodeParam_t field##__LINE__ = {var, sizeof(var)}; \
  71. PB_VAR_NAME->field.funcs.encode = pbEncStringCallback; \
  72. PB_VAR_NAME->field.arg = &field##__LINE__;
  73. /**
  74. * For decode/encode array.
  75. */
  76. #define PB_DEC_ARRAY(var, field, fdec) \
  77. pbArrayDecodeParam_t field##__LINE__ = { \
  78. .data = var, \
  79. .cnt = sizeof(var) / sizeof(var[0]), \
  80. .idx = 0, \
  81. .decode = fdec}; \
  82. PB_VAR_NAME->field.funcs.decode = pbDecArrayCallback; \
  83. PB_VAR_NAME->field.arg = &field##__LINE__;
  84. #define PB_ENC_ARRAY(var, field, fenc) \
  85. pbArrayEncodeParam_t field##__LINE__ = { \
  86. .data = var, \
  87. .cnt = sizeof(var) / sizeof(var[0]), \
  88. .encode = fenc}; \
  89. PB_VAR_NAME->field.funcs.encode = pbEncArrayCallback; \
  90. PB_VAR_NAME->field.arg = &field##__LINE__;
  91. /**
  92. * For decode/encode 2-D array.
  93. */
  94. #define PB_DEC_ARRAY2D(var, field, fdec) \
  95. pbArrayDecodeParam_t field##__LINE__ = { \
  96. .data = var, \
  97. .cnt = sizeof(var) / sizeof(var[0][0]), \
  98. .idx = 0, \
  99. .decode = fdec}; \
  100. PB_VAR_NAME->field.funcs.decode = pbDecArrayCallback; \
  101. PB_VAR_NAME->field.arg = &field##__LINE__;
  102. #define PB_ENC_ARRAY2D(var, field, fenc) \
  103. pbArrayEncodeParam_t field##__LINE__ = { \
  104. .data = var, \
  105. .cnt = sizeof(var) / sizeof(var[0][0]), \
  106. .encode = fenc}; \
  107. PB_VAR_NAME->field.funcs.encode = pbEncArrayCallback; \
  108. PB_VAR_NAME->field.arg = &field##__LINE__;
  109. typedef struct pbArrayDecodeParam
  110. {
  111. void *data; // pointer to the address of first submsg
  112. unsigned cnt; // max submsg count, for check
  113. unsigned idx; // currrent submsg index
  114. bool (*decode)(pb_istream_t *stream, struct pbArrayDecodeParam *param);
  115. } pbArrayDecodeParam_t;
  116. typedef struct pbArrayEncodeParam
  117. {
  118. const void *data; // pointer to the address of first submsg
  119. unsigned cnt; // max submsg count, for loop
  120. bool (*encode)(pb_ostream_t *stream, const struct pbArrayEncodeParam *param, unsigned idx);
  121. } pbArrayEncodeParam_t;
  122. bool pbDecArrayCallback(pb_istream_t *stream, const pb_field_t *field, void **arg);
  123. bool pbEncArrayCallback(pb_ostream_t *stream, const pb_field_t *field, void *const *arg);
  124. typedef struct
  125. {
  126. void *data;
  127. unsigned cnt;
  128. } pbStringDecodeParam_t;
  129. typedef struct
  130. {
  131. const void *data;
  132. unsigned cnt;
  133. } pbStringEncodeParam_t;
  134. bool pbDecStringCallback(pb_istream_t *stream, const pb_field_t *field, void **arg);
  135. bool pbEncStringCallback(pb_ostream_t *stream, const pb_field_t *field, void *const *arg);
  136. /**
  137. * \brief encode PB fields to stream buffer
  138. *
  139. * When \p buf is NULL, this can be used to get the encoded stream size.
  140. *
  141. * \param fields PB fields
  142. * \param pbs PB struct
  143. * \param buf buffer to be encoded to
  144. * \param size buffer size
  145. * \return
  146. * - encoded stream size
  147. * - -1 on error
  148. * - encode error
  149. * - \size is smaller than needed and \p buf is not NULL
  150. */
  151. int pbEncodeToMem(const pb_field_t *fields, void *pbs, void *buf, size_t size);
  152. #ifdef __cplusplus
  153. }
  154. #endif
  155. #endif