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