stream.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*
  2. * Packet interface
  3. * Copyright (C) 1999 Kunihiro Ishiguro
  4. *
  5. * This file is part of GNU Zebra.
  6. *
  7. * GNU Zebra is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation; either version 2, or (at your option) any
  10. * later version.
  11. *
  12. * GNU Zebra is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with GNU Zebra; see the file COPYING. If not, write to the Free
  19. * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  20. * 02111-1307, USA.
  21. */
  22. #ifndef _ZEBRA_STREAM_H
  23. #define _ZEBRA_STREAM_H
  24. #include "prefix.h"
  25. /*
  26. * A stream is an arbitrary buffer, whose contents generally are assumed to
  27. * be in network order.
  28. *
  29. * A stream has the following attributes associated with it:
  30. *
  31. * - size: the allocated, invariant size of the buffer.
  32. *
  33. * - getp: the get position marker, denoting the offset in the stream where
  34. * the next read (or 'get') will be from. This getp marker is
  35. * automatically adjusted when data is read from the stream, the
  36. * user may also manipulate this offset as they wish, within limits
  37. * (see below)
  38. *
  39. * - endp: the end position marker, denoting the offset in the stream where
  40. * valid data ends, and if the user attempted to write (or
  41. * 'put') data where that data would be written (or 'put') to.
  42. *
  43. * These attributes are all size_t values.
  44. *
  45. * Constraints:
  46. *
  47. * 1. getp can never exceed endp
  48. *
  49. * - hence if getp is equal to endp, there is no more valid data that can be
  50. * gotten from the stream (though, the user may reposition getp to earlier in
  51. * the stream, if they wish).
  52. *
  53. * 2. endp can never exceed size
  54. *
  55. * - hence, if endp is equal to size, then the stream is full, and no more
  56. * data can be written to the stream.
  57. *
  58. * In other words the following must always be true, and the stream
  59. * abstraction is allowed internally to assert that the following property
  60. * holds true for a stream, as and when it wishes:
  61. *
  62. * getp <= endp <= size
  63. *
  64. * It is the users responsibility to ensure this property is never violated.
  65. *
  66. * A stream therefore can be thought of like this:
  67. *
  68. * ---------------------------------------------------
  69. * |XXXXXXXXXXXXXXXXXXXXXXXX |
  70. * ---------------------------------------------------
  71. * ^ ^ ^
  72. * getp endp size
  73. *
  74. * This shows a stream containing data (shown as 'X') up to the endp offset.
  75. * The stream is empty from endp to size. Without adjusting getp, there are
  76. * still endp-getp bytes of valid data to be read from the stream.
  77. *
  78. * Methods are provided to get and put to/from the stream, as well as
  79. * retrieve the values of the 3 markers and manipulate the getp marker.
  80. *
  81. * Note:
  82. * At the moment, newly allocated streams are zero filled. Hence, one can
  83. * use stream_forward_endp() to effectively create arbitrary zero-fill
  84. * padding. However, note that stream_reset() does *not* zero-out the
  85. * stream. This property should **not** be relied upon.
  86. *
  87. * Best practice is to use stream_put (<stream *>, NULL, <size>) to zero out
  88. * any part of a stream which isn't otherwise written to.
  89. */
  90. /* Stream buffer. */
  91. struct stream
  92. {
  93. struct stream *next;
  94. /* Remainder is ***private*** to stream
  95. * direct access is frowned upon!
  96. * Use the appropriate functions/macros
  97. */
  98. size_t getp; /* next get position */
  99. size_t endp; /* last valid data position */
  100. size_t size; /* size of data segment */
  101. unsigned char *data; /* data pointer */
  102. };
  103. /* First in first out queue structure. */
  104. struct stream_fifo
  105. {
  106. size_t count;
  107. struct stream *head;
  108. struct stream *tail;
  109. };
  110. /* Utility macros. */
  111. #define STREAM_SIZE(S) ((S)->size)
  112. /* number of bytes which can still be written */
  113. #define STREAM_WRITEABLE(S) ((S)->size - (S)->endp)
  114. /* number of bytes still to be read */
  115. #define STREAM_READABLE(S) ((S)->endp - (S)->getp)
  116. #define STREAM_CONCAT_REMAIN(S1, S2, size) \
  117. ((size) - (S1)->endp - (S2)->endp)
  118. /* deprecated macros - do not use in new code */
  119. #define STREAM_PNT(S) stream_pnt((S))
  120. #define STREAM_DATA(S) ((S)->data)
  121. #define STREAM_REMAIN(S) STREAM_WRITEABLE((S))
  122. /* Stream prototypes.
  123. * For stream_{put,get}S, the S suffix mean:
  124. *
  125. * c: character (unsigned byte)
  126. * w: word (two bytes)
  127. * l: long (two words)
  128. * q: quad (four words)
  129. */
  130. extern struct stream *stream_new (size_t);
  131. extern void stream_free (struct stream *);
  132. extern struct stream * stream_copy (struct stream *, struct stream *src);
  133. extern struct stream *stream_dup (struct stream *);
  134. extern size_t stream_resize (struct stream *, size_t);
  135. extern size_t stream_get_getp (struct stream *);
  136. extern size_t stream_get_endp (struct stream *);
  137. extern size_t stream_get_size (struct stream *);
  138. extern u_char *stream_get_data (struct stream *);
  139. /**
  140. * Create a new stream structure; copy offset bytes from s1 to the new
  141. * stream; copy s2 data to the new stream; copy rest of s1 data to the
  142. * new stream.
  143. */
  144. extern struct stream *stream_dupcat(struct stream *s1, struct stream *s2,
  145. size_t offset);
  146. extern void stream_set_getp (struct stream *, size_t);
  147. extern void stream_set_endp (struct stream *, size_t);
  148. extern void stream_forward_getp (struct stream *, size_t);
  149. extern void stream_forward_endp (struct stream *, size_t);
  150. /* steam_put: NULL source zeroes out size_t bytes of stream */
  151. extern void stream_put (struct stream *, const void *, size_t);
  152. extern int stream_putc (struct stream *, u_char);
  153. extern int stream_putc_at (struct stream *, size_t, u_char);
  154. extern int stream_putw (struct stream *, u_int16_t);
  155. extern int stream_putw_at (struct stream *, size_t, u_int16_t);
  156. extern int stream_putl (struct stream *, u_int32_t);
  157. extern int stream_putl_at (struct stream *, size_t, u_int32_t);
  158. extern int stream_putq (struct stream *, uint64_t);
  159. extern int stream_putq_at (struct stream *, size_t, uint64_t);
  160. extern int stream_put_ipv4 (struct stream *, u_int32_t);
  161. extern int stream_put_in_addr (struct stream *, struct in_addr *);
  162. extern int stream_put_prefix (struct stream *, struct prefix *);
  163. extern void stream_get (void *, struct stream *, size_t);
  164. extern u_char stream_getc (struct stream *);
  165. extern u_char stream_getc_from (struct stream *, size_t);
  166. extern u_int16_t stream_getw (struct stream *);
  167. extern u_int16_t stream_getw_from (struct stream *, size_t);
  168. extern u_int32_t stream_getl (struct stream *);
  169. extern u_int32_t stream_getl_from (struct stream *, size_t);
  170. extern uint64_t stream_getq (struct stream *);
  171. extern uint64_t stream_getq_from (struct stream *, size_t);
  172. extern u_int32_t stream_get_ipv4 (struct stream *);
  173. /* IEEE-754 floats */
  174. extern float stream_getf (struct stream *);
  175. extern double stream_getd (struct stream *);
  176. extern int stream_putf (struct stream *, float);
  177. extern int stream_putd (struct stream *, double);
  178. #undef stream_read
  179. #undef stream_write
  180. /* Deprecated: assumes blocking I/O. Will be removed.
  181. Use stream_read_try instead. */
  182. extern int stream_read (struct stream *, int, size_t);
  183. /* Read up to size bytes into the stream.
  184. Return code:
  185. >0: number of bytes read
  186. 0: end-of-file
  187. -1: fatal error
  188. -2: transient error, should retry later (i.e. EAGAIN or EINTR)
  189. This is suitable for use with non-blocking file descriptors.
  190. */
  191. extern ssize_t stream_read_try(struct stream *s, int fd, size_t size);
  192. extern ssize_t stream_recvmsg (struct stream *s, int fd, struct msghdr *,
  193. int flags, size_t size);
  194. extern ssize_t stream_recvfrom (struct stream *s, int fd, size_t len,
  195. int flags, struct sockaddr *from,
  196. socklen_t *fromlen);
  197. extern size_t stream_write (struct stream *, const void *, size_t);
  198. /* reset the stream. See Note above */
  199. extern void stream_reset (struct stream *);
  200. /* move unread data to start of stream, discarding read data */
  201. extern void stream_discard (struct stream *);
  202. extern int stream_flush (struct stream *, int);
  203. extern int stream_empty (struct stream *); /* is the stream empty? */
  204. /* deprecated */
  205. extern u_char *stream_pnt (struct stream *);
  206. /* Stream fifo. */
  207. extern struct stream_fifo *stream_fifo_new (void);
  208. extern void stream_fifo_push (struct stream_fifo *fifo, struct stream *s);
  209. extern struct stream *stream_fifo_pop (struct stream_fifo *fifo);
  210. extern struct stream *stream_fifo_head (struct stream_fifo *fifo);
  211. extern void stream_fifo_clean (struct stream_fifo *fifo);
  212. extern void stream_fifo_free (struct stream_fifo *fifo);
  213. #endif /* _ZEBRA_STREAM_H */