2 * UCW Library -- A simple growing buffer
4 * (c) 2004, Robert Spalek <robert@ucw.cz>
5 * (c) 2005, Martin Mares <mj@ucw.cz>
7 * Define the following macros:
9 * GBUF_TYPE data type of records stored in the buffer
10 * GBUF_PREFIX(x) add a name prefix to all global symbols
11 * GBUF_TRACE(msg...) log growing of buffer [optional]
13 * This software may be freely distributed and used according to the terms
14 * of the GNU Lesser General Public License.
18 * Type identifier of the buffer.
19 * The macro is not available outside the header file,
20 * but it is used in the definitions of functions.
22 #define BUF_T GBUF_PREFIX(t)
26 * `ptr` holds the memory and `len` is the current
27 * length of available memory.
29 typedef struct BUF_T {
35 * Initializes an empty growing buffer in @b.
37 static inline void GBUF_PREFIX(init)(BUF_T *b)
44 * Frees all memory in the buffer and returns it
47 static void UNUSED GBUF_PREFIX(done)(BUF_T *b)
56 * Sets the length of the buffer @b to exactly @len.
57 * Do not use for the growing (you can use this at the end,
58 * when you know the exact size), it would be slow.
60 * Use <<fun__GENERIC_LINK_|GBUF_PREFIX|grow|,`GBUF_PREFIX(grow)()`>>
63 static void UNUSED GBUF_PREFIX(set_size)(BUF_T *b, size_t len)
66 b->ptr = xrealloc(b->ptr, len * sizeof(GBUF_TYPE));
68 GBUF_TRACE(STRINGIFY_EXPANDED(BUF_T) " growing to %zu items", len);
72 static void UNUSED GBUF_PREFIX(do_grow)(BUF_T *b, size_t len)
74 if (len < 2*b->len) // to ensure logarithmic cost
76 GBUF_PREFIX(set_size)(b, len);
80 * Sets the size of the buffer @b to at last @len.
81 * It grows in exponential manner, to ensure the total cost
82 * of reallocs is linear with the final size.
84 * You can tweak the final size (when you do not need to grow
86 * <<fun__GENERIC_LINK_|GBUF_PREFIX|set_size|,`GBUF_PREFIX(set_size)()`>>.
88 static inline GBUF_TYPE *GBUF_PREFIX(grow)(BUF_T *b, size_t len)
90 if (unlikely(len > b->len))
91 GBUF_PREFIX(do_grow)(b, len);