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