modules/ma/bitmask.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following functions.
  1. MA_isset
  2. MA_set
  3. MA_clear
  4. MA_new
  5. MA_prt
  6. MA_and
  7. MA_xor
  8. MA_or
  9. MA_not
  10. MA_bitcount
  11. MA_to_string
  12. main

   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) {
     /* [<][>][^][v][top][bottom][index][help] */
  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) {
     /* [<][>][^][v][top][bottom][index][help] */
  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) {
     /* [<][>][^][v][top][bottom][index][help] */
  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,...) {
     /* [<][>][^][v][top][bottom][index][help] */
  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) {
     /* [<][>][^][v][top][bottom][index][help] */
  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) {
     /* [<][>][^][v][top][bottom][index][help] */
 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) {
     /* [<][>][^][v][top][bottom][index][help] */
 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) {
     /* [<][>][^][v][top][bottom][index][help] */
 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) {
     /* [<][>][^][v][top][bottom][index][help] */
 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) {
     /* [<][>][^][v][top][bottom][index][help] */
 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) {
     /* [<][>][^][v][top][bottom][index][help] */
 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() {
     /* [<][>][^][v][top][bottom][index][help] */
 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

/* [<][>][^][v][top][bottom][index][help] */