pb_common.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /* pb_common.c: Common support functions for pb_encode.c and pb_decode.c.
  2. *
  3. * 2014 Petteri Aimonen <jpa@kapsi.fi>
  4. */
  5. #include "pb_common.h"
  6. static bool load_descriptor_values(pb_field_iter_t *iter)
  7. {
  8. uint32_t word0;
  9. uint32_t data_offset;
  10. uint8_t format;
  11. int8_t size_offset;
  12. if (iter->index >= iter->descriptor->field_count)
  13. return false;
  14. word0 = iter->descriptor->field_info[iter->field_info_index];
  15. format = word0 & 3;
  16. iter->tag = (pb_size_t)((word0 >> 2) & 0x3F);
  17. iter->type = (pb_type_t)((word0 >> 8) & 0xFF);
  18. if (format == 0)
  19. {
  20. /* 1-word format */
  21. iter->array_size = 1;
  22. size_offset = (int8_t)((word0 >> 24) & 0x0F);
  23. data_offset = (word0 >> 16) & 0xFF;
  24. iter->data_size = (pb_size_t)((word0 >> 28) & 0x0F);
  25. }
  26. else if (format == 1)
  27. {
  28. /* 2-word format */
  29. uint32_t word1 = iter->descriptor->field_info[iter->field_info_index + 1];
  30. iter->array_size = (pb_size_t)((word0 >> 16) & 0x0FFF);
  31. iter->tag = (pb_size_t)(iter->tag | ((word1 >> 28) << 6));
  32. size_offset = (int8_t)((word0 >> 28) & 0x0F);
  33. data_offset = word1 & 0xFFFF;
  34. iter->data_size = (pb_size_t)((word1 >> 16) & 0x0FFF);
  35. }
  36. else if (format == 2)
  37. {
  38. /* 4-word format */
  39. uint32_t word1 = iter->descriptor->field_info[iter->field_info_index + 1];
  40. uint32_t word2 = iter->descriptor->field_info[iter->field_info_index + 2];
  41. uint32_t word3 = iter->descriptor->field_info[iter->field_info_index + 3];
  42. iter->array_size = (pb_size_t)(word0 >> 16);
  43. iter->tag = (pb_size_t)(iter->tag | ((word1 >> 8) << 6));
  44. size_offset = (int8_t)(word1 & 0xFF);
  45. data_offset = word2;
  46. iter->data_size = (pb_size_t)word3;
  47. }
  48. else
  49. {
  50. /* 8-word format */
  51. uint32_t word1 = iter->descriptor->field_info[iter->field_info_index + 1];
  52. uint32_t word2 = iter->descriptor->field_info[iter->field_info_index + 2];
  53. uint32_t word3 = iter->descriptor->field_info[iter->field_info_index + 3];
  54. uint32_t word4 = iter->descriptor->field_info[iter->field_info_index + 4];
  55. iter->array_size = (pb_size_t)word4;
  56. iter->tag = (pb_size_t)(iter->tag | ((word1 >> 8) << 6));
  57. size_offset = (int8_t)(word1 & 0xFF);
  58. data_offset = word2;
  59. iter->data_size = (pb_size_t)word3;
  60. }
  61. iter->pField = (char*)iter->message + data_offset;
  62. if (size_offset)
  63. {
  64. iter->pSize = (char*)iter->pField - size_offset;
  65. }
  66. else if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED &&
  67. (PB_ATYPE(iter->type) == PB_ATYPE_STATIC ||
  68. PB_ATYPE(iter->type) == PB_ATYPE_POINTER))
  69. {
  70. /* Fixed count array */
  71. iter->pSize = &iter->array_size;
  72. }
  73. else
  74. {
  75. iter->pSize = NULL;
  76. }
  77. if (PB_ATYPE(iter->type) == PB_ATYPE_POINTER && iter->pField != NULL)
  78. {
  79. iter->pData = *(void**)iter->pField;
  80. }
  81. else
  82. {
  83. iter->pData = iter->pField;
  84. }
  85. if (PB_LTYPE(iter->type) == PB_LTYPE_SUBMESSAGE)
  86. {
  87. iter->submsg_desc = iter->descriptor->submsg_info[iter->submessage_index];
  88. }
  89. else
  90. {
  91. iter->submsg_desc = NULL;
  92. }
  93. return true;
  94. }
  95. static void advance_iterator(pb_field_iter_t *iter)
  96. {
  97. iter->index++;
  98. if (iter->index >= iter->descriptor->field_count)
  99. {
  100. /* Restart */
  101. iter->index = 0;
  102. iter->field_info_index = 0;
  103. iter->submessage_index = 0;
  104. iter->required_field_index = 0;
  105. }
  106. else
  107. {
  108. /* Increment indexes based on previous field type.
  109. * All field info formats have the following fields:
  110. * - lowest 2 bits tell the amount of words in the descriptor (2^n words)
  111. * - bits 2..7 give the lowest bits of tag number.
  112. * - bits 8..15 give the field type.
  113. */
  114. uint32_t prev_descriptor = iter->descriptor->field_info[iter->field_info_index];
  115. pb_type_t prev_type = (prev_descriptor >> 8) & 0xFF;
  116. pb_size_t descriptor_len = (pb_size_t)(1 << (prev_descriptor & 3));
  117. iter->field_info_index = (pb_size_t)(iter->field_info_index + descriptor_len);
  118. if (PB_HTYPE(prev_type) == PB_HTYPE_REQUIRED)
  119. {
  120. iter->required_field_index++;
  121. }
  122. if (PB_LTYPE(prev_type) == PB_LTYPE_SUBMESSAGE)
  123. {
  124. iter->submessage_index++;
  125. }
  126. }
  127. }
  128. bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_msgdesc_t *desc, void *message)
  129. {
  130. memset(iter, 0, sizeof(*iter));
  131. iter->descriptor = desc;
  132. iter->message = message;
  133. return load_descriptor_values(iter);
  134. }
  135. bool pb_field_iter_begin_extension(pb_field_iter_t *iter, pb_extension_t *extension)
  136. {
  137. const pb_msgdesc_t *msg = (const pb_msgdesc_t*)extension->type->arg;
  138. bool status;
  139. if (PB_ATYPE(msg->field_info[0] >> 8) == PB_ATYPE_POINTER)
  140. {
  141. /* For pointer extensions, the pointer is stored directly
  142. * in the extension structure. This avoids having an extra
  143. * indirection. */
  144. status = pb_field_iter_begin(iter, msg, &extension->dest);
  145. }
  146. else
  147. {
  148. status = pb_field_iter_begin(iter, msg, extension->dest);
  149. }
  150. iter->pSize = &extension->found;
  151. return status;
  152. }
  153. bool pb_field_iter_next(pb_field_iter_t *iter)
  154. {
  155. advance_iterator(iter);
  156. (void)load_descriptor_values(iter);
  157. return iter->index != 0;
  158. }
  159. bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag)
  160. {
  161. if (iter->tag == tag)
  162. {
  163. return true; /* Nothing to do, correct field already. */
  164. }
  165. else
  166. {
  167. pb_size_t start = iter->index;
  168. uint32_t fieldinfo;
  169. do
  170. {
  171. /* Advance iterator but don't load values yet */
  172. advance_iterator(iter);
  173. /* Do fast check for tag number match */
  174. fieldinfo = iter->descriptor->field_info[iter->field_info_index];
  175. if (((fieldinfo >> 2) & 0x3F) == (tag & 0x3F))
  176. {
  177. /* Good candidate, check further */
  178. (void)load_descriptor_values(iter);
  179. if (iter->tag == tag &&
  180. PB_LTYPE(iter->type) != PB_LTYPE_EXTENSION)
  181. {
  182. /* Found it */
  183. return true;
  184. }
  185. }
  186. } while (iter->index != start);
  187. /* Searched all the way back to start, and found nothing. */
  188. (void)load_descriptor_values(iter);
  189. return false;
  190. }
  191. }
  192. bool pb_default_field_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_t *field)
  193. {
  194. if (field->data_size == sizeof(pb_callback_t))
  195. {
  196. pb_callback_t *pCallback = (pb_callback_t*)field->pData;
  197. if (pCallback != NULL)
  198. {
  199. if (istream != NULL && pCallback->funcs.decode != NULL)
  200. {
  201. #ifdef PB_OLD_CALLBACK_STYLE
  202. return pCallback->funcs.decode(istream, field, pCallback->arg);
  203. #else
  204. return pCallback->funcs.decode(istream, field, &pCallback->arg);
  205. #endif
  206. }
  207. if (ostream != NULL && pCallback->funcs.encode != NULL)
  208. {
  209. #ifdef PB_OLD_CALLBACK_STYLE
  210. return pCallback->funcs.encode(ostream, field, pCallback->arg);
  211. #else
  212. return pCallback->funcs.encode(ostream, field, &pCallback->arg);
  213. #endif
  214. }
  215. }
  216. }
  217. return true; /* Success, but didn't do anything */
  218. }