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