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