payload_builder.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #include <string.h>
  2. #include "payload_builder.h"
  3. #define pb_check_capacity(pb, needed) \
  4. if ((pb)->current + (needed) > (pb)->end) { \
  5. if ((pb)->full_handler == NULL || !(pb)->full_handler(pb, needed)) (pb)->ok = 0; \
  6. }
  7. /** Write from a buffer */
  8. bool pb_buf(PayloadBuilder *pb, const uint8_t *buf, uint32_t len)
  9. {
  10. pb_check_capacity(pb, len);
  11. if (!pb->ok) return false;
  12. memcpy(pb->current, buf, len);
  13. pb->current += len;
  14. return true;
  15. }
  16. /** Write s zero terminated string */
  17. bool pb_string(PayloadBuilder *pb, const char *str)
  18. {
  19. uint32_t len = (uint32_t) strlen(str);
  20. pb_check_capacity(pb, len+1);
  21. if (!pb->ok) return false;
  22. memcpy(pb->current, str, len+1);
  23. pb->current += len+1;
  24. return true;
  25. }
  26. /** Write uint8_t to the buffer */
  27. bool pb_u8(PayloadBuilder *pb, uint8_t byte)
  28. {
  29. pb_check_capacity(pb, 1);
  30. if (!pb->ok) return false;
  31. *pb->current++ = byte;
  32. return true;
  33. }
  34. /** Write uint16_t to the buffer. */
  35. bool pb_u16(PayloadBuilder *pb, uint16_t word)
  36. {
  37. pb_check_capacity(pb, 2);
  38. if (!pb->ok) return false;
  39. if (pb->bigendian) {
  40. *pb->current++ = (uint8_t) ((word >> 8) & 0xFF);
  41. *pb->current++ = (uint8_t) (word & 0xFF);
  42. } else {
  43. *pb->current++ = (uint8_t) (word & 0xFF);
  44. *pb->current++ = (uint8_t) ((word >> 8) & 0xFF);
  45. }
  46. return true;
  47. }
  48. /** Write uint32_t to the buffer. */
  49. bool pb_u32(PayloadBuilder *pb, uint32_t word)
  50. {
  51. pb_check_capacity(pb, 4);
  52. if (!pb->ok) return false;
  53. if (pb->bigendian) {
  54. *pb->current++ = (uint8_t) ((word >> 24) & 0xFF);
  55. *pb->current++ = (uint8_t) ((word >> 16) & 0xFF);
  56. *pb->current++ = (uint8_t) ((word >> 8) & 0xFF);
  57. *pb->current++ = (uint8_t) (word & 0xFF);
  58. } else {
  59. *pb->current++ = (uint8_t) (word & 0xFF);
  60. *pb->current++ = (uint8_t) ((word >> 8) & 0xFF);
  61. *pb->current++ = (uint8_t) ((word >> 16) & 0xFF);
  62. *pb->current++ = (uint8_t) ((word >> 24) & 0xFF);
  63. }
  64. return true;
  65. }
  66. /** Write int8_t to the buffer. */
  67. bool pb_i8(PayloadBuilder *pb, int8_t byte)
  68. {
  69. return pb_u8(pb, ((union conv8){.i8 = byte}).u8);
  70. }
  71. /** Write int16_t to the buffer. */
  72. bool pb_i16(PayloadBuilder *pb, int16_t word)
  73. {
  74. return pb_u16(pb, ((union conv16){.i16 = word}).u16);
  75. }
  76. /** Write int32_t to the buffer. */
  77. bool pb_i32(PayloadBuilder *pb, int32_t word)
  78. {
  79. return pb_u32(pb, ((union conv32){.i32 = word}).u32);
  80. }
  81. /** Write 4-byte float to the buffer. */
  82. bool pb_float(PayloadBuilder *pb, float f)
  83. {
  84. return pb_u32(pb, ((union conv32){.f32 = f}).u32);
  85. }