1 | /***************************************
2 | $Revision: 1.15 $
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,2000,2001,2002 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 "rip.h"
34 |
35 | #include <stdio.h>
36 | #include <stdarg.h>
37 | #include <stdlib.h>
38 | #include <assert.h>
39 |
40 | #include <string.h>
41 |
42 | int MA_isset(mask_t d, unsigned b) {
43 | return(
44 | (d.data[b / MASK_BITS_BASESIZE] &(1 <<(b % MASK_BITS_BASESIZE)))
45 | > 0);
46 | }
47 |
48 | void MA_set(mask_t *m_ptr, unsigned b, unsigned v) {
49 | assert(b < MASK_MAX);
50 | assert(v == 0 || v == 1);
51 |
52 | if(v == 1)
53 | m_ptr->data[b / MASK_BITS_BASESIZE] |=(1 <<(b % MASK_BITS_BASESIZE));
54 | else
55 | m_ptr->data[b / MASK_BITS_BASESIZE] &= ~(1 <<(b % MASK_BITS_BASESIZE));
56 | }
57 |
58 | void MA_clear(mask_t *m_ptr) {
59 | memset(m_ptr, 0, sizeof(mask_t));
60 | } /* MA_clear() */
61 |
62 |
63 | /* set bits in dptr. variable number of args, terminated by MA_END
64 |
65 | MA_END is -1, so the arguments are of type signed int
66 | */
67 | mask_t MA_new(int n,...) {
68 | va_list ap;
69 | mask_t d;
70 |
71 | MA_clear(&d);
72 |
73 | /* cover the "empty mask" case => MA_new(MA_END) invoked */
74 | for ( va_start(ap, n); n != MA_END; n = va_arg(ap, int) ) {
75 | MA_set(&d, (unsigned) n, 1);
76 | }
77 | va_end(ap);
78 |
79 | return d;
80 | }
81 |
82 |
83 | void MA_prt(mask_t m) {
84 | unsigned i;
85 |
86 | for (i = 0; i < MASK_MAX; i++) {
87 | printf("%d", MA_isset(m, i));
88 | }
89 |
90 | printf("\n");
91 |
92 | for (i = 0; i < MASK_BITS_WORDS; i++) {
93 | printf("0x%0*X ", 2 * (int)sizeof(MASK_BITS_BASETYPE), m.data[i]);
94 | }
95 |
96 | printf("\n");
97 | }
98 |
99 | /* Perform a logical AND on two masks.
100 | Author: ottrey
101 | Date: Tue Jul 6 13:28:24 CEST 1999
102 | NB: This operation could/should be done a word at a time?
103 | */
104 | mask_t MA_and(mask_t a, mask_t b) {
105 | mask_t c;
106 | unsigned i;
107 |
108 | for (i=0; i < MASK_BITS_WORDS; i++ ) {
109 | c.data[i] = a.data[i] & b.data[i];
110 | }
111 | return c;
112 | } /* MA_and() */
113 |
114 | /* Perform a logical XOR on two masks.
115 | Author: ottrey
116 | Date: Thu Jul 8 14:50:14 CEST 1999
117 | NB: This operation could/should be done a word at a time?
118 | */
119 | mask_t MA_xor(mask_t a, mask_t b) {
120 | mask_t c;
121 | unsigned i;
122 |
123 | for (i=0; i < MASK_BITS_WORDS; i++ ) {
124 | c.data[i] = a.data[i] ^ b.data[i];
125 | }
126 |
127 | return c;
128 |
129 | } /* MA_xor() */
130 |
131 | /* Perform a logical OR on two masks.
132 | Author: ottrey
133 | Date: Thu Jul 8 16:34:34 CEST 1999
134 | NB: This operation could/should be done a word at a time?
135 | */
136 | mask_t MA_or(mask_t a, mask_t b) {
137 | mask_t c;
138 | unsigned i;
139 |
140 | for (i=0; i < MASK_BITS_WORDS; i++ ) {
141 | c.data[i] = a.data[i] | b.data[i];
142 | }
143 |
144 | return c;
145 |
146 | } /* MA_or() */
147 |
148 | /* Perform a logical NOT operation on a mask.
149 | Author: marek
150 | Date: Fri Jan 14 17:15:00 MET 2000
151 | NB: This operation is done a word at a time.
152 | */
153 | mask_t MA_not(mask_t a) {
154 | mask_t c;
155 | unsigned i;
156 |
157 | for (i=0; i < MASK_BITS_WORDS; i++ ) {
158 | c.data[i] = ~a.data[i];
159 | }
160 | return c;
161 | }
162 |
163 | /* Counts the number of bits set. */
164 | int MA_bitcount(mask_t m) {
165 | unsigned i;
166 | int count=0;
167 |
168 | for (i=0; i < MASK_MAX; i++) {
169 | count += MA_isset(m, i);
170 | }
171 |
172 | return count;
173 |
174 | } /* MA_bitcount() */
175 |
176 | /* Convert the bitmap to a string comprising of tokens from an array of tokens.
177 | Author: ottrey
178 | Date: Tue Jul 6 13:28:24 CEST 1999
179 | */
180 | char *MA_to_string(mask_t mask, char * const *tokens) {
181 | char str_buf[STR_L];
182 | int count;
183 | unsigned i;
184 | int length;
185 |
186 | count=0;
187 | strcpy(str_buf, "{");
188 | for (i=0; tokens[i] != NULL; i++) {
189 | if ( MA_isset(mask, i) != 0) {
190 | strcat(str_buf, tokens[i]);
191 | strcat(str_buf, ",");
192 | count++;
193 | }
194 | }
195 | if (count == 0) {
196 | strcat(str_buf, "NULL ");
197 | }
198 | length = strlen(str_buf);
199 | str_buf[length-1] = '}';
200 |
201 | return UT_strdup(str_buf);
202 |
203 | } /* MA_to_string() */
204 |
205 | #ifdef MODULE_TEST
206 | void
207 | main() {
208 | mask_t d;
209 |
210 | d = MA_new(1, 4, 56, 3, 5, 7, 19, MA_END);
211 |
212 | MA_prt(d);
213 |
214 | MA_set(&d, 3, 0);
215 | MA_set(&d, 7, 0);
216 | MA_set(&d, 9, 0);
217 | MA_set(&d, 19, 0);
218 |
219 | MA_prt(d);
220 | }
221 | #endif