Add rz_bv_range_set and rz_bv_is_all_one to bitvector lib (#2891)
This commit is contained in:
parent
d1f9006b8f
commit
a9c59ce1dd
3 changed files with 63 additions and 2 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue