Commit | Line | Data |
---|---|---|
9b5ac6ff | 1 | .\" -*-nroff-*- |
2 | .de VS | |
3 | .sp 1 | |
4 | .RS | |
5 | .nf | |
6 | .ft B | |
7 | .. | |
8 | .de VE | |
9 | .ft R | |
10 | .fi | |
11 | .RE | |
12 | .sp 1 | |
13 | .. | |
14 | .de hP | |
15 | .IP | |
16 | .ft B | |
17 | \h'-\w'\\$1\ 'u'\\$1\ \c | |
18 | .ft P | |
19 | .. | |
20 | .ie t .ds o \(bu | |
21 | .el .ds o o | |
22 | .TH buf 3 "23 September 2005" "Straylight/Edgeware" "mLib utilities library" | |
23 | .SH NAME | |
24 | buf \- reading and writing stuff in buffers | |
25 | .\" @BBASE | |
26 | .\" @BLIM | |
27 | .\" @BCUR | |
28 | .\" @BSZ | |
29 | .\" @BLEN | |
30 | .\" @BLEFT | |
31 | .\" @BSTEP | |
32 | .\" @BBAD | |
33 | .\" @BOK | |
34 | .\" @BENSURE | |
35 | . | |
36 | .\" @buf_init | |
37 | .\" @buf_break | |
38 | .\" @buf_flip | |
39 | .\" @buf_ensure | |
40 | .\" @buf_get | |
41 | .\" @buf_put | |
42 | . | |
43 | .\" @buf_getbyte | |
44 | .\" @buf_putbyte | |
45 | . | |
46 | .\" @buf_getu8 | |
47 | .\" @buf_getu16 | |
48 | .\" @buf_getu16b | |
49 | .\" @buf_getu16l | |
50 | .\" @buf_getu24 | |
51 | .\" @buf_getu24b | |
52 | .\" @buf_getu24l | |
53 | .\" @buf_getu32 | |
54 | .\" @buf_getu32b | |
55 | .\" @buf_getu32l | |
56 | . | |
57 | .\" @buf_putu8 | |
58 | .\" @buf_putu16 | |
59 | .\" @buf_putu16b | |
60 | .\" @buf_putu16l | |
61 | .\" @buf_putu24 | |
62 | .\" @buf_putu24b | |
63 | .\" @buf_putu24l | |
64 | .\" @buf_putu32 | |
65 | .\" @buf_putu32b | |
66 | .\" @buf_putu32l | |
67 | . | |
68 | .\" @buf_getbuf8 | |
69 | .\" @buf_getbuf16 | |
70 | .\" @buf_getbuf16b | |
71 | .\" @buf_getbuf16l | |
72 | .\" @buf_getbuf24 | |
73 | .\" @buf_getbuf24b | |
74 | .\" @buf_getbuf24l | |
75 | .\" @buf_getbuf32 | |
76 | .\" @buf_getbuf32b | |
77 | .\" @buf_getbuf32l | |
78 | .\" @buf_getbufz | |
79 | . | |
80 | .\" @buf_putbuf8 | |
81 | .\" @buf_putbuf16 | |
82 | .\" @buf_putbuf16b | |
83 | .\" @buf_putbuf16l | |
84 | .\" @buf_putbuf24 | |
85 | .\" @buf_putbuf24b | |
86 | .\" @buf_putbuf24l | |
87 | .\" @buf_putbuf32 | |
88 | .\" @buf_putbuf32b | |
89 | .\" @buf_putbuf32l | |
90 | .\" @buf_putbufz | |
91 | . | |
92 | .\" @buf_getmem16 | |
93 | .\" @buf_getmem16b | |
94 | .\" @buf_getmem16l | |
95 | .\" @buf_getmem24 | |
96 | .\" @buf_getmem24b | |
97 | .\" @buf_getmem24l | |
98 | .\" @buf_getmem32 | |
99 | .\" @buf_getmem32b | |
100 | .\" @buf_getmem32l | |
101 | .\" @buf_getmem8 | |
102 | .\" @buf_getmemz | |
103 | . | |
104 | .\" @buf_putmem8 | |
105 | .\" @buf_putmem16 | |
106 | .\" @buf_putmem16b | |
107 | .\" @buf_putmem16l | |
108 | .\" @buf_putmem24 | |
109 | .\" @buf_putmem24b | |
110 | .\" @buf_putmem24l | |
111 | .\" @buf_putmem32 | |
112 | .\" @buf_putmem32b | |
113 | .\" @buf_putmem32l | |
114 | .\" @buf_putmemz | |
115 | . | |
116 | .\" @buf_putstr8 | |
117 | .\" @buf_putstr16 | |
118 | .\" @buf_putstr16b | |
119 | .\" @buf_putstr16l | |
120 | .\" @buf_putstr24 | |
121 | .\" @buf_putstr24b | |
122 | .\" @buf_putstr24l | |
123 | .\" @buf_putstr32 | |
124 | .\" @buf_putstr32b | |
125 | .\" @buf_putstr32l | |
126 | .\" @buf_putstrz | |
127 | . | |
128 | .\" @buf_getdstr8 | |
129 | .\" @buf_getdstr16 | |
130 | .\" @buf_getdstr16b | |
131 | .\" @buf_getdstr16l | |
132 | .\" @buf_getdstr24 | |
133 | .\" @buf_getdstr24b | |
134 | .\" @buf_getdstr24l | |
135 | .\" @buf_getdstr32 | |
136 | .\" @buf_getdstr32b | |
137 | .\" @buf_getdstr32l | |
138 | .\" @buf_getdstrz | |
139 | . | |
140 | .\" @buf_putdstr8 | |
141 | .\" @buf_putdstr16 | |
142 | .\" @buf_putdstr16b | |
143 | .\" @buf_putdstr16l | |
144 | .\" @buf_putdstr24 | |
145 | .\" @buf_putdstr24b | |
146 | .\" @buf_putdstr24l | |
147 | .\" @buf_putdstr32 | |
148 | .\" @buf_putdstr32b | |
149 | .\" @buf_putdstr32l | |
150 | .\" @buf_putdstrz | |
151 | .SH SYNOPSIS | |
152 | .nf | |
153 | .B "#include <mLib/dstr.h>" | |
154 | ||
4729aa69 MW |
155 | .B "typedef struct { ...\& } buf;" |
156 | ||
9b5ac6ff | 157 | .BI "void buf_init(buf *" b ", void *" p ", size_t " sz ); |
158 | .BI "void buf_flip(buf *" b ); | |
159 | .BI "octet *BBASE(buf *" b ); | |
160 | .BI "octet *BLIM(buf *" b ); | |
161 | .BI "octet *BCUR(buf *" b ); | |
162 | .BI "ptrdiff_t BSZ(buf *" b ); | |
163 | .BI "ptrdiff_t BLEN(buf *" b ); | |
164 | .BI "ptrdiff_t BLEFT(buf *" b ); | |
165 | ||
166 | .BI "int buf_break(buf *" b ); | |
167 | .BI "int BBAD(buf *" b ); | |
168 | .BI "int BOK(buf *" b ); | |
169 | ||
170 | .BI "int buf_ensure(buf *" b ", size_t " sz ); | |
171 | .BI "int BENSURE(buf *" b ", size_t " sz ); | |
5c819006 | 172 | .BI "octet *BSTEP(buf *" b ", size_t " sz ); |
9b5ac6ff | 173 | |
174 | .BI "void *buf_get(buf *" b ", size_t " sz ); | |
175 | .BI "void *buf_put(buf *" b ", const void *" p ", size_t " sz ); | |
176 | ||
177 | .BI "int buf_getbyte(buf *" b ); | |
178 | .BI "int buf_putbyte(buf *" b ", int ch" ); | |
179 | .BI "int buf_getu" suff "(buf *" b ", uint" suff " *" w ); | |
180 | .BI "int buf_putu" suff "(buf *" b ", uint" suff " " w ); | |
181 | .BI "void *buf_getmem" suff "(buf *" b ", size_t *" sz ); | |
182 | .BI "int buf_putmem" suff "(buf *" b ", const void *" p ", size_t " sz ); | |
183 | .BI "int buf_getbuf" suff "(buf *" b ", buf *" bb ); | |
184 | .BI "int buf_putbuf" suff "(buf *" b ", buf *" bb ); | |
185 | .BI "int buf_getdstr" suff "(buf *" b ", dstr *" d ); | |
186 | .BI "int buf_putdstr" suff "(buf *" b ", dstr *" d ); | |
187 | .BI "int buf_putstr" suff "(buf *" b ", const char *" p ); | |
188 | .fi | |
189 | .SH DESCRIPTION | |
190 | The | |
191 | .B buf | |
192 | interface allows relatively convenient reading and writing of structured | |
193 | binary data from and to fixed-size memory buffers. It's useful for | |
194 | formatting and parsing down network data packets, for example. | |
195 | .SS "Buffer basics" | |
196 | A buffer has three important pointers associated with it: | |
197 | .TP | |
198 | .I base | |
199 | The base address of the buffer. | |
200 | .TP | |
201 | .I limit | |
202 | Just past the last usable byte in the buffer | |
203 | .TP | |
204 | .I current | |
205 | The position in the buffer at which the next read or write will occur. | |
206 | .PP | |
207 | A buffer is created using the | |
208 | .B buf_init | |
209 | function. You must pass it the buffer base address and size, and a | |
d4efbcd9 | 210 | pointer to a |
9b5ac6ff | 211 | .B buf |
212 | structure to fill in. It doesn't allocate any memory, so you don't need | |
213 | to dispose of the | |
214 | .B buf | |
215 | structure in any way before forgetting about it. | |
216 | .PP | |
217 | A collection of macros is provided for finding the positions of the | |
218 | various interesting pointers known about a buffer, and the sizes of the | |
219 | regions of memory they imply. | |
220 | .TP | |
221 | .B BBASE | |
222 | The buffer's | |
223 | .I base | |
224 | pointer. | |
225 | .TP | |
226 | .B BLIM | |
227 | The buffer's | |
228 | .I limit | |
229 | pointer. | |
230 | .TP | |
231 | .B BCUR | |
232 | The buffer's | |
233 | .I current | |
234 | pointer. | |
235 | .TP | |
236 | .B BSZ | |
237 | The size of the buffer; i.e., | |
238 | .I limit | |
239 | \- | |
240 | .IR base . | |
241 | .TP | |
242 | .B BLEN | |
243 | The length of data in the buffer (if writing) or the amount of data | |
d4efbcd9 | 244 | read (if reading); i.e., |
9b5ac6ff | 245 | .I current |
246 | \- | |
247 | .IR base . | |
248 | .TP | |
249 | .B BLEFT | |
250 | The amount of space left in the buffer (if writing) or the amount of | |
251 | data yet to read (if reading); i.e., | |
252 | .I limit | |
253 | \- | |
254 | .IR current . | |
255 | .PP | |
256 | The function | |
257 | .B buf_flip | |
258 | takes a buffer which has been used for writing, and makes it suitable | |
259 | for reading. This turns out to be useful when building packets in | |
d4efbcd9 | 260 | multi-layered networking software. Its precise behaviour is to preserve |
9b5ac6ff | 261 | .IR base , |
262 | to set | |
263 | .I limit | |
264 | to | |
265 | .IR current , | |
d4efbcd9 | 266 | and to set |
9b5ac6ff | 267 | .I current |
268 | to | |
269 | .IR base . | |
270 | .PP | |
271 | A buffer can be | |
272 | .IR broken , | |
273 | to indicate that it has overflowed or that its contents are otherwise | |
274 | invalid. The various buffer access functions described below all fail | |
275 | on a broken buffer, and any errors they encounter cause the buffer to | |
276 | become broken. Most simple programs which only use the supplied buffer | |
277 | access functions can avoid the tedium of error-checking every function | |
278 | call and just check the brokenness state at the end of their run. | |
279 | .PP | |
280 | The function | |
281 | .B buf_break | |
282 | will break a buffer. The macro | |
283 | .B BBAD | |
284 | reports true (nonzero) if its buffer argument is broken, or false (zero) | |
285 | otherwise; its counterpart | |
286 | .B BOK | |
287 | reports true if the buffer is OK, and false if it is broken. | |
288 | .SS "Low-level buffer access" | |
289 | Access to the data in the buffer is usually sequential. The | |
290 | .B BENSURE | |
291 | macro (or the equivalent | |
292 | .B buf_ensure | |
293 | function) checks that the buffer is OK and that there is enough space | |
294 | remaining in the buffer for | |
295 | .I sz | |
296 | bytes: if so, it returns zero; otherwise it breaks the buffer and | |
297 | returns \-1. | |
298 | .PP | |
299 | The | |
300 | .B BSTEP | |
301 | macro advances the buffer's | |
302 | .I current | |
303 | pointer by | |
304 | .I sz | |
305 | bytes. It does no bounds checking. Together with | |
306 | .BR BENSURE , | |
307 | this provides sequential access to the buffer's contents. | |
308 | .PP | |
309 | The | |
310 | .B buf_get | |
311 | function is the basis of most buffer access functions, whether for | |
312 | reading or writing. If the buffer is OK, and there are | |
313 | .I sz | |
314 | or more bytes remaining, it steps the buffer's | |
315 | .I current | |
316 | pointer by | |
317 | .I sz | |
d4efbcd9 | 318 | and returns the |
9b5ac6ff | 319 | .I original |
320 | (pre-stepping) | |
321 | .I current | |
322 | pointer; otherwise it breaks the buffer if necessary, and returns a null | |
323 | pointer. | |
324 | .PP | |
325 | The | |
326 | .B buf_put | |
d4efbcd9 | 327 | function writes |
9b5ac6ff | 328 | .I sz |
329 | bytes of data starting at | |
330 | .I p | |
331 | to the buffer. If it succeeded, it returns 0; otherwise it returns \-1. | |
332 | .SS "Formatted buffer access" | |
333 | The function | |
334 | .B buf_getbyte | |
335 | returns the next byte from a buffer as a nonnegative integer, or \-1 on | |
336 | error. The function | |
337 | .B buf_putbyte | |
338 | writes its argument to a buffer, and returns 0 on succes; it returns \-1 | |
339 | if it failed. | |
340 | .PP | |
341 | Many of the remaining functions deal with integer formatting and buffer | |
342 | lengths. The functions support 8-, 16-, 24- and 32-bit integers, in | |
343 | big- or little-endian order; on platforms with 64-bit integers, these | |
344 | are supported too. The functions' names carry a suffix which is the | |
345 | width in bits of the integers they deal with and an optional | |
346 | .RB ` l ' | |
347 | for little- or | |
348 | .RB ` b ' | |
349 | for big-endian byte order. (The variant with no letter uses big-endian | |
350 | order. Use of these variants tends to mean `I don't really care, but be | |
351 | consistent,' and is not recommended if you have an externally-defined | |
352 | spec you're meant to be compatible with.) | |
353 | .PP | |
354 | The function | |
355 | .BI buf_getu suff | |
356 | reads an integer. On success, it stores the integer it read at the | |
357 | address | |
358 | .I w | |
359 | given, and returns zero; on failure, it returns \-1. The function | |
360 | .BI buf_putu suff | |
361 | write an integer. It returns zero on success or \-1 on failure. | |
362 | .PP | |
363 | Functions which deal with block lengths assume the length is prefixed to | |
364 | the data, and don't include themselves. They also have an additional | |
365 | .RB ` z ' | |
366 | variant, which deals with zero-terminated data. No checks are done on | |
367 | writing that the data written contains no zero bytes. | |
368 | .PP | |
369 | The function | |
370 | .BI buf_getmem suff | |
371 | fetches a block of data. On success, it returns its base address and | |
372 | stores its length at the given address; on failure, it returns null. | |
373 | The function | |
374 | .BI buf_putmem suff | |
375 | writes a block of data; it return zero on success or \-1 on failure. | |
376 | .PP | |
377 | The functon | |
378 | .BI buf_getbuf suff | |
379 | fetches a block of data and makes a second buffer point to it, i.e., | |
380 | setting its | |
381 | .I base | |
382 | and | |
383 | .I current | |
384 | pointers to the start of the block and its | |
385 | .I limit | |
386 | pointer to just past the end. No copying of bulk data is performed. | |
387 | The function | |
388 | .BI buf_putbuf suff | |
389 | writes the contents of a buffer (i.e., between its | |
390 | .I base | |
391 | and | |
392 | .I current | |
393 | pointers). The function | |
394 | .BI buf_getdstr suff | |
395 | fetches a block of data and append it to a dynamic string (see | |
396 | .BR dstr (3)). | |
397 | The function | |
398 | .BI buf_putdstr suff | |
399 | writes the contents of a dynamic string to a buffer. Finally, the | |
400 | function | |
401 | .BI buf_putstr suff | |
402 | writes a standard C null-terminated string to a buffer. All these | |
403 | functions return zero on success or \-1 on failure. | |
404 | .SH "SEE ALSO" | |
405 | .BR dstr (3), | |
406 | .BR mLib (3). | |
407 | .SH AUTHOR | |
408 | Mark Wooding, <mdw@distorted.org.uk> |