chiark / gitweb /
001dc9a152417507d16f9ab4c86078ed57d11acf
[mLib] / buf / 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 .ta 2n
15 .B "#include <mLib/lbuf.h>"
16 .PP
17 .B "enum {"
18 .B "    LBUF_CRLF,"
19 .B "    LBUF_STRICTCRLF,"
20 .B "    ..."
21 .B "};"
22 .B "#define LBUF_ENABLE ..."
23 .PP
24 .B "typedef struct {"
25 .B "    unsigned f;"
26 .B "    ..."
27 .B "} lbuf;"
28 .PP
29 .B "typedef void lbuf_func(char *" s ", size_t " len ", void *" p );
30 .PP
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 );
38 .fi
39 .SH "DESCRIPTION"
40 The declarations in
41 .B <mLib/lbuf.h>
42 implement a handy object called a
43 .IR "line buffer" .
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
49 newline characters.
50 .PP
51 The state of a line buffer is stored in an object of type
52 .BR lbuf .
53 This is a structure which must be allocated by the caller.  The
54 structure should normally be considered opaque (see the section on
55 .B Disablement
56 for an exception to this).
57 .SS "Initialization and finalization"
58 The function
59 .B lbuf_init
60 initializes a line buffer ready for use.  It is given three arguments:
61 .TP
62 .BI "lbuf *" b
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.
66 .TP
67 .BI "lbuf_func *" func
68 The
69 .I line-handler
70 function to which the line buffer should pass completed lines of text.
71 See
72 .B "Line-handler functions"
73 below for a description of this function.
74 .TP
75 .BI "void *" p
76 A pointer argument to be passed to the function when a completed line of
77 text arrives.
78 .PP
79 The amount of memory set aside for reading lines is configurable.  It
80 may be set by calling
81 .B lbuf_setsize
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,
85 .BR arena_global (3);
86 this may be changed by altering the buffer's
87 .B a
88 member to refer to a different arena at any time when the buffer is
89 unallocated.
90 .PP
91 A line buffer must be destroyed after use by calling
92 .BR lbuf_destroy ,
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.
97 .PP
98 The simple interface is
99 .BR lbuf_snarf .
100 This function is given three arguments: a pointer
101 .I b
102 to a line buffer structure; a pointer
103 .I p
104 to a chunk of data to read; and the size
105 .I sz
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.
108 .PP
109 The complex interface is the pair of functions
110 .B lbuf_free
111 and
112 .BR lbuf_flush .
113 .PP
114 The
115 .B lbuf_free
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
118 the address
119 .I b
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
122 the argument
123 .IR p .
124 The caller's data must be written to ascending memory locations starting
125 at
126 .BI * p
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.
129 .PP
130 Once the free area has had some data written to it,
131 .B lbuf_flush
132 is called to examine the new data and break it into text lines.  This is
133 given three arguments:
134 .TP
135 .BI "lbuf *" b
136 The address of the line buffer.
137 .TP
138 .BI "char *" p
139 The address at which the new data has been written.  This must be the
140 base address returned from
141 .BR lbuf_free .
142 .TP
143 .BI "size_t " len
144 The number of bytes which have been written to the buffer.
145 .PP
146 The
147 .B lbuf_flush
148 function breaks the new data into lines as described below, and passes
149 each one in turn to the line-handler function.
150 .PP
151 The
152 .B lbuf_snarf
153 function is trivially implemented in terms of the more complex
154 .BR lbuf_free / lbuf_flush
155 interface.
156 .SS "Line breaking"
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
161 .B delim
162 member of the
163 .B lbuf
164 structure: the default value is
165 .BR LBUF_CRLF .
166 If set to
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.
170 .PP
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
176 line completely.
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
180 .I s
181 of the line which has just been read; the length
182 .I len
183 of the line (not including the null terminator), and the pointer
184 .I p
185 which was set up in the call to
186 .BR lbuf_init .
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.
191 .PP
192 The line pointer argument
193 .I s
194 may be null to signify end-of-file; in this case, the length
195 .I len
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
200 call the function
201 .BR lbuf_close
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
206 the end-of-file.
207 .SS "Disablement"
208 The line buffer is intended to be used in higher-level program objects,
209 such as the buffer selector described in
210 .BR selbuf (3).
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
215 .I disable
216 the object so that it doesn't see any more data.
217 .PP
218 Clearly, since an
219 .B lbuf_flush
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
223 its data source.
224 .PP
225 Rather than invent some complex interface for this, the line buffer
226 exports one of its structure members, a flags word called
227 .BR f .
228 A higher-level object wishing to disable the line buffer simply clears
229 the bit
230 .B LBUF_ENABLE
231 in this flags word.
232 .PP
233 Disabling a buffer causes an immediate return from
234 .BR lbuf_flush .
235 However, it is not permitted for the functions
236 .B lbuf_flush
237 or
238 .B lbuf_close
239 to be called on a disabled buffer.  (This condition isn't checked for;
240 it'll just do the wrong thing.)  Furthermore, the
241 .B lbuf_snarf
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
244 general
245 .BR lbuf_free / lbuf_flush .
246 .SH "SEE ALSO"
247 .BR selbuf (3),
248 .BR mLib (3).
249 .SH "AUTHOR"
250 Mark Wooding, <mdw@distorted.org.uk>