2 .TH lbuf 3 "6 July 1999" "Straylight/Edgeware" "mLib utilities library"
4 lbuf \- split lines out of asynchronously received blocks
15 .B "#include <mLib/lbuf.h>"
19 .B " LBUF_STRICTCRLF,"
22 .B "#define LBUF_ENABLE ..."
29 .B "typedef void lbuf_func(char *" s ", size_t " len ", void *" p );
31 .BI "void lbuf_flush(lbuf *" b ", char *" p ", size_t " len );
32 .BI "void lbuf_close(lbuf *" b );
33 .BI "size_t lbuf_free(lbuf *" b ", char **" p );
34 .BI "void lbuf_snarf(lbuf *" b ", const void *" p ", size_t " sz );
35 .BI "void lbuf_setsize(lbuf *" b ", size_t " sz );
36 .BI "void lbuf_init(lbuf *" b ", lbuf_func *" func ", void *" p );
37 .BI "void lbuf_destroy(lbuf *" b );
42 implement a handy object called a
44 Given unpredictably-sized chunks of data, the line buffer extracts
45 completed lines of text and passes them to a caller-supplied function.
46 This is useful in nonblocking network servers, for example: the server
47 can feed input from a client into a line buffer as it arrives and deal
48 with completed text lines as they appear without having to wait for
51 The state of a line buffer is stored in an object of type
53 This is a structure which must be allocated by the caller. The
54 structure should normally be considered opaque (see the section on
56 for an exception to this).
57 .SS "Initialization and finalization"
60 initializes a line buffer ready for use. It is given three arguments:
63 A pointer to the block of memory to use for the line buffer. The line
64 buffer will allocate memory to store incoming data automatically: this
65 structure just contains bookkeeping information.
67 .BI "lbuf_func *" func
70 function to which the line buffer should pass completed lines of text.
72 .B "Line-handler functions"
73 below for a description of this function.
76 A pointer argument to be passed to the function when a completed line of
79 The amount of memory set aside for reading lines is configurable. It
82 at any time when the buffer is empty. The default limit is 256 bytes.
83 Lines longer than the limit are truncated. By default, the buffer is
84 allocated from the current arena,
86 this may be changed by altering the buffer's
88 member to refer to a different arena at any time when the buffer is
91 A line buffer must be destroyed after use by calling
93 passing it the address of the buffer block.
94 .SS "Inserting data into the buffer"
95 There are two interfaces for inserting data into the buffer. One's much
96 simpler than the other, although it's less expressive.
98 The simple interface is
100 This function is given three arguments: a pointer
102 to a line buffer structure; a pointer
104 to a chunk of data to read; and the size
106 of the chunk of data. The data is pushed through the line buffer and
107 any complete lines are passed on to the line handler.
109 The complex interface is the pair of functions
116 function returns the address and size of a free portion of the line
117 buffer's memory into which data may be written. The function is passed
120 of the line buffer. Its result is the size of the free area, and it
121 writes the base address of this free space to the location pointed to by
124 The caller's data must be written to ascending memory locations starting
127 and no data may be written beyond the end of the free space. However,
128 it isn't necessary to completely fill the buffer.
130 Once the free area has had some data written to it,
132 is called to examine the new data and break it into text lines. This is
133 given three arguments:
136 The address of the line buffer.
139 The address at which the new data has been written. This must be the
140 base address returned from
144 The number of bytes which have been written to the buffer.
148 function breaks the new data into lines as described below, and passes
149 each one in turn to the line-handler function.
153 function is trivially implemented in terms of the more complex
154 .BR lbuf_free / lbuf_flush
157 By default, the line buffer considers a line to end with either a simple
158 linefeed character (the normal Unix convention) or a
159 carriage-return/linefeed pair (the Internet convention). This can be
160 changed by modifying the
164 structure: the default value is
167 .BR LBUF_STRICTCRLF ,
168 only a carriage-return/linefeed pair will terminate a line. Any other
169 value is a single character which is considered to be the line terminator.
171 The line buffer has a fixed amount of memory available to it. This is
172 deliberate, to prevent a trivial attack whereby a remote user sends a
173 stream of data containing no newline markers, wasting the server's
174 memory. Instead, the buffer will truncate overly long lines (silently)
175 and return only the initial portion. It will ignore the rest of the
177 .SS "Line-handler functions"
178 Completed lines, as already said, are passed to the caller's
179 line-handler function. It is given three arguments: the address
181 of the line which has just been read; the length
183 of the line (not including the null terminator), and the pointer
185 which was set up in the call to
187 The line passed is null-terminated, and has had its trailing newline
188 stripped. The area of memory in which the string is located may be
189 overwritten by the line-handler function, although writing beyond the
190 terminating zero byte is not permitted.
192 The line pointer argument
194 may be null to signify end-of-file; in this case, the length
196 will be zero. See the next section.
197 .SS "Flushing the remaining data"
198 When the client program knows that there's no more data arriving (for
199 example, an end-of-file condition exists on its data source) it should
202 to flush out the remaining data in the buffer as one last (improperly
203 terminated) line. This will pass the remaining text to the line
204 handler, if there is any, and then call the handler one final time with
205 a null pointer rather than the address of a text line to inform it of
208 The line buffer is intended to be used in higher-level program objects,
209 such as the buffer selector described in
211 Unfortunately, a concept from this high level needs to exist at the line
212 buffer level, which complicates the description somewhat. The idea is
213 that, when a line-handler attached to some higher-level object decides
214 that it's read enough, it can
216 the object so that it doesn't see any more data.
220 call can emit more than one line, it must be aware that the line handler
221 isn't interested in any more lines. However, this fact must also be
222 signalled to the higher-level object so that it can detach itself from
225 Rather than invent some complex interface for this, the line buffer
226 exports one of its structure members, a flags word called
228 A higher-level object wishing to disable the line buffer simply clears
233 Disabling a buffer causes an immediate return from
235 However, it is not permitted for the functions
239 to be called on a disabled buffer. (This condition isn't checked for;
240 it'll just do the wrong thing.) Furthermore, the
242 function does not handle disablement at all, because it would complicate
243 the interface so much that it wouldn't have any advantage over the more
245 .BR lbuf_free / lbuf_flush .
250 Mark Wooding, <mdw@distorted.org.uk>