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