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