1
0

Message.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #ifndef Message_H
  16. #define Message_H
  17. #include "exception/Er.h"
  18. #include "memory/Allocator.h"
  19. #include "util/Bits.h"
  20. #include "util/Endian.h"
  21. #include "util/Linker.h"
  22. Linker_require("wire/Message.c")
  23. #include <stdint.h>
  24. typedef struct Message
  25. {
  26. /** The length of the message. */
  27. int32_t _length;
  28. /** The number of bytes of padding BEFORE where bytes begins. */
  29. int32_t _padding;
  30. /** The content. */
  31. uint8_t* msgbytes;
  32. /** Amount of bytes of storage space available in the message. */
  33. int32_t _capacity;
  34. // Amount of associated data
  35. int32_t _adLen;
  36. // Pointer to associated data
  37. uint8_t* _ad;
  38. /**
  39. * When sending/receiving a Message on a unix socket, a file descriptor to attach.
  40. * Caviat: In order to maintain backward compatibility with a Message which is
  41. * allocated using calloc, file descriptor 0 is referred to by -1
  42. */
  43. int _associatedFd;
  44. #ifdef PARANOIA
  45. /** This is used inside of Iface.h to support Iface_next() */
  46. struct Iface* currentIface;
  47. #endif
  48. /** The allocator which allocated space for this message. */
  49. struct Allocator* _alloc;
  50. } Message_t;
  51. static inline struct Allocator* Message_getAlloc(struct Message* msg)
  52. {
  53. return msg->_alloc;
  54. }
  55. static inline int32_t Message_getLength(struct Message* msg)
  56. {
  57. return msg->_length;
  58. }
  59. static inline Er_DEFUN(void Message_truncate(struct Message* msg, int32_t newLen))
  60. {
  61. if (newLen > msg->_length) {
  62. Er_raise(msg->_alloc, "Message_truncate(%d) message length is %d", newLen, msg->_length);
  63. }
  64. msg->_length = newLen;
  65. Er_ret();
  66. }
  67. static inline int32_t Message_getPadding(struct Message* msg)
  68. {
  69. return msg->_padding;
  70. }
  71. static inline int32_t Message_getCapacity(struct Message* msg)
  72. {
  73. return msg->_capacity;
  74. }
  75. static inline Message_t Message_foreign(uint32_t len, uint8_t* bytes)
  76. {
  77. return (Message_t){ ._length = len, .msgbytes = bytes, ._capacity = len };
  78. }
  79. // static inline Er_DEFUN(void Message_ecopy(struct Message* to, struct Message* from, uint32_t amt))
  80. // {
  81. // }
  82. struct Message* Message_new(uint32_t messageLength,
  83. uint32_t amountOfPadding,
  84. struct Allocator* alloc);
  85. void Message_setAssociatedFd(struct Message* msg, int fd);
  86. int Message_getAssociatedFd(struct Message* msg);
  87. struct Message* Message_clone(struct Message* toClone, struct Allocator* alloc);
  88. static inline Er_DEFUN(uint8_t* Message_peakBytes(struct Message* msg, int32_t len))
  89. {
  90. if (len > msg->_length) {
  91. Er_raise(msg->_alloc, "peakBytes(%d) too big, message length is %d", len, msg->_length);
  92. }
  93. Er_ret(msg->msgbytes);
  94. }
  95. /**
  96. * Pretend to shift the content forward by amount.
  97. * Really it shifts the bytes value backward.
  98. */
  99. static inline Er_DEFUN(void Message_eshift(struct Message* toShift, int32_t amount))
  100. {
  101. if (amount > 0 && toShift->_padding < amount) {
  102. Er_raise(toShift->_alloc, "buffer overflow adding %d to length %d",
  103. amount, toShift->_length);
  104. } else if (toShift->_length < (-amount)) {
  105. Er_raise(toShift->_alloc, "buffer underflow");
  106. }
  107. toShift->_length += amount;
  108. toShift->_capacity += amount;
  109. toShift->msgbytes -= amount;
  110. toShift->_padding -= amount;
  111. Er_ret();
  112. }
  113. static inline Er_DEFUN(void Message_epushAd(struct Message* restrict msg,
  114. const void* restrict object,
  115. size_t size))
  116. {
  117. if (msg->_padding < (int)size) {
  118. Er_raise(msg->_alloc, "not enough padding to push ad");
  119. }
  120. if (object) {
  121. Bits_memcpy(msg->_ad, object, size);
  122. } else {
  123. Bits_memset(msg->_ad, 0x00, size);
  124. }
  125. msg->_adLen += size;
  126. msg->_padding -= size;
  127. msg->_ad = &msg->_ad[size];
  128. Er_ret();
  129. }
  130. static inline Er_DEFUN(void Message_epopAd(struct Message* restrict msg,
  131. void* restrict object,
  132. size_t size))
  133. {
  134. if (msg->_adLen < (int)size) {
  135. Er_raise(msg->_alloc, "underflow, cannot pop ad");
  136. }
  137. msg->_adLen -= size;
  138. msg->_padding += size;
  139. msg->_ad = &msg->_ad[-((int)size)];
  140. if (object) {
  141. Bits_memcpy(object, msg->_ad, size);
  142. }
  143. Er_ret();
  144. }
  145. static inline void Message_reset(struct Message* toShift)
  146. {
  147. Assert_true(toShift->_length <= toShift->_capacity);
  148. Er_assert(Message_epopAd(toShift, NULL, toShift->_adLen));
  149. toShift->_length = toShift->_capacity;
  150. Er_assert(Message_eshift(toShift, -toShift->_length));
  151. }
  152. static inline Er_DEFUN(void Message_epush(struct Message* restrict msg,
  153. const void* restrict object,
  154. size_t size))
  155. {
  156. Er(Message_eshift(msg, (int)size));
  157. if (object) {
  158. Bits_memcpy(msg->msgbytes, object, size);
  159. } else {
  160. Bits_memset(msg->msgbytes, 0x00, size);
  161. }
  162. Er_ret();
  163. }
  164. static inline Er_DEFUN(void Message_epop(struct Message* restrict msg,
  165. void* restrict object,
  166. size_t size))
  167. {
  168. Er(Message_eshift(msg, -(int)size));
  169. if (object) {
  170. Bits_memcpy(object, &msg->msgbytes[-((int)size)], size);
  171. }
  172. Er_ret();
  173. }
  174. #define Message_pushH(size) \
  175. static inline Er_DEFUN(void Message_epush ## size ## h \
  176. (struct Message* msg, uint ## size ## _t dat)) \
  177. { \
  178. Er(Message_epush(msg, &dat, (size)/8)); \
  179. Er_ret(); \
  180. }
  181. #define Message_popH(size) \
  182. static inline Er_DEFUN(uint ## size ## _t Message_epop ## size ## h(struct Message* msg)) \
  183. { \
  184. uint ## size ## _t out; \
  185. Er(Message_epop(msg, &out, (size)/8)); \
  186. Er_ret(out); \
  187. }
  188. #define Message_popBE(size) \
  189. static inline Er_DEFUN(uint ## size ## _t Message_epop ## size ## be(struct Message* msg)) \
  190. { \
  191. uint ## size ## _t out = Er(Message_epop ## size ## h(msg)); \
  192. uint ## size ## _t out1 = Endian_bigEndianToHost ## size (out); \
  193. Er_ret(out1); \
  194. }
  195. #define Message_popLE(size) \
  196. static inline Er_DEFUN(uint ## size ## _t Message_epop ## size ## le(struct Message* msg)) \
  197. { \
  198. uint ## size ## _t out = Er(Message_epop ## size ## h(msg)); \
  199. uint ## size ## _t out1 = Endian_littleEndianToHost ## size (out); \
  200. Er_ret(out1); \
  201. }
  202. #define Message_pushPop(size) \
  203. Message_pushH(size) Message_popH(size) Message_popBE(size) Message_popLE(size)
  204. Message_pushH(8)
  205. Message_popH(8)
  206. #define Message_epush8 Message_epush8h
  207. #define Message_epop8 Message_epop8h
  208. Message_pushPop(16)
  209. Message_pushPop(32)
  210. Message_pushPop(64)
  211. #define Message_epush16le(msg, x) Message_epush16h(msg, Endian_hostToLittleEndian16(x))
  212. #define Message_epush32le(msg, x) Message_epush16h(msg, Endian_hostToLittleEndian32(x))
  213. #define Message_epush64le(msg, x) Message_epush16h(msg, Endian_hostToLittleEndian64(x))
  214. #define Message_epush16be(msg, x) Message_epush16h(msg, Endian_hostToBigEndian16(x))
  215. #define Message_epush32be(msg, x) Message_epush32h(msg, Endian_hostToBigEndian32(x))
  216. #define Message_epush64be(msg, x) Message_epush64h(msg, Endian_hostToBigEndian64(x))
  217. #endif