2 .TH pkbuf 3 "16 July 2000" "Straylight/Edgeware" "mLib utilities library"
4 pkbuf \- split packets out of asynchronously received blocks
14 .B "#include <mLib/pkbuf.h>"
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 ,
22 .BI " void (*" func ")(octet *" b ", size_t " sz ", pkbuf *" pk ,
23 .BI " size_t *" keep ", void *" p ),
25 .BI "void pkbuf_destroy(pkbuf *" pk );
32 Given unpredictably-sized chunks of data, the packet buffer extracts
33 completed packets of data, with sizes ascertained by a handler
36 The state of a packet buffer is stored in an object of type
38 This is a structure which must be allocated by the caller. The
39 structure should normally be considered opaque (see the section on
41 for an exception to this).
42 .SS "Initialization and finalization"
45 initializes a packet buffer ready for use. It is given three arguments:
48 A pointer to the block of memory to use for the packet buffer. The packet
49 buffer will allocate memory to store incoming data automatically: this
50 structure just contains bookkeeping information.
53 .BI "void (*" func ")(octet *" b ", size_t " sz ", pkbuf *" p ,
54 .BI " size_t *" keep ", void *" p )
58 function to which the packet buffer should pass packets of data when
62 A pointer argument to be passed to the function when a packet arrives.
64 By default, the buffer is
65 allocated from the current arena,
67 this may be changed by altering the buffer's
69 member to refer to a different arena at any time when the buffer is
72 A packet buffer must be destroyed after use by calling
74 passing it the address of the buffer block.
75 .SS "Inserting data into the buffer"
76 There are two interfaces for inserting data into the buffer. One's much
77 simpler than the other, although it's less expressive.
79 The simple interface is
81 This function is given three arguments: a pointer
83 to a packet buffer structure; a pointer
85 to a chunk of data to read; and the size
87 of the chunk of data. The data is pushed through the packet buffer and
88 any complete packets are passed on to the packet handler.
90 The complex interface is the pair of functions
97 function returns the address and size of a free portion of the packet
98 buffer's memory into which data may be written. The function is passed
101 of the packet buffer. Its result is the size of the free area, and it
102 writes the base address of this free space to the location pointed to by
105 The caller's data must be written to ascending memory locations starting
108 and no data may be written beyond the end of the free space. However,
109 it isn't necessary to completely fill the buffer.
111 Once the free area has had some data written to it,
113 is called to examine the new data and break it into packets. This is
114 given three arguments:
117 The address of the packet buffer.
120 The address at which the new data has been written. This must be the
121 base address returned from
125 The number of bytes which have been written to the buffer.
129 function breaks the new data into packets as described below, and passes
130 each one in turn to the packet-handler function.
134 function is trivially implemented in terms of the more complex
135 .B pkbuf_free / pkbuf_flush
137 .SS "Packet breaking and the handler fucntion"
140 is used to inform the packet buffer of the expected length of the next
141 packet. It is given the pointer
143 to the packet buffer and a size
147 When enough data has arrived, the packet-handler function is called, and
151 A pointer to the packet data in the buffer, or zero to signify
155 The size of the packet, as previously configured via
159 A pointer to the packet buffer.
162 A location in which to store the number of bytes of the current packet
163 to be retained. The bytes kept are from the end of the current packet:
164 if you want to keep bytes from the beginning of the packet, you should
165 move them into the right place.
168 The pointer which was set up in the call to
171 .SS "Flushing the remaining data"
172 When the client program knows that there's no more data arriving (for
173 example, an end-of-file condition exists on its data source) it should
176 This will call the handler one final time with a null pointer to inform
177 it of the end-of-file.
179 The packet buffer is intended to be used in higher-level program
180 objects, such as the packet selector described in
182 Unfortunately, a concept from this high level needs to exist at the
183 packet buffer level, which complicates the description somewhat. The
184 idea is that, when a packet-handler attached to some higher-level object
185 decides that it's read enough, it can
187 the object so that it doesn't see any more data.
191 call can emit more than one packet, so it must be aware that the packet
192 handler isn't interested in any more packet. However, this fact must
193 also be signalled to the higher-level object so that it can detach
194 itself from its data source.
196 Rather than invent some complex interface for this, the packet buffer
197 exports one of its structure members,
199 A higher-level object wishing to disable the packet buffer simply clears
204 Disabling a buffer causes an immediate return from
206 However, it is not permitted for the functions
210 to be called on a disabled buffer. (This condition isn't checked for;
211 it'll just do the wrong thing.) Furthermore, the
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
216 .BR pkbuf_free / pkbuf_flush .
222 Mark Wooding, <mdw@nsict.org>