lib/bits.c

Go to the documentation of this file.
00001 /* bits - handle operations on arrays of bits. 
00002  *
00003  * This file is copyright 2002 Jim Kent, but license is hereby
00004  * granted for all use - public, private or commercial. */
00005 
00006 #include "common.h"
00007 #include "bits.h"
00008 
00009 static char const rcsid[] = "$Id: bits.c,v 1.19 2006/02/28 05:40:46 markd Exp $";
00010 
00011 
00012 static Bits oneBit[8] = { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1};
00013 static Bits leftMask[8] = {0xFF, 0x7F, 0x3F, 0x1F,  0xF,  0x7,  0x3,  0x1,};
00014 static Bits rightMask[8] = {0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF,};
00015 int bitsInByte[256];
00016 
00017 static boolean inittedBitsInByte = FALSE;
00018 
00019 void bitsInByteInit()
00020 /* Initialize bitsInByte array. */
00021 {
00022 int i;
00023 
00024 if (!inittedBitsInByte)
00025     {
00026     inittedBitsInByte = TRUE;
00027     for (i=0; i<256; ++i)
00028         {
00029         int count = 0;
00030         if (i&1)
00031             count = 1;
00032         if (i&2)
00033             ++count;
00034         if (i&4)
00035             ++count;
00036         if (i&8)
00037             ++count;
00038         if (i&0x10)
00039             ++count;
00040         if (i&0x20)
00041             ++count;
00042         if (i&0x40)
00043             ++count;
00044         if (i&0x80)
00045             ++count;
00046         bitsInByte[i] = count;
00047         }
00048     }
00049 }
00050 
00051 Bits *bitAlloc(int bitCount)
00052 /* Allocate bits. */
00053 {
00054 int byteCount = ((bitCount+7)>>3);
00055 return needLargeZeroedMem(byteCount);
00056 }
00057 
00058 Bits *bitRealloc(Bits *b, int bitCount, int newBitCount)
00059 /* Resize a bit array.  If b is null, allocate a new array */
00060 {
00061 int byteCount = ((bitCount+7)>>3);
00062 int newByteCount = ((newBitCount+7)>>3);
00063 return needLargeZeroedMemResize(b, byteCount, newByteCount);
00064 }
00065 
00066 Bits *bitClone(Bits* orig, int bitCount)
00067 /* Clone bits. */
00068 {
00069 int byteCount = ((bitCount+7)>>3);
00070 Bits* bits = needLargeZeroedMem(byteCount);
00071 memcpy(bits, orig, byteCount);
00072 return bits;
00073 }
00074 
00075 void bitFree(Bits **pB)
00076 /* Free bits. */
00077 {
00078 freez(pB);
00079 }
00080 
00081 void bitSetOne(Bits *b, int bitIx)
00082 /* Set a single bit. */
00083 {
00084 b[bitIx>>3] |= oneBit[bitIx&7];
00085 }
00086 
00087 void bitClearOne(Bits *b, int bitIx)
00088 /* Clear a single bit. */
00089 {
00090 b[bitIx>>3] &= ~oneBit[bitIx&7];
00091 }
00092 
00093 void bitSetRange(Bits *b, int startIx, int bitCount)
00094 /* Set a range of bits. */
00095 {
00096 int endIx = (startIx + bitCount - 1);
00097 int startByte = (startIx>>3);
00098 int endByte = (endIx>>3);
00099 int startBits = (startIx&7);
00100 int endBits = (endIx&7);
00101 int i;
00102 
00103 if (startByte == endByte)
00104     {
00105     b[startByte] |= (leftMask[startBits] & rightMask[endBits]);
00106     return;
00107     }
00108 b[startByte] |= leftMask[startBits];
00109 for (i = startByte+1; i<endByte; ++i)
00110     b[i] = 0xff;
00111 b[endByte] |= rightMask[endBits];
00112 }
00113 
00114 
00115 boolean bitReadOne(Bits *b, int bitIx)
00116 /* Read a single bit. */
00117 {
00118 return (b[bitIx>>3] & oneBit[bitIx&7]) != 0;
00119 }
00120 
00121 int bitCountRange(Bits *b, int startIx, int bitCount)
00122 /* Count number of bits set in range. */
00123 {
00124 int endIx = (startIx + bitCount - 1);
00125 int startByte = (startIx>>3);
00126 int endByte = (endIx>>3);
00127 int startBits = (startIx&7);
00128 int endBits = (endIx&7);
00129 int i;
00130 int count = 0;
00131 
00132 if (!inittedBitsInByte)
00133     bitsInByteInit();
00134 if (startByte == endByte)
00135     return bitsInByte[b[startByte] & leftMask[startBits] & rightMask[endBits]];
00136 count = bitsInByte[b[startByte] & leftMask[startBits]];
00137 for (i = startByte+1; i<endByte; ++i)
00138     count += bitsInByte[b[i]];
00139 count += bitsInByte[b[endByte] & rightMask[endBits]];
00140 return count;
00141 }
00142 
00143 int bitFind(Bits *b, int startIx, boolean val, int bitCount)
00144 /* Find the index of the the next set bit. */
00145 {
00146 unsigned char notByteVal = val ? 0 : 0xff;
00147 int iBit = startIx;
00148 int endByte = ((bitCount-1)>>3);
00149 int iByte;
00150 
00151 /* scan initial byte */
00152 while (((iBit & 7) != 0) && (iBit < bitCount))
00153     {
00154     if (bitReadOne(b, iBit) == val)
00155         return iBit;
00156     iBit++;
00157     }
00158 
00159 /* scan byte at a time, if not already in last byte */
00160 iByte = (iBit >> 3);
00161 if (iByte < endByte)
00162     {
00163     while ((iByte < endByte) && (b[iByte] == notByteVal))
00164         iByte++;
00165     iBit = iByte << 3;
00166     }
00167 
00168 /* scan last byte */
00169 while (iBit < bitCount)
00170     {
00171     if (bitReadOne(b, iBit) == val)
00172         return iBit;
00173     iBit++;
00174     }
00175  return bitCount;  /* not found */
00176 }
00177 
00178 int bitFindSet(Bits *b, int startIx, int bitCount)
00179 /* Find the index of the the next set bit. */
00180 {
00181 return bitFind(b, startIx, TRUE, bitCount);
00182 }
00183 
00184 int bitFindClear(Bits *b, int startIx, int bitCount)
00185 /* Find the index of the the next clear bit. */
00186 {
00187 return bitFind(b, startIx, FALSE, bitCount);
00188 }
00189 
00190 void bitClear(Bits *b, int bitCount)
00191 /* Clear many bits (possibly up to 7 beyond bitCount). */
00192 {
00193 int byteCount = ((bitCount+7)>>3);
00194 zeroBytes(b, byteCount);
00195 }
00196 
00197 void bitClearRange(Bits *b, int startIx, int bitCount)
00198 /* Clear a range of bits. */
00199 {
00200 int endIx = (startIx + bitCount - 1);
00201 int startByte = (startIx>>3);
00202 int endByte = (endIx>>3);
00203 int startBits = (startIx&7);
00204 int endBits = (endIx&7);
00205 int i;
00206 
00207 if (startByte == endByte)
00208     {
00209     b[startByte] &= ~(leftMask[startBits] & rightMask[endBits]);
00210     return;
00211     }
00212 b[startByte] &= ~leftMask[startBits];
00213 for (i = startByte+1; i<endByte; ++i)
00214     b[i] = 0x00;
00215 b[endByte] &= ~rightMask[endBits];
00216 }
00217 
00218 void bitAnd(Bits *a, Bits *b, int bitCount)
00219 /* And two bitmaps.  Put result in a. */
00220 {
00221 int byteCount = ((bitCount+7)>>3);
00222 while (--byteCount >= 0)
00223     {
00224     *a = (*a & *b++);
00225     a++;
00226     }
00227 }
00228 
00229 void bitOr(Bits *a, Bits *b, int bitCount)
00230 /* Or two bitmaps.  Put result in a. */
00231 {
00232 int byteCount = ((bitCount+7)>>3);
00233 while (--byteCount >= 0)
00234     {
00235     *a = (*a | *b++);
00236     a++;
00237     }
00238 }
00239 
00240 void bitXor(Bits *a, Bits *b, int bitCount)
00241 {
00242 int byteCount = ((bitCount+7)>>3);
00243 while (--byteCount >= 0)
00244     {
00245     *a = (*a ^ *b++);
00246     a++;
00247     }
00248 }
00249 
00250 void bitNot(Bits *a, int bitCount)
00251 /* Flip all bits in a. */
00252 {
00253 int byteCount = ((bitCount+7)>>3);
00254 while (--byteCount >= 0)
00255     {
00256     *a = ~*a;
00257     a++;
00258     }
00259 }
00260 
00261 void bitPrint(Bits *a, int startIx, int bitCount, FILE* out)
00262 /* Print part or all of bit map as a string of 0s and 1s.  Mostly useful for
00263  * debugging */
00264 {
00265 int i;
00266 for (i = startIx; i < bitCount; i++)
00267     {
00268     if (bitReadOne(a, i))
00269         fputc('1', out);
00270     else
00271         fputc('0', out);
00272     }
00273 fputc('\n', out);
00274 }
00275 

Generated on Tue Dec 25 18:39:30 2007 for blat by  doxygen 1.5.2