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