diff options
author | Christopher Peplin <chris.peplin@rhubarbtech.com> | 2013-12-29 11:44:03 -0500 |
---|---|---|
committer | Christopher Peplin <chris.peplin@rhubarbtech.com> | 2013-12-29 11:44:03 -0500 |
commit | a855335e3ad18a9d0094357eb39622448f8649a9 (patch) | |
tree | 0c00ced6710ee783febd34d8e28d7f3140031a87 | |
parent | 6830d35b449141305f137f78f09c2b879bfb9b33 (diff) |
Standardize argument ordering for bitfield functions.
-rw-r--r-- | src/bitfield/bitfield.c | 21 | ||||
-rw-r--r-- | src/bitfield/bitfield.h | 62 | ||||
-rw-r--r-- | tests/bitfield_tests.c | 10 |
3 files changed, 72 insertions, 21 deletions
diff --git a/src/bitfield/bitfield.c b/src/bitfield/bitfield.c index b0396413..934d5a6a 100644 --- a/src/bitfield/bitfield.c +++ b/src/bitfield/bitfield.c @@ -55,24 +55,21 @@ uint8_t nthByte(const uint64_t source, const uint16_t byteNum) { return (source >> (64 - ((byteNum + 1) * CHAR_BIT))) & 0xFF; } -uint8_t getNibble(const uint8_t nibble_index, const uint8_t data[], - const uint8_t length) { +uint8_t getNibble(const uint8_t source[], const uint8_t source_length, + const uint8_t nibble_index) { uint8_t byte_index = nibble_index / 2; - uint8_t result; - if(byte_index < length) { - result = data[byte_index]; - if(nibble_index % 2 == 0) { - result >>= NIBBLE_SIZE; - } + uint8_t result = getByte(source, source_length, byte_index); + if(nibble_index % 2 == 0) { + result >>= NIBBLE_SIZE; } result &= bitmask(NIBBLE_SIZE); return result; } -uint8_t getByte(const uint8_t byte_index, const uint8_t data[], - const uint8_t length) { - if(byte_index < length) { - return data[byte_index]; +uint8_t getByte(const uint8_t source[], const uint8_t source_length, + const uint8_t byte_index) { + if(byte_index < source_length) { + return source[byte_index]; } return 0; } diff --git a/src/bitfield/bitfield.h b/src/bitfield/bitfield.h index bf5c9b7d..45e3ba26 100644 --- a/src/bitfield/bitfield.h +++ b/src/bitfield/bitfield.h @@ -8,11 +8,28 @@ extern "C" { #endif -uint8_t getNibble(const uint8_t nibble_index, const uint8_t data[], - const uint8_t length); +/* Public: Return a single nibble from the byte array, with range checking. + * + * source - the source byte array. + * source_length - the total length of the source array. + * nibble_index - the index of the nibble to retreive. The leftmost nibble is + * index 0. + * + * Returns the retreived nibble, right aligned in a uint8_t. + */ +uint8_t getNibble(const uint8_t source[], const uint8_t source_length, + const uint8_t nibble_index); -uint8_t getByte(const uint8_t byte_index, const uint8_t data[], - const uint8_t length); +/* Public: Return a single byte from the byte array, with range checking. + * + * source - the source byte array. + * source_length - the total length of the source array. + * byte_index - the index of the byte to retreive. The leftmost byte is index 0. + * + * Returns the retreived byte. + */ +uint8_t getByte(const uint8_t source[], const uint8_t source_length, + const uint8_t byte_index); /* Public: Copy a range of bits from one bit array to another. * @@ -23,6 +40,17 @@ uint8_t getByte(const uint8_t byte_index, const uint8_t data[], * A bit array with regards to this function always has the leftmost bit in byte * 0, i.e. bit index is the leftmost bit of byte 0. Endianness does not matter. * + * For example: + * + * uint8_t source[4] = {0x11, 0x22, 0x33, 0x44}; + * uint8_t destination[4] = {0}; + * copyBits(source, sizeof(source), 8, 8, destination, + * sizeof(destination), 0); + * // destination[0] == 0x22 + * // destination[1] == 0x0 + * // destination[2] == 0x0 + * // destination[3] == 0x0 + * * Thanks to * http://stackoverflow.com/questions/3534535/whats-a-time-efficient-algorithm-to-copy-unaligned-bit-arrays * for the implementation of the algorithm. @@ -50,6 +78,32 @@ bool copyBits(const uint8_t* source_origin, const uint16_t source_length, uint8_t* destination_origin, const uint16_t destination_length, const uint16_t destination_offset); +/* Public: Copy a range of bits from one array to another, right aligning the + * result. + * + * This is mostly useful if you want to cast the result to an integer type + * instead of a byte array. + * + * For example: + * + * uint8_t source[4] = {0x11, 0x22, 0x33, 0x44}; + * uint8_t destination[4] = {0}; + * copyBitsRightAligned(source, sizeof(source), 8, 8, destination, + * sizeof(destination)); + * // destination[0] == 0x0 + * // destination[1] == 0x0 + * // destination[2] == 0x0 + * // destination[3] == 0x22 + * + * int value = (int)destination; + * // value == 0x22 == 32 + * + * The arguments are the same as copyBits, but without the destination_offset + * option - that's set automatically to right align the result. + * + * Returns true if the copy was successful and false if the range exceeded the + * size of the source or destination, or if the range size negative or 0. + */ bool copyBitsRightAligned(const uint8_t source[], const uint16_t source_length, const uint16_t offset, const uint16_t bit_count, uint8_t* destination, const uint16_t destination_length); diff --git a/tests/bitfield_tests.c b/tests/bitfield_tests.c index e2304ea0..00a28a36 100644 --- a/tests/bitfield_tests.c +++ b/tests/bitfield_tests.c @@ -193,9 +193,9 @@ END_TEST START_TEST (test_get_byte) { uint8_t data[4] = {0x12, 0x34, 0x56, 0x78}; - uint8_t result = getByte(0, data, sizeof(data)); + uint8_t result = getByte(data, sizeof(data), 0); ck_assert_int_eq(result, 0x12); - result = getByte(3, data, sizeof(data)); + result = getByte(data, sizeof(data), 3); ck_assert_int_eq(result, 0x78); } END_TEST @@ -203,11 +203,11 @@ END_TEST START_TEST (test_get_nibble) { uint8_t data[4] = {0x12, 0x34, 0x56, 0x78}; - uint8_t result = getNibble(0, data, sizeof(data)); + uint8_t result = getNibble(data, sizeof(data), 0); ck_assert_int_eq(result, 0x1); - result = getNibble(1, data, sizeof(data)); + result = getNibble(data, sizeof(data), 1); ck_assert_int_eq(result, 0x2); - result = getNibble(2, data, sizeof(data)); + result = getNibble(data, sizeof(data), 2); ck_assert_int_eq(result, 0x3); } END_TEST |