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