]> mj.ucw.cz Git - libucw.git/blob - lib/gbuf.h
log() is now signal-safe.
[libucw.git] / lib / gbuf.h
1 /*
2  *      UCW Library -- A simple growing buffer
3  *
4  *      (c) 2004, Robert Spalek <robert@ucw.cz>
5  *      (c) 2005, Martin Mares <mj@ucw.cz>
6  *
7  *      Define the following macros:
8  *
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]
12  *
13  *      This software may be freely distributed and used according to the terms
14  *      of the GNU Lesser General Public License.
15  */
16
17 #include <stdlib.h>
18
19 #define BUF_T   GBUF_PREFIX(t)
20
21 typedef struct
22 {
23   uns len;
24   GBUF_TYPE *ptr;
25 }
26 BUF_T;
27
28 static inline void
29 GBUF_PREFIX(init)(BUF_T *b)
30 {
31   b->ptr = NULL;
32   b->len = 0;
33 }
34
35 static void UNUSED
36 GBUF_PREFIX(done)(BUF_T *b)
37 {
38   if (b->ptr)
39     xfree(b->ptr);
40   b->ptr = NULL;
41   b->len = 0;
42 }
43
44 static void UNUSED
45 GBUF_PREFIX(set_size)(BUF_T *b, uns len)
46 {
47   b->len = len;
48   b->ptr = xrealloc(b->ptr, len * sizeof(GBUF_TYPE));
49 #ifdef GBUF_TRACE
50   GBUF_TRACE(STRINGIFY_EXPANDED(BUF_T) " growing to %u items", len);
51 #endif
52 }
53
54 static void UNUSED
55 GBUF_PREFIX(do_grow)(BUF_T *b, uns len)
56 {
57   if (len < 2*b->len)                   // to ensure logarithmic cost
58     len = 2*b->len;
59   GBUF_PREFIX(set_size)(b, len);
60 }
61
62 static inline GBUF_TYPE *
63 GBUF_PREFIX(grow)(BUF_T *b, uns len)
64 {
65   if (unlikely(len > b->len))
66     GBUF_PREFIX(do_grow)(b, len);
67   return b->ptr;
68 }
69
70 #undef  GBUF_TYPE
71 #undef  GBUF_PREFIX
72 #undef  GBUF_TRACE
73 #undef  BUF_T