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