pb_encode.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913
  1. /* pb_encode.c -- encode a protobuf using minimal resources
  2. *
  3. * 2011 Petteri Aimonen <jpa@kapsi.fi>
  4. */
  5. #include "pb.h"
  6. #include "pb_encode.h"
  7. #include "pb_common.h"
  8. /* Use the GCC warn_unused_result attribute to check that all return values
  9. * are propagated correctly. On other compilers and gcc before 3.4.0 just
  10. * ignore the annotation.
  11. */
  12. #if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4)
  13. #define checkreturn
  14. #else
  15. #define checkreturn __attribute__((warn_unused_result))
  16. #endif
  17. /**************************************
  18. * Declarations internal to this file *
  19. **************************************/
  20. typedef bool (*pb_encoder_t)(pb_ostream_t *stream, const pb_field_t *field, const void *src) checkreturn;
  21. static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count);
  22. static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *field, const void *pData, size_t count, pb_encoder_t func);
  23. static bool checkreturn encode_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData);
  24. static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb_extension_t *extension);
  25. static bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData);
  26. static void *pb_const_cast(const void *p);
  27. static bool checkreturn pb_enc_bool(pb_ostream_t *stream, const pb_field_t *field, const void *src);
  28. static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src);
  29. static bool checkreturn pb_enc_uvarint(pb_ostream_t *stream, const pb_field_t *field, const void *src);
  30. static bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *field, const void *src);
  31. static bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, const void *src);
  32. static bool checkreturn pb_enc_fixed64(pb_ostream_t *stream, const pb_field_t *field, const void *src);
  33. static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src);
  34. static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src);
  35. static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src);
  36. static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src);
  37. #ifdef PB_WITHOUT_64BIT
  38. #define pb_int64_t int32_t
  39. #define pb_uint64_t uint32_t
  40. static bool checkreturn pb_encode_negative_varint(pb_ostream_t *stream, pb_uint64_t value);
  41. #else
  42. #define pb_int64_t int64_t
  43. #define pb_uint64_t uint64_t
  44. #endif
  45. /* --- Function pointers to field encoders ---
  46. * Order in the array must match pb_action_t LTYPE numbering.
  47. */
  48. static const pb_encoder_t PB_ENCODERS[PB_LTYPES_COUNT] = {
  49. &pb_enc_bool,
  50. &pb_enc_varint,
  51. &pb_enc_uvarint,
  52. &pb_enc_svarint,
  53. &pb_enc_fixed32,
  54. &pb_enc_fixed64,
  55. &pb_enc_bytes,
  56. &pb_enc_string,
  57. &pb_enc_submessage,
  58. NULL, /* extensions */
  59. &pb_enc_fixed_length_bytes
  60. };
  61. /*******************************
  62. * pb_ostream_t implementation *
  63. *******************************/
  64. static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count)
  65. {
  66. size_t i;
  67. pb_byte_t *dest = (pb_byte_t*)stream->state;
  68. stream->state = dest + count;
  69. for (i = 0; i < count; i++)
  70. dest[i] = buf[i];
  71. return true;
  72. }
  73. pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize)
  74. {
  75. pb_ostream_t stream;
  76. #ifdef PB_BUFFER_ONLY
  77. stream.callback = (void*)1; /* Just a marker value */
  78. #else
  79. stream.callback = &buf_write;
  80. #endif
  81. stream.state = buf;
  82. stream.max_size = bufsize;
  83. stream.bytes_written = 0;
  84. #ifndef PB_NO_ERRMSG
  85. stream.errmsg = NULL;
  86. #endif
  87. return stream;
  88. }
  89. bool checkreturn pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count)
  90. {
  91. if (count > 0 && stream->callback != NULL)
  92. {
  93. if (stream->bytes_written + count < stream->bytes_written ||
  94. stream->bytes_written + count > stream->max_size)
  95. {
  96. PB_RETURN_ERROR(stream, "stream full");
  97. }
  98. #ifdef PB_BUFFER_ONLY
  99. if (!buf_write(stream, buf, count))
  100. PB_RETURN_ERROR(stream, "io error");
  101. #else
  102. if (!stream->callback(stream, buf, count))
  103. PB_RETURN_ERROR(stream, "io error");
  104. #endif
  105. }
  106. stream->bytes_written += count;
  107. return true;
  108. }
  109. /*************************
  110. * Encode a single field *
  111. *************************/
  112. /* Read a bool value without causing undefined behavior even if the value
  113. * is invalid. See issue #434 and
  114. * https://stackoverflow.com/questions/27661768/weird-results-for-conditional
  115. */
  116. static bool safe_read_bool(const void *pSize)
  117. {
  118. const char *p = (const char *)pSize;
  119. size_t i;
  120. for (i = 0; i < sizeof(bool); i++)
  121. {
  122. if (p[i] != 0)
  123. return true;
  124. }
  125. return false;
  126. }
  127. /* Encode a static array. Handles the size calculations and possible packing. */
  128. static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *field,
  129. const void *pData, size_t count, pb_encoder_t func)
  130. {
  131. size_t i;
  132. const void *p;
  133. #ifndef PB_ENCODE_ARRAYS_UNPACKED
  134. size_t size;
  135. #endif
  136. if (count == 0)
  137. return true;
  138. if (PB_ATYPE(field->type) != PB_ATYPE_POINTER && count > field->array_size)
  139. PB_RETURN_ERROR(stream, "array max size exceeded");
  140. #ifndef PB_ENCODE_ARRAYS_UNPACKED
  141. /* We always pack arrays if the datatype allows it. */
  142. if (PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE)
  143. {
  144. if (!pb_encode_tag(stream, PB_WT_STRING, field->tag))
  145. return false;
  146. /* Determine the total size of packed array. */
  147. if (PB_LTYPE(field->type) == PB_LTYPE_FIXED32)
  148. {
  149. size = 4 * count;
  150. }
  151. else if (PB_LTYPE(field->type) == PB_LTYPE_FIXED64)
  152. {
  153. size = 8 * count;
  154. }
  155. else
  156. {
  157. pb_ostream_t sizestream = PB_OSTREAM_SIZING;
  158. p = pData;
  159. for (i = 0; i < count; i++)
  160. {
  161. if (!func(&sizestream, field, p))
  162. return false;
  163. p = (const char*)p + field->data_size;
  164. }
  165. size = sizestream.bytes_written;
  166. }
  167. if (!pb_encode_varint(stream, (pb_uint64_t)size))
  168. return false;
  169. if (stream->callback == NULL)
  170. return pb_write(stream, NULL, size); /* Just sizing.. */
  171. /* Write the data */
  172. p = pData;
  173. for (i = 0; i < count; i++)
  174. {
  175. if (!func(stream, field, p))
  176. return false;
  177. p = (const char*)p + field->data_size;
  178. }
  179. }
  180. else
  181. #endif
  182. {
  183. p = pData;
  184. for (i = 0; i < count; i++)
  185. {
  186. if (!pb_encode_tag_for_field(stream, field))
  187. return false;
  188. /* Normally the data is stored directly in the array entries, but
  189. * for pointer-type string and bytes fields, the array entries are
  190. * actually pointers themselves also. So we have to dereference once
  191. * more to get to the actual data. */
  192. if (PB_ATYPE(field->type) == PB_ATYPE_POINTER &&
  193. (PB_LTYPE(field->type) == PB_LTYPE_STRING ||
  194. PB_LTYPE(field->type) == PB_LTYPE_BYTES))
  195. {
  196. if (!func(stream, field, *(const void* const*)p))
  197. return false;
  198. }
  199. else
  200. {
  201. if (!func(stream, field, p))
  202. return false;
  203. }
  204. p = (const char*)p + field->data_size;
  205. }
  206. }
  207. return true;
  208. }
  209. /* In proto3, all fields are optional and are only encoded if their value is "non-zero".
  210. * This function implements the check for the zero value. */
  211. static bool pb_check_proto3_default_value(const pb_field_t *field, const void *pData)
  212. {
  213. pb_type_t type = field->type;
  214. const void *pSize = (const char*)pData + field->size_offset;
  215. if (PB_HTYPE(type) == PB_HTYPE_REQUIRED)
  216. {
  217. /* Required proto2 fields inside proto3 submessage, pretty rare case */
  218. return false;
  219. }
  220. else if (PB_HTYPE(type) == PB_HTYPE_REPEATED)
  221. {
  222. /* Repeated fields inside proto3 submessage: present if count != 0 */
  223. if (field->size_offset != 0)
  224. return *(const pb_size_t*)pSize == 0;
  225. else if (PB_ATYPE(type) == PB_ATYPE_STATIC)
  226. return false; /* Fixed length array */
  227. }
  228. else if (PB_HTYPE(type) == PB_HTYPE_ONEOF)
  229. {
  230. /* Oneof fields */
  231. return *(const pb_size_t*)pSize == 0;
  232. }
  233. else if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL && field->size_offset != 0)
  234. {
  235. /* Proto2 optional fields inside proto3 submessage */
  236. return safe_read_bool(pSize) == false;
  237. }
  238. /* Rest is proto3 singular fields */
  239. if (PB_ATYPE(type) == PB_ATYPE_STATIC)
  240. {
  241. if (PB_LTYPE(type) == PB_LTYPE_BYTES)
  242. {
  243. const pb_bytes_array_t *bytes = (const pb_bytes_array_t*)pData;
  244. return bytes->size == 0;
  245. }
  246. else if (PB_LTYPE(type) == PB_LTYPE_STRING)
  247. {
  248. return *(const char*)pData == '\0';
  249. }
  250. else if (PB_LTYPE(type) == PB_LTYPE_FIXED_LENGTH_BYTES)
  251. {
  252. /* Fixed length bytes is only empty if its length is fixed
  253. * as 0. Which would be pretty strange, but we can check
  254. * it anyway. */
  255. return field->data_size == 0;
  256. }
  257. else if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE)
  258. {
  259. /* Check all fields in the submessage to find if any of them
  260. * are non-zero. The comparison cannot be done byte-per-byte
  261. * because the C struct may contain padding bytes that must
  262. * be skipped.
  263. */
  264. pb_field_iter_t iter;
  265. if (pb_field_iter_begin(&iter, (const pb_field_t*)field->ptr, pb_const_cast(pData)))
  266. {
  267. do
  268. {
  269. if (!pb_check_proto3_default_value(iter.pos, iter.pData))
  270. {
  271. return false;
  272. }
  273. } while (pb_field_iter_next(&iter));
  274. }
  275. return true;
  276. }
  277. }
  278. /* Compares pointers to NULL in case of FT_POINTER */
  279. if (PB_ATYPE(type) == PB_ATYPE_POINTER && PB_LTYPE(type) > PB_LTYPE_LAST_PACKABLE)
  280. {
  281. return !*(const void**)((uintptr_t)pData);
  282. }
  283. {
  284. /* Catch-all branch that does byte-per-byte comparison for zero value.
  285. *
  286. * This is for all pointer fields, and for static PB_LTYPE_VARINT,
  287. * UVARINT, SVARINT, FIXED32, FIXED64, EXTENSION fields, and also
  288. * callback fields. These all have integer or pointer value which
  289. * can be compared with 0.
  290. */
  291. pb_size_t i;
  292. const char *p = (const char*)pData;
  293. for (i = 0; i < field->data_size; i++)
  294. {
  295. if (p[i] != 0)
  296. {
  297. return false;
  298. }
  299. }
  300. return true;
  301. }
  302. }
  303. /* Encode a field with static or pointer allocation, i.e. one whose data
  304. * is available to the encoder directly. */
  305. static bool checkreturn encode_basic_field(pb_ostream_t *stream,
  306. const pb_field_t *field, const void *pData)
  307. {
  308. pb_encoder_t func;
  309. bool implicit_has;
  310. const void *pSize = &implicit_has;
  311. func = PB_ENCODERS[PB_LTYPE(field->type)];
  312. if (field->size_offset)
  313. {
  314. /* Static optional, repeated or oneof field */
  315. pSize = (const char*)pData + field->size_offset;
  316. }
  317. else if (PB_HTYPE(field->type) == PB_HTYPE_OPTIONAL)
  318. {
  319. /* Proto3 style field, optional but without explicit has_ field. */
  320. implicit_has = !pb_check_proto3_default_value(field, pData);
  321. }
  322. else
  323. {
  324. /* Required field, always present */
  325. implicit_has = true;
  326. }
  327. if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
  328. {
  329. /* pData is a pointer to the field, which contains pointer to
  330. * the data. If the 2nd pointer is NULL, it is interpreted as if
  331. * the has_field was false.
  332. */
  333. pData = *(const void* const*)pData;
  334. implicit_has = (pData != NULL);
  335. }
  336. switch (PB_HTYPE(field->type))
  337. {
  338. case PB_HTYPE_REQUIRED:
  339. if (!pData)
  340. PB_RETURN_ERROR(stream, "missing required field");
  341. if (!pb_encode_tag_for_field(stream, field))
  342. return false;
  343. if (!func(stream, field, pData))
  344. return false;
  345. break;
  346. case PB_HTYPE_OPTIONAL:
  347. if (safe_read_bool(pSize))
  348. {
  349. if (!pb_encode_tag_for_field(stream, field))
  350. return false;
  351. if (!func(stream, field, pData))
  352. return false;
  353. }
  354. break;
  355. case PB_HTYPE_REPEATED: {
  356. pb_size_t count;
  357. if (field->size_offset != 0) {
  358. count = *(const pb_size_t*)pSize;
  359. } else {
  360. count = field->array_size;
  361. }
  362. if (!encode_array(stream, field, pData, count, func))
  363. return false;
  364. break;
  365. }
  366. case PB_HTYPE_ONEOF:
  367. if (*(const pb_size_t*)pSize == field->tag)
  368. {
  369. if (!pb_encode_tag_for_field(stream, field))
  370. return false;
  371. if (!func(stream, field, pData))
  372. return false;
  373. }
  374. break;
  375. default:
  376. PB_RETURN_ERROR(stream, "invalid field type");
  377. }
  378. return true;
  379. }
  380. /* Encode a field with callback semantics. This means that a user function is
  381. * called to provide and encode the actual data. */
  382. static bool checkreturn encode_callback_field(pb_ostream_t *stream,
  383. const pb_field_t *field, const void *pData)
  384. {
  385. const pb_callback_t *callback = (const pb_callback_t*)pData;
  386. #ifdef PB_OLD_CALLBACK_STYLE
  387. const void *arg = callback->arg;
  388. #else
  389. void * const *arg = &(callback->arg);
  390. #endif
  391. if (callback->funcs.encode != NULL)
  392. {
  393. if (!callback->funcs.encode(stream, field, arg))
  394. PB_RETURN_ERROR(stream, "callback error");
  395. }
  396. return true;
  397. }
  398. /* Encode a single field of any callback or static type. */
  399. static bool checkreturn encode_field(pb_ostream_t *stream,
  400. const pb_field_t *field, const void *pData)
  401. {
  402. switch (PB_ATYPE(field->type))
  403. {
  404. case PB_ATYPE_STATIC:
  405. case PB_ATYPE_POINTER:
  406. return encode_basic_field(stream, field, pData);
  407. case PB_ATYPE_CALLBACK:
  408. return encode_callback_field(stream, field, pData);
  409. default:
  410. PB_RETURN_ERROR(stream, "invalid field type");
  411. }
  412. }
  413. /* Default handler for extension fields. Expects to have a pb_field_t
  414. * pointer in the extension->type->arg field. */
  415. static bool checkreturn default_extension_encoder(pb_ostream_t *stream,
  416. const pb_extension_t *extension)
  417. {
  418. const pb_field_t *field = (const pb_field_t*)extension->type->arg;
  419. if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
  420. {
  421. /* For pointer extensions, the pointer is stored directly
  422. * in the extension structure. This avoids having an extra
  423. * indirection. */
  424. return encode_field(stream, field, &extension->dest);
  425. }
  426. else
  427. {
  428. return encode_field(stream, field, extension->dest);
  429. }
  430. }
  431. /* Walk through all the registered extensions and give them a chance
  432. * to encode themselves. */
  433. static bool checkreturn encode_extension_field(pb_ostream_t *stream,
  434. const pb_field_t *field, const void *pData)
  435. {
  436. const pb_extension_t *extension = *(const pb_extension_t* const *)pData;
  437. PB_UNUSED(field);
  438. while (extension)
  439. {
  440. bool status;
  441. if (extension->type->encode)
  442. status = extension->type->encode(stream, extension);
  443. else
  444. status = default_extension_encoder(stream, extension);
  445. if (!status)
  446. return false;
  447. extension = extension->next;
  448. }
  449. return true;
  450. }
  451. /*********************
  452. * Encode all fields *
  453. *********************/
  454. static void *pb_const_cast(const void *p)
  455. {
  456. /* Note: this casts away const, in order to use the common field iterator
  457. * logic for both encoding and decoding. */
  458. union {
  459. void *p1;
  460. const void *p2;
  461. } t;
  462. t.p2 = p;
  463. return t.p1;
  464. }
  465. bool checkreturn pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct)
  466. {
  467. pb_field_iter_t iter;
  468. if (!pb_field_iter_begin(&iter, fields, pb_const_cast(src_struct)))
  469. return true; /* Empty message type */
  470. do {
  471. if (PB_LTYPE(iter.pos->type) == PB_LTYPE_EXTENSION)
  472. {
  473. /* Special case for the extension field placeholder */
  474. if (!encode_extension_field(stream, iter.pos, iter.pData))
  475. return false;
  476. }
  477. else
  478. {
  479. /* Regular field */
  480. if (!encode_field(stream, iter.pos, iter.pData))
  481. return false;
  482. }
  483. } while (pb_field_iter_next(&iter));
  484. return true;
  485. }
  486. bool pb_encode_delimited(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct)
  487. {
  488. return pb_encode_submessage(stream, fields, src_struct);
  489. }
  490. bool pb_encode_nullterminated(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct)
  491. {
  492. const pb_byte_t zero = 0;
  493. if (!pb_encode(stream, fields, src_struct))
  494. return false;
  495. return pb_write(stream, &zero, 1);
  496. }
  497. bool pb_get_encoded_size(size_t *size, const pb_field_t fields[], const void *src_struct)
  498. {
  499. pb_ostream_t stream = PB_OSTREAM_SIZING;
  500. if (!pb_encode(&stream, fields, src_struct))
  501. return false;
  502. *size = stream.bytes_written;
  503. return true;
  504. }
  505. /********************
  506. * Helper functions *
  507. ********************/
  508. #ifdef PB_WITHOUT_64BIT
  509. bool checkreturn pb_encode_negative_varint(pb_ostream_t *stream, pb_uint64_t value)
  510. {
  511. pb_byte_t buffer[10];
  512. size_t i = 0;
  513. size_t compensation = 32;/* we need to compensate 32 bits all set to 1 */
  514. while (value)
  515. {
  516. buffer[i] = (pb_byte_t)((value & 0x7F) | 0x80);
  517. value >>= 7;
  518. if (compensation)
  519. {
  520. /* re-set all the compensation bits we can or need */
  521. size_t bits = compensation > 7 ? 7 : compensation;
  522. value ^= (pb_uint64_t)((0xFFu >> (8 - bits)) << 25); /* set the number of bits needed on the lowest of the most significant 7 bits */
  523. compensation -= bits;
  524. }
  525. i++;
  526. }
  527. buffer[i - 1] &= 0x7F; /* Unset top bit on last byte */
  528. return pb_write(stream, buffer, i);
  529. }
  530. #endif
  531. bool checkreturn pb_encode_varint(pb_ostream_t *stream, pb_uint64_t value)
  532. {
  533. pb_byte_t buffer[10];
  534. size_t i = 0;
  535. if (value <= 0x7F)
  536. {
  537. pb_byte_t v = (pb_byte_t)value;
  538. return pb_write(stream, &v, 1);
  539. }
  540. while (value)
  541. {
  542. buffer[i] = (pb_byte_t)((value & 0x7F) | 0x80);
  543. value >>= 7;
  544. i++;
  545. }
  546. buffer[i-1] &= 0x7F; /* Unset top bit on last byte */
  547. return pb_write(stream, buffer, i);
  548. }
  549. bool checkreturn pb_encode_svarint(pb_ostream_t *stream, pb_int64_t value)
  550. {
  551. pb_uint64_t zigzagged;
  552. if (value < 0)
  553. zigzagged = ~((pb_uint64_t)value << 1);
  554. else
  555. zigzagged = (pb_uint64_t)value << 1;
  556. return pb_encode_varint(stream, zigzagged);
  557. }
  558. bool checkreturn pb_encode_fixed32(pb_ostream_t *stream, const void *value)
  559. {
  560. uint32_t val = *(const uint32_t*)value;
  561. pb_byte_t bytes[4];
  562. bytes[0] = (pb_byte_t)(val & 0xFF);
  563. bytes[1] = (pb_byte_t)((val >> 8) & 0xFF);
  564. bytes[2] = (pb_byte_t)((val >> 16) & 0xFF);
  565. bytes[3] = (pb_byte_t)((val >> 24) & 0xFF);
  566. return pb_write(stream, bytes, 4);
  567. }
  568. #ifndef PB_WITHOUT_64BIT
  569. bool checkreturn pb_encode_fixed64(pb_ostream_t *stream, const void *value)
  570. {
  571. uint64_t val = *(const uint64_t*)value;
  572. pb_byte_t bytes[8];
  573. bytes[0] = (pb_byte_t)(val & 0xFF);
  574. bytes[1] = (pb_byte_t)((val >> 8) & 0xFF);
  575. bytes[2] = (pb_byte_t)((val >> 16) & 0xFF);
  576. bytes[3] = (pb_byte_t)((val >> 24) & 0xFF);
  577. bytes[4] = (pb_byte_t)((val >> 32) & 0xFF);
  578. bytes[5] = (pb_byte_t)((val >> 40) & 0xFF);
  579. bytes[6] = (pb_byte_t)((val >> 48) & 0xFF);
  580. bytes[7] = (pb_byte_t)((val >> 56) & 0xFF);
  581. return pb_write(stream, bytes, 8);
  582. }
  583. #endif
  584. bool checkreturn pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number)
  585. {
  586. pb_uint64_t tag = ((pb_uint64_t)field_number << 3) | wiretype;
  587. return pb_encode_varint(stream, tag);
  588. }
  589. bool checkreturn pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t *field)
  590. {
  591. pb_wire_type_t wiretype;
  592. switch (PB_LTYPE(field->type))
  593. {
  594. case PB_LTYPE_BOOL:
  595. case PB_LTYPE_VARINT:
  596. case PB_LTYPE_UVARINT:
  597. case PB_LTYPE_SVARINT:
  598. wiretype = PB_WT_VARINT;
  599. break;
  600. case PB_LTYPE_FIXED32:
  601. wiretype = PB_WT_32BIT;
  602. break;
  603. case PB_LTYPE_FIXED64:
  604. wiretype = PB_WT_64BIT;
  605. break;
  606. case PB_LTYPE_BYTES:
  607. case PB_LTYPE_STRING:
  608. case PB_LTYPE_SUBMESSAGE:
  609. case PB_LTYPE_FIXED_LENGTH_BYTES:
  610. wiretype = PB_WT_STRING;
  611. break;
  612. default:
  613. PB_RETURN_ERROR(stream, "invalid field type");
  614. }
  615. return pb_encode_tag(stream, wiretype, field->tag);
  616. }
  617. bool checkreturn pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size)
  618. {
  619. if (!pb_encode_varint(stream, (pb_uint64_t)size))
  620. return false;
  621. return pb_write(stream, buffer, size);
  622. }
  623. bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct)
  624. {
  625. /* First calculate the message size using a non-writing substream. */
  626. pb_ostream_t substream = PB_OSTREAM_SIZING;
  627. size_t size;
  628. bool status;
  629. if (!pb_encode(&substream, fields, src_struct))
  630. {
  631. #ifndef PB_NO_ERRMSG
  632. stream->errmsg = substream.errmsg;
  633. #endif
  634. return false;
  635. }
  636. size = substream.bytes_written;
  637. if (!pb_encode_varint(stream, (pb_uint64_t)size))
  638. return false;
  639. if (stream->callback == NULL)
  640. return pb_write(stream, NULL, size); /* Just sizing */
  641. if (stream->bytes_written + size > stream->max_size)
  642. PB_RETURN_ERROR(stream, "stream full");
  643. /* Use a substream to verify that a callback doesn't write more than
  644. * what it did the first time. */
  645. substream.callback = stream->callback;
  646. substream.state = stream->state;
  647. substream.max_size = size;
  648. substream.bytes_written = 0;
  649. #ifndef PB_NO_ERRMSG
  650. substream.errmsg = NULL;
  651. #endif
  652. status = pb_encode(&substream, fields, src_struct);
  653. stream->bytes_written += substream.bytes_written;
  654. stream->state = substream.state;
  655. #ifndef PB_NO_ERRMSG
  656. stream->errmsg = substream.errmsg;
  657. #endif
  658. if (substream.bytes_written != size)
  659. PB_RETURN_ERROR(stream, "submsg size changed");
  660. return status;
  661. }
  662. /* Field encoders */
  663. static bool checkreturn pb_enc_bool(pb_ostream_t *stream, const pb_field_t *field, const void *src)
  664. {
  665. uint32_t value = safe_read_bool(src) ? 1 : 0;
  666. PB_UNUSED(field);
  667. return pb_encode_varint(stream, value);
  668. }
  669. static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src)
  670. {
  671. pb_int64_t value = 0;
  672. if (field->data_size == sizeof(int_least8_t))
  673. value = *(const int_least8_t*)src;
  674. else if (field->data_size == sizeof(int_least16_t))
  675. value = *(const int_least16_t*)src;
  676. else if (field->data_size == sizeof(int32_t))
  677. value = *(const int32_t*)src;
  678. else if (field->data_size == sizeof(pb_int64_t))
  679. value = *(const pb_int64_t*)src;
  680. else
  681. PB_RETURN_ERROR(stream, "invalid data_size");
  682. #ifdef PB_WITHOUT_64BIT
  683. if (value < 0)
  684. return pb_encode_negative_varint(stream, (pb_uint64_t)value);
  685. else
  686. #endif
  687. return pb_encode_varint(stream, (pb_uint64_t)value);
  688. }
  689. static bool checkreturn pb_enc_uvarint(pb_ostream_t *stream, const pb_field_t *field, const void *src)
  690. {
  691. pb_uint64_t value = 0;
  692. if (field->data_size == sizeof(uint_least8_t))
  693. value = *(const uint_least8_t*)src;
  694. else if (field->data_size == sizeof(uint_least16_t))
  695. value = *(const uint_least16_t*)src;
  696. else if (field->data_size == sizeof(uint32_t))
  697. value = *(const uint32_t*)src;
  698. else if (field->data_size == sizeof(pb_uint64_t))
  699. value = *(const pb_uint64_t*)src;
  700. else
  701. PB_RETURN_ERROR(stream, "invalid data_size");
  702. return pb_encode_varint(stream, value);
  703. }
  704. static bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *field, const void *src)
  705. {
  706. pb_int64_t value = 0;
  707. if (field->data_size == sizeof(int_least8_t))
  708. value = *(const int_least8_t*)src;
  709. else if (field->data_size == sizeof(int_least16_t))
  710. value = *(const int_least16_t*)src;
  711. else if (field->data_size == sizeof(int32_t))
  712. value = *(const int32_t*)src;
  713. else if (field->data_size == sizeof(pb_int64_t))
  714. value = *(const pb_int64_t*)src;
  715. else
  716. PB_RETURN_ERROR(stream, "invalid data_size");
  717. return pb_encode_svarint(stream, value);
  718. }
  719. static bool checkreturn pb_enc_fixed64(pb_ostream_t *stream, const pb_field_t *field, const void *src)
  720. {
  721. PB_UNUSED(field);
  722. #ifndef PB_WITHOUT_64BIT
  723. return pb_encode_fixed64(stream, src);
  724. #else
  725. PB_UNUSED(src);
  726. PB_RETURN_ERROR(stream, "no 64bit support");
  727. #endif
  728. }
  729. static bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, const void *src)
  730. {
  731. PB_UNUSED(field);
  732. return pb_encode_fixed32(stream, src);
  733. }
  734. static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src)
  735. {
  736. const pb_bytes_array_t *bytes = NULL;
  737. size_t allocsize;
  738. bytes = (const pb_bytes_array_t*)src;
  739. if (src == NULL)
  740. {
  741. /* Treat null pointer as an empty bytes field */
  742. return pb_encode_string(stream, NULL, 0);
  743. }
  744. allocsize = PB_BYTES_ARRAY_T_ALLOCSIZE(bytes->size);
  745. if (allocsize < bytes->size ||
  746. (PB_ATYPE(field->type) == PB_ATYPE_STATIC && allocsize > field->data_size))
  747. {
  748. PB_RETURN_ERROR(stream, "bytes size exceeded");
  749. }
  750. return pb_encode_string(stream, bytes->bytes, bytes->size);
  751. }
  752. static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src)
  753. {
  754. size_t size = 0;
  755. size_t max_size = field->data_size;
  756. const char *p = (const char*)src;
  757. if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
  758. max_size = (size_t)-1;
  759. if (src == NULL)
  760. {
  761. size = 0; /* Treat null pointer as an empty string */
  762. }
  763. else
  764. {
  765. /* strnlen() is not always available, so just use a loop */
  766. while (size < max_size && *p != '\0')
  767. {
  768. size++;
  769. p++;
  770. }
  771. }
  772. return pb_encode_string(stream, (const pb_byte_t*)src, size);
  773. }
  774. static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src)
  775. {
  776. if (field->ptr == NULL)
  777. PB_RETURN_ERROR(stream, "invalid field descriptor");
  778. return pb_encode_submessage(stream, (const pb_field_t*)field->ptr, src);
  779. }
  780. static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src)
  781. {
  782. return pb_encode_string(stream, (const pb_byte_t*)src, field->data_size);
  783. }