From 8404fb0212f9fb77bc53b23004b829b488430700 Mon Sep 17 00:00:00 2001 From: Yves-Alexis Perez Date: Sat, 11 Apr 2015 22:03:59 +0200 Subject: Imported Upstream version 5.3.0 --- src/libstrongswan/plugins/bliss/bliss_bitpacker.c | 207 ++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 src/libstrongswan/plugins/bliss/bliss_bitpacker.c (limited to 'src/libstrongswan/plugins/bliss/bliss_bitpacker.c') diff --git a/src/libstrongswan/plugins/bliss/bliss_bitpacker.c b/src/libstrongswan/plugins/bliss/bliss_bitpacker.c new file mode 100644 index 000000000..4d8446119 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_bitpacker.c @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY;https://www.hsr.ch/HSR-intern-Anmeldung.4409.0.html?&no_cache=1 without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "bliss_bitpacker.h" + +typedef struct private_bliss_bitpacker_t private_bliss_bitpacker_t; + +/** + * Private data structure for bliss_bitpacker_t object + */ +struct private_bliss_bitpacker_t { + /** + * Public interface. + */ + bliss_bitpacker_t public; + + /** + * Current number of bits written to buffer + */ + size_t bits; + + /** + * Bit buffer for up to 32 bits + */ + uint32_t bits_buf; + + /** + * Bits left in the bit buffer + */ + size_t bits_left; + + /** + * Buffer + */ + chunk_t buf; + + /** + * Read/Write pointer into buffer + */ + chunk_t pos; + +}; + +METHOD(bliss_bitpacker_t, get_bits, size_t, + private_bliss_bitpacker_t *this) +{ + return this->bits; +} + +METHOD(bliss_bitpacker_t, write_bits, bool, + private_bliss_bitpacker_t *this, uint32_t value, size_t bits) +{ + if (bits == 0) + { + return TRUE; + } + if (bits > 32) + { + return FALSE; + } + if (bits < 32) + { + value &= (1 << bits) - 1; + } + this->bits += bits; + + while (TRUE) + { + if (bits <= this->bits_left) + { + this->bits_buf |= value << (this->bits_left - bits); + this->bits_left -= bits; + return TRUE; + } + + this->bits_buf |= value >> (bits - this->bits_left); + value &= (1 << (bits - this->bits_left)) - 1; + bits -= this->bits_left; + + if (this->pos.len < 8) + { + return FALSE; + } + htoun32(this->pos.ptr, this->bits_buf); + this->pos = chunk_skip(this->pos, 4); + this->bits_buf = 0; + this->bits_left = 32; + } +} + +METHOD(bliss_bitpacker_t, read_bits, bool, + private_bliss_bitpacker_t *this, uint32_t *value, size_t bits) +{ + if (bits > 32) + { + return FALSE; + } + *value = 0; + + while (TRUE) + { + if (this->bits_left == 0) + { + if (this->pos.len < 4) + { + return FALSE; + } + this->bits_buf = untoh32(this->pos.ptr); + this->pos = chunk_skip(this->pos, 4); + this->bits_left = 32; + } + if (bits <= this->bits_left) + { + *value |= this->bits_buf >> (this->bits_left - bits); + this->bits_buf &= (1 << (this->bits_left - bits)) - 1; + this->bits_left -= bits; + + return TRUE; + } + *value |= this->bits_buf << (bits - this->bits_left); + bits -= this->bits_left; + this->bits_left = 0; + } +} + +METHOD(bliss_bitpacker_t, extract_buf, chunk_t, + private_bliss_bitpacker_t *this) +{ + chunk_t buf; + + htoun32(this->pos.ptr, this->bits_buf); + this->pos.len -= 4; + buf = this->buf; + buf.len = this->buf.len - this->pos.len - this->bits_left/8; + this->buf = this->pos = chunk_empty; + + return buf; +} + +METHOD(bliss_bitpacker_t, destroy, void, + private_bliss_bitpacker_t *this) +{ + free(this->buf.ptr); + free(this); +} + +/** + * See header. + */ +bliss_bitpacker_t *bliss_bitpacker_create(uint16_t max_bits) +{ + private_bliss_bitpacker_t *this; + + INIT(this, + .public = { + .get_bits = _get_bits, + .write_bits = _write_bits, + .read_bits = _read_bits, + .extract_buf = _extract_buf, + .destroy = _destroy, + }, + .bits_left = 32, + .buf = chunk_alloc(round_up(max_bits, 32)/8), + ); + + this->pos = this->buf; + + return &this->public; +} + +/** + * See header. + */ +bliss_bitpacker_t *bliss_bitpacker_create_from_data(chunk_t data) +{ + private_bliss_bitpacker_t *this; + + INIT(this, + .public = { + .get_bits = _get_bits, + .write_bits = _write_bits, + .read_bits = _read_bits, + .extract_buf = _extract_buf, + .destroy = _destroy, + }, + .bits = 8 * data.len, + .buf = chunk_alloc(round_up(data.len, 4)), + ); + + memset(this->buf.ptr + this->buf.len - 4, 0x00, 4); + memcpy(this->buf.ptr, data.ptr, data.len); + this->pos = this->buf; + + return &this->public; +} -- cgit v1.2.3