1.Dd December 4, 2000 2.Dt sf_sbuf 3 3.Os 4.Sh NAME 5.Nm sbuf_init , 6.Nm sbuf_free , 7.Nm sbuf_clear , 8.Nm sbuf_zero , 9.Nm sbuf_add , 10.Nm sbuf_add2 , 11.Nm sbuf_trim, 12.Nm sbuf_detach , 13.Nm sbuf_extend , 14.Nm sbuf_sprintf , 15.Nm sbuf_vsprintf, 16.Nm sbuf_fetch , 17.Nm sbuf_fgets 18.Nd smart buffers manipulation functions 19.Sh SYNOPSIS 20.Fd #include <strfunc.h> 21.Pp 22Create, and destroy the buffer 23.Ft sbuf * 24.Fn sbuf_init "void" 25.Ft void 26.Fn sbuf_free "sbuf *sb" 27.Pp 28Clean and truncate the buffer 29.Ft int 30.Fn sbuf_clear "sbuf *sb" 31.Pp 32Just clean the buffer 33.Ft int 34.Fn sbuf_zero "sbuf *sb" 35.Pp 36Add values to the end of the buffer 37.Ft ssize_t 38.Fn sbuf_add "sbuf *sb" "conat char *string" 39.Ft ssize_t 40.Fn sbuf_add2 "sbuf *sb" "const void *data" "size_t nbytes" 41.Pp 42Trim buffer from left or right side 43.Ft ssize_t 44.Fn sbuf_trim "sbuf *sb" "int _from_left" "size_t nbytes" 45.Pp 46Detach the buffer contents 47.Ft char * 48.Fn sbuf_detach "sbuf *sb" "size_t *optLength" "size_t *optSize" 49.Pp 50Extend the buffer 51.Ft ssize_t 52.Fn sbuf_extend "sbuf *" "size_t upto" 53.Pp 54Add the formatted string 55.Ft ssize_t 56.Fn sbuf_sprintf "sbuf *" "const char *fmt" "..." 57.Ft ssize_t 58.Fn sbuf_vsprintf "sbuf *" "const char *fmt" "va_list ap" 59.Pp 60Get a first len characters or token 61.Ft char * 62.Fn sbuf_fetch "sbuf *" "size_t optLen" "char *optDelimiter" "size_t *optRetLen" "int flags" 63.Pp 64Get a line from the stream 65.Ft char * 66.Fn sbuf_fgets "sbuf *" "FILE *stream" 67.Pp 68.Sh DESCRIPTION 69These routines give the user a method of manipulating smart buffers. Smart 70buffers are used to omit headache of checking the buffer boundaries every 71time you're trying to add something. 72.Pp 73Buffers may be used to handle any types of data. Internally, the buffer 74always contain the terminating NULL and thus significiantly simplifies 75the string handling. 76.Pp 77Here is the sbuf structure (public): 78.Bd -literal 79typedef struct { 80 char *buf; /* The buffer data */ 81 size_t len; /* Offset to end of real data ('\0') */ 82 size_t size; /* Allocated memory */ 83 size_t off; /* Offset to start of real data */ 84} sbuf; 85 86.Ed 87The following macros are available for your convenience 88.Bd -literal 89#define sbuf2ptr(sb) ((sb)->buf + (sb)->off) 90#define sbuf_len(sb) ((sb)->len - (sb)->off) /* Meaningful length */ 91.Ed 92.Pp 93To create a buffer, you must invoke 94.Fn sbuf_init 95first. After all the necessary operations, the 96.Em sbuf * 97structure must be disposed with 98.Fn sbuf_free . 99.Pp 100After the buffer is created, you might want to add a data to the buffer. 101It can be done using 102.Fn sbuf_add "sbuf *sb" "const char *string" 103and 104.Fn sbuf_add2 "sbuf *sb" "const void *data" "size_t nbytes" 105functions. The second function does not rely on ASCIIZ idea and places the 106.Em nbytes 107of the 108.Em data 109into the smart buffer. Both functions automatically extend buffer to fit 110all the characters provided. In case of error, the functions will return -1 111and the buffer will be left intact. 112Upon success, 113.Fn sbuf_add 114returns with the number of written bytes and 115.Fn sbuf_add2 116returns with the adjusted 117.Nm len 118field of the passed 119.Nm sbuf * 120structure. Otherwise a -1 is returned by both functions. 121.Pp 122.Fn sbuf_trim 123trims given number of characters off the buffer from the left or right side, 124returning a number of bytes actually trimmed (which may be less than requested 125in case the actual buffer length is smaller). This is a zero-cost operation, 126as it just shifts pointers. 127.Pp 128.Fn sbuf_detach 129used to detach the buffer from the smart buffer descriptor, and return 130a pointer to that detached memory. If 131the optional 132.Em optLength 133or 134.Em optSize 135are given, 136.Fn sbuf_detach 137will fill them with the actual values of the buffer length (number of 138meaningful bytes) and buffer size (allocated memory) appropriately. 139Upon detach, the smart buffer descriptor will be re-initialized 140to contain new, empty buffer. After detaching, the buffer descriptor 141.Em ( sbuf ) 142will be reinitialized (read "empty"). 143.Pp 144To pre-extend the buffer up to the specified size, use 145.Fn sbuf_extend . 146This function will also clear the buffer from the current position 147.Em ( sb->len ) 148to the end of the allocated memory. 149.Pp 150.Fn sbuf_sprintf 151and 152.Fn sbuf_vsprintf 153functions used to add the formatted string to the end of the buffer. 154These functions returns the number of bytes actually writen. Buffer 155will be automatically extended to fit the string. In case of error, 156-1 will be returned and buffer will be left intact. See the 157manual pages on 158.Xr sprintf 3 159and 160.Xr vsprintf 3 161to learn more. 162.Pp 163.Fn sbuf_fetch 164used to fetch the substring or token from the start of the buffer. 165If 166.Em optLen 167argument is zero 168.Em optDdelimiter 169must contain the set of delimiting characters, overwise ignored. 170The 171.Em flags 172argument controls the behavior of splitting routinge most like 173in 174.Xr splitf 3 175function, with exception that the buffer can't be split by regular expression. 176.Em optRetLen 177will contain the length of returned string. 178.Ed 179.Pp 180.Fn sbuf_fgets 181is analogous to plain 182.Xr fgets 3 , 183but has the significant feature. It adds the whole line from the given 184stream to the buffer and returns the pointer. The buffer is reallocated 185to suffice the memory requirements by this line. 186.Pp 187.Sh RETURN VALUES 188All functions returning 189.Ft ssize_t 190may fail with -1 and the set errno to the appropriate value. 191.Pp 192All functions returning pointer values 193.Ft ( sbuf * , 194.Ft char * ) 195may fail with NULL and the set errno to the appropriate value. 196.Pp 197By default, functions may not fail with ENOMEM unless the library 198memory control behavior was changed, see 199.Xr sf_mem 3 . 200.Sh EXAMPLE 201Here is an example of creating and filling the smart buffer. 202.Bd -literal 203void main() { 204 sbuf *sb; /* Declare a buffer pointer */ 205 206 sb=sbuf_init(); /* Create and initialize buffer */ 207 208 /* Add some data */ 209 sbuf_add(sb, "one\en"); 210 sbuf_add2(sb, "two\en", sizeof("two\en") - 1); 211 212 /* This will print: 213 * "one\entwo\en" 214 */ 215 printf("%s", sb->buf); 216 217 /* Add the formatted string */ 218 sbuf_sprintf(sb, "one: %d\en", 1); 219 220 /* This will print: 221 * "one\entwo\enone: 1\en" 222 */ 223 printf("%s", sb->buf); 224 225 /* Destroy the buffer */ 226 sbuf_free(sb); 227}; 228.Ed 229.Pp 230Here is an example of reading the stream line-by-line. 231.Bd -literal 232void readfile(FILE *stream) { 233 sbuf *sb; 234 char *p; 235 236 sb = sbuf_init(); 237 238 while((p = sbuf_fgets(sb, stream) != NULL) { 239 printf("Read line: %s", p); 240 241 /* Rewind buffer */ 242 sbuf_zero(sb); 243 }; 244 245 sbuf_free(sb); 246}; 247.Ed 248.Pp 249.Sh SEE ALSO 250.Xr strfunc 3 , 251.Xr splitf 3 , 252.Xr sprintf 3 , 253.Xr fgets 3 . 254.Sh AUTHORS 255.An Lev Walkin <vlm@lionet.info> 256