Annotation of embedaddon/ntp/lib/isc/buffer.c, revision 1.1
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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>