1 | /***************************************
2 | $Revision: 1.12 $
3 |
4 | bitmask (ma) - bitmask.c - library for manipulating fixed size bitmasks.
5 |
6 | Status: NOT REVUED, TESTED, INCOMPLETE
7 |
8 | Design and implementation by: Marek Bukowy, Chris Ottrey.
9 |
10 | ******************/ /******************
11 | Copyright (c) 1999 RIPE NCC
12 |
13 | All Rights Reserved
14 |
15 | Permission to use, copy, modify, and distribute this software and its
16 | documentation for any purpose and without fee is hereby granted,
17 | provided that the above copyright notice appear in all copies and that
18 | both that copyright notice and this permission notice appear in
19 | supporting documentation, and that the name of the author not be
20 | used in advertising or publicity pertaining to distribution of the
21 | software without specific, written prior permission.
22 |
23 | THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
24 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
25 | AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
26 | DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
27 | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
28 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29 | ***************************************/
30 |
31 |
32 |
33 | #include <stdio.h>
34 | #include <stdarg.h>
35 | #include <stdlib.h>
36 | #include <assert.h>
37 |
38 | #include <string.h>
39 |
40 | #include "bitmask.h"
41 | #include "memwrap.h"
42 | #include "globaldefs.h"
43 |
44 | int MA_isset(mask_t d, unsigned b) {
45 | return(
46 | (d.data[b / MASK_BITS_BASESIZE] &(1 <<(b % MASK_BITS_BASESIZE)))
47 | > 0);
48 | }
49 |
50 | void MA_set(mask_t *m_ptr, unsigned b, unsigned v) {
51 | assert(b < MASK_MAX);
52 | assert(v == 0 || v == 1);
53 |
54 | if(v == 1)
55 | m_ptr->data[b / MASK_BITS_BASESIZE] |=(1 <<(b % MASK_BITS_BASESIZE));
56 | else
57 | m_ptr->data[b / MASK_BITS_BASESIZE] &= ~(1 <<(b % MASK_BITS_BASESIZE));
58 | }
59 |
60 | void MA_clear(mask_t *m_ptr) {
61 | memset(m_ptr, 0, sizeof(mask_t));
62 | } /* MA_clear() */
63 |
64 |
65 | /* set bits in dptr. variable number of args, terminated by MA_END
66 |
67 | MA_END is -1, so the arguments are of type signed int
68 | */
69 | mask_t MA_new(int n,...) {
70 | va_list ap;
71 | mask_t d;
72 |
73 | MA_clear(&d);
74 |
75 | /* cover the "empty mask" case => MA_new(MA_END) invoked */
76 | for ( va_start(ap, n); n != MA_END; n = va_arg(ap, int) ) {
77 | MA_set(&d, (unsigned) n, 1);
78 | }
79 | va_end(ap);
80 |
81 | return d;
82 | }
83 |
84 |
85 | void MA_prt(mask_t m) {
86 | unsigned i;
87 |
88 | for (i = 0; i < MASK_MAX; i++) {
89 | printf("%d", MA_isset(m, i));
90 | }
91 |
92 | printf("\n");
93 |
94 | for (i = 0; i < MASK_BITS_WORDS; i++) {
95 | printf("0x%0*X ", 2 * sizeof(MASK_BITS_BASETYPE), m.data[i]);
96 | }
97 |
98 | printf("\n");
99 | }
100 |
101 | /* Perform a logical AND on two masks.
102 | Author: ottrey
103 | Date: Tue Jul 6 13:28:24 CEST 1999
104 | NB: This operation could/should be done a word at a time?
105 | */
106 | mask_t MA_and(mask_t a, mask_t b) {
107 | mask_t c;
108 | unsigned i;
109 |
110 | for (i=0; i < MASK_BITS_WORDS; i++ ) {
111 | c.data[i] = a.data[i] & b.data[i];
112 | }
113 | return c;
114 | } /* MA_and() */
115 |
116 | /* Perform a logical XOR on two masks.
117 | Author: ottrey
118 | Date: Thu Jul 8 14:50:14 CEST 1999
119 | NB: This operation could/should be done a word at a time?
120 | */
121 | mask_t MA_xor(mask_t a, mask_t b) {
122 | mask_t c;
123 | unsigned i;
124 |
125 | for (i=0; i < MASK_BITS_WORDS; i++ ) {
126 | c.data[i] = a.data[i] ^ b.data[i];
127 | }
128 |
129 | return c;
130 |
131 | } /* MA_xor() */
132 |
133 | /* Perform a logical OR on two masks.
134 | Author: ottrey
135 | Date: Thu Jul 8 16:34:34 CEST 1999
136 | NB: This operation could/should be done a word at a time?
137 | */
138 | mask_t MA_or(mask_t a, mask_t b) {
139 | mask_t c;
140 | unsigned i;
141 |
142 | for (i=0; i < MASK_BITS_WORDS; i++ ) {
143 | c.data[i] = a.data[i] | b.data[i];
144 | }
145 |
146 | return c;
147 |
148 | } /* MA_or() */
149 |
150 | /* Perform a logical NOT operation on a mask.
151 | Author: marek
152 | Date: Fri Jan 14 17:15:00 MET 2000
153 | NB: This operation is done a word at a time.
154 | */
155 | mask_t MA_not(mask_t a) {
156 | mask_t c;
157 | unsigned i;
158 |
159 | for (i=0; i < MASK_BITS_WORDS; i++ ) {
160 | c.data[i] = ~a.data[i];
161 | }
162 | return c;
163 | }
164 |
165 | /* Counts the number of bits set. */
166 | int MA_bitcount(mask_t m) {
167 | unsigned i;
168 | int count=0;
169 |
170 | for (i=0; i < MASK_MAX; i++) {
171 | count += MA_isset(m, i);
172 | }
173 |
174 | return count;
175 |
176 | } /* MA_bitcount() */
177 |
178 | /* Convert the bitmap to a string comprising of tokens from an array of tokens.
179 | Author: ottrey
180 | Date: Tue Jul 6 13:28:24 CEST 1999
181 | */
182 | char *MA_to_string(mask_t mask, char * const *tokens) {
183 | char *str;
184 | char str_buf[STR_L];
185 | int count;
186 | unsigned i;
187 | int length;
188 |
189 | strcpy(str_buf, "");
190 |
191 | count=0;
192 | sprintf(str_buf, "{");
193 | for (i=0; tokens[i] != NULL; i++) {
194 | if ( MA_isset(mask, i) != 0) {
195 | strcat(str_buf, tokens[i]);
196 | strcat(str_buf, ",");
197 | count++;
198 | }
199 | }
200 | if (count == 0) {
201 | strcat(str_buf, "NULL ");
202 | }
203 | length = strlen(str_buf);
204 | str_buf[length-1] = '}';
205 |
206 | /* str = (char *)calloc(1, strlen(str_buf)+1); */
207 | dieif(wr_calloc( (void **) &str, 1, strlen(str_buf)+1) != UT_OK);
208 |
209 | strcpy(str, str_buf);
210 |
211 | return str;
212 |
213 | } /* MA_to_string() */
214 |
215 | #ifdef MODULE_TEST
216 | void
217 | main() {
218 | mask_t d;
219 |
220 | d = MA_new(1, 4, 56, 3, 5, 7, 19, MA_END);
221 |
222 | MA_prt(d);
223 |
224 | MA_set(&d, 3, 0);
225 | MA_set(&d, 7, 0);
226 | MA_set(&d, 9, 0);
227 | MA_set(&d, 19, 0);
228 |
229 | MA_prt(d);
230 | }
231 | #endif