diff options
-rw-r--r-- | include/osmocom/core/bitvec.h | 2 | ||||
-rw-r--r-- | src/bitvec.c | 35 |
2 files changed, 28 insertions, 9 deletions
diff --git a/include/osmocom/core/bitvec.h b/include/osmocom/core/bitvec.h index d4c7d680..19466abb 100644 --- a/include/osmocom/core/bitvec.h +++ b/include/osmocom/core/bitvec.h @@ -28,6 +28,7 @@ #include <stdint.h> #include <osmocom/core/talloc.h> +#include <osmocom/core/defs.h> #include <stdbool.h> /*! A single GSM bit @@ -57,6 +58,7 @@ int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnum, int bitvec_set_bit(struct bitvec *bv, enum bit_value bit); int bitvec_get_bit_high(struct bitvec *bv); int bitvec_set_bits(struct bitvec *bv, const enum bit_value *bits, unsigned int count); +int bitvec_set_u64(struct bitvec *bv, uint64_t v, uint8_t num_bits, bool use_lh); int bitvec_set_uint(struct bitvec *bv, unsigned int in, unsigned int count); int bitvec_get_uint(struct bitvec *bv, unsigned int num_bits); int bitvec_find_bit_pos(const struct bitvec *bv, unsigned int n, enum bit_value val); diff --git a/src/bitvec.c b/src/bitvec.c index f07b42c3..24049cda 100644 --- a/src/bitvec.c +++ b/src/bitvec.c @@ -215,24 +215,41 @@ int bitvec_set_bits(struct bitvec *bv, const enum bit_value *bits, unsigned int return 0; } -/*! set multiple bits (based on numeric value) at current pos - * \return 0 in case of success; negative in case of error */ -int bitvec_set_uint(struct bitvec *bv, unsigned int ui, unsigned int num_bits) +/*! set multiple bits (based on numeric value) at current pos. + * \param[in] bv bit vector. + * \param[in] v mask representing which bits needs to be set. + * \param[in] num_bits number of meaningful bits in the mask. + * \param[in] use_lh whether to interpret the bits as L/H values or as 0/1. + * \return 0 on success; negative in case of error. */ +int bitvec_set_u64(struct bitvec *bv, uint64_t v, uint8_t num_bits, bool use_lh) { - int rc; - unsigned i; + uint8_t i; + + if (num_bits > 64) + return -E2BIG; + for (i = 0; i < num_bits; i++) { - int bit = 0; - if (ui & (1u << (num_bits - i - 1))) - bit = 1; + int rc; + enum bit_value bit = use_lh ? L : 0; + + if (v & ((uint64_t)1 << (num_bits - i - 1))) + bit = use_lh ? H : 1; + rc = bitvec_set_bit(bv, bit); - if (rc) + if (rc != 0) return rc; } return 0; } +/*! set multiple bits (based on numeric value) at current pos. + * \return 0 in case of success; negative in case of error. */ +int bitvec_set_uint(struct bitvec *bv, unsigned int ui, unsigned int num_bits) +{ + return bitvec_set_u64(bv, ui, num_bits, false); +} + /*! get multiple bits (num_bits) from beginning of vector (MSB side) * \return 16bit signed integer retrieved from bit vector */ int16_t bitvec_get_int16_msb(const struct bitvec *bv, unsigned int num_bits) |