1 /* MIT (BSD) license - see LICENSE file for details */
2 #include <ccan/membuf/membuf.h>
7 void membuf_init_(struct membuf *mb,
8 void *elems, size_t num_elems, size_t elemsize,
9 void *(*expandfn)(struct membuf *, void *, size_t))
12 mb->start = mb->end = 0;
13 mb->max_elems = num_elems;
15 mb->expandfn = expandfn;
18 size_t membuf_prepare_space_(struct membuf *mb,
19 size_t num_extra, size_t elemsize)
21 char *oldstart = membuf_elems_(mb, elemsize);
23 /* Always reset in the trivial empty case. */
24 if (mb->start == mb->end)
25 mb->start = mb->end = 0;
27 if (membuf_num_space_(mb) >= num_extra)
30 /* There are two ways to make space: enlarge buffer, and memmove
31 * down. We use a simple heuristic: if we are using less than half
32 * the buffer, and memmove would get us sufficient space, do that. */
33 if (membuf_num_elems_(mb) <= mb->max_elems / 2
34 && membuf_num_elems_(mb) + num_extra <= mb->max_elems) {
35 memmove(mb->elems, oldstart, (mb->end - mb->start) * elemsize);
41 /* Since we're going to expand, at least double. */
42 if (num_extra < mb->max_elems)
43 num_extra = mb->max_elems;
45 expand = mb->expandfn(mb, mb->elems,
46 (mb->max_elems + num_extra) * elemsize);
50 mb->max_elems += num_extra;
54 return (char *)membuf_elems_(mb, elemsize) - oldstart;
57 void *membuf_realloc(struct membuf *mb, void *rawelems, size_t newsize)
59 return realloc(rawelems, newsize);