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