rbuf.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /* Licensed under BSD-MIT - see LICENSE file for details */
  2. #ifndef CCAN_RBUF_H
  3. #define CCAN_RBUF_H
  4. #include <stdio.h> // For size_t
  5. #include <limits.h> // For UCHAR_MAX
  6. #include <assert.h>
  7. #include <stdbool.h>
  8. struct rbuf {
  9. int fd;
  10. /* Where to read next. */
  11. char *start;
  12. /* How much of what is there is valid. */
  13. size_t len;
  14. /* The entire buffer memory we have to work with. */
  15. char *buf, *buf_end;
  16. };
  17. /**
  18. * rbuf_init - set up a buffer.
  19. * @buf: the struct rbuf.
  20. * @fd: the file descriptor.
  21. * @buf: the buffer to use.
  22. * @buf_max: the size of the buffer.
  23. */
  24. static inline void rbuf_init(struct rbuf *buf,
  25. int fd, char *buffer, size_t buf_max)
  26. {
  27. buf->fd = fd;
  28. buf->start = buf->buf = buffer;
  29. buf->len = 0;
  30. buf->buf_end = buffer + buf_max;
  31. }
  32. /**
  33. * rbuf_open - set up a buffer by opening a file.
  34. * @buf: the struct rbuf.
  35. * @filename: the filename
  36. * @buf: the buffer to use.
  37. * @buf_max: the size of the buffer.
  38. *
  39. * Returns false if the open fails. If @buf_max is 0, then the buffer
  40. * will be resized to rbuf_good_size() on first rbuf_fill.
  41. *
  42. * Example:
  43. * struct rbuf in;
  44. *
  45. * if (!rbuf_open(&in, "foo", NULL, 0))
  46. * err(1, "Could not open foo");
  47. */
  48. bool rbuf_open(struct rbuf *rbuf, const char *name, char *buf, size_t buf_max);
  49. /**
  50. * rbuf_good_size - get a good buffer size for this fd.
  51. * @fd: the file descriptor.
  52. *
  53. * If you don't know what size you want, try this.
  54. */
  55. size_t rbuf_good_size(int fd);
  56. /**
  57. * rbuf_fill - read into a buffer if it's empty.
  58. * @buf: the struct rbuf
  59. * @resize: the call to resize the buffer.
  60. *
  61. * If @resize is needed and is NULL, or returns false, rbuf_read will
  62. * return NULL (with errno set to ENOMEM). If a read fails, then NULL
  63. * is also returned. If there is nothing more to read, it will return
  64. * NULL with errno set to 0. Otherwise, returns @buf->start; @buf->len
  65. * is the valid length of the buffer.
  66. *
  67. * You need to call rbuf_consume() to mark data in the buffer as
  68. * consumed.
  69. *
  70. * Example:
  71. * while (rbuf_fill(&in, realloc)) {
  72. * printf("%.*s\n", (int)in.len, in.start);
  73. * rbuf_consume(&in, in.len);
  74. * }
  75. * if (errno)
  76. * err(1, "reading foo");
  77. */
  78. void *rbuf_fill(struct rbuf *rbuf, void *(*resize)(void *buf, size_t len));
  79. /**
  80. * rbuf_consume - helper to use up data in a buffer.
  81. * @buf: the struct rbuf
  82. * @len: the length (from @buf->start) you used.
  83. *
  84. * After rbuf_fill() you should indicate the data you've used with
  85. * rbuf_consume(). That way rbuf_fill() will know if it has anything
  86. * to do.
  87. */
  88. static inline void rbuf_consume(struct rbuf *buf, size_t len)
  89. {
  90. buf->len -= len;
  91. buf->start += len;
  92. }
  93. /**
  94. * rbuf_fill_all - read rest of file into a buffer.
  95. * @buf: the struct rbuf
  96. * @resize: the call to resize the buffer.
  97. *
  98. * If @resize is needed and is NULL, or returns false, rbuf_read_all
  99. * will return NULL (with errno set to ENOMEM). If a read fails,
  100. * then NULL is also returned, otherwise returns @buf->start.
  101. *
  102. * Example:
  103. * if (!rbuf_fill_all(&in, realloc)) {
  104. * if (errno)
  105. * err(1, "reading foo");
  106. * }
  107. */
  108. void *rbuf_fill_all(struct rbuf *rbuf, void *(*resize)(void *buf, size_t len));
  109. /**
  110. * rbuf_read_str - fill into a buffer up to a terminator, and consume string.
  111. * @buf: the struct rbuf
  112. * @term: the character to terminate the read.
  113. * @resize: the call to resize the buffer.
  114. *
  115. * If @resize is needed and is NULL, or returns false, rbuf_read_str
  116. * will return NULL (with errno set to ENOMEM). If a read fails,
  117. * then NULL is also returned, otherwise the next string. It
  118. * replaces the terminator @term (if any) with NUL, otherwise NUL
  119. * is placed after EOF. If you need to, you can tell this has happened
  120. * because the nul terminator will be at @buf->start (normally it will
  121. * be at @buf->start - 1).
  122. *
  123. * If there is nothing remaining to be read, NULL is returned with
  124. * errno set to 0, unless @term is NUL, in which case it returns the
  125. * empty string.
  126. *
  127. * Note: using @term set to NUL is a cheap way of getting an entire
  128. * file into a C string, as long as the file doesn't contain NUL.
  129. *
  130. * Example:
  131. * char *line;
  132. *
  133. * line = rbuf_read_str(&in, '\n', realloc);
  134. * if (!line) {
  135. * if (errno)
  136. * err(1, "reading foo");
  137. * else
  138. * printf("Empty file\n");
  139. * } else
  140. * printf("First line is %s\n", line);
  141. *
  142. */
  143. char *rbuf_read_str(struct rbuf *rbuf, char term,
  144. void *(*resize)(void *buf, size_t len));
  145. #endif /* CCAN_RBUF_H */