1 /* dynbuf.h 2 ** dynamic (growable) buffer 3 ** wcm, 2004.04.21 - 2012.08.04 4 ** === 5 */ 6 #ifndef DYNBUF_H 7 #define DYNBUF_H 8 9 #include <stddef.h> /* size_t */ 10 #include <unistd.h> /* ssize_t */ 11 12 #define DYNBUF_INITSIZE 1 13 14 struct dynbuf { 15 void *buf; 16 size_t n; /* actual size allocated */ 17 size_t p; /* current position (aka "length", "used") */ 18 }; 19 typedef struct dynbuf dynbuf_t; 20 21 /* constructor for malloc'ed dynbuf: */ 22 extern dynbuf_t * dynbuf_new(void); 23 24 /* destructor for malloc'ed dynbuf: */ 25 extern void dynbuf_free(dynbuf_t *); 26 27 /* dynbuf_INIT() 28 ** static dynbuf object initialization 29 ** usage: 30 ** dynbuf_t dyn = dynbuf_INIT(); 31 ** 32 ** should be preferred to: 33 ** dynbuf_t d = {0,0,0}; 34 */ 35 #define dynbuf_INIT() {NULL, 0, 0} 36 37 /* release internal buffer only: */ 38 extern void dynbuf_freebuf(dynbuf_t *); 39 40 /* no memory release, just set d->p = 0 */ 41 extern void dynbuf_clear(dynbuf_t *); 42 #define dynbuf_CLEAR(d) ((d)->p = 0) 43 44 /* accessors: */ 45 extern void * dynbuf_buf(dynbuf_t *); 46 extern size_t dynbuf_len(dynbuf_t *); 47 /* accessor macros: */ 48 #define dynbuf_BUF(d) ((d)->buf) 49 #define dynbuf_LEN(d) ((d)->p) 50 51 /* if necessary, grow to accomodate total need */ 52 /* return -1 error, 0 no error */ 53 extern int dynbuf_need(dynbuf_t *, size_t need); 54 55 /* if necessary, grow to accomodate additional add */ 56 /* return -1 error, 0 no error */ 57 extern int dynbuf_grow(dynbuf_t *, size_t add); 58 59 /* dynbuf_put*() functions: 60 ** "put" means _append_ to dynbuf 61 ** 62 ** return -1 on error, 0 no error 63 */ 64 extern int dynbuf_put(dynbuf_t *to, const dynbuf_t *from); 65 extern int dynbuf_putbuf(dynbuf_t *, const void *buf, size_t len); 66 67 /* dynbuf_putb() 68 ** append single byte to buffer 69 */ 70 extern int dynbuf_putb(dynbuf_t *, unsigned char b); 71 72 /* dynbuf_putc() 73 ** append single char 74 ** note: 75 ** requires char argument in a string, eg: 76 ** dynbuf_putc(d, "K") 77 ** note: 78 ** **deprecated** 79 ** see dynbuf_putb() 80 */ 81 #define dynbuf_putc(d,c) dynbuf_putbuf((d),&(c),1) 82 83 /* dynbuf_puts() 84 ** str is NUL terminated, 85 ** NUL is _not_ copied into dynbuf 86 */ 87 extern int dynbuf_puts(dynbuf_t *, const char *str); 88 89 /* append '\0' to buffer: */ 90 extern int dynbuf_putnul(dynbuf_t *); 91 #define dynbuf_putNUL(d,c) dynbuf_putb((d),'\0') 92 93 /* "copy" buf into dynbuf, overwriting previous contents: */ 94 extern int dynbuf_copy(dynbuf_t *to, const dynbuf_t *from); 95 extern int dynbuf_copybuf(dynbuf_t *, const void *buf, size_t len); 96 97 /* 98 ** str is NUL terminated, 99 ** NUL is _not_ copied into dynbuf 100 */ 101 extern int dynbuf_copys(dynbuf_t *, const char *str); 102 103 /* dynbuf_pack() 104 ** pack variable number of uintXX_t arguments specified in fmt into dynbuf 105 ** fmt specification: 106 ** 'b': 1 byte uchar_t 107 ** 's': 2 bytes uint16_t 108 ** 'd': 4 bytes uint32_t 109 ** 'L': 8 bytes uint64_t 110 ** 111 ** return: 112 ** >= 0 : number of bytes packed 113 ** -1 : error, errno set 114 ** 115 ** errno values include: 116 ** EINVAL: unknown specifier in fmt 117 ** ENOMEM: allocation failure 118 ** 119 ** notes: 120 ** dynbuf version of upak_pack() 121 */ 122 extern ssize_t dynbuf_pack(dynbuf_t *, const char *fmt, ...); 123 124 #endif /* DYNBUF_H */ 125