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