Return to bliss_bitpacker.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / bliss |
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: }