00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "BitVector.hh"
00022
00023 BitVector::BitVector(unsigned char* baseBytePtr,
00024 unsigned baseBitOffset,
00025 unsigned totNumBits) {
00026 setup(baseBytePtr, baseBitOffset, totNumBits);
00027 }
00028
00029 void BitVector::setup(unsigned char* baseBytePtr,
00030 unsigned baseBitOffset,
00031 unsigned totNumBits) {
00032 fBaseBytePtr = baseBytePtr;
00033 fBaseBitOffset = baseBitOffset;
00034 fTotNumBits = totNumBits;
00035 fCurBitIndex = 0;
00036 }
00037
00038 static unsigned char const singleBitMask[8]
00039 = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
00040
00041 #define MAX_LENGTH 32
00042
00043 void BitVector::putBits(unsigned from, unsigned numBits) {
00044 unsigned char tmpBuf[4];
00045 unsigned overflowingBits = 0;
00046
00047 if (numBits > MAX_LENGTH) {
00048 numBits = MAX_LENGTH;
00049 }
00050
00051 if (numBits > fTotNumBits - fCurBitIndex) {
00052 overflowingBits = numBits - (fTotNumBits - fCurBitIndex);
00053 }
00054
00055 tmpBuf[0] = (unsigned char)(from>>24);
00056 tmpBuf[1] = (unsigned char)(from>>16);
00057 tmpBuf[2] = (unsigned char)(from>>8);
00058 tmpBuf[3] = (unsigned char)from;
00059
00060 shiftBits(fBaseBytePtr, fBaseBitOffset + fCurBitIndex,
00061 tmpBuf, MAX_LENGTH - numBits,
00062 numBits - overflowingBits );
00063 fCurBitIndex += numBits - overflowingBits;
00064 }
00065
00066
00067 void BitVector::put1Bit(unsigned bit) {
00068
00069 if (fCurBitIndex >= fTotNumBits) {
00070 return;
00071 } else {
00072 unsigned totBitOffset = fBaseBitOffset + fCurBitIndex++;
00073 unsigned char mask = singleBitMask[totBitOffset%8];
00074 if (bit) {
00075 fBaseBytePtr[totBitOffset/8] |= mask;
00076 } else {
00077 fBaseBytePtr[totBitOffset/8] &=~ mask;
00078 }
00079 }
00080 }
00081
00082
00083 unsigned BitVector::getBits(unsigned numBits) {
00084 unsigned char tmpBuf[4];
00085 unsigned overflowingBits = 0;
00086
00087 if (numBits > MAX_LENGTH) {
00088 numBits = MAX_LENGTH;
00089 }
00090
00091 if (numBits > fTotNumBits - fCurBitIndex) {
00092 overflowingBits = numBits - (fTotNumBits - fCurBitIndex);
00093 }
00094
00095 shiftBits(tmpBuf, 0,
00096 fBaseBytePtr, fBaseBitOffset + fCurBitIndex,
00097 numBits - overflowingBits );
00098 fCurBitIndex += numBits - overflowingBits;
00099
00100 unsigned result
00101 = (tmpBuf[0]<<24) | (tmpBuf[1]<<16) | (tmpBuf[2]<<8) | tmpBuf[3];
00102 result >>= (MAX_LENGTH - numBits);
00103 result &= (0xFFFFFFFF << overflowingBits);
00104 return result;
00105 }
00106
00107 unsigned BitVector::get1Bit() {
00108
00109
00110 if (fCurBitIndex >= fTotNumBits) {
00111 return 0;
00112 } else {
00113 unsigned totBitOffset = fBaseBitOffset + fCurBitIndex++;
00114 unsigned char curFromByte = fBaseBytePtr[totBitOffset/8];
00115 unsigned result = (curFromByte >> (7-(totBitOffset%8))) & 0x01;
00116 return result;
00117 }
00118 }
00119
00120 void BitVector::skipBits(unsigned numBits) {
00121 if (numBits > fTotNumBits - fCurBitIndex) {
00122 fCurBitIndex = fTotNumBits;
00123 } else {
00124 fCurBitIndex += numBits;
00125 }
00126 }
00127
00128
00129 void shiftBits(unsigned char* toBasePtr, unsigned toBitOffset,
00130 unsigned char const* fromBasePtr, unsigned fromBitOffset,
00131 unsigned numBits) {
00132
00133 unsigned char const* fromBytePtr = fromBasePtr + fromBitOffset/8;
00134 unsigned fromBitRem = fromBitOffset%8;
00135 unsigned char* toBytePtr = toBasePtr + toBitOffset/8;
00136 unsigned toBitRem = toBitOffset%8;
00137
00138 while (numBits-- > 0) {
00139 unsigned char fromBitMask = singleBitMask[fromBitRem];
00140 unsigned char fromBit = (*fromBytePtr)&fromBitMask;
00141 unsigned char toBitMask = singleBitMask[toBitRem];
00142
00143 if (fromBit != 0) {
00144 *toBytePtr |= toBitMask;
00145 } else {
00146 *toBytePtr &=~ toBitMask;
00147 }
00148
00149 if (++fromBitRem == 8) {
00150 ++fromBytePtr;
00151 fromBitRem = 0;
00152 }
00153 if (++toBitRem == 8) {
00154 ++toBytePtr;
00155 toBitRem = 0;
00156 }
00157 }
00158 }