Add rz_bv_range_set and rz_bv_is_all_one to bitvector lib (#2891)

This commit is contained in:
Heersin 2022-08-10 08:20:16 +08:00 committed by GitHub
parent d1f9006b8f
commit a9c59ce1dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 2 deletions

View file

@ -40,6 +40,7 @@ RZ_API void rz_bv_free(RZ_NULLABLE RzBitVector *bv);
// read and write to a bit
RZ_API bool rz_bv_set(RZ_NONNULL RzBitVector *bv, ut32 pos, bool b);
RZ_API bool rz_bv_set_all(RZ_NONNULL RzBitVector *bv, bool b);
RZ_API bool rz_bv_set_range(RZ_NONNULL RzBitVector *bv, ut32 pos_start, ut32 pos_end, bool b);
RZ_API bool rz_bv_toggle(RZ_NONNULL RzBitVector *bv, ut32 pos);
RZ_API bool rz_bv_toggle_all(RZ_NONNULL RzBitVector *bv);
RZ_API RZ_OWN RzBitVector *rz_bv_append_zero(RZ_NONNULL RzBitVector *bv, ut32 delta_len);
@ -85,6 +86,7 @@ RZ_API ut32 rz_bv_to_ut32(RZ_NONNULL const RzBitVector *x);
RZ_API ut64 rz_bv_to_ut64(RZ_NONNULL const RzBitVector *x);
// misc
RZ_API bool rz_bv_is_zero_vector(RZ_NONNULL const RzBitVector *x);
RZ_API bool rz_bv_is_all_one(RZ_NONNULL const RzBitVector *x);
RZ_API RZ_OWN RzBitVector *rz_bv_new_from_ut64(ut32 length, ut64 value);
RZ_API RZ_OWN RzBitVector *rz_bv_new_from_st64(ut32 length, st64 value);
RZ_API RZ_OWN RzBitVector *rz_bv_new_from_bytes_le(RZ_IN RZ_NONNULL const ut8 *buf, ut32 bit_offset, ut32 size);

View file

@ -1464,3 +1464,42 @@ RZ_API ut64 rz_bv_to_ut64(RZ_NONNULL const RzBitVector *x) {
}
return ret;
}
/**
* set a range of bits to bool value `b`, the range is inclusive
* pos_end element is also included
* \param bv RzBitVector
* \param pos_start start index of range
* \param pos_end end index of range
* \param b bool value
* \return return true if success, else return false
*/
RZ_API bool rz_bv_set_range(RZ_NONNULL RzBitVector *bv, ut32 pos_start, ut32 pos_end, bool b) {
rz_return_val_if_fail(bv, false);
if (pos_start > bv->len - 1 || pos_end > bv->len - 1) {
return false;
}
for (ut32 i = pos_start; i <= pos_end; ++i) {
rz_bv_set(bv, i, b);
}
return true;
}
/**
* check if bitvector's bits are all set to bit 1
* \param x RzBitVector
* \return true if all bits of bv `x` are set to 1
*/
RZ_API bool rz_bv_is_all_one(RZ_NONNULL const RzBitVector *x) {
rz_return_val_if_fail(x, false);
// could not use ~0 as full-vector when bits < 64
for (ut32 i = 0; i < x->len; ++i) {
if (rz_bv_get(x, i) == 0) {
return false;
}
}
return true;
}

View file

@ -970,33 +970,53 @@ static bool test_rz_bv_len_bytes(void) {
mu_end;
}
bool test_rz_bv_set_all(void) {
bool test_rz_bv_set_operations(void) {
RzBitVector *bv = rz_bv_new(43);
rz_bv_set_all(bv, true);
mu_assert_streq_free(rz_bv_as_hex_string(bv, false), "0x7ffffffffff", "set all 1");
mu_assert_true(rz_bv_is_all_one(bv), "all bits are 1");
rz_bv_set_all(bv, false);
mu_assert_streq_free(rz_bv_as_hex_string(bv, false), "0x0", "set all 0");
mu_assert_false(rz_bv_is_all_one(bv), "not all 1");
rz_bv_free(bv);
bv = rz_bv_new(64);
rz_bv_set_all(bv, true);
mu_assert_streq_free(rz_bv_as_hex_string(bv, false), "0xffffffffffffffff", "set all 1");
mu_assert_true(rz_bv_is_all_one(bv), "all bits are 1");
rz_bv_set_all(bv, false);
mu_assert_streq_free(rz_bv_as_hex_string(bv, false), "0x0", "set all 0");
mu_assert_false(rz_bv_is_all_one(bv), "not all 1");
rz_bv_free(bv);
bv = rz_bv_new(73);
rz_bv_set_all(bv, true);
mu_assert_streq_free(rz_bv_as_hex_string(bv, false), "0x1ffffffffffffffffff", "set all 1");
mu_assert_true(rz_bv_is_all_one(bv), "all bits are 1");
rz_bv_set_all(bv, false);
mu_assert_streq_free(rz_bv_as_hex_string(bv, false), "0x0", "set all 0");
mu_assert_false(rz_bv_is_all_one(bv), "not all 1");
rz_bv_free(bv);
bv = rz_bv_new(80);
rz_bv_set_all(bv, true);
mu_assert_streq_free(rz_bv_as_hex_string(bv, false), "0xffffffffffffffffffff", "set all 1");
mu_assert_true(rz_bv_is_all_one(bv), "all bits are 1");
rz_bv_set_all(bv, false);
mu_assert_streq_free(rz_bv_as_hex_string(bv, false), "0x0", "set all 0");
mu_assert_false(rz_bv_is_all_one(bv), "not all 1");
rz_bv_free(bv);
bv = rz_bv_new(42);
rz_bv_set_range(bv, 0, bv->len - 1, true);
mu_assert_true(rz_bv_is_all_one(bv), "set all 1 by set_range");
// 11 1111 1111 1111 1100 0000 0011 1111 1111 1111 1111
rz_bv_set_range(bv, 18, 25, false);
mu_assert_streq_free(rz_bv_as_hex_string(bv, false), "0x3fffc03ffff", "range set 18~25 to 0");
rz_bv_free(bv);
bv = rz_bv_new(16);
mu_assert_false(rz_bv_set_range(bv, 16, 20, true), "set out of range");
rz_bv_free(bv);
mu_end;
}
@ -1125,7 +1145,7 @@ bool all_tests() {
mu_run_test(test_rz_bv_div);
mu_run_test(test_rz_bv_mod);
mu_run_test(test_rz_bv_len_bytes);
mu_run_test(test_rz_bv_set_all);
mu_run_test(test_rz_bv_set_operations);
mu_run_test(test_rz_bv_set_to_bytes_le);
mu_run_test(test_rz_bv_copy_nbits);