1/*
2 * Copyright (C) 2004-2007  Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000, 2001  Internet Software Consortium.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* $Id: lwbuffer.h,v 1.22 2007/06/19 23:47:23 tbox Exp $ */
19
20
21/*! \file lwres/lwbuffer.h
22 *
23 * A buffer is a region of memory, together with a set of related subregions.
24 * Buffers are used for parsing and I/O operations.
25 *
26 * The 'used region' and the 'available' region are disjoint, and their
27 * union is the buffer's region.  The used region extends from the beginning
28 * of the buffer region to the last used byte.  The available region
29 * extends from one byte greater than the last used byte to the end of the
30 * buffer's region.  The size of the used region can be changed using various
31 * buffer commands.  Initially, the used region is empty.
32 *
33 * The used region is further subdivided into two disjoint regions: the
34 * 'consumed region' and the 'remaining region'.  The union of these two
35 * regions is the used region.  The consumed region extends from the beginning
36 * of the used region to the byte before the 'current' offset (if any).  The
37 * 'remaining' region the current pointer to the end of the used
38 * region.  The size of the consumed region can be changed using various
39 * buffer commands.  Initially, the consumed region is empty.
40 *
41 * The 'active region' is an (optional) subregion of the remaining region.
42 * It extends from the current offset to an offset in the remaining region
43 * that is selected with lwres_buffer_setactive().  Initially, the active
44 * region is empty.  If the current offset advances beyond the chosen offset,
45 * the active region will also be empty.
46 *
47 * \verbatim
48 *  /----- used region -----\/-- available --\
49 *  +----------------------------------------+
50 *  | consumed  | remaining |                |
51 *  +----------------------------------------+
52 *  a           b     c     d                e
53 *
54 * a == base of buffer.
55 * b == current pointer.  Can be anywhere between a and d.
56 * c == active pointer.  Meaningful between b and d.
57 * d == used pointer.
58 * e == length of buffer.
59 *
60 * a-e == entire (length) of buffer.
61 * a-d == used region.
62 * a-b == consumed region.
63 * b-d == remaining region.
64 * b-c == optional active region.
65 * \endverbatim
66 *
67 * The following invariants are maintained by all routines:
68 *
69 *\verbatim
70 *	length > 0
71 *
72 *	base is a valid pointer to length bytes of memory
73 *
74 *	0 <= used <= length
75 *
76 *	0 <= current <= used
77 *
78 *	0 <= active <= used
79 *	(although active < current implies empty active region)
80 *\endverbatim
81 *
82 * \li MP:
83 *	Buffers have no synchronization.  Clients must ensure exclusive
84 *	access.
85 *
86 * \li Reliability:
87 *	No anticipated impact.
88 *
89 * \li Resources:
90 *	Memory: 1 pointer + 6 unsigned integers per buffer.
91 *
92 * \li Security:
93 *	No anticipated impact.
94 *
95 * \li Standards:
96 *	None.
97 */
98
99#ifndef LWRES_LWBUFFER_H
100#define LWRES_LWBUFFER_H 1
101
102/***
103 *** Imports
104 ***/
105
106#include <lwres/lang.h>
107#include <lwres/int.h>
108
109LWRES_LANG_BEGINDECLS
110
111/***
112 *** Magic numbers
113 ***/
114#define LWRES_BUFFER_MAGIC		0x4275663fU	/* Buf?. */
115
116#define LWRES_BUFFER_VALID(b)		((b) != NULL && \
117					 (b)->magic == LWRES_BUFFER_MAGIC)
118
119/*!
120 * The following macros MUST be used only on valid buffers.  It is the
121 * caller's responsibility to ensure this by using the LWRES_BUFFER_VALID
122 * check above, or by calling another lwres_buffer_*() function (rather than
123 * another macro.)
124 */
125
126/*!
127 * Get the length of the used region of buffer "b"
128 */
129#define LWRES_BUFFER_USEDCOUNT(b)	((b)->used)
130
131/*!
132 * Get the length of the available region of buffer "b"
133 */
134#define LWRES_BUFFER_AVAILABLECOUNT(b)	((b)->length - (b)->used)
135
136#define LWRES_BUFFER_REMAINING(b)	((b)->used - (b)->current)
137
138/*!
139 * Note that the buffer structure is public.  This is principally so buffer
140 * operations can be implemented using macros.  Applications are strongly
141 * discouraged from directly manipulating the structure.
142 */
143
144typedef struct lwres_buffer lwres_buffer_t;
145/*!
146 * Buffer data structure
147 */
148struct lwres_buffer {
149	unsigned int		magic;
150	unsigned char 	       *base;
151	/* The following integers are byte offsets from 'base'. */
152	unsigned int		length;
153	unsigned int		used;
154	unsigned int 		current;
155	unsigned int 		active;
156};
157
158/***
159 *** Functions
160 ***/
161
162void
163lwres_buffer_init(lwres_buffer_t *b, void *base, unsigned int length);
164/**<
165 * Make 'b' refer to the 'length'-byte region starting at base.
166 *
167 * Requires:
168 *
169 *	'length' > 0
170 *
171 *	'base' is a pointer to a sequence of 'length' bytes.
172 *
173 */
174
175void
176lwres_buffer_invalidate(lwres_buffer_t *b);
177/**<
178 * Make 'b' an invalid buffer.
179 *
180 * Requires:
181 *	'b' is a valid buffer.
182 *
183 * Ensures:
184 *	If assertion checking is enabled, future attempts to use 'b' without
185 *	calling lwres_buffer_init() on it will cause an assertion failure.
186 */
187
188void
189lwres_buffer_add(lwres_buffer_t *b, unsigned int n);
190/**<
191 * Increase the 'used' region of 'b' by 'n' bytes.
192 *
193 * Requires:
194 *
195 *	'b' is a valid buffer
196 *
197 *	used + n <= length
198 *
199 */
200
201void
202lwres_buffer_subtract(lwres_buffer_t *b, unsigned int n);
203/**<
204 * Decrease the 'used' region of 'b' by 'n' bytes.
205 *
206 * Requires:
207 *
208 *	'b' is a valid buffer
209 *
210 *	used >= n
211 *
212 */
213
214void
215lwres_buffer_clear(lwres_buffer_t *b);
216/**<
217 * Make the used region empty.
218 *
219 * Requires:
220 *
221 *	'b' is a valid buffer
222 *
223 * Ensures:
224 *
225 *	used = 0
226 *
227 */
228
229
230void
231lwres_buffer_first(lwres_buffer_t *b);
232/**<
233 * Make the consumed region empty.
234 *
235 * Requires:
236 *
237 *	'b' is a valid buffer
238 *
239 * Ensures:
240 *
241 *	current == 0
242 *
243 */
244
245void
246lwres_buffer_forward(lwres_buffer_t *b, unsigned int n);
247/**<
248 * Increase the 'consumed' region of 'b' by 'n' bytes.
249 *
250 * Requires:
251 *
252 *	'b' is a valid buffer
253 *
254 *	current + n <= used
255 *
256 */
257
258void
259lwres_buffer_back(lwres_buffer_t *b, unsigned int n);
260/**<
261 * Decrease the 'consumed' region of 'b' by 'n' bytes.
262 *
263 * Requires:
264 *
265 *	'b' is a valid buffer
266 *
267 *	n <= current
268 *
269 */
270
271lwres_uint8_t
272lwres_buffer_getuint8(lwres_buffer_t *b);
273/**<
274 * Read an unsigned 8-bit integer from 'b' and return it.
275 *
276 * Requires:
277 *
278 *	'b' is a valid buffer.
279 *
280 *	The length of the available region of 'b' is at least 1.
281 *
282 * Ensures:
283 *
284 *	The current pointer in 'b' is advanced by 1.
285 *
286 * Returns:
287 *
288 *	A 8-bit unsigned integer.
289 */
290
291void
292lwres_buffer_putuint8(lwres_buffer_t *b, lwres_uint8_t val);
293/**<
294 * Store an unsigned 8-bit integer from 'val' into 'b'.
295 *
296 * Requires:
297 *	'b' is a valid buffer.
298 *
299 *	The length of the unused region of 'b' is at least 1.
300 *
301 * Ensures:
302 *	The used pointer in 'b' is advanced by 1.
303 */
304
305lwres_uint16_t
306lwres_buffer_getuint16(lwres_buffer_t *b);
307/**<
308 * Read an unsigned 16-bit integer in network byte order from 'b', convert
309 * it to host byte order, and return it.
310 *
311 * Requires:
312 *
313 *	'b' is a valid buffer.
314 *
315 *	The length of the available region of 'b' is at least 2.
316 *
317 * Ensures:
318 *
319 *	The current pointer in 'b' is advanced by 2.
320 *
321 * Returns:
322 *
323 *	A 16-bit unsigned integer.
324 */
325
326void
327lwres_buffer_putuint16(lwres_buffer_t *b, lwres_uint16_t val);
328/**<
329 * Store an unsigned 16-bit integer in host byte order from 'val'
330 * into 'b' in network byte order.
331 *
332 * Requires:
333 *	'b' is a valid buffer.
334 *
335 *	The length of the unused region of 'b' is at least 2.
336 *
337 * Ensures:
338 *	The used pointer in 'b' is advanced by 2.
339 */
340
341lwres_uint32_t
342lwres_buffer_getuint32(lwres_buffer_t *b);
343/**<
344 * Read an unsigned 32-bit integer in network byte order from 'b', convert
345 * it to host byte order, and return it.
346 *
347 * Requires:
348 *
349 *	'b' is a valid buffer.
350 *
351 *	The length of the available region of 'b' is at least 2.
352 *
353 * Ensures:
354 *
355 *	The current pointer in 'b' is advanced by 2.
356 *
357 * Returns:
358 *
359 *	A 32-bit unsigned integer.
360 */
361
362void
363lwres_buffer_putuint32(lwres_buffer_t *b, lwres_uint32_t val);
364/**<
365 * Store an unsigned 32-bit integer in host byte order from 'val'
366 * into 'b' in network byte order.
367 *
368 * Requires:
369 *	'b' is a valid buffer.
370 *
371 *	The length of the unused region of 'b' is at least 4.
372 *
373 * Ensures:
374 *	The used pointer in 'b' is advanced by 4.
375 */
376
377void
378lwres_buffer_putmem(lwres_buffer_t *b, const unsigned char *base,
379		    unsigned int length);
380/**<
381 * Copy 'length' bytes of memory at 'base' into 'b'.
382 *
383 * Requires:
384 *	'b' is a valid buffer.
385 *
386 *	'base' points to 'length' bytes of valid memory.
387 *
388 */
389
390void
391lwres_buffer_getmem(lwres_buffer_t *b, unsigned char *base,
392		    unsigned int length);
393/**<
394 * Copy 'length' bytes of memory from 'b' into 'base'.
395 *
396 * Requires:
397 *	'b' is a valid buffer.
398 *
399 *	'base' points to at least 'length' bytes of valid memory.
400 *
401 *	'b' have at least 'length' bytes remaining.
402 */
403
404LWRES_LANG_ENDDECLS
405
406#endif /* LWRES_LWBUFFER_H */
407