Source File modules/ma/bitmask.c

    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