libsepol: Move ebitmap_* functions from mcstrans to libsepol

This patches moves some ebitmap functions (and, xor, not, etc.) from
mcstrans into libsepol, where they really belong and could be used by
other applications (e.g. CIL)

Signed-off-by: Eric Paris <eparis@redhat.com>
Acked-by: Dan Walsh <dwalsh@redhat.com>
diff --git a/libsepol/src/ebitmap.c b/libsepol/src/ebitmap.c
index cc6a915..be6b591 100644
--- a/libsepol/src/ebitmap.c
+++ b/libsepol/src/ebitmap.c
@@ -71,6 +71,82 @@
 	return 0;
 }
 
+int ebitmap_and(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2)
+{
+	unsigned int i, length = min(ebitmap_length(e1), ebitmap_length(e2));
+	ebitmap_init(dst);
+	for (i=0; i < length; i++) {
+		if (ebitmap_get_bit(e1, i) && ebitmap_get_bit(e2, i)) {
+			int rc = ebitmap_set_bit(dst, i, 1);
+			if (rc < 0)
+				return rc;
+		}
+	}
+	return 0;
+}
+
+int ebitmap_xor(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2)
+{
+	unsigned int i, length = max(ebitmap_length(e1), ebitmap_length(e2));
+	ebitmap_init(dst);
+	for (i=0; i < length; i++) {
+		int val = ebitmap_get_bit(e1, i) ^ ebitmap_get_bit(e2, i);
+		int rc = ebitmap_set_bit(dst, i, val);
+		if (rc < 0)
+			return rc;
+	}
+	return 0;
+}
+
+int ebitmap_not(ebitmap_t *dst, ebitmap_t *e1, unsigned int maxbit)
+{
+	unsigned int i;
+	ebitmap_init(dst);
+	for (i=0; i < maxbit; i++) {
+		int val = ebitmap_get_bit(e1, i);
+		int rc = ebitmap_set_bit(dst, i, !val);
+		if (rc < 0)
+			return rc;
+	}
+	return 0;
+}
+
+int ebitmap_andnot(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2, unsigned int maxbit)
+{
+	ebitmap_t e3;
+	ebitmap_init(dst);
+	int rc = ebitmap_not(&e3, e2, maxbit);
+	if (rc < 0)
+		return rc;
+	rc = ebitmap_and(dst, e1, &e3);
+	ebitmap_destroy(&e3);
+	if (rc < 0)
+		return rc;
+	return 0;
+}
+
+unsigned int ebitmap_cardinality(ebitmap_t *e1)
+{
+	unsigned int i, count = 0;
+	for (i=ebitmap_startbit(e1); i < ebitmap_length(e1); i++)
+		if (ebitmap_get_bit(e1, i))
+			count++;
+	return count;
+}
+
+int ebitmap_hamming_distance(ebitmap_t * e1, ebitmap_t * e2)
+{
+	if (ebitmap_cmp(e1, e2))
+		return 0;
+	ebitmap_t tmp;
+	int rc = ebitmap_xor(&tmp, e1, e2);
+	if (rc < 0)
+		return -1;
+	int distance = ebitmap_cardinality(&tmp);
+	ebitmap_destroy(&tmp);
+	return distance;
+}
+
 int ebitmap_cmp(const ebitmap_t * e1, const ebitmap_t * e2)
 {
 	ebitmap_node_t *n1, *n2;