patterncMinor
Function for reading bits
Viewed 0 times
bitsreadingfunctionfor
Problem
I've made this simple function for reading N bits from an
Main:
Result:
unsigned char* (with a possible offset) and I'm willing to share it here, get a review, suggestions for improving it, etc...typedef struct bits_t {
unsigned char *data;
unsigned int len;
} bits_t;
bits_t *read_bits(unsigned char *src, int bits_offset, int nbits){
unsigned int curr_bit, curr_byte, remaining_to_read, bit_position_in_byte;
curr_bit = curr_byte = 0;
remaining_to_read = nbits;
bits_t *bits = malloc(sizeof(bits_t));
bits->len = nbits;
bits->data = calloc(1, bits->len);
for(curr_bit = 1; curr_bit = bits_offset && remaining_to_read){
curr_byte = (curr_bit - 1) / 8;
bit_position_in_byte = (curr_bit - 1) - (curr_byte * 8);
bits->data[remaining_to_read - 1] = read_bit(src[curr_byte], bit_position_in_byte);
remaining_to_read--;
}
}
return bits;
}Main:
unsigned char *x = "oo";
bits_t *bits = read_bits(x, 0, 16);
for(i = 0; i len; i++){
printf("%d", bits->data[i]);
}Result:
0110111101101111Solution
- Consider checking
src[currentByte]for'\0'and abort when it's true (apparently the passed in string wasn't long enough). Depends on your usage though.
- Alternatively to the previous point you could add a
source_lengthparameter to let the caller supply the information of how long the sequence really is.
-
I would consider changing the interface slightly. Have some methods which manage the object for you:
bits_t *new_bits_t(int nbits)
{
bits_t *res = malloc(sizeof(bits_t));
res->data = calloc(nbits);
res->len = nbits;
return res;
}
// frees the memory allocated for the structure and sets the reference to NULL
void delete_bits_t(bits_t **bits)
{
if (bits == NULL || *bits == NULL) return;
free((*bits)->data);
free(*bits);
*bits = NULL;
}Then your
read_bits function could fill in the structure passed in and also return error code in case the reading failed (i.e. source is too short):int read_bits(unsigned char *src, bits_t *bits, int bits_offset)
{
...
}-
bit_position_in_byte = (curr_bit - 1) - (curr_byte * 8); should be equivalent to bit_position_in_byte = (curr_bit - 1) % 8;- Your loop is one based for some reason but inside the loop you have to subtract 1 from
current_biteverywhere. You should just make your loop 0 based which would de-clutter the loop a bit.
- I would find
bit_in_bytejust as descriptive a name asbit_position_in_byte.
-
You could get rid of the
remaining_to_read by calculating the position:for (curr_bit = 0; curr_bit data[nbits - curr_bit - 1] = read_bit(src[input_byte], bit_in_byte);
}- The loop apparently fills
datafrom the end which seems little bit unexpected to me (kind of string reversal).
Code Snippets
bits_t *new_bits_t(int nbits)
{
bits_t *res = malloc(sizeof(bits_t));
res->data = calloc(nbits);
res->len = nbits;
return res;
}
// frees the memory allocated for the structure and sets the reference to NULL
void delete_bits_t(bits_t **bits)
{
if (bits == NULL || *bits == NULL) return;
free((*bits)->data);
free(*bits);
*bits = NULL;
}int read_bits(unsigned char *src, bits_t *bits, int bits_offset)
{
...
}for (curr_bit = 0; curr_bit < nbits; ++curr_bit) {
input_bit = curr_bit + bits_offset - 1;
input_byte = input_bit / 8;
bit_in_byte = input_bit % 8;
bits->data[nbits - curr_bit - 1] = read_bit(src[input_byte], bit_in_byte);
}Context
StackExchange Code Review Q#35555, answer score: 3
Revisions (0)
No revisions yet.