zbuf.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /* Stream/packet buffer API
  2. * Copyright (c) 2014-2015 Timo Teräs
  3. *
  4. * This file is free software: you may copy, redistribute and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 2 of the License, or
  7. * (at your option) any later version.
  8. */
  9. #ifndef ZBUF_H
  10. #define ZBUF_H
  11. #include <stdint.h>
  12. #include <string.h>
  13. #include <endian.h>
  14. #include <sys/types.h>
  15. #include "zassert.h"
  16. #include "list.h"
  17. struct zbuf {
  18. struct list_head queue_list;
  19. unsigned allocated : 1;
  20. unsigned error : 1;
  21. uint8_t *buf, *end;
  22. uint8_t *head, *tail;
  23. };
  24. struct zbuf_queue {
  25. struct list_head queue_head;
  26. };
  27. struct zbuf *zbuf_alloc(size_t size);
  28. void zbuf_init(struct zbuf *zb, void *buf, size_t len, size_t datalen);
  29. void zbuf_free(struct zbuf *zb);
  30. static inline size_t zbuf_size(struct zbuf *zb)
  31. {
  32. return zb->end - zb->buf;
  33. }
  34. static inline size_t zbuf_used(struct zbuf *zb)
  35. {
  36. return zb->tail - zb->head;
  37. }
  38. static inline size_t zbuf_tailroom(struct zbuf *zb)
  39. {
  40. return zb->end - zb->tail;
  41. }
  42. static inline size_t zbuf_headroom(struct zbuf *zb)
  43. {
  44. return zb->head - zb->buf;
  45. }
  46. void zbuf_reset(struct zbuf *zb);
  47. void zbuf_reset_head(struct zbuf *zb, void *ptr);
  48. ssize_t zbuf_read(struct zbuf *zb, int fd, size_t maxlen);
  49. ssize_t zbuf_write(struct zbuf *zb, int fd);
  50. ssize_t zbuf_recv(struct zbuf *zb, int fd);
  51. ssize_t zbuf_send(struct zbuf *zb, int fd);
  52. static inline void zbuf_set_rerror(struct zbuf *zb)
  53. {
  54. zb->error = 1;
  55. zb->head = zb->tail;
  56. }
  57. static inline void zbuf_set_werror(struct zbuf *zb)
  58. {
  59. zb->error = 1;
  60. zb->tail = zb->end;
  61. }
  62. static inline void *__zbuf_pull(struct zbuf *zb, size_t size, int error)
  63. {
  64. void *head = zb->head;
  65. if (size > zbuf_used(zb)) {
  66. if (error) zbuf_set_rerror(zb);
  67. return NULL;
  68. }
  69. zb->head += size;
  70. return head;
  71. }
  72. #define zbuf_pull(zb, type) ((type *)__zbuf_pull(zb, sizeof(type), 1))
  73. #define zbuf_pulln(zb, sz) ((void *)__zbuf_pull(zb, sz, 1))
  74. #define zbuf_may_pull(zb, type) ((type *)__zbuf_pull(zb, sizeof(type), 0))
  75. #define zbuf_may_pulln(zb, sz) ((void *)__zbuf_pull(zb, sz, 0))
  76. void *zbuf_may_pull_until(struct zbuf *zb, const char *sep, struct zbuf *msg);
  77. static inline void zbuf_get(struct zbuf *zb, void *dst, size_t len)
  78. {
  79. void *src = zbuf_pulln(zb, len);
  80. if (src) memcpy(dst, src, len);
  81. }
  82. static inline uint8_t zbuf_get8(struct zbuf *zb)
  83. {
  84. uint8_t *src = zbuf_pull(zb, uint8_t);
  85. if (src) return *src;
  86. return 0;
  87. }
  88. static inline uint32_t zbuf_get32(struct zbuf *zb)
  89. {
  90. struct unaligned32 {
  91. uint32_t value;
  92. } __attribute__((packed));
  93. struct unaligned32 *v = zbuf_pull(zb, struct unaligned32);
  94. if (v) return v->value;
  95. return 0;
  96. }
  97. static inline uint16_t zbuf_get_be16(struct zbuf *zb)
  98. {
  99. struct unaligned16 {
  100. uint16_t value;
  101. } __attribute__((packed));
  102. struct unaligned16 *v = zbuf_pull(zb, struct unaligned16);
  103. if (v) return be16toh(v->value);
  104. return 0;
  105. }
  106. static inline uint32_t zbuf_get_be32(struct zbuf *zb)
  107. {
  108. return be32toh(zbuf_get32(zb));
  109. }
  110. static inline void *__zbuf_push(struct zbuf *zb, size_t size, int error)
  111. {
  112. void *tail = zb->tail;
  113. if (size > zbuf_tailroom(zb)) {
  114. if (error) zbuf_set_werror(zb);
  115. return NULL;
  116. }
  117. zb->tail += size;
  118. return tail;
  119. }
  120. #define zbuf_push(zb, type) ((type *)__zbuf_push(zb, sizeof(type), 1))
  121. #define zbuf_pushn(zb, sz) ((void *)__zbuf_push(zb, sz, 1))
  122. #define zbuf_may_push(zb, type) ((type *)__zbuf_may_push(zb, sizeof(type), 0))
  123. #define zbuf_may_pushn(zb, sz) ((void *)__zbuf_push(zb, sz, 0))
  124. static inline void zbuf_put(struct zbuf *zb, const void *src, size_t len)
  125. {
  126. void *dst = zbuf_pushn(zb, len);
  127. if (dst) memcpy(dst, src, len);
  128. }
  129. static inline void zbuf_put8(struct zbuf *zb, uint8_t val)
  130. {
  131. uint8_t *dst = zbuf_push(zb, uint8_t);
  132. if (dst) *dst = val;
  133. }
  134. static inline void zbuf_put_be16(struct zbuf *zb, uint16_t val)
  135. {
  136. struct unaligned16 {
  137. uint16_t value;
  138. } __attribute__((packed));
  139. struct unaligned16 *v = zbuf_push(zb, struct unaligned16);
  140. if (v) v->value = htobe16(val);
  141. }
  142. static inline void zbuf_put_be32(struct zbuf *zb, uint32_t val)
  143. {
  144. struct unaligned32 {
  145. uint32_t value;
  146. } __attribute__((packed));
  147. struct unaligned32 *v = zbuf_push(zb, struct unaligned32);
  148. if (v) v->value = htobe32(val);
  149. }
  150. void zbuf_copy(struct zbuf *zb, struct zbuf *src, size_t len);
  151. void zbufq_init(struct zbuf_queue *);
  152. void zbufq_reset(struct zbuf_queue *);
  153. void zbufq_queue(struct zbuf_queue *, struct zbuf *);
  154. int zbufq_write(struct zbuf_queue *, int);
  155. #endif