This is an automated email from the ASF dual-hosted git repository.

kasjer pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit 4ab74a6915cf5c79bf6092263b75fb4a8b450c68
Author: Jerzy Kasenberg <[email protected]>
AuthorDate: Thu Jun 25 15:09:24 2026 +0200

    util: Add bit_set
    
    Simple API to work with bit set.
    
    Signed-off-by: Jerzy Kasenberg <[email protected]>
---
 hw/util/bit_set/include/bit_set/bit_set.h | 130 ++++++++++++++++++++++++++++++
 hw/util/bit_set/pkg.yml                   |  24 ++++++
 hw/util/bit_set/src/bit_set.c             | 112 +++++++++++++++++++++++++
 3 files changed, 266 insertions(+)

diff --git a/hw/util/bit_set/include/bit_set/bit_set.h 
b/hw/util/bit_set/include/bit_set/bit_set.h
new file mode 100644
index 000000000..2f343c871
--- /dev/null
+++ b/hw/util/bit_set/include/bit_set/bit_set.h
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _UTIL_BIT_SET_H_
+#define _UTIL_BIT_SET_H_
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <os/endian.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Set bit from other bit set
+ *
+ * @param bit_set - pointer to first byte of a bit set
+ * @param start_bit - first bit to set
+ * @param bit_count - number of bits to set
+ * @param src_bits - source bits (starting from bit 0)
+ */
+void bit_set_set_bits(void *bit_set, int start_bit, int bit_count, const void 
*src_bits);
+
+/**
+ * Get bits from bit set
+ *
+ * @param bit_set - pointer to first byte of a bit set
+ * @param start_bit - first bit to extract
+ * @param bit_count - number of bits to extract
+ * @param dst_bits - buffer for extracted bits (little endian buffer)
+ */
+void bit_set_get_bits(const void *bit_set, int start_bit, int bit_count, void 
*dst_bits);
+
+/**
+ * Get single bit value from bit set in little endian order
+ *
+ * @param bit_set - pointer to first byte of a bit set
+ * @param bit_num - bit to get
+ * @return value of bit_num bit
+ */
+uint32_t bit_set_get_bit(const void *bit_set, int bit_num);
+
+/**
+ * Set bit in bit set
+ *
+ * @param bit_set - pointer to first byte of a bit set
+ * @param bit_num - bit to set value
+ * @param val - 0 or 1 value to set
+ */
+void bit_set_set_bit(void *bit_set, int bit_num, uint32_t val);
+
+/**
+ * Set bit in bit set
+ *
+ * @param bit_set - pointer to first byte of a bit set
+ * @param bit_num - bit to set value
+ * @return bit value after flip
+ */
+uint32_t bit_set_flip_bit(void *bit_set, int bit_num);
+
+/**
+ * Reverse bytes in bit set
+ * This can be useful if original buffer contains bytes in bit endian order
+ *
+ * @param bit_set - bit set to revers order
+ * @param bit_count - number of bits in bit set
+ */
+static inline void
+bit_set_reverse(void *bit_set, int bit_count)
+{
+    swap_in_place(bit_set, ((bit_count + 7) >> 3));
+}
+
+/**
+ * Get 32 bit value from bit set starting from given bit
+ * This function is wrapper to ease extraction of bit fields
+ *
+ * @param bit_set - pointer to first byte of a bit set
+ * @param start_bit - first bit to extract
+ * @param bit_count - number of bits to extract
+ * @return 32 bit value in host order
+ */
+static inline uint32_t
+bit_set_get_uint32(const void *bit_set, int start_bit, int bit_count)
+{
+    uint32_t val = 0;
+
+    bit_set_get_bits(bit_set, start_bit, bit_count, &val);
+
+    return le32toh(val);
+}
+
+/**
+ * Set number of bit in bit set from host order integer value
+ *
+ * @param bit_set - pointer to first byte of a bit set
+ * @param start_bit - first bit to set
+ * @param bit_count - number of bits to set
+ * @param val - host order val to set in bit field
+ */
+static inline void
+bit_set_set_uint32(void *bit_set, int start_bit, int bit_count, uint32_t val)
+{
+    val = htole32(val);
+
+    bit_set_set_bits(bit_set, start_bit, bit_count, &val);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/util/bit_set/pkg.yml b/hw/util/bit_set/pkg.yml
new file mode 100644
index 000000000..f2d960e8c
--- /dev/null
+++ b/hw/util/bit_set/pkg.yml
@@ -0,0 +1,24 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: util/bit_set
+pkg.description: Bit manipulation package
+pkg.author: "Apache Mynewt <[email protected]>"
+pkg.homepage: "http://mynewt.apache.org/";
+pkg.keywords:
diff --git a/hw/util/bit_set/src/bit_set.c b/hw/util/bit_set/src/bit_set.c
new file mode 100644
index 000000000..91e10c0bb
--- /dev/null
+++ b/hw/util/bit_set/src/bit_set.c
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANYÄ„
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <stdint.h>
+#include <bit_set/bit_set.h>
+#include <os/endian.h>
+#include <os/os.h>
+
+void
+bit_set_set_bits(void *bit_set, int start_bit, int bit_count, const void 
*src_bits)
+{
+    const uint8_t *src_bytes = (uint8_t *)src_bits;
+    uint32_t bits = *src_bytes++;
+    int start_byte = start_bit >> 3;
+
+    uint8_t *bytes = start_byte + (uint8_t *)bit_set;
+    start_bit -= start_byte << 3;
+    int src_bit_offset = start_bit;
+
+    while (bit_count > 0) {
+        int n = min(bit_count, 8);
+        uint8_t mask = ((1 << n) - 1) << start_bit;
+        uint8_t b = (*bytes & ~mask) | ((bits << start_bit) & mask);
+        *bytes++ = b;
+        bit_count -= 8 - start_bit;
+        bits >>= 8 - start_bit;
+        start_bit = 0;
+        bits |= (*src_bytes++) << src_bit_offset;
+    }
+}
+
+void
+bit_set_get_bits(const void *bit_set, int start_bit, int bit_count, void 
*dst_bits)
+{
+    uint8_t *dst_bytes = (uint8_t *)dst_bits;
+    int start_byte = start_bit >> 3;
+    const uint8_t *bytes = start_byte + (const uint8_t *)bit_set;
+    start_bit -= start_byte << 3;
+    uint32_t bits = 0;
+    uint32_t dst_bit_offset = 0;
+    int dst_bit_count = 0;
+
+    while (dst_bit_count > 0 || bit_count > 0) {
+        if (bit_count) {
+            int n = min(bit_count, 8 - start_bit);
+            bits |= ((*bytes++) >> start_bit) << dst_bit_offset;
+            if (start_bit) {
+                dst_bit_offset = 8 - start_bit;
+                start_bit = 0;
+            }
+            dst_bit_count += n;
+            bit_count -= n;
+        }
+        if (bit_count <= 0 || dst_bit_count >= 8) {
+            if (dst_bit_count < 8) {
+                uint8_t mask = (1 << dst_bit_count) - 1;
+                bits &= (1 << dst_bit_count) - 1;
+                *dst_bytes = (*dst_bytes & ~mask) | (bits & mask);
+            } else {
+                *dst_bytes++ = (uint8_t)bits;
+            }
+            dst_bit_count -= 8;
+            bits >>= 8;
+        }
+    }
+}
+
+uint32_t
+bit_set_get_bit(const void *bit_set, int bit_num)
+{
+    uint8_t b;
+
+    bit_set_get_bits(bit_set, bit_num, 1, &b);
+
+    return b;
+}
+
+void
+bit_set_set_bit(void *bit_set, int bit_num, uint32_t val)
+{
+    uint8_t b = val & 1;
+
+    bit_set_set_bits(bit_set, bit_num, 1, &b);
+}
+
+uint32_t
+bit_set_flip_bit(void *bit_set, int bit_num)
+{
+    uint8_t b;
+
+    bit_set_get_bits(bit_set, bit_num, 1, &b);
+    b ^= 1;
+    bit_set_set_bits(bit_set, bit_num, 1, &b);
+
+    return b;
+}

Reply via email to