Annotation of embedaddon/strongswan/src/libstrongswan/bio/bio_writer.c, revision 1.1.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>