00001 #include "otsdaq-core/BitManipulator/BitManipulator.h"
00002 #include "otsdaq-core/MessageFacility/MessageFacility.h"
00003 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
00004 #include <cstdlib>
00005 #include <sstream>
00006 #include <iostream>
00007
00008 using namespace ots;
00009
00010
00011
00012 BitManipulator::BitManipulator()
00013 {
00014 }
00015
00016
00017 BitManipulator::~BitManipulator()
00018 {}
00019
00020
00021 uint64_t BitManipulator::insertBits(uint64_t& data, uint64_t value, unsigned int startBit, unsigned int numberOfBits)
00022 {
00023
00024 for(unsigned int i=0; i<numberOfBits; i++)
00025 data &= ~((uint64_t)1 << (startBit+i));
00026
00027 data |= (value << startBit);
00028
00029 return data;
00030 }
00031
00032
00033 uint64_t BitManipulator::insertBits(std::string& data, uint64_t value, unsigned int startBit, unsigned int numberOfBits)
00034 {
00035 uint8_t toWrite = 0;
00036 const unsigned int bitsInAByte = 8;
00037
00038 uint8_t overWritten = 0;
00039 int startByte = startBit/bitsInAByte;
00040 int finalByte = (startBit + numberOfBits-1)/bitsInAByte;
00041 int startBitInByte = startBit%bitsInAByte;
00042 int finalBitInByte = (startBit + numberOfBits-1)%bitsInAByte;
00043 int tmp;
00044 int firstByteLength = bitsInAByte;
00045 int lastByteLength = (startBit + numberOfBits)%bitsInAByte;
00046
00047
00048
00049
00050 for( int j = 0; j <= finalByte - startByte; ++j)
00051 {
00052 if (j != 0)
00053 startBitInByte = 0;
00054 if (j != finalByte - startByte)
00055 finalBitInByte = 7;
00056 else
00057 finalBitInByte = (startBit + numberOfBits-1)%8;
00058
00059 tmp = finalBitInByte;
00060 finalBitInByte = 7 - startBitInByte;
00061 startBitInByte = 7 - tmp;
00062
00063
00064
00065 overWritten = data.substr(startByte+j,1).data()[0];
00066
00067
00068 toWrite = (uint8_t)0;
00069 for (int y = 0; y <= finalBitInByte - startBitInByte; ++y)
00070 {
00071 if (finalByte - startByte > 1)
00072 {
00073 if (j != finalByte - startByte)
00074 toWrite |= ((value >> (lastByteLength + (finalByte - startByte -1 -j)*8 + y))&1) << y;
00075 else
00076 toWrite |= ((value >> (lastByteLength + y))&1) << y;
00077 }
00078 else if (finalByte - startByte == 1)
00079 toWrite |= ((value >> (lastByteLength*(1-j) + y))&1) << y;
00080 else if (finalByte - startByte == 0)
00081 toWrite |= ((value >> y)&1) << y;
00082
00083 }
00084
00085
00086
00087 for(int n=0; n<finalBitInByte - startBitInByte + 1; n++)
00088 {
00089 overWritten &= ~((uint64_t)1 << (startBitInByte+n));
00090 }
00091
00092
00093 overWritten |= (toWrite << startBitInByte);
00094
00095
00096 data[startByte+j] = overWritten;
00097
00098 if (j == 0)
00099 firstByteLength = finalBitInByte - startBitInByte + 1;
00100 }
00101
00102 return (uint64_t)overWritten;
00103 }
00104
00105
00106 uint64_t BitManipulator::reverseBits(uint64_t data, unsigned int startBit, unsigned int numberOfBits)
00107 {
00108 uint64_t reversedData = 0;
00109 for(unsigned int r=startBit; r<numberOfBits; r++)
00110 reversedData |= ((data>>r)&1)<<(numberOfBits-1-r);
00111 return reversedData;
00112 }
00113
00114
00115 uint32_t BitManipulator::insertBits(uint32_t& data, uint32_t value, unsigned int startBit, unsigned int numberOfBits)
00116 {
00117
00118 value = value << startBit;
00119 for(unsigned int i=0; i<32; i++)
00120 {
00121 if( i>=startBit && i<startBit+numberOfBits)
00122 data &= ~((uint32_t)1 << i);
00123 else
00124 value &= ~((uint32_t)1 << i);
00125 }
00126 data += value;
00127
00128 return data;
00129 }
00130
00131
00132 uint32_t BitManipulator::insertBits(std::string& data, uint32_t value, unsigned int startBit, unsigned int numberOfBits)
00133 {
00134 uint8_t toWrite = 0;
00135 const unsigned int bitsInAByte = 8;
00136
00137 uint8_t overWritten = 0;
00138 int startByte = startBit/bitsInAByte;
00139 int finalByte = (startBit + numberOfBits-1)/bitsInAByte;
00140 int startBitInByte = startBit%8;
00141 int finalBitInByte = (startBit + numberOfBits-1)%bitsInAByte;
00142 int tmp;
00143 int firstByteLength = bitsInAByte;
00144 int lastByteLength = (startBit + numberOfBits)%bitsInAByte;
00145
00146
00147
00148
00149 for( int j = 0; j <= finalByte - startByte; ++j)
00150 {
00151 if (j != 0)
00152 startBitInByte = 0;
00153 if (j != finalByte - startByte)
00154 finalBitInByte = 7;
00155 else
00156 finalBitInByte = (startBit + numberOfBits-1)%8;
00157
00158 tmp = finalBitInByte;
00159 finalBitInByte = 7 - startBitInByte;
00160 startBitInByte = 7 - tmp;
00161
00162
00163
00164 overWritten = data.substr(startByte+j,1).data()[0];
00165
00166
00167 toWrite = (uint8_t)0;
00168 for (int y = 0; y <= finalBitInByte - startBitInByte; ++y)
00169 {
00170 if (finalByte - startByte > 1)
00171 {
00172 if (j != finalByte - startByte)
00173 toWrite |= ((value >> (lastByteLength + (finalByte - startByte -1 -j)*8 + y))&1) << y;
00174 else
00175 toWrite |= ((value >> (lastByteLength + y))&1) << y;
00176 }
00177 else if (finalByte - startByte == 1)
00178 toWrite |= ((value >> (lastByteLength*(1-j) + y))&1) << y;
00179 else if (finalByte - startByte == 0)
00180 toWrite |= ((value >> y)&1) << y;
00181
00182 }
00183
00184
00185
00186 for(int n=0; n<finalBitInByte - startBitInByte + 1; n++)
00187 {
00188 overWritten &= ~((uint32_t)1 << (startBitInByte+n));
00189 }
00190
00191
00192 overWritten |= (toWrite << startBitInByte);
00193
00194
00195 data[startByte+j] = overWritten;
00196
00197 if (j == 0)
00198 firstByteLength = finalBitInByte - startBitInByte + 1;
00199 }
00200
00201 return (uint32_t)overWritten;
00202 }
00203
00204
00205 uint32_t BitManipulator::reverseBits(uint32_t data, unsigned int startBit, unsigned int numberOfBits)
00206 {
00207 uint32_t reversedData = 0;
00208 for(unsigned int r=startBit; r<startBit+numberOfBits; r++)
00209 reversedData |= ((data>>r)&1)<<(numberOfBits-1-r);
00210 return reversedData;
00211 }
00212
00213
00214 uint32_t BitManipulator::readBits(uint32_t data, unsigned int startBit, unsigned int numberOfBits)
00215 {
00216 uint32_t returnData = 0;
00217 for(unsigned int r=startBit; r<startBit+numberOfBits; r++)
00218 returnData += ((data>>r)&0x1)<<(r-startBit);
00219 return returnData;
00220 }