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