Return to buffer.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / lib / isc |
1.1 ! misho 1: /* ! 2: * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") ! 3: * Copyright (C) 1998-2002 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: buffer.c,v 1.49 2008/09/25 04:02:39 tbox Exp $ */ ! 19: ! 20: /*! \file */ ! 21: ! 22: #include <config.h> ! 23: ! 24: #include <isc/buffer.h> ! 25: #include <isc/mem.h> ! 26: #include <isc/region.h> ! 27: #include <isc/string.h> ! 28: #include <isc/util.h> ! 29: ! 30: void ! 31: isc__buffer_init(isc_buffer_t *b, const void *base, unsigned int length) { ! 32: /* ! 33: * Make 'b' refer to the 'length'-byte region starting at 'base'. ! 34: * XXXDCL see the comment in buffer.h about base being const. ! 35: */ ! 36: ! 37: REQUIRE(b != NULL); ! 38: ! 39: ISC__BUFFER_INIT(b, base, length); ! 40: } ! 41: ! 42: void ! 43: isc__buffer_initnull(isc_buffer_t *b) { ! 44: /* ! 45: * Initialize a new buffer which has no backing store. This can ! 46: * later be grown as needed and swapped in place. ! 47: */ ! 48: ! 49: ISC__BUFFER_INIT(b, NULL, 0); ! 50: } ! 51: ! 52: void ! 53: isc_buffer_reinit(isc_buffer_t *b, void *base, unsigned int length) { ! 54: /* ! 55: * Re-initialize the buffer enough to reconfigure the base of the ! 56: * buffer. We will swap in the new buffer, after copying any ! 57: * data we contain into the new buffer and adjusting all of our ! 58: * internal pointers. ! 59: * ! 60: * The buffer must not be smaller than the length of the original ! 61: * buffer. ! 62: */ ! 63: REQUIRE(b->length <= length); ! 64: REQUIRE(base != NULL); ! 65: ! 66: (void)memmove(base, b->base, b->length); ! 67: b->base = base; ! 68: b->length = length; ! 69: } ! 70: ! 71: void ! 72: isc__buffer_invalidate(isc_buffer_t *b) { ! 73: /* ! 74: * Make 'b' an invalid buffer. ! 75: */ ! 76: ! 77: REQUIRE(ISC_BUFFER_VALID(b)); ! 78: REQUIRE(!ISC_LINK_LINKED(b, link)); ! 79: REQUIRE(b->mctx == NULL); ! 80: ! 81: ISC__BUFFER_INVALIDATE(b); ! 82: } ! 83: ! 84: void ! 85: isc__buffer_region(isc_buffer_t *b, isc_region_t *r) { ! 86: /* ! 87: * Make 'r' refer to the region of 'b'. ! 88: */ ! 89: ! 90: REQUIRE(ISC_BUFFER_VALID(b)); ! 91: REQUIRE(r != NULL); ! 92: ! 93: ISC__BUFFER_REGION(b, r); ! 94: } ! 95: ! 96: void ! 97: isc__buffer_usedregion(isc_buffer_t *b, isc_region_t *r) { ! 98: /* ! 99: * Make 'r' refer to the used region of 'b'. ! 100: */ ! 101: ! 102: REQUIRE(ISC_BUFFER_VALID(b)); ! 103: REQUIRE(r != NULL); ! 104: ! 105: ISC__BUFFER_USEDREGION(b, r); ! 106: } ! 107: ! 108: void ! 109: isc__buffer_availableregion(isc_buffer_t *b, isc_region_t *r) { ! 110: /* ! 111: * Make 'r' refer to the available region of 'b'. ! 112: */ ! 113: ! 114: REQUIRE(ISC_BUFFER_VALID(b)); ! 115: REQUIRE(r != NULL); ! 116: ! 117: ISC__BUFFER_AVAILABLEREGION(b, r); ! 118: } ! 119: ! 120: void ! 121: isc__buffer_add(isc_buffer_t *b, unsigned int n) { ! 122: /* ! 123: * Increase the 'used' region of 'b' by 'n' bytes. ! 124: */ ! 125: ! 126: REQUIRE(ISC_BUFFER_VALID(b)); ! 127: REQUIRE(b->used + n <= b->length); ! 128: ! 129: ISC__BUFFER_ADD(b, n); ! 130: } ! 131: ! 132: void ! 133: isc__buffer_subtract(isc_buffer_t *b, unsigned int n) { ! 134: /* ! 135: * Decrease the 'used' region of 'b' by 'n' bytes. ! 136: */ ! 137: ! 138: REQUIRE(ISC_BUFFER_VALID(b)); ! 139: REQUIRE(b->used >= n); ! 140: ! 141: ISC__BUFFER_SUBTRACT(b, n); ! 142: } ! 143: ! 144: void ! 145: isc__buffer_clear(isc_buffer_t *b) { ! 146: /* ! 147: * Make the used region empty. ! 148: */ ! 149: ! 150: REQUIRE(ISC_BUFFER_VALID(b)); ! 151: ! 152: ISC__BUFFER_CLEAR(b); ! 153: } ! 154: ! 155: void ! 156: isc__buffer_consumedregion(isc_buffer_t *b, isc_region_t *r) { ! 157: /* ! 158: * Make 'r' refer to the consumed region of 'b'. ! 159: */ ! 160: ! 161: REQUIRE(ISC_BUFFER_VALID(b)); ! 162: REQUIRE(r != NULL); ! 163: ! 164: ISC__BUFFER_CONSUMEDREGION(b, r); ! 165: } ! 166: ! 167: void ! 168: isc__buffer_remainingregion(isc_buffer_t *b, isc_region_t *r) { ! 169: /* ! 170: * Make 'r' refer to the remaining region of 'b'. ! 171: */ ! 172: ! 173: REQUIRE(ISC_BUFFER_VALID(b)); ! 174: REQUIRE(r != NULL); ! 175: ! 176: ISC__BUFFER_REMAININGREGION(b, r); ! 177: } ! 178: ! 179: void ! 180: isc__buffer_activeregion(isc_buffer_t *b, isc_region_t *r) { ! 181: /* ! 182: * Make 'r' refer to the active region of 'b'. ! 183: */ ! 184: ! 185: REQUIRE(ISC_BUFFER_VALID(b)); ! 186: REQUIRE(r != NULL); ! 187: ! 188: ISC__BUFFER_ACTIVEREGION(b, r); ! 189: } ! 190: ! 191: void ! 192: isc__buffer_setactive(isc_buffer_t *b, unsigned int n) { ! 193: /* ! 194: * Sets the end of the active region 'n' bytes after current. ! 195: */ ! 196: ! 197: REQUIRE(ISC_BUFFER_VALID(b)); ! 198: REQUIRE(b->current + n <= b->used); ! 199: ! 200: ISC__BUFFER_SETACTIVE(b, n); ! 201: } ! 202: ! 203: void ! 204: isc__buffer_first(isc_buffer_t *b) { ! 205: /* ! 206: * Make the consumed region empty. ! 207: */ ! 208: ! 209: REQUIRE(ISC_BUFFER_VALID(b)); ! 210: ! 211: ISC__BUFFER_FIRST(b); ! 212: } ! 213: ! 214: void ! 215: isc__buffer_forward(isc_buffer_t *b, unsigned int n) { ! 216: /* ! 217: * Increase the 'consumed' region of 'b' by 'n' bytes. ! 218: */ ! 219: ! 220: REQUIRE(ISC_BUFFER_VALID(b)); ! 221: REQUIRE(b->current + n <= b->used); ! 222: ! 223: ISC__BUFFER_FORWARD(b, n); ! 224: } ! 225: ! 226: void ! 227: isc__buffer_back(isc_buffer_t *b, unsigned int n) { ! 228: /* ! 229: * Decrease the 'consumed' region of 'b' by 'n' bytes. ! 230: */ ! 231: ! 232: REQUIRE(ISC_BUFFER_VALID(b)); ! 233: REQUIRE(n <= b->current); ! 234: ! 235: ISC__BUFFER_BACK(b, n); ! 236: } ! 237: ! 238: void ! 239: isc_buffer_compact(isc_buffer_t *b) { ! 240: unsigned int length; ! 241: void *src; ! 242: ! 243: /* ! 244: * Compact the used region by moving the remaining region so it occurs ! 245: * at the start of the buffer. The used region is shrunk by the size ! 246: * of the consumed region, and the consumed region is then made empty. ! 247: */ ! 248: ! 249: REQUIRE(ISC_BUFFER_VALID(b)); ! 250: ! 251: src = isc_buffer_current(b); ! 252: length = isc_buffer_remaininglength(b); ! 253: (void)memmove(b->base, src, (size_t)length); ! 254: ! 255: if (b->active > b->current) ! 256: b->active -= b->current; ! 257: else ! 258: b->active = 0; ! 259: b->current = 0; ! 260: b->used = length; ! 261: } ! 262: ! 263: isc_uint8_t ! 264: isc_buffer_getuint8(isc_buffer_t *b) { ! 265: unsigned char *cp; ! 266: isc_uint8_t result; ! 267: ! 268: /* ! 269: * Read an unsigned 8-bit integer from 'b' and return it. ! 270: */ ! 271: ! 272: REQUIRE(ISC_BUFFER_VALID(b)); ! 273: REQUIRE(b->used - b->current >= 1); ! 274: ! 275: cp = isc_buffer_current(b); ! 276: b->current += 1; ! 277: result = ((isc_uint8_t)(cp[0])); ! 278: ! 279: return (result); ! 280: } ! 281: ! 282: void ! 283: isc__buffer_putuint8(isc_buffer_t *b, isc_uint8_t val) { ! 284: REQUIRE(ISC_BUFFER_VALID(b)); ! 285: REQUIRE(b->used + 1 <= b->length); ! 286: ! 287: ISC__BUFFER_PUTUINT8(b, val); ! 288: } ! 289: ! 290: isc_uint16_t ! 291: isc_buffer_getuint16(isc_buffer_t *b) { ! 292: unsigned char *cp; ! 293: isc_uint16_t result; ! 294: ! 295: /* ! 296: * Read an unsigned 16-bit integer in network byte order from 'b', ! 297: * convert it to host byte order, and return it. ! 298: */ ! 299: ! 300: REQUIRE(ISC_BUFFER_VALID(b)); ! 301: REQUIRE(b->used - b->current >= 2); ! 302: ! 303: cp = isc_buffer_current(b); ! 304: b->current += 2; ! 305: result = ((unsigned int)(cp[0])) << 8; ! 306: result |= ((unsigned int)(cp[1])); ! 307: ! 308: return (result); ! 309: } ! 310: ! 311: void ! 312: isc__buffer_putuint16(isc_buffer_t *b, isc_uint16_t val) { ! 313: REQUIRE(ISC_BUFFER_VALID(b)); ! 314: REQUIRE(b->used + 2 <= b->length); ! 315: ! 316: ISC__BUFFER_PUTUINT16(b, val); ! 317: } ! 318: ! 319: void ! 320: isc__buffer_putuint24(isc_buffer_t *b, isc_uint32_t val) { ! 321: REQUIRE(ISC_BUFFER_VALID(b)); ! 322: REQUIRE(b->used + 3 <= b->length); ! 323: ! 324: ISC__BUFFER_PUTUINT24(b, val); ! 325: } ! 326: ! 327: isc_uint32_t ! 328: isc_buffer_getuint32(isc_buffer_t *b) { ! 329: unsigned char *cp; ! 330: isc_uint32_t result; ! 331: ! 332: /* ! 333: * Read an unsigned 32-bit integer in network byte order from 'b', ! 334: * convert it to host byte order, and return it. ! 335: */ ! 336: ! 337: REQUIRE(ISC_BUFFER_VALID(b)); ! 338: REQUIRE(b->used - b->current >= 4); ! 339: ! 340: cp = isc_buffer_current(b); ! 341: b->current += 4; ! 342: result = ((unsigned int)(cp[0])) << 24; ! 343: result |= ((unsigned int)(cp[1])) << 16; ! 344: result |= ((unsigned int)(cp[2])) << 8; ! 345: result |= ((unsigned int)(cp[3])); ! 346: ! 347: return (result); ! 348: } ! 349: ! 350: void ! 351: isc__buffer_putuint32(isc_buffer_t *b, isc_uint32_t val) { ! 352: REQUIRE(ISC_BUFFER_VALID(b)); ! 353: REQUIRE(b->used + 4 <= b->length); ! 354: ! 355: ISC__BUFFER_PUTUINT32(b, val); ! 356: } ! 357: ! 358: isc_uint64_t ! 359: isc_buffer_getuint48(isc_buffer_t *b) { ! 360: unsigned char *cp; ! 361: isc_uint64_t result; ! 362: ! 363: /* ! 364: * Read an unsigned 48-bit integer in network byte order from 'b', ! 365: * convert it to host byte order, and return it. ! 366: */ ! 367: ! 368: REQUIRE(ISC_BUFFER_VALID(b)); ! 369: REQUIRE(b->used - b->current >= 6); ! 370: ! 371: cp = isc_buffer_current(b); ! 372: b->current += 6; ! 373: result = ((isc_int64_t)(cp[0])) << 40; ! 374: result |= ((isc_int64_t)(cp[1])) << 32; ! 375: result |= ((isc_int64_t)(cp[2])) << 24; ! 376: result |= ((isc_int64_t)(cp[3])) << 16; ! 377: result |= ((isc_int64_t)(cp[4])) << 8; ! 378: result |= ((isc_int64_t)(cp[5])); ! 379: ! 380: return (result); ! 381: } ! 382: ! 383: void ! 384: isc__buffer_putuint48(isc_buffer_t *b, isc_uint64_t val) { ! 385: isc_uint16_t valhi; ! 386: isc_uint32_t vallo; ! 387: ! 388: REQUIRE(ISC_BUFFER_VALID(b)); ! 389: REQUIRE(b->used + 6 <= b->length); ! 390: ! 391: valhi = (isc_uint16_t)(val >> 32); ! 392: vallo = (isc_uint32_t)(val & 0xFFFFFFFF); ! 393: ISC__BUFFER_PUTUINT16(b, valhi); ! 394: ISC__BUFFER_PUTUINT32(b, vallo); ! 395: } ! 396: ! 397: void ! 398: isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base, ! 399: unsigned int length) ! 400: { ! 401: REQUIRE(ISC_BUFFER_VALID(b)); ! 402: REQUIRE(b->used + length <= b->length); ! 403: ! 404: ISC__BUFFER_PUTMEM(b, base, length); ! 405: } ! 406: ! 407: void ! 408: isc__buffer_putstr(isc_buffer_t *b, const char *source) { ! 409: unsigned int l; ! 410: unsigned char *cp; ! 411: ! 412: REQUIRE(ISC_BUFFER_VALID(b)); ! 413: REQUIRE(source != NULL); ! 414: ! 415: /* ! 416: * Do not use ISC__BUFFER_PUTSTR(), so strlen is only done once. ! 417: */ ! 418: l = strlen(source); ! 419: ! 420: REQUIRE(l <= isc_buffer_availablelength(b)); ! 421: ! 422: cp = isc_buffer_used(b); ! 423: memcpy(cp, source, l); ! 424: b->used += l; ! 425: } ! 426: ! 427: isc_result_t ! 428: isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r) { ! 429: unsigned char *base; ! 430: unsigned int available; ! 431: ! 432: REQUIRE(ISC_BUFFER_VALID(b)); ! 433: REQUIRE(r != NULL); ! 434: ! 435: /* ! 436: * XXXDCL ! 437: */ ! 438: base = isc_buffer_used(b); ! 439: available = isc_buffer_availablelength(b); ! 440: if (r->length > available) ! 441: return (ISC_R_NOSPACE); ! 442: memcpy(base, r->base, r->length); ! 443: b->used += r->length; ! 444: ! 445: return (ISC_R_SUCCESS); ! 446: } ! 447: ! 448: isc_result_t ! 449: isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer, ! 450: unsigned int length) ! 451: { ! 452: isc_buffer_t *dbuf; ! 453: ! 454: REQUIRE(dynbuffer != NULL); ! 455: REQUIRE(*dynbuffer == NULL); ! 456: ! 457: dbuf = isc_mem_get(mctx, length + sizeof(isc_buffer_t)); ! 458: if (dbuf == NULL) ! 459: return (ISC_R_NOMEMORY); ! 460: ! 461: isc_buffer_init(dbuf, ((unsigned char *)dbuf) + sizeof(isc_buffer_t), ! 462: length); ! 463: dbuf->mctx = mctx; ! 464: ! 465: *dynbuffer = dbuf; ! 466: ! 467: return (ISC_R_SUCCESS); ! 468: } ! 469: ! 470: void ! 471: isc_buffer_free(isc_buffer_t **dynbuffer) { ! 472: unsigned int real_length; ! 473: isc_buffer_t *dbuf; ! 474: isc_mem_t *mctx; ! 475: ! 476: REQUIRE(dynbuffer != NULL); ! 477: REQUIRE(ISC_BUFFER_VALID(*dynbuffer)); ! 478: REQUIRE((*dynbuffer)->mctx != NULL); ! 479: ! 480: dbuf = *dynbuffer; ! 481: *dynbuffer = NULL; /* destroy external reference */ ! 482: ! 483: real_length = dbuf->length + sizeof(isc_buffer_t); ! 484: mctx = dbuf->mctx; ! 485: dbuf->mctx = NULL; ! 486: isc_buffer_invalidate(dbuf); ! 487: ! 488: isc_mem_put(mctx, dbuf, real_length); ! 489: }