#include "TBits.h"
#include "string.h"
#include "Riostream.h"
ClassImp(TBits)
TBits::TBits(UInt_t nbits) : fNbits(nbits)
{
   
   if (nbits <= 0) nbits = 8;
   fNbytes  = ((nbits-1)/8) + 1;
   fAllBits = new UChar_t[fNbytes];
   
   memset(fAllBits,0,fNbytes);
}
TBits::TBits(const TBits &original) : TObject(original), fNbits(original.fNbits),
   fNbytes(original.fNbytes)
{
   
   fAllBits = new UChar_t[fNbytes];
   memcpy(fAllBits,original.fAllBits,fNbytes);
}
TBits& TBits::operator=(const TBits& rhs)
{
   
   if (this != &rhs) {
      TObject::operator=(rhs);
      fNbits   = rhs.fNbits;
      fNbytes  = rhs.fNbytes;
      delete [] fAllBits;
      if (fNbytes != 0) {
         fAllBits = new UChar_t[fNbytes];
         memcpy(fAllBits,rhs.fAllBits,fNbytes);
      } else {
         fAllBits = 0;
      }
   }
   return *this;
}
TBits::~TBits()
{
   
   delete [] fAllBits;
}
void TBits::Clear(Option_t * )
{
   
   delete [] fAllBits;
   fAllBits = 0;
   fNbits   = 0;
   fNbytes  = 0;
}
void TBits::Compact()
{
   
   if (!fNbits || !fAllBits) return;
   UInt_t needed;
   for(needed=fNbytes-1;
       needed > 0 && fAllBits[needed]==0; ) { needed--; };
   needed++;
   if (needed!=fNbytes) {
      UChar_t *old_location = fAllBits;
      fAllBits = new UChar_t[needed];
      memcpy(fAllBits,old_location,needed);
      delete [] old_location;
      fNbytes = needed;
      fNbits = 8*fNbytes;
   }
}
UInt_t TBits::CountBits(UInt_t startBit) const
{
   
   const Int_t nbits[256] = {
             0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,
             1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
             1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
             2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
             1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
             2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
             2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
             3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
             1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
             2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
             2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
             3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
             2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
             3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
             3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
             4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8};
   UInt_t i,count = 0;
   if (startBit == 0) {
      for(i=0; i<fNbytes; i++) {
         count += nbits[fAllBits[i]];
      }
      return count;
   }
   if (startBit >= fNbits) return count;
   UInt_t startByte = startBit/8;
   UInt_t ibit = startBit%8;
   if (ibit) {
      for (i=ibit;i<8;i++) {
         if (fAllBits[startByte] & (1<<ibit)) count++;
      }
      startByte++;
   }
   for(i=startByte; i<fNbytes; i++) {
      count += nbits[fAllBits[i]];
   }
   return count;
}
void TBits::DoAndEqual(const TBits& rhs)
{
   
   
   
   UInt_t min = (fNbytes<rhs.fNbytes) ? fNbytes : rhs.fNbytes;
   for(UInt_t i=0; i<min; ++i) {
      fAllBits[i] &= rhs.fAllBits[i];
   }
   if (fNbytes>min) {
      memset(&(fAllBits[min]),0,fNbytes-min);
   }
}
void TBits::DoOrEqual(const TBits& rhs)
{
   
   
   
   UInt_t min = (fNbytes<rhs.fNbytes) ? fNbytes : rhs.fNbytes;
   for(UInt_t i=0; i<min; ++i) {
      fAllBits[i] |= rhs.fAllBits[i];
   }
}
void TBits::DoXorEqual(const TBits& rhs)
{
   
   
   
   UInt_t min = (fNbytes<rhs.fNbytes) ? fNbytes : rhs.fNbytes;
   for(UInt_t i=0; i<min; ++i) {
      fAllBits[i] ^= rhs.fAllBits[i];
   }
}
void TBits::DoFlip()
{
   
   for(UInt_t i=0; i<fNbytes; ++i) {
      fAllBits[i] = ~fAllBits[i];
   }
   
}
void TBits::DoLeftShift(UInt_t shift)
{
   
   if (shift==0) return;
   const UInt_t wordshift = shift / 8;
   const UInt_t offset = shift % 8;
   if (offset==0) {
      for(UInt_t n = fNbytes - 1; n >= wordshift; --n) {
         fAllBits[n] = fAllBits[ n - wordshift ];
      }
   } else {
      const UInt_t sub_offset = 8 - offset;
      for(UInt_t n = fNbytes - 1; n > wordshift; --n) {
         fAllBits[n] = (fAllBits[n - wordshift] << offset) |
                       (fAllBits[n - wordshift - 1] >> sub_offset);
      }
      fAllBits[wordshift] = fAllBits[0] << offset;
   }
   memset(fAllBits,0,wordshift);
}
void TBits::DoRightShift(UInt_t shift)
{
   
   if (shift==0) return;
   const UInt_t wordshift = shift / 8;
   const UInt_t offset = shift % 8;
   const UInt_t limit = fNbytes - wordshift - 1;
   if (offset == 0)
      for (UInt_t n = 0; n <= limit; ++n)
         fAllBits[n] = fAllBits[n + wordshift];
   else
   {
      const UInt_t sub_offset = 8 - offset;
      for (UInt_t n = 0; n < limit; ++n)
         fAllBits[n] = (fAllBits[n + wordshift] >> offset) |
                       (fAllBits[n + wordshift + 1] << sub_offset);
      fAllBits[limit] = fAllBits[fNbytes-1] >> offset;
   }
   memset(&(fAllBits[limit + 1]),0, fNbytes - limit - 1);
}
UInt_t TBits::FirstNullBit(UInt_t startBit) const
{
   
   const Int_t fbits[256] = {
             0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
             0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
             0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
             0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
             0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
             0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
             0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
             0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,
             0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
             0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
             0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
             0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
             0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
             0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
             0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
             0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,8};
   UInt_t i;
   if (startBit == 0) {
      for(UInt_t i=0; i<fNbytes; i++) {
         if (fAllBits[i] != 255) return 8*i + fbits[fAllBits[i]];
      }
      return fNbits;
   }
   if (startBit >= fNbits) return fNbits;
   UInt_t startByte = startBit/8;
   UInt_t ibit = startBit%8;
   if (ibit) {
      for (i=ibit;i<8;i++) {
         if ((fAllBits[startByte] & (1<<i)) == 0) return 8*startByte+i;
      }
      startByte++;
   }
   for(i=startByte; i<fNbytes; i++) {
      if (fAllBits[i] != 255) return 8*i + fbits[fAllBits[i]];
   }
   return fNbits;
}
UInt_t TBits::FirstSetBit(UInt_t startBit) const
{
   
   const Int_t fbits[256] = {
             8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
             4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
             5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
             4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
             6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
             4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
             5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
             4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
             7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
             4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
             5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
             4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
             6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
             4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
             5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
             4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0};
   UInt_t i;
   if (startBit == 0) {
      for(UInt_t i=0; i<fNbytes; i++) {
         if (fAllBits[i] != 0) return 8*i + fbits[fAllBits[i]];
      }
      return fNbits;
   }
   if (startBit >= fNbits) return fNbits;
   UInt_t startByte = startBit/8;
   UInt_t ibit = startBit%8;
   if (ibit) {
      for (i=ibit;i<8;i++) {
         if ((fAllBits[startByte] & (1<<i)) != 0) return 8*startByte+i;
      }
      startByte++;
   }
   for(i=startByte; i<fNbytes; i++) {
      if (fAllBits[i] != 0) return 8*i + fbits[fAllBits[i]];
   }
   return fNbits;
}
void TBits::Output(ostream &os) const
{
   
   for(UInt_t i=0; i<fNbytes; ++i) {
      UChar_t val = fAllBits[fNbytes - 1 - i];
      for (UInt_t j=0; j<8; ++j) {
         os << (bool)(val&0x80);
         val <<= 1;
      }
   }
}
void TBits::Paint(Option_t *)
{
   
   
}
void TBits::Print(Option_t *) const
{
   
   Int_t count = 0;
   for(UInt_t i=0; i<fNbytes; ++i) {
      UChar_t val = fAllBits[i];
      for (UInt_t j=0; j<8; ++j) {
         if (val & 1) printf(" bit:%4d = 1\n",count);
         count++;
         val = val >> 1;
      }
   }
}
void TBits::ResetAllBits(Bool_t)
{
   
   if (fAllBits) memset(fAllBits,0,fNbytes);
}
void TBits::ReserveBytes(UInt_t nbytes)
{
   
   if (nbytes > fNbytes) {
      
      UChar_t *newBits=new UChar_t[nbytes];
      delete[] fAllBits;
      fNbytes=nbytes;
      fAllBits=newBits;
   }
}
void TBits::Set(UInt_t nbits, const Char_t *array)
{
   
   UInt_t nbytes=(nbits+7)>>3;
   ReserveBytes(nbytes);
   fNbits=nbits;
   memcpy(fAllBits, array, nbytes);
}
void TBits::Get(Char_t *array) const
{
   
   memcpy(array, fAllBits, (fNbits+7)>>3);
}
 #ifdef R__BYTESWAP  /* means we are on little endian */
 
void TBits::Set(UInt_t nbits, const Short_t *array)
{
   
   Set(nbits, (const Char_t*)array);
}
void TBits::Set(UInt_t nbits, const Int_t *array)
{
   
   Set(nbits, (const Char_t*)array);
}
void TBits::Set(UInt_t nbits, const Long64_t *array)
{
   
   Set(nbits, (const Char_t*)array);
}
void TBits::Get(Short_t *array) const
{
   
   Get((Char_t*)array);
}
void TBits::Get(Int_t *array) const
{
   
   Get((Char_t*)array);
}
void TBits::Get(Long64_t *array) const
{
   
   Get((Char_t*)array);
}
#else
 
void TBits::Set(UInt_t nbits, const Short_t *array)
{
   
   UInt_t nbytes = ((nbits+15)>>3)&~1;
   ReserveBytes(nbytes);
   fNbits=nbits;
   const UChar_t *cArray = (const UChar_t*)array;
   for (UInt_t i=0; i<nbytes; i+=2) {
      fAllBits[i] = cArray[i+1];
      fAllBits[i+1] = cArray[i];
   }
}
void TBits::Set(UInt_t nbits, const Int_t *array)
{
   
   UInt_t nbytes = ((nbits+31)>>3)&~3;
   ReserveBytes(nbytes);
   fNbits=nbits;
   const UChar_t *cArray = (const UChar_t*)array;
   for (UInt_t i=0; i<nbytes; i+=4) {
      fAllBits[i] = cArray[i+3];
      fAllBits[i+1] = cArray[i+2];
      fAllBits[i+2] = cArray[i+1];
      fAllBits[i+3] = cArray[i];
   }
}
void TBits::Set(UInt_t nbits, const Long64_t *array)
{
   
   UInt_t nbytes = ((nbits+63)>>3)&~7;
   ReserveBytes(nbytes);
   fNbits=nbits;
   const UChar_t *cArray = (const UChar_t*)array;
   for (UInt_t i=0; i<nbytes; i+=8) {
      fAllBits[i] = cArray[i+7];
      fAllBits[i+1] = cArray[i+6];
      fAllBits[i+2] = cArray[i+5];
      fAllBits[i+3] = cArray[i+4];
      fAllBits[i+4] = cArray[i+3];
      fAllBits[i+5] = cArray[i+2];
      fAllBits[i+6] = cArray[i+1];
      fAllBits[i+7] = cArray[i];
   }
}
void TBits::Get(Short_t *array) const
{
   
   UInt_t nBytes = (fNbits+7)>>3;
   UInt_t nSafeBytes = nBytes&~1;
   UChar_t *cArray=(UChar_t*)array;
   for (UInt_t i=0; i<nSafeBytes; i+=2) {
      cArray[i] = fAllBits[i+1];
      cArray[i+1] = fAllBits[i];
   }
   if (nBytes>nSafeBytes) {
      cArray[nSafeBytes+1] = fAllBits[nSafeBytes];
   }
}
void TBits::Get(Int_t *array) const
{
   
   UInt_t nBytes = (fNbits+7)>>3;
   UInt_t nSafeBytes = nBytes&~3;
   UChar_t *cArray=(UChar_t*)array;
   UInt_t i;
   for (i=0; i<nSafeBytes; i+=4) {
      cArray[i] = fAllBits[i+3];
      cArray[i+1] = fAllBits[i+2];
      cArray[i+2] = fAllBits[i+1];
      cArray[i+3] = fAllBits[i];
   }
   for (i=0; i<nBytes-nSafeBytes; ++i) {
      cArray[nSafeBytes + (3 - i)] = fAllBits[nSafeBytes + i];
   }
}
void TBits::Get(Long64_t *array) const
{
   
   UInt_t nBytes = (fNbits+7)>>3;
   UInt_t nSafeBytes = nBytes&~7;
   UChar_t *cArray=(UChar_t*)array;
   UInt_t i;
   for (i=0; i<nSafeBytes; i+=8) {
      cArray[i] = fAllBits[i+7];
      cArray[i+1] = fAllBits[i+6];
      cArray[i+2] = fAllBits[i+5];
      cArray[i+3] = fAllBits[i+4];
      cArray[i+4] = fAllBits[i+3];
      cArray[i+5] = fAllBits[i+2];
      cArray[i+6] = fAllBits[i+1];
      cArray[i+7] = fAllBits[i];
   }
   for (i=0; i<nBytes-nSafeBytes; ++i) {
      cArray[nSafeBytes + (7 - i)] = fAllBits[nSafeBytes + i];
   }
}
#endif
Bool_t TBits::operator==(const TBits &other) const
{
   
   if (fNbits != other.fNbits) {
      return kFALSE;
   }
   return !memcmp(fAllBits, other.fAllBits, (fNbits+7)>>3);
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.