chiark / gitweb /
@@@ wip type definitions in manpage synopses
[mLib] / buf / pkbuf.3
1 .\" -*-nroff-*-
2 .TH pkbuf 3 "16 July 2000" "Straylight/Edgeware" "mLib utilities library"
3 .SH "NAME"
4 pkbuf \- split packets out of asynchronously received blocks
5 .\" @pkbuf_flush
6 .\" @pkbuf_close
7 .\" @pkbuf_free
8 .\" @pkbuf_snarf
9 .\" @pkbuf_want
10 .\" @pkbuf_init
11 .\" @pkbuf_destroy
12 .SH "SYNOPSIS"
13 .nf
14 .B "#include <mLib/pkbuf.h>"
15
16 .B "enum {"
17 .B "\h'4n'PKBUF_ENABLE = ..."
18 .B "};"
19
20 .B "typedef struct {"
21 .B "\h'4n'unsigned f;"
22 .B "\h'4n'..."
23 .B "} pkbuf;"
24
25 .ds mT \fBtypedef void pkbuf_func(
26 .B "\*(mToctet *" b ", size_t " sz ", pkbuf *" p ,
27 .BI "\h'\w'\*(mT'u'size_t *" keep ", void *" p );
28
29 .BI "void pkbuf_flush(pkbuf *" pk ", octet *" p ", size_t " len );
30 .BI "void pkbuf_close(pkbuf *" pk );
31 .BI "size_t pkbuf_free(pkbuf *" pk ", octet **" p );
32 .BI "void pkbuf_snarf(pkbuf *" pk ", const void *" p ", size_t " sz );
33 .BI "void pkbuf_want(pkbuf *" pk ", size_t " want );
34 .BI "void pkbuf_init(pkbuf *" pk ", pkbuf_func *" func ", void *" p );
35 .BI "void pkbuf_destroy(pkbuf *" pk );
36 .fi
37 .SH "DESCRIPTION"
38 The declarations in
39 .B <mLib/pkbuf.h>
40 implement a
41 .IR "packet buffer" .
42 Given unpredictably-sized chunks of data, the packet buffer extracts
43 completed packets of data, with sizes ascertained by a handler
44 function.
45 .PP
46 The state of a packet buffer is stored in an object of type
47 .BR pkbuf .
48 This is a structure which must be allocated by the caller.  The
49 structure should normally be considered opaque (see the section on
50 .B Disablement
51 for an exception to this).
52 .SS "Initialization and finalization"
53 The function
54 .B pkbuf_init
55 initializes a packet buffer ready for use.  It is given three arguments:
56 .TP
57 .BI "pkbuf *" pk
58 A pointer to the block of memory to use for the packet buffer.  The packet
59 buffer will allocate memory to store incoming data automatically: this
60 structure just contains bookkeeping information.
61 .TP
62 .BI "pkbuf_func *" func
63 The
64 .I packet-handler
65 function to which the packet buffer should pass packets of data when
66 they're received.  See
67 .B "Packet breaking and the handler function"
68 below.
69 .TP
70 .BI "void *" p
71 A pointer argument to be passed to the function when a packet arrives.
72 .PP
73 By default, the buffer is
74 allocated from the current arena,
75 .BR arena_global (3);
76 this may be changed by altering the buffer's
77 .B a
78 member to refer to a different arena at any time when the buffer is
79 unallocated.
80 .PP
81 A packet buffer must be destroyed after use by calling
82 .BR pkbuf_destroy ,
83 passing it the address of the buffer block.
84 .SS "Inserting data into the buffer"
85 There are two interfaces for inserting data into the buffer.  One's much
86 simpler than the other, although it's less expressive.
87 .PP
88 The simple interface is
89 .BR pkbuf_snarf .
90 This function is given three arguments: a pointer
91 .I pk
92 to a packet buffer structure; a pointer
93 .I p
94 to a chunk of data to read; and the size
95 .I sz
96 of the chunk of data.  The data is pushed through the packet buffer and
97 any complete packets are passed on to the packet handler.
98 .PP
99 The complex interface is the pair of functions
100 .I pkbuf_free
101 and
102 .IR pkbuf_flush .
103 .PP
104 The
105 .B pkbuf_free
106 function returns the address and size of a free portion of the packet
107 buffer's memory into which data may be written.  The function is passed
108 the address
109 .I pk
110 of the packet buffer.  Its result is the size of the free area, and it
111 writes the base address of this free space to the location pointed to by
112 the argument
113 .IR p .
114 The caller's data must be written to ascending memory locations starting
115 at
116 .BI * p
117 and no data may be written beyond the end of the free space.  However,
118 it isn't necessary to completely fill the buffer.
119 .PP
120 Once the free area has had some data written to it,
121 .B pkbuf_flush
122 is called to examine the new data and break it into packets.  This is
123 given three arguments:
124 .TP
125 .BI "pkbuf *" pk
126 The address of the packet buffer.
127 .TP
128 .BI "octet *" p
129 The address at which the new data has been written.  This must be the
130 base address returned from
131 .BR pkbuf_free .
132 .TP
133 .BI "size_t " len
134 The number of bytes which have been written to the buffer.
135 .PP
136 The
137 .B pkbuf_flush
138 function breaks the new data into packets as described below, and passes
139 each one in turn to the packet-handler function.
140 .PP
141 The
142 .B pkbuf_snarf
143 function is trivially implemented in terms of the more complex
144 .BR pkbuf_free / pkbuf_flush
145 interface.
146 .SS "Packet breaking and the handler function"
147 The function
148 .B pkbuf_want
149 is used to inform the packet buffer of the expected length of the next
150 packet.  It is given the pointer
151 .I pk
152 to the packet buffer and a size
153 .I sz
154 of the packet.
155 .PP
156 When enough data has arrived, the packet-handler function is called.  It
157 is passed:
158 .TP
159 .BI "octet *" b
160 A pointer to the packet data in the buffer, or zero to signify
161 end-of-file.
162 .TP
163 .BI "size_t " sz
164 The size of the packet, as previously configured via
165 .BR pkbuf_want .
166 .TP
167 .BI "pkbuf *" pk
168 A pointer to the packet buffer.
169 .TP
170 .BI "size_t *" keep
171 A location in which to store the number of bytes of the current packet
172 to be retained.  The bytes kept are from the end of the current packet:
173 if you want to keep bytes from the beginning of the packet, you should
174 move them into the right place.
175 .TP
176 .BI "void *" p
177 The pointer which was set up in the call to
178 .BR pkbuf_init .
179 .PP
180 .SS "Flushing the remaining data"
181 When the client program knows that there's no more data arriving (for
182 example, an end-of-file condition exists on its data source) it should
183 call the function
184 .BR pkbuf_close .
185 This will call the handler one final time with a null pointer to inform
186 it of the end-of-file.
187 .SS "Disablement"
188 The packet buffer is intended to be used in higher-level program
189 objects, such as the packet selector described in
190 .BR selpk (3).
191 Unfortunately, a concept from this high level needs to exist at the
192 packet buffer level, which complicates the description somewhat.  The
193 idea is that, when a packet-handler attached to some higher-level object
194 decides that it's read enough, it can
195 .I disable
196 the object so that it doesn't see any more data.
197 .PP
198 Clearly, since an
199 .B pkbuf_flush
200 call can emit more than one packet, it must be aware that the packet
201 handler isn't interested in any more packet.  However, this fact must
202 also be signalled to the higher-level object so that it can detach
203 itself from its data source.
204 .PP
205 Rather than invent some complex interface for this, the packet buffer
206 exports one of its structure members, a flags words called
207 .BR f .
208 A higher-level object wishing to disable the packet buffer simply clears
209 the bit
210 .B PKBUF_ENABLE
211 in this flags word.
212 .PP
213 Disabling a buffer causes an immediate return from
214 .BR pkbuf_flush .
215 However, it is not permitted for the functions
216 .B pkbuf_flush
217 or
218 .B pkbuf_close
219 to be called on a disabled buffer.  (This condition isn't checked for;
220 it'll just do the wrong thing.)  Furthermore, the
221 .B pkbuf_snarf
222 function does not handle disablement at all, because it would complicate
223 the interface so much that it wouldn't have any advantage over the more
224 general
225 .BR pkbuf_free / pkbuf_flush .
226 .SH "SEE ALSO"
227 .BR lbuf (3),
228 .BR selpk (3),
229 .BR mLib (3).
230 .SH "AUTHOR"
231 Mark Wooding, <mdw@distorted.org.uk>