bitpack 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|