diff --git a/bit_array.c b/bit_array.c index 94ba04e..3a0750c 100644 --- a/bit_array.c +++ b/bit_array.c @@ -899,6 +899,9 @@ uint64_t bit_array_get_wordn(const BIT_ARRAY* bitarr, bit_index_t start, int n) // // Set a word at a time // +// Doesn't extend bit array. However it is safe to TRY to set bits beyond the +// end of the array, as long as: `start` is < `bit_array_length(arr)` +// void bit_array_set_word64(BIT_ARRAY* bitarr, bit_index_t start, uint64_t word) { @@ -910,14 +913,14 @@ void bit_array_set_word32(BIT_ARRAY* bitarr, bit_index_t start, uint32_t word) { assert(start < bitarr->num_of_bits); word_t w = _get_word(bitarr, start); - _set_word(bitarr, start, (w & ~(word_t)0xffffffff) | word); + _set_word(bitarr, start, bitmask_merge(w, word, 0xffffffff00000000UL)); } void bit_array_set_word16(BIT_ARRAY* bitarr, bit_index_t start, uint16_t word) { assert(start < bitarr->num_of_bits); word_t w = _get_word(bitarr, start); - _set_word(bitarr, start, (w & ~(word_t)0xffff) | word); + _set_word(bitarr, start, bitmask_merge(w, word, 0xffffffffffff0000UL)); } void bit_array_set_word8(BIT_ARRAY* bitarr, bit_index_t start, uint8_t byte) diff --git a/bit_array.h b/bit_array.h index 70b50ad..3b73a63 100644 --- a/bit_array.h +++ b/bit_array.h @@ -170,6 +170,8 @@ uint8_t bit_array_get_word8(const BIT_ARRAY* bitarr, bit_index_t start); uint64_t bit_array_get_wordn(const BIT_ARRAY* bitarr, bit_index_t start, int n); // Set 64 bits at once from a particular start position +// Doesn't extend bit array. However it is safe to TRY to set bits beyond the +// end of the array, as long as: `start` is < `bit_array_length(arr)` void bit_array_set_word64(BIT_ARRAY* bitarr, bit_index_t start, uint64_t word); void bit_array_set_word32(BIT_ARRAY* bitarr, bit_index_t start, uint32_t word); void bit_array_set_word16(BIT_ARRAY* bitarr, bit_index_t start, uint16_t word); diff --git a/dev/bit_array_test.c b/dev/bit_array_test.c index e209e7c..1d75a95 100644 --- a/dev/bit_array_test.c +++ b/dev/bit_array_test.c @@ -2397,6 +2397,39 @@ void test_add_and_minus_single_word() SUITE_END(); } +void test_get_set_bytes() +{ + SUITE_START("get/set byte"); + + const size_t nbytes = 8; + uint8_t bytes[nbytes] = {0x55,0x31,0x5A,0x12,0x02,0x31,0xC3,0x1E}; + size_t s, i; + + BIT_ARRAY *arr = bit_array_create(nbytes*8); + + // Set bytes using different offsets + for(s = 0; s < 8; s++) { + bit_array_clear_all(arr); + for(i = 0; i < nbytes-1; i++) { + bit_array_set_word8(arr, i*8+s, bytes[i]); + ASSERT(bit_array_get_word8(arr, i*8+s) == bytes[i]); + } + // Setting bytes doesn't extend the array - check last byte with masking + i = nbytes-1; + bit_array_set_word8(arr, i*8+s, bytes[i]); + ASSERT(bit_array_get_word8(arr, i*8+s) == (bytes[i] & (0xff>>s))); + + // Check bits + for(i = 0; i < s; i++) ASSERT(bit_array_get(arr, i) == 0); + for(i = s; i < nbytes*8; i++) + ASSERT(bit_array_get(arr, i) == bitset_get(bytes, i-s)); + } + + bit_array_free(arr); + + SUITE_END(); +} + // test new features of bitarr library. // - resize from 0 // - get/set/clear/toggle/assign auto-resize @@ -2539,6 +2572,7 @@ int main(int argc, char* argv[]) // Test functions test_copy(); + test_get_set_bytes(); test_parity(); test_interleave();