@@@ much mess, mostly manpages
[mLib] / buf / lbuf.3.in
CommitLineData
05fbeb03 1.\" -*-nroff-*-
c4ccbbf9
MW
2.\"
3.\" Manual for line buffering
4.\"
5.\" (c) 1999--2003, 2005, 2007, 2009, 2023, 2024 Straylight/Edgeware
6.\"
7.
8.\"----- Licensing notice ---------------------------------------------------
9.\"
10.\" This file is part of the mLib utilities library.
11.\"
12.\" mLib is free software: you can redistribute it and/or modify it under
13.\" the terms of the GNU Library General Public License as published by
14.\" the Free Software Foundation; either version 2 of the License, or (at
15.\" your option) any later version.
16.\"
17.\" mLib is distributed in the hope that it will be useful, but WITHOUT
18.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
20.\" License for more details.
21.\"
22.\" You should have received a copy of the GNU Library General Public
23.\" License along with mLib. If not, write to the Free Software
24.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
25.\" USA.
26.
27.\"--------------------------------------------------------------------------
28.so ../defs.man \" @@@PRE@@@
29.
30.\"--------------------------------------------------------------------------
31.TH lbuf 3mLib "6 July 1999" "Straylight/Edgeware" "mLib utilities library"
05fbeb03 32.\" @lbuf_close
33.\" @lbuf_free
34.\" @lbuf_snarf
31e83d07 35.\" @lbuf_setsize
05fbeb03 36.\" @lbuf_init
31e83d07 37.\" @lbuf_destroy
c4ccbbf9
MW
38.
39.\"--------------------------------------------------------------------------
40.SH "NAME"
41lbuf \- split lines out of asynchronously received blocks
42.
43.\"--------------------------------------------------------------------------
05fbeb03 44.SH "SYNOPSIS"
c4ccbbf9 45.
05fbeb03 46.nf
adec5584 47.ta 2n
05fbeb03 48.B "#include <mLib/lbuf.h>"
d056fbdf 49.PP
4729aa69 50.B "enum {"
adec5584
MW
51.B " LBUF_CRLF,"
52.B " LBUF_STRICTCRLF,"
53.B " ..."
4729aa69
MW
54.B "};"
55.B "#define LBUF_ENABLE ..."
d056fbdf 56.PP
4729aa69 57.B "typedef struct {"
adec5584
MW
58.B " unsigned f;"
59.B " ..."
4729aa69 60.B "} lbuf;"
d056fbdf 61.PP
4729aa69 62.B "typedef void lbuf_func(char *" s ", size_t " len ", void *" p );
d056fbdf 63.PP
05fbeb03 64.BI "void lbuf_flush(lbuf *" b ", char *" p ", size_t " len );
c4ccbbf9 65.\" @lbuf_flush
05fbeb03 66.BI "void lbuf_close(lbuf *" b );
67.BI "size_t lbuf_free(lbuf *" b ", char **" p );
68.BI "void lbuf_snarf(lbuf *" b ", const void *" p ", size_t " sz );
cededfbe 69.BI "void lbuf_setsize(lbuf *" b ", size_t " sz );
83c63e03 70.BI "void lbuf_init(lbuf *" b ", lbuf_func *" func ", void *" p );
cededfbe 71.BI "void lbuf_destroy(lbuf *" b );
05fbeb03 72.fi
c4ccbbf9
MW
73.
74.\"--------------------------------------------------------------------------
05fbeb03 75.SH "DESCRIPTION"
c4ccbbf9 76.
05fbeb03 77The declarations in
78.B <mLib/lbuf.h>
79implement a handy object called a
80.IR "line buffer" .
81Given unpredictably-sized chunks of data, the line buffer extracts
82completed lines of text and passes them to a caller-supplied function.
83This is useful in nonblocking network servers, for example: the server
84can feed input from a client into a line buffer as it arrives and deal
85with completed text lines as they appear without having to wait for
86newline characters.
87.PP
88The state of a line buffer is stored in an object of type
89.BR lbuf .
90This is a structure which must be allocated by the caller. The
91structure should normally be considered opaque (see the section on
92.B Disablement
93for an exception to this).
c4ccbbf9 94.
05fbeb03 95.SS "Initialization and finalization"
96The function
97.B lbuf_init
98initializes a line buffer ready for use. It is given three arguments:
99.TP
ff76c38f 100.BI "lbuf *" b
31e83d07 101A pointer to the block of memory to use for the line buffer. The line
102buffer will allocate memory to store incoming data automatically: this
103structure just contains bookkeeping information.
05fbeb03 104.TP
83c63e03 105.BI "lbuf_func *" func
05fbeb03 106The
107.I line-handler
108function to which the line buffer should pass completed lines of text.
83c63e03 109See
110.B "Line-handler functions"
111below for a description of this function.
05fbeb03 112.TP
ff76c38f 113.BI "void *" p
05fbeb03 114A pointer argument to be passed to the function when a completed line of
115text arrives.
116.PP
cededfbe 117The amount of memory set aside for reading lines is configurable. It
118may be set by calling
119.B lbuf_setsize
120at any time when the buffer is empty. The default limit is 256 bytes.
121Lines longer than the limit are truncated. By default, the buffer is
122allocated from the current arena,
123.BR arena_global (3);
124this may be changed by altering the buffer's
125.B a
126member to refer to a different arena at any time when the buffer is
127unallocated.
128.PP
129A line buffer must be destroyed after use by calling
130.BR lbuf_destroy ,
131passing it the address of the buffer block.
c4ccbbf9 132.
05fbeb03 133.SS "Inserting data into the buffer"
134There are two interfaces for inserting data into the buffer. One's much
135simpler than the other, although it's less expressive.
136.PP
137The simple interface is
138.BR lbuf_snarf .
139This function is given three arguments: a pointer
140.I b
141to a line buffer structure; a pointer
142.I p
d0053e2e 143to a chunk of data to read; and the size
05fbeb03 144.I sz
145of the chunk of data. The data is pushed through the line buffer and
146any complete lines are passed on to the line handler.
147.PP
148The complex interface is the pair of functions
d0053e2e 149.B lbuf_free
05fbeb03 150and
d0053e2e 151.BR lbuf_flush .
05fbeb03 152.PP
d4efbcd9 153The
05fbeb03 154.B lbuf_free
155function returns the address and size of a free portion of the line
156buffer's memory into which data may be written. The function is passed
d4efbcd9 157the address
31e83d07 158.I b
05fbeb03 159of the line buffer. Its result is the size of the free area, and it
160writes the base address of this free space to the location pointed to by
161the argument
162.IR p .
163The caller's data must be written to ascending memory locations starting
164at
165.BI * p
166and no data may be written beyond the end of the free space. However,
167it isn't necessary to completely fill the buffer.
168.PP
169Once the free area has had some data written to it,
170.B lbuf_flush
171is called to examine the new data and break it into text lines. This is
172given three arguments:
173.TP
ff76c38f 174.BI "lbuf *" b
05fbeb03 175The address of the line buffer.
176.TP
ff76c38f 177.BI "char *" p
05fbeb03 178The address at which the new data has been written. This must be the
179base address returned from
180.BR lbuf_free .
181.TP
ff76c38f 182.BI "size_t " len
05fbeb03 183The number of bytes which have been written to the buffer.
184.PP
185The
186.B lbuf_flush
187function breaks the new data into lines as described below, and passes
188each one in turn to the line-handler function.
189.PP
190The
191.B lbuf_snarf
192function is trivially implemented in terms of the more complex
d0053e2e 193.BR lbuf_free / lbuf_flush
05fbeb03 194interface.
c4ccbbf9 195.
05fbeb03 196.SS "Line breaking"
83c63e03 197By default, the line buffer considers a line to end with either a simple
198linefeed character (the normal Unix convention) or a
199carriage-return/linefeed pair (the Internet convention). This can be
200changed by modifying the
201.B delim
202member of the
203.B lbuf
204structure: the default value is
205.BR LBUF_CRLF .
206If set to
207.BR LBUF_STRICTCRLF ,
208only a carriage-return/linefeed pair will terminate a line. Any other
209value is a single character which is considered to be the line terminator.
05fbeb03 210.PP
211The line buffer has a fixed amount of memory available to it. This is
212deliberate, to prevent a trivial attack whereby a remote user sends a
213stream of data containing no newline markers, wasting the server's
214memory. Instead, the buffer will truncate overly long lines (silently)
215and return only the initial portion. It will ignore the rest of the
216line completely.
c4ccbbf9 217.
05fbeb03 218.SS "Line-handler functions"
219Completed lines, as already said, are passed to the caller's
4729aa69 220line-handler function. It is given three arguments: the address
05fbeb03 221.I s
83c63e03 222of the line which has just been read; the length
223.I len
224of the line (not including the null terminator), and the pointer
05fbeb03 225.I p
226which was set up in the call to
d0053e2e 227.BR lbuf_init .
05fbeb03 228The line passed is null-terminated, and has had its trailing newline
229stripped. The area of memory in which the string is located may be
230overwritten by the line-handler function, although writing beyond the
231terminating zero byte is not permitted.
232.PP
233The line pointer argument
234.I s
83c63e03 235may be null to signify end-of-file; in this case, the length
236.I len
237will be zero. See the next section.
c4ccbbf9 238.
05fbeb03 239.SS "Flushing the remaining data"
240When the client program knows that there's no more data arriving (for
241example, an end-of-file condition exists on its data source) it should
242call the function
243.BR lbuf_close
244to flush out the remaining data in the buffer as one last (improperly
245terminated) line. This will pass the remaining text to the line
246handler, if there is any, and then call the handler one final time with
247a null pointer rather than the address of a text line to inform it of
248the end-of-file.
c4ccbbf9 249.
05fbeb03 250.SS "Disablement"
251The line buffer is intended to be used in higher-level program objects,
252such as the buffer selector described in
253.BR selbuf (3).
254Unfortunately, a concept from this high level needs to exist at the line
255buffer level, which complicates the description somewhat. The idea is
256that, when a line-handler attached to some higher-level object decides
257that it's read enough, it can
258.I disable
259the object so that it doesn't see any more data.
260.PP
261Clearly, since an
262.B lbuf_flush
528c8b4d 263call can emit more than one line, it must be aware that the line handler
264isn't interested in any more lines. However, this fact must also be
265signalled to the higher-level object so that it can detach itself from
266its data source.
05fbeb03 267.PP
268Rather than invent some complex interface for this, the line buffer
3bc42912 269exports one of its structure members, a flags word called
270.BR f .
05fbeb03 271A higher-level object wishing to disable the line buffer simply clears
272the bit
273.B LBUF_ENABLE
3bc42912 274in this flags word.
05fbeb03 275.PP
276Disabling a buffer causes an immediate return from
277.BR lbuf_flush .
278However, it is not permitted for the functions
279.B lbuf_flush
280or
281.B lbuf_close
282to be called on a disabled buffer. (This condition isn't checked for;
283it'll just do the wrong thing.) Furthermore, the
284.B lbuf_snarf
285function does not handle disablement at all, because it would complicate
286the interface so much that it wouldn't have any advantage over the more
287general
288.BR lbuf_free / lbuf_flush .
c4ccbbf9
MW
289.
290.\"--------------------------------------------------------------------------
05fbeb03 291.SH "SEE ALSO"
c4ccbbf9 292.
05fbeb03 293.BR selbuf (3),
294.BR mLib (3).
c4ccbbf9
MW
295.
296.\"--------------------------------------------------------------------------
05fbeb03 297.SH "AUTHOR"
c4ccbbf9 298.
9b5ac6ff 299Mark Wooding, <mdw@distorted.org.uk>
c4ccbbf9
MW
300.
301.\"----- That's all, folks --------------------------------------------------