uint8_t data[4] = {0x12, 0x34, 0x56, 0x78};
uint8_t result = get_byte(data, sizeof(data), 0);
- uint8_t result = get_nibble(data, sizeof(data), 0);
- fail_unless(copy_bits_right_aligned(data, 4, 4, 12, result, 4));
+ // result = 0x12;
+ result = get_nibble(data, sizeof(data), 0);
+ // result = 0x1;
+ bool success = copy_bits_right_aligned(data, 4, 4, 12, result, 4)
+ // success == true
+ // result[0] == 0x2
+ // result[1] == 0x34
## 8 Byte Bitfield Decoding
// result = 0x574d555a;
data = 0x00000000F34DFCFF;
- result = nth_byte(data, 0);
+ result = eightbyte_get_byte(data, 0, false);
//result = 0x0
- result = nth_byte(data, 4);
+ result = eightbyte_get_byte(data, 4, false);
//result = 0xF3
+ result = eightbyte_get_nibble(data, 10, false);
+ //result = 0x4;
+
## 8 Byte Bitfield Encoding
uint64_t data = 0;
return byte_count;
}
+uint8_t eightbyte_get_nibble(const uint64_t source, const uint8_t nibble_index,
+ const bool big_endian) {
+ return get_bit_field(source, NIBBLE_SIZE * nibble_index, NIBBLE_SIZE,
+ big_endian);
+}
+
+uint8_t eightbyte_get_byte(const uint64_t source, const uint8_t byte_index,
+ const bool big_endian) {
+ // TODO we're not handling swapped endianness - we could use get_bit_field
+ // but this might be more efficient
+ return (source >> (EIGHTBYTE_BIT - ((byte_index + 1) * CHAR_BIT))) & 0xFF;
+}
+
uint64_t get_bit_field(uint64_t source, const uint16_t offset,
- const uint16_t bit_count, bool big_endian) {
+ const uint16_t bit_count, const bool big_endian) {
int startByte = offset / CHAR_BIT;
int endByte = (offset + bit_count - 1) / CHAR_BIT;
*destination |= value;
return true;
}
-
-uint8_t nth_byte(const uint64_t source, const uint16_t byte_index) {
- return (source >> (EIGHTBYTE_BIT - ((byte_index + 1) * CHAR_BIT))) & 0xFF;
-}
-
* Returns the value of the requested bit field, right aligned in a uint64_t.
*/
uint64_t get_bit_field(uint64_t source, const uint16_t offset,
- const uint16_t bit_count, bool big_endian);
+ const uint16_t bit_count, const bool big_endian);
+
+/* Public: Return a single nibble from the payload, with range checking.
+ *
+ * source - the source payload.
+ * nibble_index - the index of the nibble to retreive. The leftmost nibble is
+ * index 0.
+ * big_endian - if the data passed in is little endian, set this to false and it
+ * will be flipped before grabbing the bit field.
+ *
+ * Returns the retreived nibble, right aligned in a uint8_t.
+ */
+uint8_t eightbyte_get_nibble(const uint64_t source, const uint8_t nibble_index,
+ const bool big_endian);
+
+/* Public: Return a single byte from the payload, with range checking.
+ *
+ * source - the source byte array.
+ * byte_index - the index of the byte to retreive. The leftmost byte is index 0.
+ * big_endian - if the data passed in is little endian, set this to false and it
+ * will be flipped before grabbing the bit field.
+ *
+ * Returns the retreived byte.
+ */
+uint8_t eightbyte_get_byte(const uint64_t source, const uint8_t byte_index,
+ const bool big_endian);
/* Public: Set the bit field in the given data array to the new value.
*
#include <string.h>
#include <stddef.h>
-#define NIBBLE_SIZE (CHAR_BIT / 2)
-
uint8_t get_nibble(const uint8_t source[], const uint8_t source_length,
const uint8_t nibble_index) {
uint8_t byte_index = nibble_index / 2;
#include <stdint.h>
#include <stdbool.h>
+#define NIBBLE_SIZE (CHAR_BIT / 2)
+
#ifdef __cplusplus
extern "C" {
#endif
}
END_TEST
-START_TEST(test_nth_byte)
+START_TEST(test_eightbyte_get_byte)
{
uint64_t data = 0x00000000F34DFCFF;
- uint8_t result = nth_byte(data, 0);
+ uint8_t result = eightbyte_get_byte(data, 0, false);
uint8_t expected = 0x0;
ck_assert_int_eq(result, expected);
- result = nth_byte(data, 4);
+ result = eightbyte_get_byte(data, 4, false);
expected = 0xF3;
ck_assert_int_eq(result, expected);
- result = nth_byte(data, 5);
+ result = eightbyte_get_byte(data, 5, false);
expected = 0x4D;
ck_assert_int_eq(result, expected);
- result = nth_byte(data, 6);
+ result = eightbyte_get_byte(data, 6, false);
expected = 0xFC;
ck_assert_int_eq(result, expected);
- result = nth_byte(data, 7);
+ result = eightbyte_get_byte(data, 7, false);
expected = 0xFF;
ck_assert_int_eq(result, expected);
}
END_TEST
+START_TEST(test_eightbyte_get_nibble)
+{
+ uint64_t data = 0x00000000F34DFCFF;
+ uint8_t result = eightbyte_get_nibble(data, 0, false);
+ uint8_t expected = 0x0;
+ ck_assert_int_eq(result, expected);
+
+ result = eightbyte_get_nibble(data, 2, false);
+ expected = 0x0;
+ ck_assert_int_eq(result, expected);
+
+ result = eightbyte_get_nibble(data, 8, false);
+ expected = 0xF;
+ ck_assert_int_eq(result, expected);
+
+ result = eightbyte_get_nibble(data, 9, false);
+ expected = 0x3;
+ ck_assert_int_eq(result, expected);
+
+ result = eightbyte_get_nibble(data, 10, false);
+ expected = 0x4;
+ ck_assert_int_eq(result, expected);
+
+ result = eightbyte_get_nibble(data, 13, false);
+ expected = 0xC;
+ ck_assert_int_eq(result, expected);
+}
+END_TEST
+
Suite* bitfieldSuite(void) {
Suite* s = suite_create("bitfield");
TCase *tc_core = tcase_create("core");
tcase_add_test(tc_core, test_set_doesnt_clobber_existing_data);
tcase_add_test(tc_core, test_set_off_byte_boundary);
tcase_add_test(tc_core, test_set_odd_number_of_bits);
- tcase_add_test(tc_core, test_nth_byte);
+ tcase_add_test(tc_core, test_eightbyte_get_nibble);
+ tcase_add_test(tc_core, test_eightbyte_get_byte);
suite_add_tcase(s, tc_core);
return s;