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