1135446Strhodes/*
2193149Sdougb * Copyright (C) 2004-2007  Internet Systems Consortium, Inc. ("ISC")
3135446Strhodes * Copyright (C) 2000, 2001  Internet Software Consortium.
4135446Strhodes *
5193149Sdougb * Permission to use, copy, modify, and/or distribute this software for any
6135446Strhodes * purpose with or without fee is hereby granted, provided that the above
7135446Strhodes * copyright notice and this permission notice appear in all copies.
8135446Strhodes *
9135446Strhodes * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10135446Strhodes * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11135446Strhodes * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12135446Strhodes * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13135446Strhodes * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14135446Strhodes * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15135446Strhodes * PERFORMANCE OF THIS SOFTWARE.
16135446Strhodes */
17135446Strhodes
18234010Sdougb/* $Id: lwbuffer.h,v 1.22 2007/06/19 23:47:23 tbox Exp $ */
19135446Strhodes
20135446Strhodes
21193149Sdougb/*! \file lwres/lwbuffer.h
22135446Strhodes *
23135446Strhodes * A buffer is a region of memory, together with a set of related subregions.
24135446Strhodes * Buffers are used for parsing and I/O operations.
25135446Strhodes *
26135446Strhodes * The 'used region' and the 'available' region are disjoint, and their
27135446Strhodes * union is the buffer's region.  The used region extends from the beginning
28135446Strhodes * of the buffer region to the last used byte.  The available region
29135446Strhodes * extends from one byte greater than the last used byte to the end of the
30135446Strhodes * buffer's region.  The size of the used region can be changed using various
31135446Strhodes * buffer commands.  Initially, the used region is empty.
32135446Strhodes *
33135446Strhodes * The used region is further subdivided into two disjoint regions: the
34135446Strhodes * 'consumed region' and the 'remaining region'.  The union of these two
35135446Strhodes * regions is the used region.  The consumed region extends from the beginning
36135446Strhodes * of the used region to the byte before the 'current' offset (if any).  The
37135446Strhodes * 'remaining' region the current pointer to the end of the used
38135446Strhodes * region.  The size of the consumed region can be changed using various
39135446Strhodes * buffer commands.  Initially, the consumed region is empty.
40135446Strhodes *
41135446Strhodes * The 'active region' is an (optional) subregion of the remaining region.
42135446Strhodes * It extends from the current offset to an offset in the remaining region
43135446Strhodes * that is selected with lwres_buffer_setactive().  Initially, the active
44135446Strhodes * region is empty.  If the current offset advances beyond the chosen offset,
45135446Strhodes * the active region will also be empty.
46135446Strhodes *
47170222Sdougb * \verbatim
48135446Strhodes *  /----- used region -----\/-- available --\
49135446Strhodes *  +----------------------------------------+
50135446Strhodes *  | consumed  | remaining |                |
51135446Strhodes *  +----------------------------------------+
52135446Strhodes *  a           b     c     d                e
53135446Strhodes *
54135446Strhodes * a == base of buffer.
55135446Strhodes * b == current pointer.  Can be anywhere between a and d.
56135446Strhodes * c == active pointer.  Meaningful between b and d.
57135446Strhodes * d == used pointer.
58135446Strhodes * e == length of buffer.
59135446Strhodes *
60135446Strhodes * a-e == entire (length) of buffer.
61135446Strhodes * a-d == used region.
62135446Strhodes * a-b == consumed region.
63135446Strhodes * b-d == remaining region.
64135446Strhodes * b-c == optional active region.
65170222Sdougb * \endverbatim
66135446Strhodes *
67135446Strhodes * The following invariants are maintained by all routines:
68135446Strhodes *
69170222Sdougb *\verbatim
70135446Strhodes *	length > 0
71135446Strhodes *
72135446Strhodes *	base is a valid pointer to length bytes of memory
73135446Strhodes *
74135446Strhodes *	0 <= used <= length
75135446Strhodes *
76135446Strhodes *	0 <= current <= used
77135446Strhodes *
78135446Strhodes *	0 <= active <= used
79135446Strhodes *	(although active < current implies empty active region)
80170222Sdougb *\endverbatim
81135446Strhodes *
82170222Sdougb * \li MP:
83135446Strhodes *	Buffers have no synchronization.  Clients must ensure exclusive
84135446Strhodes *	access.
85135446Strhodes *
86170222Sdougb * \li Reliability:
87135446Strhodes *	No anticipated impact.
88135446Strhodes *
89170222Sdougb * \li Resources:
90135446Strhodes *	Memory: 1 pointer + 6 unsigned integers per buffer.
91135446Strhodes *
92170222Sdougb * \li Security:
93135446Strhodes *	No anticipated impact.
94135446Strhodes *
95170222Sdougb * \li Standards:
96135446Strhodes *	None.
97135446Strhodes */
98135446Strhodes
99170222Sdougb#ifndef LWRES_LWBUFFER_H
100170222Sdougb#define LWRES_LWBUFFER_H 1
101170222Sdougb
102135446Strhodes/***
103135446Strhodes *** Imports
104135446Strhodes ***/
105135446Strhodes
106135446Strhodes#include <lwres/lang.h>
107135446Strhodes#include <lwres/int.h>
108135446Strhodes
109135446StrhodesLWRES_LANG_BEGINDECLS
110135446Strhodes
111135446Strhodes/***
112135446Strhodes *** Magic numbers
113135446Strhodes ***/
114135446Strhodes#define LWRES_BUFFER_MAGIC		0x4275663fU	/* Buf?. */
115135446Strhodes
116135446Strhodes#define LWRES_BUFFER_VALID(b)		((b) != NULL && \
117135446Strhodes					 (b)->magic == LWRES_BUFFER_MAGIC)
118135446Strhodes
119170222Sdougb/*!
120135446Strhodes * The following macros MUST be used only on valid buffers.  It is the
121135446Strhodes * caller's responsibility to ensure this by using the LWRES_BUFFER_VALID
122135446Strhodes * check above, or by calling another lwres_buffer_*() function (rather than
123135446Strhodes * another macro.)
124135446Strhodes */
125135446Strhodes
126170222Sdougb/*!
127135446Strhodes * Get the length of the used region of buffer "b"
128135446Strhodes */
129135446Strhodes#define LWRES_BUFFER_USEDCOUNT(b)	((b)->used)
130135446Strhodes
131170222Sdougb/*!
132135446Strhodes * Get the length of the available region of buffer "b"
133135446Strhodes */
134135446Strhodes#define LWRES_BUFFER_AVAILABLECOUNT(b)	((b)->length - (b)->used)
135135446Strhodes
136135446Strhodes#define LWRES_BUFFER_REMAINING(b)	((b)->used - (b)->current)
137135446Strhodes
138170222Sdougb/*!
139135446Strhodes * Note that the buffer structure is public.  This is principally so buffer
140135446Strhodes * operations can be implemented using macros.  Applications are strongly
141135446Strhodes * discouraged from directly manipulating the structure.
142135446Strhodes */
143135446Strhodes
144135446Strhodestypedef struct lwres_buffer lwres_buffer_t;
145170222Sdougb/*!
146170222Sdougb * Buffer data structure
147170222Sdougb */
148135446Strhodesstruct lwres_buffer {
149135446Strhodes	unsigned int		magic;
150135446Strhodes	unsigned char 	       *base;
151135446Strhodes	/* The following integers are byte offsets from 'base'. */
152135446Strhodes	unsigned int		length;
153135446Strhodes	unsigned int		used;
154135446Strhodes	unsigned int 		current;
155135446Strhodes	unsigned int 		active;
156135446Strhodes};
157135446Strhodes
158135446Strhodes/***
159135446Strhodes *** Functions
160135446Strhodes ***/
161135446Strhodes
162135446Strhodesvoid
163135446Strhodeslwres_buffer_init(lwres_buffer_t *b, void *base, unsigned int length);
164170222Sdougb/**<
165135446Strhodes * Make 'b' refer to the 'length'-byte region starting at base.
166135446Strhodes *
167135446Strhodes * Requires:
168135446Strhodes *
169135446Strhodes *	'length' > 0
170135446Strhodes *
171135446Strhodes *	'base' is a pointer to a sequence of 'length' bytes.
172135446Strhodes *
173135446Strhodes */
174135446Strhodes
175135446Strhodesvoid
176135446Strhodeslwres_buffer_invalidate(lwres_buffer_t *b);
177170222Sdougb/**<
178135446Strhodes * Make 'b' an invalid buffer.
179135446Strhodes *
180135446Strhodes * Requires:
181135446Strhodes *	'b' is a valid buffer.
182135446Strhodes *
183135446Strhodes * Ensures:
184135446Strhodes *	If assertion checking is enabled, future attempts to use 'b' without
185135446Strhodes *	calling lwres_buffer_init() on it will cause an assertion failure.
186135446Strhodes */
187135446Strhodes
188135446Strhodesvoid
189135446Strhodeslwres_buffer_add(lwres_buffer_t *b, unsigned int n);
190170222Sdougb/**<
191135446Strhodes * Increase the 'used' region of 'b' by 'n' bytes.
192135446Strhodes *
193135446Strhodes * Requires:
194135446Strhodes *
195135446Strhodes *	'b' is a valid buffer
196135446Strhodes *
197135446Strhodes *	used + n <= length
198135446Strhodes *
199135446Strhodes */
200135446Strhodes
201135446Strhodesvoid
202135446Strhodeslwres_buffer_subtract(lwres_buffer_t *b, unsigned int n);
203170222Sdougb/**<
204135446Strhodes * Decrease the 'used' region of 'b' by 'n' bytes.
205135446Strhodes *
206135446Strhodes * Requires:
207135446Strhodes *
208135446Strhodes *	'b' is a valid buffer
209135446Strhodes *
210135446Strhodes *	used >= n
211135446Strhodes *
212135446Strhodes */
213135446Strhodes
214135446Strhodesvoid
215135446Strhodeslwres_buffer_clear(lwres_buffer_t *b);
216170222Sdougb/**<
217135446Strhodes * Make the used region empty.
218135446Strhodes *
219135446Strhodes * Requires:
220135446Strhodes *
221135446Strhodes *	'b' is a valid buffer
222135446Strhodes *
223135446Strhodes * Ensures:
224135446Strhodes *
225135446Strhodes *	used = 0
226135446Strhodes *
227135446Strhodes */
228135446Strhodes
229170222Sdougb
230135446Strhodesvoid
231135446Strhodeslwres_buffer_first(lwres_buffer_t *b);
232170222Sdougb/**<
233135446Strhodes * Make the consumed region empty.
234135446Strhodes *
235135446Strhodes * Requires:
236135446Strhodes *
237135446Strhodes *	'b' is a valid buffer
238135446Strhodes *
239135446Strhodes * Ensures:
240135446Strhodes *
241135446Strhodes *	current == 0
242135446Strhodes *
243135446Strhodes */
244135446Strhodes
245135446Strhodesvoid
246135446Strhodeslwres_buffer_forward(lwres_buffer_t *b, unsigned int n);
247170222Sdougb/**<
248135446Strhodes * Increase the 'consumed' region of 'b' by 'n' bytes.
249135446Strhodes *
250135446Strhodes * Requires:
251135446Strhodes *
252135446Strhodes *	'b' is a valid buffer
253135446Strhodes *
254135446Strhodes *	current + n <= used
255135446Strhodes *
256135446Strhodes */
257135446Strhodes
258135446Strhodesvoid
259135446Strhodeslwres_buffer_back(lwres_buffer_t *b, unsigned int n);
260170222Sdougb/**<
261135446Strhodes * Decrease the 'consumed' region of 'b' by 'n' bytes.
262135446Strhodes *
263135446Strhodes * Requires:
264135446Strhodes *
265135446Strhodes *	'b' is a valid buffer
266135446Strhodes *
267135446Strhodes *	n <= current
268135446Strhodes *
269135446Strhodes */
270135446Strhodes
271135446Strhodeslwres_uint8_t
272135446Strhodeslwres_buffer_getuint8(lwres_buffer_t *b);
273170222Sdougb/**<
274135446Strhodes * Read an unsigned 8-bit integer from 'b' and return it.
275135446Strhodes *
276135446Strhodes * Requires:
277135446Strhodes *
278135446Strhodes *	'b' is a valid buffer.
279135446Strhodes *
280135446Strhodes *	The length of the available region of 'b' is at least 1.
281135446Strhodes *
282135446Strhodes * Ensures:
283135446Strhodes *
284135446Strhodes *	The current pointer in 'b' is advanced by 1.
285135446Strhodes *
286135446Strhodes * Returns:
287135446Strhodes *
288135446Strhodes *	A 8-bit unsigned integer.
289135446Strhodes */
290135446Strhodes
291135446Strhodesvoid
292135446Strhodeslwres_buffer_putuint8(lwres_buffer_t *b, lwres_uint8_t val);
293170222Sdougb/**<
294135446Strhodes * Store an unsigned 8-bit integer from 'val' into 'b'.
295135446Strhodes *
296135446Strhodes * Requires:
297135446Strhodes *	'b' is a valid buffer.
298135446Strhodes *
299135446Strhodes *	The length of the unused region of 'b' is at least 1.
300135446Strhodes *
301135446Strhodes * Ensures:
302135446Strhodes *	The used pointer in 'b' is advanced by 1.
303135446Strhodes */
304135446Strhodes
305135446Strhodeslwres_uint16_t
306135446Strhodeslwres_buffer_getuint16(lwres_buffer_t *b);
307170222Sdougb/**<
308135446Strhodes * Read an unsigned 16-bit integer in network byte order from 'b', convert
309135446Strhodes * it to host byte order, and return it.
310135446Strhodes *
311135446Strhodes * Requires:
312135446Strhodes *
313135446Strhodes *	'b' is a valid buffer.
314135446Strhodes *
315135446Strhodes *	The length of the available region of 'b' is at least 2.
316135446Strhodes *
317135446Strhodes * Ensures:
318135446Strhodes *
319135446Strhodes *	The current pointer in 'b' is advanced by 2.
320135446Strhodes *
321135446Strhodes * Returns:
322135446Strhodes *
323135446Strhodes *	A 16-bit unsigned integer.
324135446Strhodes */
325135446Strhodes
326135446Strhodesvoid
327135446Strhodeslwres_buffer_putuint16(lwres_buffer_t *b, lwres_uint16_t val);
328170222Sdougb/**<
329135446Strhodes * Store an unsigned 16-bit integer in host byte order from 'val'
330135446Strhodes * into 'b' in network byte order.
331135446Strhodes *
332135446Strhodes * Requires:
333135446Strhodes *	'b' is a valid buffer.
334135446Strhodes *
335135446Strhodes *	The length of the unused region of 'b' is at least 2.
336135446Strhodes *
337135446Strhodes * Ensures:
338135446Strhodes *	The used pointer in 'b' is advanced by 2.
339135446Strhodes */
340135446Strhodes
341135446Strhodeslwres_uint32_t
342135446Strhodeslwres_buffer_getuint32(lwres_buffer_t *b);
343170222Sdougb/**<
344135446Strhodes * Read an unsigned 32-bit integer in network byte order from 'b', convert
345135446Strhodes * it to host byte order, and return it.
346135446Strhodes *
347135446Strhodes * Requires:
348135446Strhodes *
349135446Strhodes *	'b' is a valid buffer.
350135446Strhodes *
351135446Strhodes *	The length of the available region of 'b' is at least 2.
352135446Strhodes *
353135446Strhodes * Ensures:
354135446Strhodes *
355135446Strhodes *	The current pointer in 'b' is advanced by 2.
356135446Strhodes *
357135446Strhodes * Returns:
358135446Strhodes *
359135446Strhodes *	A 32-bit unsigned integer.
360135446Strhodes */
361135446Strhodes
362135446Strhodesvoid
363135446Strhodeslwres_buffer_putuint32(lwres_buffer_t *b, lwres_uint32_t val);
364170222Sdougb/**<
365135446Strhodes * Store an unsigned 32-bit integer in host byte order from 'val'
366135446Strhodes * into 'b' in network byte order.
367135446Strhodes *
368135446Strhodes * Requires:
369135446Strhodes *	'b' is a valid buffer.
370135446Strhodes *
371135446Strhodes *	The length of the unused region of 'b' is at least 4.
372135446Strhodes *
373135446Strhodes * Ensures:
374135446Strhodes *	The used pointer in 'b' is advanced by 4.
375135446Strhodes */
376135446Strhodes
377135446Strhodesvoid
378135446Strhodeslwres_buffer_putmem(lwres_buffer_t *b, const unsigned char *base,
379135446Strhodes		    unsigned int length);
380170222Sdougb/**<
381135446Strhodes * Copy 'length' bytes of memory at 'base' into 'b'.
382135446Strhodes *
383135446Strhodes * Requires:
384135446Strhodes *	'b' is a valid buffer.
385135446Strhodes *
386135446Strhodes *	'base' points to 'length' bytes of valid memory.
387135446Strhodes *
388135446Strhodes */
389135446Strhodes
390135446Strhodesvoid
391135446Strhodeslwres_buffer_getmem(lwres_buffer_t *b, unsigned char *base,
392135446Strhodes		    unsigned int length);
393170222Sdougb/**<
394135446Strhodes * Copy 'length' bytes of memory from 'b' into 'base'.
395135446Strhodes *
396135446Strhodes * Requires:
397135446Strhodes *	'b' is a valid buffer.
398135446Strhodes *
399135446Strhodes *	'base' points to at least 'length' bytes of valid memory.
400135446Strhodes *
401135446Strhodes *	'b' have at least 'length' bytes remaining.
402135446Strhodes */
403135446Strhodes
404135446StrhodesLWRES_LANG_ENDDECLS
405135446Strhodes
406135446Strhodes#endif /* LWRES_LWBUFFER_H */
407