bitpack 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +7 -0
- data/LICENSE +20 -0
- data/README +98 -0
- data/Rakefile +87 -0
- data/ext/bitpack.c +483 -0
- data/ext/bitpack.h +350 -0
- data/ext/bitpack_ext.c +662 -0
- data/ext/extconf.rb +8 -0
- data/lib/bitpack.rb +53 -0
- data/test/bitpack_tests.rb +405 -0
- metadata +57 -0
data/ext/bitpack.h
ADDED
@@ -0,0 +1,350 @@
|
|
1
|
+
#ifndef _BITPACK_H
|
2
|
+
#define _BITPACK_H
|
3
|
+
|
4
|
+
/**
|
5
|
+
* @file bitpack.h
|
6
|
+
* @brief bitpack typedefs, defines, and exported function prototypes
|
7
|
+
*/
|
8
|
+
|
9
|
+
/** Bitpack success return value. */
|
10
|
+
#define BITPACK_RV_SUCCESS 1
|
11
|
+
|
12
|
+
/** Bitpack failure return value. */
|
13
|
+
#define BITPACK_RV_ERROR 0
|
14
|
+
|
15
|
+
/**
|
16
|
+
* The number of bytes allocated by bitpack_init_default() to hold the
|
17
|
+
* bitpack.
|
18
|
+
*/
|
19
|
+
#define BITPACK_DEFAULT_MEM_SIZE 32
|
20
|
+
|
21
|
+
/** The maximum size of a bitpack error string. */
|
22
|
+
#define BITPACK_ERR_BUF_SIZE 100
|
23
|
+
|
24
|
+
/** The various bitpack error types. */
|
25
|
+
typedef enum {
|
26
|
+
BITPACK_ERR_CLEAR = 0,
|
27
|
+
BITPACK_ERR_MALLOC_FAILED = 1,
|
28
|
+
BITPACK_ERR_INVALID_INDEX = 2,
|
29
|
+
BITPACK_ERR_VALUE_TOO_BIG = 3,
|
30
|
+
BITPACK_ERR_RANGE_TOO_BIG = 4,
|
31
|
+
BITPACK_ERR_READ_PAST_END = 5,
|
32
|
+
BITPACK_ERR_EMPTY = 6
|
33
|
+
} bitpack_err_t;
|
34
|
+
|
35
|
+
struct _bitpack_t
|
36
|
+
{
|
37
|
+
unsigned long size; /** size of bitpack in bits */
|
38
|
+
unsigned long read_pos; /** current position for reading */
|
39
|
+
unsigned long data_size; /** amount of allocated memory */
|
40
|
+
unsigned char *data; /** pointer to the acutal data */
|
41
|
+
bitpack_err_t error; /** error status of last operation */
|
42
|
+
char error_str[BITPACK_ERR_BUF_SIZE]; /** error string of last operation */
|
43
|
+
};
|
44
|
+
|
45
|
+
/** The Bitpack object type. */
|
46
|
+
typedef struct _bitpack_t *bitpack_t;
|
47
|
+
|
48
|
+
/**
|
49
|
+
* @brief Default bitpack constructor.
|
50
|
+
*
|
51
|
+
* Allocates and returns a new bitpack object. @c BITPACK_DEFAULT_MEM_SIZE bytes
|
52
|
+
* are allocated to store the bits. Use #bitpack_init() to control the
|
53
|
+
* number of bytes allocated by the constructor.
|
54
|
+
*
|
55
|
+
* @return the newly allocated bitpack object
|
56
|
+
*/
|
57
|
+
#define bitpack_init_default() bitpack_init(BITPACK_DEFAULT_MEM_SIZE)
|
58
|
+
|
59
|
+
/**
|
60
|
+
* @brief Bitpack constructor.
|
61
|
+
*
|
62
|
+
* Allocates and returns a new bitpack object. The number of bytes allocated
|
63
|
+
* to store the bits is specified by the num_bytes parameter.
|
64
|
+
*
|
65
|
+
* @param[in] num_bytes number of bytes to allocate for bit storage
|
66
|
+
* @return the newly allocated bitpack object
|
67
|
+
*/
|
68
|
+
bitpack_t bitpack_init(unsigned long num_bytes);
|
69
|
+
|
70
|
+
/**
|
71
|
+
* @brief Bitpack constructor.
|
72
|
+
*
|
73
|
+
* Allocates and returns a new bitpack object. The contents of the bitpack
|
74
|
+
* are initialized from an external byte array. The contents of the external
|
75
|
+
* byte array are copied into the bitpack object and are not modified.
|
76
|
+
*
|
77
|
+
* @param[in] bytes pointer to the external byte array
|
78
|
+
* @param[in] num_bytes size of the external byte array
|
79
|
+
* @return the newly allocated bitpack object
|
80
|
+
*/
|
81
|
+
bitpack_t bitpack_init_from_bytes(unsigned char *bytes, unsigned long num_bytes);
|
82
|
+
|
83
|
+
/**
|
84
|
+
* @brief Bitpack destructor.
|
85
|
+
*
|
86
|
+
* Destroys a bitpack object, freeing all memory it contained.
|
87
|
+
*
|
88
|
+
* @param[in] bp the bitpack object
|
89
|
+
*/
|
90
|
+
void bitpack_destroy(bitpack_t bp);
|
91
|
+
|
92
|
+
/**
|
93
|
+
* @brief Access the current size in bits of the bitpack object.
|
94
|
+
*
|
95
|
+
* @param[in] bp the bitpack object
|
96
|
+
* @return the current size of the bitpack object
|
97
|
+
*/
|
98
|
+
unsigned long bitpack_size(bitpack_t bp);
|
99
|
+
|
100
|
+
/**
|
101
|
+
* @brief Access the amount of data currently allocated to this bitpack object.
|
102
|
+
*
|
103
|
+
* @param[in] bp the bitpack object
|
104
|
+
* @return the number of bytes allocated
|
105
|
+
*/
|
106
|
+
unsigned long bitpack_data_size(bitpack_t bp);
|
107
|
+
|
108
|
+
/**
|
109
|
+
* @brief Access the current read position of the bitpack object.
|
110
|
+
*
|
111
|
+
* Returns the current postion in the bitpack object that the next call to
|
112
|
+
* bitpack_read_bits() or bitpack_read_bytes() will start reading bits.
|
113
|
+
*
|
114
|
+
* @param[in] bp the bitpack object
|
115
|
+
* @return the current read position
|
116
|
+
*/
|
117
|
+
unsigned long bitpack_read_pos(bitpack_t bp);
|
118
|
+
|
119
|
+
/**
|
120
|
+
* @brief Reset the current read position to the beginning of the bitpack object.
|
121
|
+
*
|
122
|
+
* @param[in] bp the bitpack object
|
123
|
+
*/
|
124
|
+
void bitpack_reset_read_pos(bitpack_t bp);
|
125
|
+
|
126
|
+
/**
|
127
|
+
* @brief Access the error type from a bitpack object.
|
128
|
+
*
|
129
|
+
* Returns the error type currently set in the bitpack object. To get the
|
130
|
+
* string representation of this error, see bitpack_get_error_str().
|
131
|
+
*
|
132
|
+
* @param[in] bp the bitpack object
|
133
|
+
* @return the error type
|
134
|
+
*/
|
135
|
+
bitpack_err_t bitpack_get_error(bitpack_t bp);
|
136
|
+
|
137
|
+
/**
|
138
|
+
* @brief Access the error string from a bitpack object.
|
139
|
+
*
|
140
|
+
* Returns a static character pointer containing the error string set in the
|
141
|
+
* bitpack object. This function should be called anytime a bitpack function
|
142
|
+
* returns @c BITPACK_RV_ERROR. The error status inside a bitpack object is
|
143
|
+
* always reset when a subsequent bitpack function is called on the object.
|
144
|
+
*
|
145
|
+
* Note that the returned string is static and should NOT be passed to @c free().
|
146
|
+
*
|
147
|
+
* @param[in] bp the bitpack object
|
148
|
+
* @return the static error string or @c NULL if the last operation on this
|
149
|
+
* bitpack object did not fail
|
150
|
+
*/
|
151
|
+
char *bitpack_get_error_str(bitpack_t bp);
|
152
|
+
|
153
|
+
/**
|
154
|
+
* @brief Turn on/set a particular bit in a bitpack object.
|
155
|
+
*
|
156
|
+
* Sets the bit at @c index. If @c index is greater than the current size of the
|
157
|
+
* bitpack object, then the size is expanded and the current append position
|
158
|
+
* is set to this index.
|
159
|
+
*
|
160
|
+
* Returns @c BITPACK_RV_SUCCESS upon success. Returns @c BITPACK_RV_ERROR upon
|
161
|
+
* error and bitpack_get_error() can be used to find out why.
|
162
|
+
*
|
163
|
+
* @param[in] bp the bitpack object
|
164
|
+
* @param[in] index the bit index to set
|
165
|
+
* @return @c BITPACK_RV_SUCCESS on success, @c BITPACK_RV_ERROR on failure
|
166
|
+
*/
|
167
|
+
int bitpack_on(bitpack_t bp, unsigned long index);
|
168
|
+
|
169
|
+
/**
|
170
|
+
* @brief Turn off/unset a particular bit in a bitpack object.
|
171
|
+
*
|
172
|
+
* Unsets the bit at @c index. If @c index is greater than the current size of the
|
173
|
+
* bitpack object, then the size is expanded and the current append position
|
174
|
+
* is set to this index.
|
175
|
+
*
|
176
|
+
* @param[in] bp the bitpack object
|
177
|
+
* @param[in] index the bit index to unset
|
178
|
+
* @return @c BITPACK_RV_SUCCESS on success, @c BITPACK_RV_ERROR on failure
|
179
|
+
*/
|
180
|
+
int bitpack_off(bitpack_t bp, unsigned long index);
|
181
|
+
|
182
|
+
/**
|
183
|
+
* @brief Access a particular bit.
|
184
|
+
*
|
185
|
+
* Get the value of the bit at @c index.
|
186
|
+
*
|
187
|
+
* @param[in] bp the bitpack object
|
188
|
+
* @param[in] index the bit index to get
|
189
|
+
* @param[out] bit value of the bit
|
190
|
+
* @return @c BITPACK_RV_SUCCESS on success, @c BITPACK_RV_ERROR on failure
|
191
|
+
*/
|
192
|
+
int bitpack_get(bitpack_t bp, unsigned long index, unsigned char *bit);
|
193
|
+
|
194
|
+
/**
|
195
|
+
* @brief Set the specified range of bits in a bitpack object.
|
196
|
+
*
|
197
|
+
* Packs @c value into @c num_bits bits starting at @c index. The number of bits
|
198
|
+
* required to represent @c value is checked against the size of the range. If
|
199
|
+
* @c index + @c num_bits is greater than the current size of the bitpack, then the
|
200
|
+
* size is adjusted appropriately.
|
201
|
+
*
|
202
|
+
* @param[in] bp the bitpack object
|
203
|
+
* @param[in] value the value to set
|
204
|
+
* @param[in] num_bits the number of bits to pack the value into
|
205
|
+
* @param[in] index the bit index to start packing value
|
206
|
+
* @return @c BITPACK_RV_SUCCESS on success, @c BITPACK_RV_ERROR on failure
|
207
|
+
*/
|
208
|
+
int bitpack_set_bits(bitpack_t bp, unsigned long value, unsigned long num_bits, unsigned long index);
|
209
|
+
|
210
|
+
/**
|
211
|
+
* @brief Set the specified range of bytes in a bitpack object.
|
212
|
+
*
|
213
|
+
* Packs the byte array @c value into @c num_bytes starting at @c index. The size of
|
214
|
+
* the bitpack object is adjust appropriately if necessary.
|
215
|
+
*
|
216
|
+
* @param[in] bp the bitpack object
|
217
|
+
* @param[in] value the byte array to set
|
218
|
+
* @param[in] num_bytes the number of bytes in @c value
|
219
|
+
* @param[in] index the bit index to start packing @c value
|
220
|
+
* @return @c BITPACK_RV_SUCCESS on success, @c BITPACK_RV_ERROR on failure
|
221
|
+
*/
|
222
|
+
int bitpack_set_bytes(bitpack_t bp, unsigned char *value, unsigned long num_bytes, unsigned long index);
|
223
|
+
|
224
|
+
/**
|
225
|
+
* @brief Access the value of a range of bits.
|
226
|
+
*
|
227
|
+
* Unpacks @c num_bits bits at index @c index and sets the value to @c value.
|
228
|
+
*
|
229
|
+
* @param[in] bp the bitpack object
|
230
|
+
* @param[in] num_bits the number of bits to unpack
|
231
|
+
* @param[in] index the bit index to start unpacking from
|
232
|
+
* @param[out] value pointer to the location to write the value of the unpacked bits to
|
233
|
+
* @return @c BITPACK_RV_SUCCESS on success, @c BITPACK_RV_ERROR on failure
|
234
|
+
*/
|
235
|
+
int bitpack_get_bits(bitpack_t bp, unsigned long num_bits, unsigned long index, unsigned long *value);
|
236
|
+
|
237
|
+
/**
|
238
|
+
* @brief Access the value of a range of bytes.
|
239
|
+
*
|
240
|
+
* Unpacks @c num_bytes bytes at index @c index and sets the value to @c value.
|
241
|
+
*
|
242
|
+
* Allocates @c num_bytes bytes to write the unpacked bytes to and sets the
|
243
|
+
* pointer pointed to by @c value to the unpacked bytes. The unpacked bytes
|
244
|
+
* should be freed by the caller.
|
245
|
+
*
|
246
|
+
* @param[in] bp the bitpack object
|
247
|
+
* @param[in] num_bytes the number of bytes to unpack
|
248
|
+
* @param[in] index the bit index to start unpacking from
|
249
|
+
* @param[out] value pointer to the location to write the unpacked byte array
|
250
|
+
* pointer to, will be set to @c NULL on failure
|
251
|
+
* @return @c BITPACK_RV_SUCCESS on success, @c BITPACK_RV_ERROR on failure
|
252
|
+
*/
|
253
|
+
int bitpack_get_bytes(bitpack_t bp, unsigned long num_bytes, unsigned long index, unsigned char **value);
|
254
|
+
|
255
|
+
/**
|
256
|
+
* @brief Append a particular value to the end of a bitpack object.
|
257
|
+
*
|
258
|
+
* Packs @c value into @c num_bits bits at the end of the bitpack object. On
|
259
|
+
* success, the size of the bitpack object is increased by @c num_bits.
|
260
|
+
*
|
261
|
+
* @param[in] bp the bitpack object
|
262
|
+
* @param[in] value the value to set
|
263
|
+
* @param[in] num_bits the number of bits to pack the value into
|
264
|
+
* @return @c BITPACK_RV_SUCCESS on success, @c BITPACK_RV_ERROR on failure
|
265
|
+
*/
|
266
|
+
#define bitpack_append_bits(bp, value, num_bits) bitpack_set_bits(bp, value, num_bits, bitpack_size(bp))
|
267
|
+
|
268
|
+
/**
|
269
|
+
* @brief Append the specified range of bytes to the end of a bitpack object.
|
270
|
+
*
|
271
|
+
* Packs the byte array @c value into @c num_bytes starting at then end of the
|
272
|
+
* bitpack object. On success, the size of the bitpack object is increased by
|
273
|
+
* @c num_bytes * 8 bits.
|
274
|
+
*
|
275
|
+
* @param[in] bp the bitpack object
|
276
|
+
* @param[in] value the byte array to set
|
277
|
+
* @param[in] num_bytes the number of bytes in @c value
|
278
|
+
* @return @c BITPACK_RV_SUCCESS on success, @c BITPACK_RV_ERROR on failure
|
279
|
+
*/
|
280
|
+
#define bitpack_append_bytes(bp, value, num_bytes) bitpack_set_bytes(bp, value, num_bytes, bitpack_size(bp))
|
281
|
+
|
282
|
+
/**
|
283
|
+
* @brief Access the value of a range of bits at the current read position.
|
284
|
+
*
|
285
|
+
* Unpacks @c num_bits bits at the current read position (see bitpack_read_pos())
|
286
|
+
* and sets the value to @c value. The current read position is advanced by
|
287
|
+
* @c num_bits bits.
|
288
|
+
*
|
289
|
+
* @param[in] bp the bitpack object
|
290
|
+
* @param[in] num_bits the number of bits to unpack
|
291
|
+
* @param[out] value pointer to the location to write the value of the unpacked bits to
|
292
|
+
* @return @c BITPACK_RV_SUCCESS on success, @c BITPACK_RV_ERROR on failure
|
293
|
+
*/
|
294
|
+
int bitpack_read_bits(bitpack_t bp, unsigned long num_bits, unsigned long *value);
|
295
|
+
|
296
|
+
/**
|
297
|
+
* @brief Access the value of a range of bytes at the current read position.
|
298
|
+
*
|
299
|
+
* Unpacks @c num_bytes bytes at the current read position (see bitpack_read_pos())
|
300
|
+
* and sets the value to @c value. The current read position is advanced by
|
301
|
+
* @c num_bytes * 8 bits.
|
302
|
+
*
|
303
|
+
* The unpacked bytes are allocated on the heap and should be freed by the
|
304
|
+
* caller.
|
305
|
+
*
|
306
|
+
* @param[in] bp the bitpack object
|
307
|
+
* @param[in] num_bytes the number of bytes to unpack
|
308
|
+
* @param[out] value pointer to the location to write the unpacked byte array
|
309
|
+
* pointer to, will be set to @c NULL on failure
|
310
|
+
* @return @c BITPACK_RV_SUCCESS on success, @c BITPACK_RV_ERROR on failure
|
311
|
+
*/
|
312
|
+
int bitpack_read_bytes(bitpack_t bp, unsigned long num_bytes, unsigned char **value);
|
313
|
+
|
314
|
+
/**
|
315
|
+
* @brief Convert the bitpack object to a string of 1s and 0s.
|
316
|
+
*
|
317
|
+
* Converts the bitpack object to its binary representation.
|
318
|
+
*
|
319
|
+
* The output string @c str is allocated on the heap and should be freed by the
|
320
|
+
* caller.
|
321
|
+
*
|
322
|
+
* @param[in] bp the bitpack object
|
323
|
+
* @param[out] str pointer to the location to write the binary string to
|
324
|
+
* @return @c BITPACK_RV_SUCCESS on success, @c BITPACK_RV_ERROR on failure
|
325
|
+
*/
|
326
|
+
int bitpack_to_bin(bitpack_t bp, char **str);
|
327
|
+
|
328
|
+
/**
|
329
|
+
* @brief Convert the bitpack object to a byte array.
|
330
|
+
*
|
331
|
+
* Converts the bitpack object to an array of bytes. If the current size of
|
332
|
+
* the bitpack object is not a multiple of 8, the last byte in the returned
|
333
|
+
* byte array will be padded with the appropriate number of 0 bits.
|
334
|
+
*
|
335
|
+
* The output string @c bytes is allocated on the heap and should be freed by the
|
336
|
+
* caller.
|
337
|
+
*
|
338
|
+
* The number of bytes returned is the current size in bits of the bitpack,
|
339
|
+
* divided by 8 and rounded up to the nearest byte. The output parameter
|
340
|
+
* @c num_bytes will tell you the exact value.
|
341
|
+
*
|
342
|
+
* @param[in] bp the bitpack object
|
343
|
+
* @param[out] value pointer to the location to write the byte array to
|
344
|
+
* @param[out] num_bytes pointer to the location to write the number of bytes returned
|
345
|
+
* @return @c BITPACK_RV_SUCCESS on success, @c BITPACK_RV_ERROR on failure
|
346
|
+
*/
|
347
|
+
int bitpack_to_bytes(bitpack_t bp, unsigned char **value, unsigned long *num_bytes);
|
348
|
+
|
349
|
+
#endif
|
350
|
+
|