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>