otsdaq  v1_01_02
 All Classes Namespaces Functions
BitManipulator.cc
1 #include "otsdaq-core/BitManipulator/BitManipulator.h"
2 #include "otsdaq-core/MessageFacility/MessageFacility.h"
3 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
4 #include <cstdlib>
5 #include <sstream>
6 #include <iostream>
7 
8 using namespace ots;
9 
10 
11 //========================================================================================================================
12 BitManipulator::BitManipulator()
13 {
14 }
15 
16 //========================================================================================================================
17 BitManipulator::~BitManipulator()
18 {}
19 
20 //========================================================================================================================
21 uint64_t BitManipulator::insertBits(uint64_t& data, uint64_t value, unsigned int startBit, unsigned int numberOfBits)
22 {
23  // std::cout << __COUT_HDR_FL__ << "Before: " << std::hex << data << "-<-" << value << std::dec << std::endl;
24  for(unsigned int i=0; i<numberOfBits; i++)
25  data &= ~((uint64_t)1 << (startBit+i));
26 
27  data |= (value << startBit);
28  // std::cout << __COUT_HDR_FL__ << "After: " << std::hex << data << "-<-" << value << std::dec << std::endl;
29  return data;
30 }
31 
32 //========================================================================================================================
33 uint64_t BitManipulator::insertBits(std::string& data, uint64_t value, unsigned int startBit, unsigned int numberOfBits)
34 {
35  uint8_t toWrite = 0;
36  const unsigned int bitsInAByte = 8;
37 
38  uint8_t overWritten = 0;
39  int startByte = startBit/bitsInAByte;
40  int finalByte = (startBit + numberOfBits-1)/bitsInAByte;
41  int startBitInByte = startBit%bitsInAByte;
42  int finalBitInByte = (startBit + numberOfBits-1)%bitsInAByte;
43  int tmp;
44  int firstByteLength = bitsInAByte;
45  int lastByteLength = (startBit + numberOfBits)%bitsInAByte;
46 
47  //
48  //std::cout << __COUT_HDR_FL__ << " start from byte : " << startByte << ", finish in " << finalByte << "\n" << std::endl;
49 
50  for( int j = 0; j <= finalByte - startByte; ++j)
51  {
52  if (j != 0)
53  startBitInByte = 0;
54  if (j != finalByte - startByte)
55  finalBitInByte = 7;
56  else
57  finalBitInByte = (startBit + numberOfBits-1)%8;
58 
59  tmp = finalBitInByte;
60  finalBitInByte = 7 - startBitInByte;
61  startBitInByte = 7 - tmp;
62 
63  //std::cout << __COUT_HDR_FL__ << "in byte : " << startByte + j << ", start bit: " << startBitInByte << ", finish in bit " << finalBitInByte << "\n" << std::endl;
64 
65  overWritten = data.substr(startByte+j,1).data()[0];
66  //std::cout << __COUT_HDR_FL__ << "value overwritten: " << hex << (uint64_t)overWritten << "\n" << std::endl;
67  // toWrite = (uint8_t)value; //FIXME you can declare value as uint8_t from the beginning 30-0600000000000000
68  toWrite = (uint8_t)0;
69  for (int y = 0; y <= finalBitInByte - startBitInByte; ++y)
70  {
71  if (finalByte - startByte > 1)
72  {
73  if (j != finalByte - startByte)
74  toWrite |= ((value >> (lastByteLength + (finalByte - startByte -1 -j)*8 + y))&1) << y;
75  else
76  toWrite |= ((value >> (lastByteLength + y))&1) << y;
77  }
78  else if (finalByte - startByte == 1)
79  toWrite |= ((value >> (lastByteLength*(1-j) + y))&1) << y;
80  else if (finalByte - startByte == 0)
81  toWrite |= ((value >> y)&1) << y;
82  // toWrite |= ((value >> (firstByteLength + (j-1)*8 + y))&1) << (j*8 + y);
83  }
84 
85  //std::cout << __COUT_HDR_FL__ << "value to manipulate: " << hex << (uint64_t)toWrite << " obtained from " << tmpVal << "\n" << std::endl;
86 
87  for(int n=0; n<finalBitInByte - startBitInByte + 1; n++)
88  {
89  overWritten &= ~((uint64_t)1 << (startBitInByte+n));
90  }
91  //std::cout << __COUT_HDR_FL__ << "value in intermediate step: " << hex << (uint64_t)overWritten << "\n" << std::endl;
92 
93  overWritten |= (toWrite << startBitInByte);
94 
95  //std::cout << __COUT_HDR_FL__ << "value to overwrite: " << hex << (uint64_t)overWritten << "\n" << std::endl;
96  data[startByte+j] = overWritten;
97 
98  if (j == 0)
99  firstByteLength = finalBitInByte - startBitInByte + 1;
100  }
101 
102  return (uint64_t)overWritten;
103 }
104 
105 //========================================================================================================================
106 uint64_t BitManipulator::reverseBits(uint64_t data, unsigned int startBit, unsigned int numberOfBits)
107 {
108  uint64_t reversedData = 0;
109  for(unsigned int r=startBit; r<numberOfBits; r++)
110  reversedData |= ((data>>r)&1)<<(numberOfBits-1-r);
111  return reversedData;
112 }
113 
114 //========================================================================================================================
115 uint32_t BitManipulator::insertBits(uint32_t& data, uint32_t value, unsigned int startBit, unsigned int numberOfBits)
116 {
117  // std::cout << __COUT_HDR_FL__ << "Before: " << hex << data << "-<-" << value << std::endl;
118  value = value << startBit;
119  for(unsigned int i=0; i<32; i++)
120  {
121  if( i>=startBit && i<startBit+numberOfBits)
122  data &= ~((uint32_t)1 << i);
123  else
124  value &= ~((uint32_t)1 << i);
125  }
126  data += value;
127  //std::cout << __COUT_HDR_FL__ << "After: " << hex << data << "-<-" << value << std::endl;
128  return data;
129 }
130 
131 //========================================================================================================================
132 uint32_t BitManipulator::insertBits(std::string& data, uint32_t value, unsigned int startBit, unsigned int numberOfBits)
133 {
134  uint8_t toWrite = 0;
135  const unsigned int bitsInAByte = 8;
136 
137  uint8_t overWritten = 0;
138  int startByte = startBit/bitsInAByte;
139  int finalByte = (startBit + numberOfBits-1)/bitsInAByte;
140  int startBitInByte = startBit%8;
141  int finalBitInByte = (startBit + numberOfBits-1)%bitsInAByte;
142  int tmp;
143  int firstByteLength = bitsInAByte;
144  int lastByteLength = (startBit + numberOfBits)%bitsInAByte;
145 
146  //
147  //std::cout << __COUT_HDR_FL__ << " start from byte : " << startByte << ", finish in " << finalByte << "\n" << std::endl;
148 
149  for( int j = 0; j <= finalByte - startByte; ++j)
150  {
151  if (j != 0)
152  startBitInByte = 0;
153  if (j != finalByte - startByte)
154  finalBitInByte = 7;
155  else
156  finalBitInByte = (startBit + numberOfBits-1)%8;
157 
158  tmp = finalBitInByte;
159  finalBitInByte = 7 - startBitInByte;
160  startBitInByte = 7 - tmp;
161 
162  //std::cout << __COUT_HDR_FL__ << "in byte : " << startByte + j << ", start bit: " << startBitInByte << ", finish in bit " << finalBitInByte << "\n" << std::endl;
163 
164  overWritten = data.substr(startByte+j,1).data()[0];
165  //std::cout << __COUT_HDR_FL__ << "value overwritten: " << hex << (uint64_t)overWritten << "\n" << std::endl;
166  // toWrite = (uint8_t)value; //FIXME you can declare value as uint8_t from the beginning 30-0600000000000000
167  toWrite = (uint8_t)0;
168  for (int y = 0; y <= finalBitInByte - startBitInByte; ++y)
169  {
170  if (finalByte - startByte > 1)
171  {
172  if (j != finalByte - startByte)
173  toWrite |= ((value >> (lastByteLength + (finalByte - startByte -1 -j)*8 + y))&1) << y;
174  else
175  toWrite |= ((value >> (lastByteLength + y))&1) << y;
176  }
177  else if (finalByte - startByte == 1)
178  toWrite |= ((value >> (lastByteLength*(1-j) + y))&1) << y;
179  else if (finalByte - startByte == 0)
180  toWrite |= ((value >> y)&1) << y;
181  // toWrite |= ((value >> (firstByteLength + (j-1)*8 + y))&1) << (j*8 + y);
182  }
183 
184  //std::cout << __COUT_HDR_FL__ << "value to manipulate: " << hex << (uint64_t)toWrite << " obtained from " << tmpVal << "\n" << std::endl;
185 
186  for(int n=0; n<finalBitInByte - startBitInByte + 1; n++)
187  {
188  overWritten &= ~((uint32_t)1 << (startBitInByte+n));
189  }
190  //std::cout << __COUT_HDR_FL__ << "value in intermediate step: " << hex << (uint64_t)overWritten << "\n" << std::endl;
191 
192  overWritten |= (toWrite << startBitInByte);
193 
194  //std::cout << __COUT_HDR_FL__ << "value to overwrite: " << hex << (uint64_t)overWritten << "\n" << std::endl;
195  data[startByte+j] = overWritten;
196 
197  if (j == 0)
198  firstByteLength = finalBitInByte - startBitInByte + 1;
199  }
200 
201  return (uint32_t)overWritten;
202 }
203 
204 //========================================================================================================================
205 uint32_t BitManipulator::reverseBits(uint32_t data, unsigned int startBit, unsigned int numberOfBits)
206 {
207  uint32_t reversedData = 0;
208  for(unsigned int r=startBit; r<startBit+numberOfBits; r++)
209  reversedData |= ((data>>r)&1)<<(numberOfBits-1-r);
210  return reversedData;
211 }
212 
213 //========================================================================================================================
214 uint32_t BitManipulator::readBits(uint32_t data, unsigned int startBit, unsigned int numberOfBits)
215 {
216  uint32_t returnData = 0;
217  for(unsigned int r=startBit; r<startBit+numberOfBits; r++)
218  returnData += ((data>>r)&0x1)<<(r-startBit);
219  return returnData;
220 }