Annotation of embedaddon/ntp/lib/isc/buffer.c, revision 1.1.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>