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