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 | |
14 | .B "#include <mLib/pkbuf.h>" | |
15 | ||
4729aa69 MW |
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 | ||
1e7e4330 | 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 ); | |
0daaeb18 | 34 | .BI "void pkbuf_init(pkbuf *" pk ", pkbuf_func *" func ", void *" p ); |
1e7e4330 | 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 | |
d4efbcd9 | 44 | function. |
1e7e4330 | 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 | |
0daaeb18 | 62 | .BI "pkbuf_func *" func |
1e7e4330 | 63 | The |
64 | .I packet-handler | |
65 | function to which the packet buffer should pass packets of data when | |
0daaeb18 | 66 | they're received. See |
67 | .B "Packet breaking and the handler function" | |
68 | below. | |
1e7e4330 | 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 | |
528c8b4d | 94 | to a chunk of data to read; and the size |
1e7e4330 | 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 | |
d4efbcd9 | 104 | The |
1e7e4330 | 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 | |
d4efbcd9 | 108 | the address |
1e7e4330 | 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 | |
528c8b4d | 144 | .BR pkbuf_free / pkbuf_flush |
1e7e4330 | 145 | interface. |
0daaeb18 | 146 | .SS "Packet breaking and the handler function" |
1e7e4330 | 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 | |
4729aa69 MW |
156 | When enough data has arrived, the packet-handler function is called. It |
157 | is passed: | |
1e7e4330 | 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 | |
528c8b4d | 200 | call can emit more than one packet, it must be aware that the packet |
1e7e4330 | 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 | |
3bc42912 | 206 | exports one of its structure members, a flags words called |
207 | .BR f . | |
1e7e4330 | 208 | A higher-level object wishing to disable the packet buffer simply clears |
209 | the bit | |
210 | .B PKBUF_ENABLE | |
3bc42912 | 211 | in this flags word. |
1e7e4330 | 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" | |
9b5ac6ff | 231 | Mark Wooding, <mdw@distorted.org.uk> |