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