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>