16cd6a6acSopenharmony_ci/* Author : Stephen Smalley, <sds@tycho.nsa.gov> */
26cd6a6acSopenharmony_ci
36cd6a6acSopenharmony_ci/* FLASK */
46cd6a6acSopenharmony_ci
56cd6a6acSopenharmony_ci/*
66cd6a6acSopenharmony_ci * An extensible bitmap is a bitmap that supports an
76cd6a6acSopenharmony_ci * arbitrary number of bits.  Extensible bitmaps are
86cd6a6acSopenharmony_ci * used to represent sets of values, such as types,
96cd6a6acSopenharmony_ci * roles, categories, and classes.
106cd6a6acSopenharmony_ci *
116cd6a6acSopenharmony_ci * Each extensible bitmap is implemented as a linked
126cd6a6acSopenharmony_ci * list of bitmap nodes, where each bitmap node has
136cd6a6acSopenharmony_ci * an explicitly specified starting bit position within
146cd6a6acSopenharmony_ci * the total bitmap.
156cd6a6acSopenharmony_ci */
166cd6a6acSopenharmony_ci
176cd6a6acSopenharmony_ci#ifndef _SEPOL_POLICYDB_EBITMAP_H_
186cd6a6acSopenharmony_ci#define _SEPOL_POLICYDB_EBITMAP_H_
196cd6a6acSopenharmony_ci
206cd6a6acSopenharmony_ci#include <stdint.h>
216cd6a6acSopenharmony_ci#include <string.h>
226cd6a6acSopenharmony_ci
236cd6a6acSopenharmony_ci#ifdef __cplusplus
246cd6a6acSopenharmony_ciextern "C" {
256cd6a6acSopenharmony_ci#endif
266cd6a6acSopenharmony_ci
276cd6a6acSopenharmony_ci#define MAPTYPE uint64_t	/* portion of bitmap in each node */
286cd6a6acSopenharmony_ci#define MAPSIZE (sizeof(MAPTYPE) * 8)	/* number of bits in node bitmap */
296cd6a6acSopenharmony_ci#define MAPBIT  1ULL		/* a bit in the node bitmap */
306cd6a6acSopenharmony_ci
316cd6a6acSopenharmony_citypedef struct ebitmap_node {
326cd6a6acSopenharmony_ci	uint32_t startbit;	/* starting position in the total bitmap */
336cd6a6acSopenharmony_ci	MAPTYPE map;		/* this node's portion of the bitmap */
346cd6a6acSopenharmony_ci	struct ebitmap_node *next;
356cd6a6acSopenharmony_ci} ebitmap_node_t;
366cd6a6acSopenharmony_ci
376cd6a6acSopenharmony_citypedef struct ebitmap {
386cd6a6acSopenharmony_ci	ebitmap_node_t *node;	/* first node in the bitmap */
396cd6a6acSopenharmony_ci	uint32_t highbit;	/* highest position in the total bitmap */
406cd6a6acSopenharmony_ci} ebitmap_t;
416cd6a6acSopenharmony_ci
426cd6a6acSopenharmony_ci#define ebitmap_is_empty(e) (((e)->highbit) == 0)
436cd6a6acSopenharmony_ci#define ebitmap_length(e) ((e)->highbit)
446cd6a6acSopenharmony_ci#define ebitmap_startbit(e) ((e)->node ? (e)->node->startbit : 0)
456cd6a6acSopenharmony_ci#define ebitmap_startnode(e) ((e)->node)
466cd6a6acSopenharmony_ci
476cd6a6acSopenharmony_cistatic inline unsigned int ebitmap_start(const ebitmap_t * e,
486cd6a6acSopenharmony_ci					 ebitmap_node_t ** n)
496cd6a6acSopenharmony_ci{
506cd6a6acSopenharmony_ci
516cd6a6acSopenharmony_ci	*n = e->node;
526cd6a6acSopenharmony_ci	return ebitmap_startbit(e);
536cd6a6acSopenharmony_ci}
546cd6a6acSopenharmony_ci
556cd6a6acSopenharmony_cistatic inline void ebitmap_init(ebitmap_t * e)
566cd6a6acSopenharmony_ci{
576cd6a6acSopenharmony_ci	memset(e, 0, sizeof(*e));
586cd6a6acSopenharmony_ci}
596cd6a6acSopenharmony_ci
606cd6a6acSopenharmony_cistatic inline unsigned int ebitmap_next(ebitmap_node_t ** n, unsigned int bit)
616cd6a6acSopenharmony_ci{
626cd6a6acSopenharmony_ci	if ((bit == ((*n)->startbit + MAPSIZE - 1)) && (*n)->next) {
636cd6a6acSopenharmony_ci		*n = (*n)->next;
646cd6a6acSopenharmony_ci		return (*n)->startbit;
656cd6a6acSopenharmony_ci	}
666cd6a6acSopenharmony_ci
676cd6a6acSopenharmony_ci	return (bit + 1);
686cd6a6acSopenharmony_ci}
696cd6a6acSopenharmony_ci
706cd6a6acSopenharmony_cistatic inline int ebitmap_node_get_bit(const ebitmap_node_t * n, unsigned int bit)
716cd6a6acSopenharmony_ci{
726cd6a6acSopenharmony_ci	if (n->map & (MAPBIT << (bit - n->startbit)))
736cd6a6acSopenharmony_ci		return 1;
746cd6a6acSopenharmony_ci	return 0;
756cd6a6acSopenharmony_ci}
766cd6a6acSopenharmony_ci
776cd6a6acSopenharmony_ci#define ebitmap_for_each_bit(e, n, bit) \
786cd6a6acSopenharmony_ci	for (bit = ebitmap_start(e, &n); bit < ebitmap_length(e); bit = ebitmap_next(&n, bit)) \
796cd6a6acSopenharmony_ci
806cd6a6acSopenharmony_ci#define ebitmap_for_each_positive_bit(e, n, bit) \
816cd6a6acSopenharmony_ci	ebitmap_for_each_bit(e, n, bit) if (ebitmap_node_get_bit(n, bit)) \
826cd6a6acSopenharmony_ci
836cd6a6acSopenharmony_ciextern int ebitmap_cmp(const ebitmap_t * e1, const ebitmap_t * e2);
846cd6a6acSopenharmony_ciextern int ebitmap_or(ebitmap_t * dst, const ebitmap_t * e1, const ebitmap_t * e2);
856cd6a6acSopenharmony_ciextern int ebitmap_union(ebitmap_t * dst, const ebitmap_t * e1);
866cd6a6acSopenharmony_ciextern int ebitmap_and(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2);
876cd6a6acSopenharmony_ciextern int ebitmap_xor(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2);
886cd6a6acSopenharmony_ciextern int ebitmap_not(ebitmap_t *dst, const ebitmap_t *e1, unsigned int maxbit);
896cd6a6acSopenharmony_ciextern int ebitmap_andnot(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2, unsigned int maxbit);
906cd6a6acSopenharmony_ciextern unsigned int ebitmap_cardinality(const ebitmap_t *e1);
916cd6a6acSopenharmony_ciextern int ebitmap_hamming_distance(const ebitmap_t * e1, const ebitmap_t * e2);
926cd6a6acSopenharmony_ciextern int ebitmap_cpy(ebitmap_t * dst, const ebitmap_t * src);
936cd6a6acSopenharmony_ciextern int ebitmap_contains(const ebitmap_t * e1, const ebitmap_t * e2);
946cd6a6acSopenharmony_ciextern int ebitmap_match_any(const ebitmap_t *e1, const ebitmap_t *e2);
956cd6a6acSopenharmony_ciextern int ebitmap_get_bit(const ebitmap_t * e, unsigned int bit);
966cd6a6acSopenharmony_ciextern int ebitmap_set_bit(ebitmap_t * e, unsigned int bit, int value);
976cd6a6acSopenharmony_ciextern int ebitmap_init_range(ebitmap_t * e, unsigned int minbit, unsigned int maxbit);
986cd6a6acSopenharmony_ciextern unsigned int ebitmap_highest_set_bit(const ebitmap_t * e);
996cd6a6acSopenharmony_ciextern void ebitmap_destroy(ebitmap_t * e);
1006cd6a6acSopenharmony_ciextern int ebitmap_read(ebitmap_t * e, void *fp);
1016cd6a6acSopenharmony_ci
1026cd6a6acSopenharmony_ci#ifdef __cplusplus
1036cd6a6acSopenharmony_ci}
1046cd6a6acSopenharmony_ci#endif
1056cd6a6acSopenharmony_ci
1066cd6a6acSopenharmony_ci#endif				/* _EBITMAP_H_ */
1076cd6a6acSopenharmony_ci
1086cd6a6acSopenharmony_ci/* FLASK */
109