Annotation of embedaddon/strongswan/src/libstrongswan/bio/bio_writer.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2012-2013 Tobias Brunner
        !             3:  * HSR Hochschule fuer Technik Rapperswil
        !             4:  *
        !             5:  * Copyright (C) 2010 Martin Willi
        !             6:  * Copyright (C) 2010 revosec AG
        !             7:  *
        !             8:  * This program is free software; you can redistribute it and/or modify it
        !             9:  * under the terms of the GNU General Public License as published by the
        !            10:  * Free Software Foundation; either version 2 of the License, or (at your
        !            11:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
        !            12:  *
        !            13:  * This program is distributed in the hope that it will be useful, but
        !            14:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            15:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        !            16:  * for more details.
        !            17:  */
        !            18: 
        !            19: #include "bio_writer.h"
        !            20: 
        !            21: typedef struct private_bio_writer_t private_bio_writer_t;
        !            22: 
        !            23: /**
        !            24:  * Private data of an bio_writer_t object.
        !            25:  */
        !            26: struct private_bio_writer_t {
        !            27: 
        !            28:        /**
        !            29:         * Public bio_writer_t interface.
        !            30:         */
        !            31:        bio_writer_t public;
        !            32: 
        !            33:        /**
        !            34:         * Allocated buffer
        !            35:         */
        !            36:        chunk_t buf;
        !            37: 
        !            38:        /**
        !            39:         * Used bytes in buffer
        !            40:         */
        !            41:        size_t used;
        !            42: 
        !            43:        /**
        !            44:         * Number of bytes to increase buffer size
        !            45:         */
        !            46:        size_t increase;
        !            47: };
        !            48: 
        !            49: /**
        !            50:  * Increase buffer size, if required
        !            51:  */
        !            52: static inline void increase(private_bio_writer_t *this, size_t required)
        !            53: {
        !            54:        bool inc = FALSE;
        !            55: 
        !            56:        while (this->used + required > this->buf.len)
        !            57:        {
        !            58:                this->buf.len += this->increase;
        !            59:                inc = TRUE;
        !            60:        }
        !            61:        if (inc)
        !            62:        {
        !            63:                this->buf.ptr = realloc(this->buf.ptr, this->buf.len);
        !            64:        }
        !            65: }
        !            66: 
        !            67: METHOD(bio_writer_t, write_uint8, void,
        !            68:        private_bio_writer_t *this, uint8_t value)
        !            69: {
        !            70:        increase(this, 1);
        !            71:        this->buf.ptr[this->used] = value;
        !            72:        this->used += 1;
        !            73: }
        !            74: 
        !            75: METHOD(bio_writer_t, write_uint16, void,
        !            76:        private_bio_writer_t *this, uint16_t value)
        !            77: {
        !            78:        increase(this, 2);
        !            79:        htoun16(this->buf.ptr + this->used, value);
        !            80:        this->used += 2;
        !            81: }
        !            82: 
        !            83: METHOD(bio_writer_t, write_uint24, void,
        !            84:        private_bio_writer_t *this, uint32_t value)
        !            85: {
        !            86:        increase(this, 3);
        !            87:        value = htonl(value);
        !            88:        memcpy(this->buf.ptr + this->used, ((char*)&value) + 1, 3);
        !            89:        this->used += 3;
        !            90: }
        !            91: 
        !            92: METHOD(bio_writer_t, write_uint32, void,
        !            93:        private_bio_writer_t *this, uint32_t value)
        !            94: {
        !            95:        increase(this, 4);
        !            96:        htoun32(this->buf.ptr + this->used, value);
        !            97:        this->used += 4;
        !            98: }
        !            99: 
        !           100: METHOD(bio_writer_t, write_uint64, void,
        !           101:        private_bio_writer_t *this, uint64_t value)
        !           102: {
        !           103:        increase(this, 8);
        !           104:        htoun64(this->buf.ptr + this->used, value);
        !           105:        this->used += 8;
        !           106: }
        !           107: 
        !           108: METHOD(bio_writer_t, write_data, void,
        !           109:        private_bio_writer_t *this, chunk_t value)
        !           110: {
        !           111:        increase(this, value.len);
        !           112:        memcpy(this->buf.ptr + this->used, value.ptr, value.len);
        !           113:        this->used += value.len;
        !           114: }
        !           115: 
        !           116: METHOD(bio_writer_t, write_data8, void,
        !           117:        private_bio_writer_t *this, chunk_t value)
        !           118: {
        !           119:        increase(this, 1 + value.len);
        !           120:        write_uint8(this, value.len);
        !           121:        write_data(this, value);
        !           122: }
        !           123: 
        !           124: METHOD(bio_writer_t, write_data16, void,
        !           125:        private_bio_writer_t *this, chunk_t value)
        !           126: {
        !           127:        increase(this, 2 + value.len);
        !           128:        write_uint16(this, value.len);
        !           129:        write_data(this, value);
        !           130: }
        !           131: 
        !           132: METHOD(bio_writer_t, write_data24, void,
        !           133:        private_bio_writer_t *this, chunk_t value)
        !           134: {
        !           135:        increase(this, 3 + value.len);
        !           136:        write_uint24(this, value.len);
        !           137:        write_data(this, value);
        !           138: }
        !           139: 
        !           140: METHOD(bio_writer_t, write_data32, void,
        !           141:        private_bio_writer_t *this, chunk_t value)
        !           142: {
        !           143:        increase(this, 4 + value.len);
        !           144:        write_uint32(this, value.len);
        !           145:        write_data(this, value);
        !           146: }
        !           147: 
        !           148: METHOD(bio_writer_t, wrap8, void,
        !           149:        private_bio_writer_t *this)
        !           150: {
        !           151:        increase(this, 1);
        !           152:        memmove(this->buf.ptr + 1, this->buf.ptr, this->used);
        !           153:        this->buf.ptr[0] = this->used;
        !           154:        this->used += 1;
        !           155: }
        !           156: 
        !           157: METHOD(bio_writer_t, wrap16, void,
        !           158:        private_bio_writer_t *this)
        !           159: {
        !           160:        increase(this, 2);
        !           161:        memmove(this->buf.ptr + 2, this->buf.ptr, this->used);
        !           162:        htoun16(this->buf.ptr, this->used);
        !           163:        this->used += 2;
        !           164: }
        !           165: 
        !           166: METHOD(bio_writer_t, wrap24, void,
        !           167:        private_bio_writer_t *this)
        !           168: {
        !           169:        uint32_t len;
        !           170: 
        !           171:        increase(this, 3);
        !           172:        memmove(this->buf.ptr + 3, this->buf.ptr, this->used);
        !           173: 
        !           174:        len = htonl(this->used);
        !           175:        memcpy(this->buf.ptr, ((char*)&len) + 1, 3);
        !           176:        this->used += 3;
        !           177: }
        !           178: 
        !           179: METHOD(bio_writer_t, wrap32, void,
        !           180:        private_bio_writer_t *this)
        !           181: {
        !           182:        increase(this, 4);
        !           183:        memmove(this->buf.ptr + 4, this->buf.ptr, this->used);
        !           184:        htoun32(this->buf.ptr, this->used);
        !           185:        this->used += 4;
        !           186: }
        !           187: 
        !           188: METHOD(bio_writer_t, skip, chunk_t,
        !           189:        private_bio_writer_t *this, size_t len)
        !           190: {
        !           191:        chunk_t skipped;
        !           192: 
        !           193:        increase(this, len);
        !           194:        skipped = chunk_create(this->buf.ptr + this->used, len);
        !           195:        this->used += len;
        !           196:        return skipped;
        !           197: }
        !           198: 
        !           199: METHOD(bio_writer_t, get_buf, chunk_t,
        !           200:        private_bio_writer_t *this)
        !           201: {
        !           202:        return chunk_create(this->buf.ptr, this->used);
        !           203: }
        !           204: 
        !           205: METHOD(bio_writer_t, extract_buf, chunk_t,
        !           206:        private_bio_writer_t *this)
        !           207: {
        !           208:        chunk_t buf = get_buf(this);
        !           209:        this->buf = chunk_empty;
        !           210:        this->used = 0;
        !           211:        return buf;
        !           212: }
        !           213: 
        !           214: METHOD(bio_writer_t, destroy, void,
        !           215:        private_bio_writer_t *this)
        !           216: {
        !           217:        free(this->buf.ptr);
        !           218:        free(this);
        !           219: }
        !           220: 
        !           221: /**
        !           222:  * See header
        !           223:  */
        !           224: bio_writer_t *bio_writer_create(uint32_t bufsize)
        !           225: {
        !           226:        private_bio_writer_t *this;
        !           227: 
        !           228:        INIT(this,
        !           229:                .public = {
        !           230:                        .write_uint8 = _write_uint8,
        !           231:                        .write_uint16 = _write_uint16,
        !           232:                        .write_uint24 = _write_uint24,
        !           233:                        .write_uint32 = _write_uint32,
        !           234:                        .write_uint64 = _write_uint64,
        !           235:                        .write_data = _write_data,
        !           236:                        .write_data8 = _write_data8,
        !           237:                        .write_data16 = _write_data16,
        !           238:                        .write_data24 = _write_data24,
        !           239:                        .write_data32 = _write_data32,
        !           240:                        .wrap8 = _wrap8,
        !           241:                        .wrap16 = _wrap16,
        !           242:                        .wrap24 = _wrap24,
        !           243:                        .wrap32 = _wrap32,
        !           244:                        .skip = _skip,
        !           245:                        .get_buf = _get_buf,
        !           246:                        .extract_buf = _extract_buf,
        !           247:                        .destroy = _destroy,
        !           248:                },
        !           249:                .increase = bufsize ? max(bufsize, 4) : 32,
        !           250:        );
        !           251:        if (bufsize)
        !           252:        {
        !           253:                this->buf = chunk_alloc(bufsize);
        !           254:        }
        !           255: 
        !           256:        return &this->public;
        !           257: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>