00001
00002
00003
00004
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
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
00053 {
00054 int byteCount = ((bitCount+7)>>3);
00055 return needLargeZeroedMem(byteCount);
00056 }
00057
00058 Bits *bitRealloc(Bits *b, int bitCount, int newBitCount)
00059
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
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
00077 {
00078 freez(pB);
00079 }
00080
00081 void bitSetOne(Bits *b, int bitIx)
00082
00083 {
00084 b[bitIx>>3] |= oneBit[bitIx&7];
00085 }
00086
00087 void bitClearOne(Bits *b, int bitIx)
00088
00089 {
00090 b[bitIx>>3] &= ~oneBit[bitIx&7];
00091 }
00092
00093 void bitSetRange(Bits *b, int startIx, int bitCount)
00094
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
00117 {
00118 return (b[bitIx>>3] & oneBit[bitIx&7]) != 0;
00119 }
00120
00121 int bitCountRange(Bits *b, int startIx, int bitCount)
00122
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
00145 {
00146 unsigned char notByteVal = val ? 0 : 0xff;
00147 int iBit = startIx;
00148 int endByte = ((bitCount-1)>>3);
00149 int iByte;
00150
00151
00152 while (((iBit & 7) != 0) && (iBit < bitCount))
00153 {
00154 if (bitReadOne(b, iBit) == val)
00155 return iBit;
00156 iBit++;
00157 }
00158
00159
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
00169 while (iBit < bitCount)
00170 {
00171 if (bitReadOne(b, iBit) == val)
00172 return iBit;
00173 iBit++;
00174 }
00175 return bitCount;
00176 }
00177
00178 int bitFindSet(Bits *b, int startIx, int bitCount)
00179
00180 {
00181 return bitFind(b, startIx, TRUE, bitCount);
00182 }
00183
00184 int bitFindClear(Bits *b, int startIx, int bitCount)
00185
00186 {
00187 return bitFind(b, startIx, FALSE, bitCount);
00188 }
00189
00190 void bitClear(Bits *b, int bitCount)
00191
00192 {
00193 int byteCount = ((bitCount+7)>>3);
00194 zeroBytes(b, byteCount);
00195 }
00196
00197 void bitClearRange(Bits *b, int startIx, int bitCount)
00198
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
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
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
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
00263
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