Mercurial > libbuf
annotate buf.h @ 14:1297027290b9
misc: add CHANGES.md
author | David Demelier <markand@malikania.fr> |
---|---|
date | Wed, 16 Dec 2020 15:41:26 +0100 |
parents | 9c6b686f797d |
children | 9f4f7a266c0b |
rev | line source |
---|---|
0 | 1 /* |
2 * buf.h -- simple string buffer for C | |
3 * | |
4 * Copyright (c) 2019-2020 David Demelier <markand@malikania.fr> | |
5 * | |
6 * Permission to use, copy, modify, and/or distribute this software for any | |
7 * purpose with or without fee is hereby granted, provided that the above | |
8 * copyright notice and this permission notice appear in all copies. | |
9 * | |
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
17 */ | |
18 | |
19 #ifndef BUF_H | |
20 #define BUF_H | |
21 | |
22 /** | |
23 * \file buf.h | |
24 * \brief Simple string buffer for C | |
25 * | |
26 * This module is meant to be copied directly into your source code and adapted | |
27 * to your needs. | |
28 * | |
29 * # Portability | |
30 * | |
31 * This module uses almost pure C99 functions without extensions but uses a few | |
32 * POSIX macros: ENOMEM. The errno global value won't be set if those macros | |
33 * are not present. | |
34 * | |
35 * It also requires the C99 features: `vsnprintf`, `va_copy`. | |
36 * | |
37 * # Allocation strategy | |
38 * | |
39 * This module will always try to allocate twice the existing buffer capacity | |
40 * unless it reaches an overflow. If overflow occurs, it will try to reallocate | |
41 * only the required portion instead. In any case, on 64-bits machine the | |
42 * maximum number is usually around 18.5PB which is far from what the system | |
43 * will allow. | |
44 * | |
45 * Functions use standard `malloc(3)`, `realloc(3)` and `free(3)` functions, if | |
46 * custom allocations are desired, simply edit buf.c and adapt BUF_ macros | |
47 * at the top of the file or set them at compile time. | |
48 */ | |
49 | |
50 #include <stdarg.h> | |
51 #include <stdbool.h> | |
52 #include <stddef.h> | |
53 | |
54 /* | |
55 * User/developer options. | |
56 * | |
57 * These macros are only used at compile time and can be redefined using | |
58 * preprocessor directives. | |
59 * | |
60 * - BUF_MALLOC: defaults to malloc | |
61 * - BUF_REALLOC: defaults to realloc | |
62 * - BUF_FREE: defaults to free | |
63 */ | |
64 | |
3
9c6b686f797d
misc: add extern C for C++ friends
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
65 /** |
9c6b686f797d
misc: add extern C for C++ friends
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
66 * \brief Function to allocate memory (defaults to malloc). |
9c6b686f797d
misc: add extern C for C++ friends
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
67 */ |
0 | 68 #if !defined(BUF_MALLOC) |
69 # define BUF_MALLOC malloc | |
70 #endif | |
71 | |
3
9c6b686f797d
misc: add extern C for C++ friends
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
72 /** |
9c6b686f797d
misc: add extern C for C++ friends
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
73 * \brief Function to reallocate memory (defaults to realloc). |
9c6b686f797d
misc: add extern C for C++ friends
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
74 */ |
0 | 75 #if !defined(BUF_REALLOC) |
76 # define BUF_REALLOC realloc | |
77 #endif | |
78 | |
3
9c6b686f797d
misc: add extern C for C++ friends
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
79 /** |
9c6b686f797d
misc: add extern C for C++ friends
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
80 * \brief Function to free memory (defaults to free). |
9c6b686f797d
misc: add extern C for C++ friends
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
81 */ |
0 | 82 #if !defined(BUF_FREE) |
83 # define BUF_FREE free | |
84 #endif | |
85 | |
3
9c6b686f797d
misc: add extern C for C++ friends
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
86 #if defined(__cplusplus) |
9c6b686f797d
misc: add extern C for C++ friends
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
87 extern "C" { |
9c6b686f797d
misc: add extern C for C++ friends
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
88 #endif |
9c6b686f797d
misc: add extern C for C++ friends
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
89 |
0 | 90 /** |
91 * \brief Buffer structure. | |
92 * | |
93 * You can initialize this structure with 0 before use. | |
94 * | |
95 * You may modify the data member yourself but make sure length member is set | |
96 * accordingly if you change its length. | |
97 * | |
98 * The capacity member contains the available size **without** including the | |
99 * null terminator, this means that a capacity of 5 means you can write 5 | |
100 * characters plus the null terminator as every function always allocate one | |
101 * more byte to terminate strings. | |
102 */ | |
103 struct buf { | |
104 char *data; /*!< String data. */ | |
105 size_t length; /*!< String length */ | |
106 size_t capacity; /*!< Capacity **not** including null */ | |
107 }; | |
108 | |
109 /** | |
110 * Initialize the string. | |
111 * | |
112 * This is equivalent to `memset(b, 0, sizeof (*b))`. | |
113 * | |
114 * \pre b != NULL | |
115 * \param b the buffer to initialize to 0 | |
116 */ | |
117 void | |
118 buf_init(struct buf *b); | |
119 | |
120 /** | |
121 * Reserve more storage to avoid reallocations. | |
122 * | |
123 * This function only change capacity and may reallocate the buffer, length | |
124 * is unchanged. | |
125 * | |
126 * \pre b != NULL | |
127 * \param b the buffer to grow | |
128 * \param desired the additional space to request | |
129 * \return false on error and sets errno | |
130 */ | |
131 bool | |
132 buf_reserve(struct buf *b, size_t desired); | |
133 | |
134 /** | |
135 * Resize the string and sets character into the new storage area if needed. | |
136 * | |
137 * In contrast to \ref buf_reserve, this function change the string length | |
3
9c6b686f797d
misc: add extern C for C++ friends
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
138 * and update the new storage with the given character. If the new size is |
0 | 139 * smaller then only length is updated, otherwise new memory can be reallocated |
140 * if needed. | |
141 * | |
142 * Use '\0' if you only want to change the length but still have a NUL | |
143 * terminated string. | |
144 * | |
145 * \pre b != NULL | |
146 * \param b the buffer to grow | |
3
9c6b686f797d
misc: add extern C for C++ friends
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
147 * \param size the new size to set |
0 | 148 * \param c the character to fill (use '\0' if not needed) |
149 * \return false on error and sets errno | |
150 */ | |
151 bool | |
152 buf_resize(struct buf *b, size_t size, char c); | |
153 | |
154 /** | |
155 * Reallocate the string to the string's length. | |
156 * | |
157 * If the function could not reallocate the memory, the old string buffer is | |
158 * kept so it is not strictly necessary to check the result. | |
159 * | |
160 * \pre b != NULL | |
161 * \param b the buffer to grow | |
162 * \return true if the string buffer was actually shrinked | |
163 */ | |
164 bool | |
165 buf_shrink(struct buf *b); | |
166 | |
167 /** | |
168 * Erase a portion of the string. | |
169 * | |
170 * \pre b != NULL | |
171 * \pre pos <= b->length | |
172 * \param b the string buffer | |
173 * \param pos the beginning of the portion | |
174 * \param count the number of characters to remove or -1 to remove up to the end | |
175 */ | |
176 void | |
177 buf_erase(struct buf *b, size_t pos, size_t count); | |
178 | |
179 /** | |
180 * Put a single character. | |
181 * | |
182 * \note This function can be slow for large amount of data. | |
183 * \pre b != NULL | |
184 * \param b the string buffer | |
185 * \param c the character to append | |
186 * \return false on error and sets errno | |
187 */ | |
188 bool | |
189 buf_putc(struct buf *b, char c); | |
190 | |
191 /** | |
192 * Put a string. | |
193 * | |
194 * \pre b != NULL | |
195 * \pre s != NULL | |
196 * \param b the string buffer | |
197 * \param s the string to append | |
198 * \return false on error and sets errno | |
199 */ | |
200 bool | |
201 buf_puts(struct buf *b, const char *s); | |
202 | |
203 /** | |
204 * Append to the string using printf(3) format. | |
205 * | |
206 * \pre b != NULL | |
207 * \pre fmt != NULL | |
208 * \param b the string buffer | |
209 * \param fmt the printf(3) format string | |
210 * \param ... additional arguments | |
211 * \return false on error and sets errno | |
212 */ | |
213 bool | |
214 buf_printf(struct buf *b, const char *fmt, ...); | |
215 | |
216 /** | |
217 * Similar to \ref buf_printf but using `va_list`. | |
218 * | |
219 * \pre b != NULL | |
220 * \pre fmt != NULL | |
221 * \param b the string buffer | |
222 * \param fmt the printf(3) format string | |
223 * \param ap the variadic arguments pointer | |
224 * \return false on error and sets errno | |
225 */ | |
226 bool | |
227 buf_vprintf(struct buf *b, const char *fmt, va_list ap); | |
228 | |
229 /** | |
230 * Cut a portion of the string pointed by src into b. | |
231 * | |
232 * The pointer b must not contain data as it will be overriden and may be let | |
233 * uninitialized. | |
234 * | |
235 * \pre b != NULL | |
236 * \pre src != NULL | |
237 * \pre pos <= b->length | |
238 * \param b the string buffer | |
239 * \param src the source origin | |
240 * \param pos the beginning of the portion | |
241 * \param count the number of characters to remove or -1 to split up to the end | |
242 * \return false on error and sets errno | |
243 */ | |
244 bool | |
245 buf_sub(struct buf *b, const struct buf *src, size_t pos, size_t count); | |
246 | |
247 /** | |
248 * Duplicate a string buffer. | |
249 * | |
250 * The pointer b must not contain data as it will be overriden and may be let | |
251 * uninitialized. | |
252 * | |
253 * \pre b != NULL | |
254 * \pre src != NULL | |
255 * \param b the string buffer | |
256 * \param src the source origin | |
257 * \return false on error and sets errno | |
258 */ | |
259 bool | |
260 buf_dup(struct buf *b, const struct buf *src); | |
261 | |
262 /** | |
263 * Clear the buffer. | |
264 * | |
265 * This function only change the string length, use \ref buf_shrink if you | |
266 * want to reduce memory usage. | |
267 * | |
268 * \pre b != NULL | |
269 * \param b the string to update | |
270 */ | |
271 void | |
272 buf_clear(struct buf *b); | |
273 | |
274 /** | |
275 * Clear the buffer. | |
276 * | |
277 * This function will effectively free the data member and set all members to | |
278 * 0. | |
279 * | |
280 * \pre b != NULL | |
281 * \param b the buffer to clear | |
282 */ | |
283 void | |
284 buf_finish(struct buf *b); | |
285 | |
3
9c6b686f797d
misc: add extern C for C++ friends
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
286 #if defined(__cplusplus) |
9c6b686f797d
misc: add extern C for C++ friends
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
287 } |
9c6b686f797d
misc: add extern C for C++ friends
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
288 #endif |
9c6b686f797d
misc: add extern C for C++ friends
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
289 |
0 | 290 #endif /* !BUF_H */ |