]> git.ozlabs.org Git - ccan/blob - ccan/rbuf/rbuf.h
base64: fix for unsigned chars (e.g. ARM).
[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 #include <ccan/membuf/membuf.h>
9
10 struct rbuf {
11         int fd;
12         MEMBUF(char) m;
13 };
14
15 /**
16  * rbuf_init - set up a buffer.
17  * @rbuf: the struct rbuf.
18  * @fd: the file descriptor.
19  * @buf: the buffer to use.
20  * @buf_max: the size of the buffer.
21  * @expandfn: usually membuf_realloc.
22  */
23 static inline void rbuf_init(struct rbuf *rbuf,
24                              int fd, char *buffer, size_t buf_max,
25                              void *(*expandfn)(struct membuf *, void *, size_t))
26 {
27         rbuf->fd = fd;
28         membuf_init(&rbuf->m, buffer, buf_max, expandfn);
29 }
30
31 /**
32  * rbuf_open - set up a buffer by opening a file.
33  * @rbuf: the struct rbuf.
34  * @filename: the filename
35  * @buf: the buffer to use.
36  * @buf_max: the size of the buffer.
37  * @expandfn: usually membuf_realloc.
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, membuf_realloc))
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                void *(*expandfn)(struct membuf *, void *, size_t));
50
51 /**
52  * rbuf_good_size - get a good buffer size for this fd.
53  * @fd: the file descriptor.
54  *
55  * If you don't know what size you want, try this.
56  */
57 size_t rbuf_good_size(int fd);
58
59 /**
60  * rbuf_fill - read into a buffer if it's empty.
61  * @rbuf: the struct rbuf
62  *
63  * If @expandfn fails, rbuf_fill will return NULL (with errno set to ENOMEM).
64  * If a read fails, then NULL is also returned.  If there is nothing more to
65  * read, it will return NULL with errno set to 0.  Otherwise, returns first
66  * populated bytes (aka. rbuf_start()); rbuf_len() is the valid length of the
67  * buffer.
68  *
69  * You need to call rbuf_consume() to mark data in the buffer as
70  * consumed.
71  *
72  * Example:
73  *      while (rbuf_fill(&in)) {
74  *              printf("%.*s\n", (int)rbuf_len(&in), rbuf_start(&in));
75  *              rbuf_consume(&in, rbuf_len(&in));
76  *      }
77  *      if (errno)
78  *              err(1, "reading foo");
79  */
80 void *rbuf_fill(struct rbuf *rbuf);
81
82 /**
83  * rbuf_consume - helper to use up data in a buffer.
84  * @rbuf: the struct rbuf
85  * @len: the length (from @buf->start) you used.
86  *
87  * After rbuf_fill() you should indicate the data you've used with
88  * rbuf_consume().  That way rbuf_fill() will know if it has anything
89  * to do.
90  */
91 static inline void rbuf_consume(struct rbuf *rbuf, size_t len)
92 {
93         membuf_consume(&rbuf->m, len);
94 }
95
96 /**
97  * rbuf_len - helper to determine how many bytes in rbuf
98  * @rbuf: the struct rbuf
99  */
100 static inline size_t rbuf_len(const struct rbuf *rbuf)
101 {
102         return membuf_num_elems(&rbuf->m);
103 }
104
105 /**
106  * rbuf_start - helper to get pointert to unconsumed bytes in rbuf
107  * @rbuf: the struct rbuf
108  */
109 static inline char *rbuf_start(const struct rbuf *rbuf)
110 {
111         return membuf_elems(&rbuf->m);
112 }
113
114 /**
115  * rbuf_fill_all - read rest of file into a buffer.
116  * @rbuf: the struct rbuf
117  *
118  * If a read or @expandfn fails then NULL returned, otherwise returns
119  * @rbuf->start.
120  *
121  * Example:
122  *      if (!rbuf_fill_all(&in))
123  *              err(1, "reading foo");
124  */
125 void *rbuf_fill_all(struct rbuf *rbuf);
126
127 /**
128  * rbuf_read_str - fill into a buffer up to a terminator, and consume string.
129  * @rbuf: the struct rbuf
130  * @term: the character to terminate the read.
131  *
132  * If a read or @expandfn fails, then NULL is returned, otherwise the next
133  * string.  It replaces the terminator @term (if any) with NUL, otherwise NUL
134  * is placed after EOF.  If you need to, you can tell this has happened
135  * because the nul terminator will be at rbuf_start(@rbuf) (normally it will be
136  * at rbuf_start(@rbuf) - 1).
137  *
138  * If there is nothing remaining to be read, NULL is returned with
139  * errno set to 0, unless @term is NUL, in which case it returns the
140  * empty string.
141  *
142  * Note: using @term set to NUL is a cheap way of getting an entire
143  * file into a C string, as long as the file doesn't contain NUL.
144  *
145  * Example:
146  *      char *line;
147  *
148  *      line = rbuf_read_str(&in, '\n');
149  *      if (!line) {
150  *              if (errno)
151  *                      err(1, "reading foo");
152  *              else
153  *                      printf("Empty file\n");
154  *      } else
155  *              printf("First line is %s\n", line);
156  *
157  */
158 char *rbuf_read_str(struct rbuf *rbuf, char term);
159
160 /**
161  * rbuf_cleanup - reset rbuf, return buffer for freeing.
162  * @rbuf: the struct rbuf
163  *
164  * The rbuf will be empty after this, and crash if you try to use it.
165  * You can rbuf_init() it again, however.
166  *
167  * Example:
168  *      free(rbuf_cleanup(&in));
169  */
170 static inline char *rbuf_cleanup(struct rbuf *rbuf)
171 {
172         return membuf_cleanup(&rbuf->m);
173 }
174 #endif /* CCAN_RBUF_H */