00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "TBits.h"
00024 #include "string.h"
00025 #include "Riostream.h"
00026
00027 ClassImp(TBits)
00028
00029
00030 TBits::TBits(UInt_t nbits) : fNbits(nbits)
00031 {
00032
00033
00034 if (nbits <= 0) nbits = 8;
00035 fNbytes = ((nbits-1)/8) + 1;
00036 fAllBits = new UChar_t[fNbytes];
00037
00038 memset(fAllBits,0,fNbytes);
00039 }
00040
00041
00042 TBits::TBits(const TBits &original) : TObject(original), fNbits(original.fNbits),
00043 fNbytes(original.fNbytes)
00044 {
00045
00046
00047 fAllBits = new UChar_t[fNbytes];
00048 memcpy(fAllBits,original.fAllBits,fNbytes);
00049
00050 }
00051
00052
00053 TBits& TBits::operator=(const TBits& rhs)
00054 {
00055
00056
00057 if (this != &rhs) {
00058 TObject::operator=(rhs);
00059 fNbits = rhs.fNbits;
00060 fNbytes = rhs.fNbytes;
00061 delete [] fAllBits;
00062 if (fNbytes != 0) {
00063 fAllBits = new UChar_t[fNbytes];
00064 memcpy(fAllBits,rhs.fAllBits,fNbytes);
00065 } else {
00066 fAllBits = 0;
00067 }
00068 }
00069 return *this;
00070 }
00071
00072
00073 TBits::~TBits()
00074 {
00075
00076
00077 delete [] fAllBits;
00078 }
00079
00080
00081 void TBits::Clear(Option_t * )
00082 {
00083
00084
00085 delete [] fAllBits;
00086 fAllBits = 0;
00087 fNbits = 0;
00088 fNbytes = 0;
00089 }
00090
00091
00092 void TBits::Compact()
00093 {
00094
00095
00096 if (!fNbits || !fAllBits) return;
00097 UInt_t needed;
00098 for(needed=fNbytes-1;
00099 needed > 0 && fAllBits[needed]==0; ) { needed--; };
00100 needed++;
00101
00102 if (needed!=fNbytes) {
00103 UChar_t *old_location = fAllBits;
00104 fAllBits = new UChar_t[needed];
00105
00106 memcpy(fAllBits,old_location,needed);
00107 delete [] old_location;
00108
00109 fNbytes = needed;
00110 fNbits = 8*fNbytes;
00111 }
00112 }
00113
00114
00115 UInt_t TBits::CountBits(UInt_t startBit) const
00116 {
00117
00118
00119 static const Int_t nbits[256] = {
00120 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,
00121 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
00122 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
00123 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
00124 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
00125 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
00126 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
00127 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
00128 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
00129 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
00130 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
00131 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
00132 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
00133 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
00134 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
00135 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8};
00136
00137 UInt_t i,count = 0;
00138 if (startBit == 0) {
00139 for(i=0; i<fNbytes; i++) {
00140 count += nbits[fAllBits[i]];
00141 }
00142 return count;
00143 }
00144 if (startBit >= fNbits) return count;
00145 UInt_t startByte = startBit/8;
00146 UInt_t ibit = startBit%8;
00147 if (ibit) {
00148 for (i=ibit;i<8;i++) {
00149 if (fAllBits[startByte] & (1<<ibit)) count++;
00150 }
00151 startByte++;
00152 }
00153 for(i=startByte; i<fNbytes; i++) {
00154 count += nbits[fAllBits[i]];
00155 }
00156 return count;
00157 }
00158
00159
00160 void TBits::DoAndEqual(const TBits& rhs)
00161 {
00162
00163
00164
00165
00166 UInt_t min = (fNbytes<rhs.fNbytes) ? fNbytes : rhs.fNbytes;
00167 for(UInt_t i=0; i<min; ++i) {
00168 fAllBits[i] &= rhs.fAllBits[i];
00169 }
00170 if (fNbytes>min) {
00171 memset(&(fAllBits[min]),0,fNbytes-min);
00172 }
00173 }
00174
00175
00176 void TBits::DoOrEqual(const TBits& rhs)
00177 {
00178
00179
00180
00181
00182 UInt_t min = (fNbytes<rhs.fNbytes) ? fNbytes : rhs.fNbytes;
00183 for(UInt_t i=0; i<min; ++i) {
00184 fAllBits[i] |= rhs.fAllBits[i];
00185 }
00186 }
00187
00188
00189 void TBits::DoXorEqual(const TBits& rhs)
00190 {
00191
00192
00193
00194
00195 UInt_t min = (fNbytes<rhs.fNbytes) ? fNbytes : rhs.fNbytes;
00196 for(UInt_t i=0; i<min; ++i) {
00197 fAllBits[i] ^= rhs.fAllBits[i];
00198 }
00199 }
00200
00201
00202 void TBits::DoFlip()
00203 {
00204
00205
00206 for(UInt_t i=0; i<fNbytes; ++i) {
00207 fAllBits[i] = ~fAllBits[i];
00208 }
00209
00210 }
00211
00212
00213 void TBits::DoLeftShift(UInt_t shift)
00214 {
00215
00216
00217 if (shift==0) return;
00218 const UInt_t wordshift = shift / 8;
00219 const UInt_t offset = shift % 8;
00220 if (offset==0) {
00221 for(UInt_t n = fNbytes - 1; n >= wordshift; --n) {
00222 fAllBits[n] = fAllBits[ n - wordshift ];
00223 }
00224 } else {
00225 const UInt_t sub_offset = 8 - offset;
00226 for(UInt_t n = fNbytes - 1; n > wordshift; --n) {
00227 fAllBits[n] = (fAllBits[n - wordshift] << offset) |
00228 (fAllBits[n - wordshift - 1] >> sub_offset);
00229 }
00230 fAllBits[wordshift] = fAllBits[0] << offset;
00231 }
00232 memset(fAllBits,0,wordshift);
00233 }
00234
00235
00236 void TBits::DoRightShift(UInt_t shift)
00237 {
00238
00239
00240 if (shift==0) return;
00241 const UInt_t wordshift = shift / 8;
00242 const UInt_t offset = shift % 8;
00243 const UInt_t limit = fNbytes - wordshift - 1;
00244
00245 if (offset == 0)
00246 for (UInt_t n = 0; n <= limit; ++n)
00247 fAllBits[n] = fAllBits[n + wordshift];
00248 else
00249 {
00250 const UInt_t sub_offset = 8 - offset;
00251 for (UInt_t n = 0; n < limit; ++n)
00252 fAllBits[n] = (fAllBits[n + wordshift] >> offset) |
00253 (fAllBits[n + wordshift + 1] << sub_offset);
00254 fAllBits[limit] = fAllBits[fNbytes-1] >> offset;
00255 }
00256
00257 memset(&(fAllBits[limit + 1]),0, fNbytes - limit - 1);
00258 }
00259
00260
00261 UInt_t TBits::FirstNullBit(UInt_t startBit) const
00262 {
00263
00264
00265 static const Int_t fbits[256] = {
00266 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
00267 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
00268 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
00269 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
00270 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
00271 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
00272 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
00273 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,
00274 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
00275 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
00276 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
00277 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
00278 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
00279 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
00280 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
00281 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,8};
00282
00283 UInt_t i;
00284 if (startBit == 0) {
00285 for(i=0; i<fNbytes; i++) {
00286 if (fAllBits[i] != 255) return 8*i + fbits[fAllBits[i]];
00287 }
00288 return fNbits;
00289 }
00290 if (startBit >= fNbits) return fNbits;
00291 UInt_t startByte = startBit/8;
00292 UInt_t ibit = startBit%8;
00293 if (ibit) {
00294 for (i=ibit;i<8;i++) {
00295 if ((fAllBits[startByte] & (1<<i)) == 0) return 8*startByte+i;
00296 }
00297 startByte++;
00298 }
00299 for(i=startByte; i<fNbytes; i++) {
00300 if (fAllBits[i] != 255) return 8*i + fbits[fAllBits[i]];
00301 }
00302 return fNbits;
00303 }
00304
00305
00306 UInt_t TBits::FirstSetBit(UInt_t startBit) const
00307 {
00308
00309
00310 static const Int_t fbits[256] = {
00311 8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
00312 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
00313 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
00314 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
00315 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
00316 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
00317 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
00318 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
00319 7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
00320 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
00321 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
00322 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
00323 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
00324 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
00325 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
00326 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0};
00327
00328 UInt_t i;
00329 if (startBit == 0) {
00330 for(i=0; i<fNbytes; i++) {
00331 if (fAllBits[i] != 0) return 8*i + fbits[fAllBits[i]];
00332 }
00333 return fNbits;
00334 }
00335 if (startBit >= fNbits) return fNbits;
00336 UInt_t startByte = startBit/8;
00337 UInt_t ibit = startBit%8;
00338 if (ibit) {
00339 for (i=ibit;i<8;i++) {
00340 if ((fAllBits[startByte] & (1<<i)) != 0) return 8*startByte+i;
00341 }
00342 startByte++;
00343 }
00344 for(i=startByte; i<fNbytes; i++) {
00345 if (fAllBits[i] != 0) return 8*i + fbits[fAllBits[i]];
00346 }
00347 return fNbits;
00348 }
00349
00350
00351 void TBits::Output(ostream &os) const
00352 {
00353
00354
00355 for(UInt_t i=0; i<fNbytes; ++i) {
00356 UChar_t val = fAllBits[fNbytes - 1 - i];
00357 for (UInt_t j=0; j<8; ++j) {
00358 os << (bool)(val&0x80);
00359 val <<= 1;
00360 }
00361 }
00362 }
00363
00364
00365 void TBits::Paint(Option_t *)
00366 {
00367
00368
00369
00370 }
00371
00372
00373 void TBits::Print(Option_t *) const
00374 {
00375
00376
00377 Int_t count = 0;
00378 for(UInt_t i=0; i<fNbytes; ++i) {
00379 UChar_t val = fAllBits[i];
00380 for (UInt_t j=0; j<8; ++j) {
00381 if (val & 1) printf(" bit:%4d = 1\n",count);
00382 count++;
00383 val = val >> 1;
00384 }
00385 }
00386 }
00387
00388
00389 void TBits::ResetAllBits(Bool_t)
00390 {
00391
00392
00393 if (fAllBits) memset(fAllBits,0,fNbytes);
00394 }
00395
00396
00397 void TBits::ReserveBytes(UInt_t nbytes)
00398 {
00399
00400
00401 if (nbytes > fNbytes) {
00402
00403 UChar_t *newBits=new UChar_t[nbytes];
00404 delete[] fAllBits;
00405 fNbytes=nbytes;
00406 fAllBits=newBits;
00407 }
00408 }
00409
00410
00411 void TBits::Set(UInt_t nbits, const Char_t *array)
00412 {
00413
00414
00415 UInt_t nbytes=(nbits+7)>>3;
00416
00417 ReserveBytes(nbytes);
00418
00419 fNbits=nbits;
00420 memcpy(fAllBits, array, nbytes);
00421 }
00422
00423
00424 void TBits::Get(Char_t *array) const
00425 {
00426
00427
00428 memcpy(array, fAllBits, (fNbits+7)>>3);
00429 }
00430
00431 #ifdef R__BYTESWAP
00432
00433
00434
00435
00436
00437
00438
00439 void TBits::Set(UInt_t nbits, const Short_t *array)
00440 {
00441
00442
00443 Set(nbits, (const Char_t*)array);
00444 }
00445
00446 void TBits::Set(UInt_t nbits, const Int_t *array)
00447 {
00448
00449
00450 Set(nbits, (const Char_t*)array);
00451 }
00452
00453 void TBits::Set(UInt_t nbits, const Long64_t *array)
00454 {
00455
00456
00457 Set(nbits, (const Char_t*)array);
00458 }
00459
00460 void TBits::Get(Short_t *array) const
00461 {
00462
00463
00464 Get((Char_t*)array);
00465 }
00466
00467 void TBits::Get(Int_t *array) const
00468 {
00469
00470
00471 Get((Char_t*)array);
00472 }
00473
00474 void TBits::Get(Long64_t *array) const
00475 {
00476
00477
00478 Get((Char_t*)array);
00479 }
00480
00481 #else
00482
00483
00484
00485
00486
00487 void TBits::Set(UInt_t nbits, const Short_t *array)
00488 {
00489
00490 UInt_t nbytes = ((nbits+15)>>3)&~1;
00491
00492 ReserveBytes(nbytes);
00493
00494 fNbits=nbits;
00495
00496 const UChar_t *cArray = (const UChar_t*)array;
00497 for (UInt_t i=0; i<nbytes; i+=2) {
00498 fAllBits[i] = cArray[i+1];
00499 fAllBits[i+1] = cArray[i];
00500 }
00501 }
00502
00503 void TBits::Set(UInt_t nbits, const Int_t *array)
00504 {
00505
00506 UInt_t nbytes = ((nbits+31)>>3)&~3;
00507
00508 ReserveBytes(nbytes);
00509
00510 fNbits=nbits;
00511
00512 const UChar_t *cArray = (const UChar_t*)array;
00513 for (UInt_t i=0; i<nbytes; i+=4) {
00514 fAllBits[i] = cArray[i+3];
00515 fAllBits[i+1] = cArray[i+2];
00516 fAllBits[i+2] = cArray[i+1];
00517 fAllBits[i+3] = cArray[i];
00518 }
00519 }
00520
00521 void TBits::Set(UInt_t nbits, const Long64_t *array)
00522 {
00523
00524 UInt_t nbytes = ((nbits+63)>>3)&~7;
00525
00526 ReserveBytes(nbytes);
00527
00528 fNbits=nbits;
00529
00530 const UChar_t *cArray = (const UChar_t*)array;
00531 for (UInt_t i=0; i<nbytes; i+=8) {
00532 fAllBits[i] = cArray[i+7];
00533 fAllBits[i+1] = cArray[i+6];
00534 fAllBits[i+2] = cArray[i+5];
00535 fAllBits[i+3] = cArray[i+4];
00536 fAllBits[i+4] = cArray[i+3];
00537 fAllBits[i+5] = cArray[i+2];
00538 fAllBits[i+6] = cArray[i+1];
00539 fAllBits[i+7] = cArray[i];
00540 }
00541 }
00542
00543 void TBits::Get(Short_t *array) const
00544 {
00545
00546
00547 UInt_t nBytes = (fNbits+7)>>3;
00548 UInt_t nSafeBytes = nBytes&~1;
00549
00550 UChar_t *cArray=(UChar_t*)array;
00551 for (UInt_t i=0; i<nSafeBytes; i+=2) {
00552 cArray[i] = fAllBits[i+1];
00553 cArray[i+1] = fAllBits[i];
00554 }
00555
00556 if (nBytes>nSafeBytes) {
00557 cArray[nSafeBytes+1] = fAllBits[nSafeBytes];
00558 }
00559 }
00560
00561 void TBits::Get(Int_t *array) const
00562 {
00563
00564
00565 UInt_t nBytes = (fNbits+7)>>3;
00566 UInt_t nSafeBytes = nBytes&~3;
00567
00568 UChar_t *cArray=(UChar_t*)array;
00569 UInt_t i;
00570 for (i=0; i<nSafeBytes; i+=4) {
00571 cArray[i] = fAllBits[i+3];
00572 cArray[i+1] = fAllBits[i+2];
00573 cArray[i+2] = fAllBits[i+1];
00574 cArray[i+3] = fAllBits[i];
00575 }
00576
00577 for (i=0; i<nBytes-nSafeBytes; ++i) {
00578 cArray[nSafeBytes + (3 - i)] = fAllBits[nSafeBytes + i];
00579 }
00580 }
00581
00582 void TBits::Get(Long64_t *array) const
00583 {
00584
00585
00586 UInt_t nBytes = (fNbits+7)>>3;
00587 UInt_t nSafeBytes = nBytes&~7;
00588
00589 UChar_t *cArray=(UChar_t*)array;
00590 UInt_t i;
00591 for (i=0; i<nSafeBytes; i+=8) {
00592 cArray[i] = fAllBits[i+7];
00593 cArray[i+1] = fAllBits[i+6];
00594 cArray[i+2] = fAllBits[i+5];
00595 cArray[i+3] = fAllBits[i+4];
00596 cArray[i+4] = fAllBits[i+3];
00597 cArray[i+5] = fAllBits[i+2];
00598 cArray[i+6] = fAllBits[i+1];
00599 cArray[i+7] = fAllBits[i];
00600 }
00601
00602 for (i=0; i<nBytes-nSafeBytes; ++i) {
00603 cArray[nSafeBytes + (7 - i)] = fAllBits[nSafeBytes + i];
00604 }
00605 }
00606
00607 #endif
00608
00609 Bool_t TBits::operator==(const TBits &other) const
00610 {
00611
00612
00613 if (fNbits == other.fNbits) {
00614 return !memcmp(fAllBits, other.fAllBits, (fNbits+7)>>3);
00615 } else if (fNbits < other.fNbits) {
00616 return !memcmp(fAllBits, other.fAllBits, (fNbits+7)>>3) && other.FirstSetBit(fNbits) == other.fNbits;
00617 } else {
00618 return !memcmp(fAllBits, other.fAllBits, (other.fNbits+7)>>3) && FirstSetBit(other.fNbits) == fNbits;
00619 }
00620 }
00621