Annotation of embedaddon/strongswan/src/libstrongswan/plugins/bliss/bliss_bitpacker.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2014 Andreas Steffen
        !             3:  * HSR Hochschule fuer Technik Rapperswil
        !             4:  *
        !             5:  * This program is free software; you can redistribute it and/or modify it
        !             6:  * under the terms of the GNU General Public License as published by the
        !             7:  * Free Software Foundation; either version 2 of the License, or (at your
        !             8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
        !             9:  *
        !            10:  * This program is distributed in the hope that it will be useful, but
        !            11:  * WITHOUT ANY WARRANTY;https://www.hsr.ch/HSR-intern-Anmeldung.4409.0.html?&no_cache=1 without even the implied warranty of MERCHANTABILITY
        !            12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        !            13:  * for more details.
        !            14:  */
        !            15: 
        !            16: #include "bliss_bitpacker.h"
        !            17: 
        !            18: typedef struct private_bliss_bitpacker_t private_bliss_bitpacker_t;
        !            19: 
        !            20: /**
        !            21:  * Private data structure for bliss_bitpacker_t object
        !            22:  */
        !            23: struct private_bliss_bitpacker_t {
        !            24:        /**
        !            25:         * Public interface.
        !            26:         */
        !            27:        bliss_bitpacker_t public;
        !            28: 
        !            29:        /**
        !            30:         * Current number of bits written to buffer
        !            31:         */
        !            32:        size_t bits;
        !            33: 
        !            34:        /**
        !            35:         * Bit buffer for up to 32 bits
        !            36:         */
        !            37:        uint32_t bits_buf;
        !            38: 
        !            39:        /**
        !            40:         * Bits left in the bit buffer
        !            41:         */
        !            42:        size_t bits_left;
        !            43: 
        !            44:        /**
        !            45:         * Buffer
        !            46:         */
        !            47:        chunk_t buf;
        !            48: 
        !            49:        /**
        !            50:         * Read/Write pointer into buffer
        !            51:         */
        !            52:        chunk_t pos;
        !            53: 
        !            54: };
        !            55: 
        !            56: METHOD(bliss_bitpacker_t, get_bits, size_t,
        !            57:        private_bliss_bitpacker_t *this)
        !            58: {
        !            59:        return this->bits;
        !            60: }
        !            61: 
        !            62: METHOD(bliss_bitpacker_t, write_bits, bool,
        !            63:        private_bliss_bitpacker_t *this, uint32_t value, size_t bits)
        !            64: {
        !            65:        if (bits == 0)
        !            66:        {
        !            67:                return TRUE;
        !            68:        }
        !            69:        if (bits > 32)
        !            70:        {
        !            71:                return FALSE;
        !            72:        }
        !            73:        if (bits < 32)
        !            74:        {
        !            75:                value &= (1 << bits) - 1;
        !            76:        }
        !            77:        this->bits += bits;
        !            78: 
        !            79:        while (TRUE)
        !            80:        {
        !            81:                if (bits <= this->bits_left)
        !            82:                {
        !            83:                        this->bits_buf |= value << (this->bits_left - bits);
        !            84:                        this->bits_left -= bits;
        !            85:                        return TRUE;
        !            86:                }
        !            87: 
        !            88:                this->bits_buf |= value >> (bits - this->bits_left);
        !            89:                value &= (1 << (bits - this->bits_left)) - 1;
        !            90:                bits -= this->bits_left;
        !            91: 
        !            92:                if (this->pos.len < 8)
        !            93:                {
        !            94:                        return FALSE;
        !            95:                }
        !            96:                htoun32(this->pos.ptr, this->bits_buf);
        !            97:                this->pos = chunk_skip(this->pos, 4);
        !            98:                this->bits_buf = 0;
        !            99:                this->bits_left = 32;
        !           100:        }
        !           101: }
        !           102: 
        !           103: METHOD(bliss_bitpacker_t, read_bits, bool,
        !           104:        private_bliss_bitpacker_t *this, uint32_t *value, size_t bits)
        !           105: {
        !           106:        if (bits > 32)
        !           107:        {
        !           108:                return FALSE;
        !           109:        }
        !           110:        *value = 0;
        !           111: 
        !           112:        while (TRUE)
        !           113:        {
        !           114:                if (this->bits_left == 0)
        !           115:                {
        !           116:                        if (this->pos.len < 4)
        !           117:                        {
        !           118:                                return FALSE;
        !           119:                        }
        !           120:                        this->bits_buf = untoh32(this->pos.ptr);
        !           121:                        this->pos = chunk_skip(this->pos, 4);
        !           122:                        this->bits_left = 32;
        !           123:                }
        !           124:                if (bits <= this->bits_left)
        !           125:                {
        !           126:                        *value |= this->bits_buf >> (this->bits_left - bits);
        !           127:                        this->bits_buf &= (1 << (this->bits_left - bits)) - 1;
        !           128:                        this->bits_left -= bits;
        !           129: 
        !           130:                        return TRUE;
        !           131:                }
        !           132:                *value |= this->bits_buf << (bits - this->bits_left);
        !           133:                bits -= this->bits_left;
        !           134:                this->bits_left = 0;
        !           135:        }
        !           136: }
        !           137: 
        !           138: METHOD(bliss_bitpacker_t, extract_buf, chunk_t,
        !           139:        private_bliss_bitpacker_t *this)
        !           140: {
        !           141:        chunk_t buf;
        !           142: 
        !           143:        htoun32(this->pos.ptr, this->bits_buf);
        !           144:        this->pos.len -= 4;
        !           145:        buf = this->buf;
        !           146:        buf.len = this->buf.len - this->pos.len - this->bits_left/8;
        !           147:        this->buf = this->pos = chunk_empty;
        !           148: 
        !           149:        return buf;
        !           150: }
        !           151: 
        !           152: METHOD(bliss_bitpacker_t, destroy, void,
        !           153:        private_bliss_bitpacker_t *this)
        !           154: {
        !           155:        free(this->buf.ptr);
        !           156:        free(this);
        !           157: }
        !           158: 
        !           159: /**
        !           160:  * See header.
        !           161:  */
        !           162: bliss_bitpacker_t *bliss_bitpacker_create(uint16_t max_bits)
        !           163: {
        !           164:        private_bliss_bitpacker_t *this;
        !           165: 
        !           166:        INIT(this,
        !           167:                .public = {
        !           168:                        .get_bits = _get_bits,
        !           169:                        .write_bits = _write_bits,
        !           170:                        .read_bits = _read_bits,
        !           171:                        .extract_buf = _extract_buf,
        !           172:                        .destroy = _destroy,
        !           173:                },
        !           174:                .bits_left = 32,
        !           175:                .buf = chunk_alloc(round_up(max_bits, 32)/8),
        !           176:        );
        !           177: 
        !           178:        this->pos = this->buf;
        !           179: 
        !           180:        return &this->public;
        !           181: }
        !           182: 
        !           183: /**
        !           184:  * See header.
        !           185:  */
        !           186: bliss_bitpacker_t *bliss_bitpacker_create_from_data(chunk_t data)
        !           187: {
        !           188:        private_bliss_bitpacker_t *this;
        !           189: 
        !           190:        INIT(this,
        !           191:                .public = {
        !           192:                        .get_bits = _get_bits,
        !           193:                        .write_bits = _write_bits,
        !           194:                        .read_bits = _read_bits,
        !           195:                        .extract_buf = _extract_buf,
        !           196:                        .destroy = _destroy,
        !           197:                },
        !           198:                .bits = 8 * data.len,
        !           199:                .buf = chunk_alloc(round_up(data.len, 4)),
        !           200:        );
        !           201: 
        !           202:        memset(this->buf.ptr + this->buf.len - 4, 0x00, 4);
        !           203:        memcpy(this->buf.ptr, data.ptr, data.len);
        !           204:        this->pos = this->buf;
        !           205: 
        !           206:        return &this->public;
        !           207: }

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