]> mj.ucw.cz Git - libucw.git/blob - lib/gbuf.h
Replaced the long-lived "close(0) if logging to file" hack by closing
[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 #define BUF_T   GBUF_PREFIX(t)
18
19 typedef struct
20 {
21   uns len;
22   GBUF_TYPE *ptr;
23 }
24 BUF_T;
25
26 static inline void
27 GBUF_PREFIX(init)(BUF_T *b)
28 {
29   b->ptr = NULL;
30   b->len = 0;
31 }
32
33 static void UNUSED
34 GBUF_PREFIX(done)(BUF_T *b)
35 {
36   if (b->ptr)
37     xfree(b->ptr);
38   b->ptr = NULL;
39   b->len = 0;
40 }
41
42 static void UNUSED
43 GBUF_PREFIX(set_size)(BUF_T *b, uns len)
44 {
45   b->len = len;
46   b->ptr = xrealloc(b->ptr, len * sizeof(GBUF_TYPE));
47 #ifdef GBUF_TRACE
48   GBUF_TRACE(STRINGIFY_EXPANDED(BUF_T) " growing to %u items", len);
49 #endif
50 }
51
52 static void UNUSED
53 GBUF_PREFIX(do_grow)(BUF_T *b, uns len)
54 {
55   if (len < 2*b->len)                   // to ensure logarithmic cost
56     len = 2*b->len;
57   GBUF_PREFIX(set_size)(b, len);
58 }
59
60 static inline GBUF_TYPE *
61 GBUF_PREFIX(grow)(BUF_T *b, uns len)
62 {
63   if (unlikely(len > b->len))
64     GBUF_PREFIX(do_grow)(b, len);
65   return b->ptr;
66 }
67
68 #undef  GBUF_TYPE
69 #undef  GBUF_PREFIX
70 #undef  GBUF_TRACE
71 #undef  BUF_T