File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / lib / isc / buffer.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:08:38 2012 UTC (12 years, 1 month ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    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.1 2012/05/29 12:08:38 misho 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>