diff mbox series

[RFC,v3,1/5] libsepol: introduce ebitmap_relative_complement()

Message ID 20211204103516.17375-1-cgzones@googlemail.com (mailing list archive)
State Superseded, archived
Headers show
Series [RFC,v3,1/5] libsepol: introduce ebitmap_relative_complement() | expand

Commit Message

Christian Göttsche Dec. 4, 2021, 10:35 a.m. UTC
Add a method for ebitmaps that computes the relative complement.
All bits set in the second ebitmap are set to zero in the first one.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>

---
v3:
   - rename from ebitmap_subtract() to ebitmap_relative_complement()
v2:
   - add shortcut for empty ebitmaps
---
 libsepol/include/sepol/policydb/ebitmap.h |  1 +
 libsepol/src/ebitmap.c                    | 18 ++++++++++++++++++
 2 files changed, 19 insertions(+)
diff mbox series

Patch

diff --git a/libsepol/include/sepol/policydb/ebitmap.h b/libsepol/include/sepol/policydb/ebitmap.h
index 81d0c7a6..076b9341 100644
--- a/libsepol/include/sepol/policydb/ebitmap.h
+++ b/libsepol/include/sepol/policydb/ebitmap.h
@@ -83,6 +83,7 @@  static inline int ebitmap_node_get_bit(const ebitmap_node_t * n, unsigned int bi
 extern int ebitmap_cmp(const ebitmap_t * e1, const ebitmap_t * e2);
 extern int ebitmap_or(ebitmap_t * dst, const ebitmap_t * e1, const ebitmap_t * e2);
 extern int ebitmap_union(ebitmap_t * dst, const ebitmap_t * e1);
+extern int ebitmap_relative_complement(ebitmap_t *dst, const ebitmap_t *e1);
 extern int ebitmap_and(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2);
 extern int ebitmap_xor(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2);
 extern int ebitmap_not(ebitmap_t *dst, const ebitmap_t *e1, unsigned int maxbit);
diff --git a/libsepol/src/ebitmap.c b/libsepol/src/ebitmap.c
index 1de3816a..5f166e8c 100644
--- a/libsepol/src/ebitmap.c
+++ b/libsepol/src/ebitmap.c
@@ -72,6 +72,24 @@  int ebitmap_union(ebitmap_t * dst, const ebitmap_t * e1)
 	return 0;
 }
 
+int ebitmap_relative_complement(ebitmap_t *dst, const ebitmap_t *e1)
+{
+	unsigned int i, length;
+
+	if (ebitmap_is_empty(dst) || ebitmap_is_empty(e1))
+		return 0;
+	
+	length = min(ebitmap_length(dst), ebitmap_length(e1));
+	for (i=0; i < length; i++) {
+		if (ebitmap_get_bit(e1, i)) {
+			int rc = ebitmap_set_bit(dst, i, 0);
+			if (rc < 0)
+				return rc;
+		}
+	}
+	return 0;
+}
+
 int ebitmap_and(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2)
 {
 	unsigned int i, length = min(ebitmap_length(e1), ebitmap_length(e2));