summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/core/bitvec.h2
-rw-r--r--src/bitvec.c35
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)