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