1*2d543d20SAndroid Build Coastguard Worker /* Author : Stephen Smalley, <[email protected]> */
2*2d543d20SAndroid Build Coastguard Worker
3*2d543d20SAndroid Build Coastguard Worker /* FLASK */
4*2d543d20SAndroid Build Coastguard Worker
5*2d543d20SAndroid Build Coastguard Worker /*
6*2d543d20SAndroid Build Coastguard Worker * An extensible bitmap is a bitmap that supports an
7*2d543d20SAndroid Build Coastguard Worker * arbitrary number of bits. Extensible bitmaps are
8*2d543d20SAndroid Build Coastguard Worker * used to represent sets of values, such as types,
9*2d543d20SAndroid Build Coastguard Worker * roles, categories, and classes.
10*2d543d20SAndroid Build Coastguard Worker *
11*2d543d20SAndroid Build Coastguard Worker * Each extensible bitmap is implemented as a linked
12*2d543d20SAndroid Build Coastguard Worker * list of bitmap nodes, where each bitmap node has
13*2d543d20SAndroid Build Coastguard Worker * an explicitly specified starting bit position within
14*2d543d20SAndroid Build Coastguard Worker * the total bitmap.
15*2d543d20SAndroid Build Coastguard Worker */
16*2d543d20SAndroid Build Coastguard Worker
17*2d543d20SAndroid Build Coastguard Worker #ifndef _SEPOL_POLICYDB_EBITMAP_H_
18*2d543d20SAndroid Build Coastguard Worker #define _SEPOL_POLICYDB_EBITMAP_H_
19*2d543d20SAndroid Build Coastguard Worker
20*2d543d20SAndroid Build Coastguard Worker #include <stdint.h>
21*2d543d20SAndroid Build Coastguard Worker #include <string.h>
22*2d543d20SAndroid Build Coastguard Worker
23*2d543d20SAndroid Build Coastguard Worker #ifdef __cplusplus
24*2d543d20SAndroid Build Coastguard Worker extern "C" {
25*2d543d20SAndroid Build Coastguard Worker #endif
26*2d543d20SAndroid Build Coastguard Worker
27*2d543d20SAndroid Build Coastguard Worker #define MAPTYPE uint64_t /* portion of bitmap in each node */
28*2d543d20SAndroid Build Coastguard Worker #define MAPSIZE (sizeof(MAPTYPE) * 8) /* number of bits in node bitmap */
29*2d543d20SAndroid Build Coastguard Worker #define MAPBIT 1ULL /* a bit in the node bitmap */
30*2d543d20SAndroid Build Coastguard Worker
31*2d543d20SAndroid Build Coastguard Worker typedef struct ebitmap_node {
32*2d543d20SAndroid Build Coastguard Worker uint32_t startbit; /* starting position in the total bitmap */
33*2d543d20SAndroid Build Coastguard Worker MAPTYPE map; /* this node's portion of the bitmap */
34*2d543d20SAndroid Build Coastguard Worker struct ebitmap_node *next;
35*2d543d20SAndroid Build Coastguard Worker } ebitmap_node_t;
36*2d543d20SAndroid Build Coastguard Worker
37*2d543d20SAndroid Build Coastguard Worker typedef struct ebitmap {
38*2d543d20SAndroid Build Coastguard Worker ebitmap_node_t *node; /* first node in the bitmap */
39*2d543d20SAndroid Build Coastguard Worker uint32_t highbit; /* highest position in the total bitmap */
40*2d543d20SAndroid Build Coastguard Worker } ebitmap_t;
41*2d543d20SAndroid Build Coastguard Worker
42*2d543d20SAndroid Build Coastguard Worker #define ebitmap_is_empty(e) (((e)->node) == NULL)
43*2d543d20SAndroid Build Coastguard Worker #define ebitmap_length(e) ((e)->node ? (e)->highbit : 0)
44*2d543d20SAndroid Build Coastguard Worker #define ebitmap_startbit(e) ((e)->node ? (e)->node->startbit : 0)
45*2d543d20SAndroid Build Coastguard Worker #define ebitmap_startnode(e) ((e)->node)
46*2d543d20SAndroid Build Coastguard Worker
ebitmap_start(const ebitmap_t * e,ebitmap_node_t ** n)47*2d543d20SAndroid Build Coastguard Worker static inline unsigned int ebitmap_start(const ebitmap_t * e,
48*2d543d20SAndroid Build Coastguard Worker ebitmap_node_t ** n)
49*2d543d20SAndroid Build Coastguard Worker {
50*2d543d20SAndroid Build Coastguard Worker
51*2d543d20SAndroid Build Coastguard Worker *n = e->node;
52*2d543d20SAndroid Build Coastguard Worker return ebitmap_startbit(e);
53*2d543d20SAndroid Build Coastguard Worker }
54*2d543d20SAndroid Build Coastguard Worker
ebitmap_init(ebitmap_t * e)55*2d543d20SAndroid Build Coastguard Worker static inline void ebitmap_init(ebitmap_t * e)
56*2d543d20SAndroid Build Coastguard Worker {
57*2d543d20SAndroid Build Coastguard Worker memset(e, 0, sizeof(*e));
58*2d543d20SAndroid Build Coastguard Worker }
59*2d543d20SAndroid Build Coastguard Worker
ebitmap_next(ebitmap_node_t ** n,unsigned int bit)60*2d543d20SAndroid Build Coastguard Worker static inline unsigned int ebitmap_next(ebitmap_node_t ** n, unsigned int bit)
61*2d543d20SAndroid Build Coastguard Worker {
62*2d543d20SAndroid Build Coastguard Worker if ((bit == ((*n)->startbit + MAPSIZE - 1)) && (*n)->next) {
63*2d543d20SAndroid Build Coastguard Worker *n = (*n)->next;
64*2d543d20SAndroid Build Coastguard Worker return (*n)->startbit;
65*2d543d20SAndroid Build Coastguard Worker }
66*2d543d20SAndroid Build Coastguard Worker
67*2d543d20SAndroid Build Coastguard Worker return (bit + 1);
68*2d543d20SAndroid Build Coastguard Worker }
69*2d543d20SAndroid Build Coastguard Worker
ebitmap_node_get_bit(const ebitmap_node_t * n,unsigned int bit)70*2d543d20SAndroid Build Coastguard Worker static inline int ebitmap_node_get_bit(const ebitmap_node_t * n, unsigned int bit)
71*2d543d20SAndroid Build Coastguard Worker {
72*2d543d20SAndroid Build Coastguard Worker if (n->map & (MAPBIT << (bit - n->startbit)))
73*2d543d20SAndroid Build Coastguard Worker return 1;
74*2d543d20SAndroid Build Coastguard Worker return 0;
75*2d543d20SAndroid Build Coastguard Worker }
76*2d543d20SAndroid Build Coastguard Worker
77*2d543d20SAndroid Build Coastguard Worker #define ebitmap_for_each_bit(e, n, bit) \
78*2d543d20SAndroid Build Coastguard Worker for (bit = ebitmap_start(e, &n); bit < ebitmap_length(e); bit = ebitmap_next(&n, bit)) \
79*2d543d20SAndroid Build Coastguard Worker
80*2d543d20SAndroid Build Coastguard Worker #define ebitmap_for_each_positive_bit(e, n, bit) \
81*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_bit(e, n, bit) if (ebitmap_node_get_bit(n, bit)) \
82*2d543d20SAndroid Build Coastguard Worker
83*2d543d20SAndroid Build Coastguard Worker extern int ebitmap_cmp(const ebitmap_t * e1, const ebitmap_t * e2);
84*2d543d20SAndroid Build Coastguard Worker extern int ebitmap_or(ebitmap_t * dst, const ebitmap_t * e1, const ebitmap_t * e2);
85*2d543d20SAndroid Build Coastguard Worker extern int ebitmap_union(ebitmap_t * dst, const ebitmap_t * e1);
86*2d543d20SAndroid Build Coastguard Worker extern int ebitmap_and(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2);
87*2d543d20SAndroid Build Coastguard Worker extern int ebitmap_xor(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2);
88*2d543d20SAndroid Build Coastguard Worker extern int ebitmap_not(ebitmap_t *dst, const ebitmap_t *e1, unsigned int maxbit);
89*2d543d20SAndroid Build Coastguard Worker extern int ebitmap_andnot(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2, unsigned int maxbit);
90*2d543d20SAndroid Build Coastguard Worker extern unsigned int ebitmap_cardinality(const ebitmap_t *e1);
91*2d543d20SAndroid Build Coastguard Worker extern int ebitmap_hamming_distance(const ebitmap_t * e1, const ebitmap_t * e2);
92*2d543d20SAndroid Build Coastguard Worker extern int ebitmap_cpy(ebitmap_t * dst, const ebitmap_t * src);
93*2d543d20SAndroid Build Coastguard Worker extern int ebitmap_contains(const ebitmap_t * e1, const ebitmap_t * e2);
94*2d543d20SAndroid Build Coastguard Worker extern int ebitmap_match_any(const ebitmap_t *e1, const ebitmap_t *e2);
95*2d543d20SAndroid Build Coastguard Worker extern int ebitmap_get_bit(const ebitmap_t * e, unsigned int bit);
96*2d543d20SAndroid Build Coastguard Worker extern int ebitmap_set_bit(ebitmap_t * e, unsigned int bit, int value);
97*2d543d20SAndroid Build Coastguard Worker extern int ebitmap_init_range(ebitmap_t * e, unsigned int minbit, unsigned int maxbit);
98*2d543d20SAndroid Build Coastguard Worker extern unsigned int ebitmap_highest_set_bit(const ebitmap_t * e);
99*2d543d20SAndroid Build Coastguard Worker extern void ebitmap_destroy(ebitmap_t * e);
100*2d543d20SAndroid Build Coastguard Worker extern int ebitmap_read(ebitmap_t * e, void *fp);
101*2d543d20SAndroid Build Coastguard Worker
102*2d543d20SAndroid Build Coastguard Worker #ifdef __cplusplus
103*2d543d20SAndroid Build Coastguard Worker }
104*2d543d20SAndroid Build Coastguard Worker #endif
105*2d543d20SAndroid Build Coastguard Worker
106*2d543d20SAndroid Build Coastguard Worker #endif /* _EBITMAP_H_ */
107*2d543d20SAndroid Build Coastguard Worker
108*2d543d20SAndroid Build Coastguard Worker /* FLASK */
109