tdaq-develop-2025-02-12
BinaryStringMacros.cc
1 #include "otsdaq/Macros/BinaryStringMacros.h"
2 
3 using namespace ots;
4 
5 //==============================================================================
12  const void* binaryBuffer,
13  unsigned int numberOfBytes,
14  const std::string& resultPreamble,
15  const std::string& resultDelimiter)
16 {
17  std::string dest;
18  dest.reserve(numberOfBytes * 2);
19  char hexstr[3];
20 
21  for(unsigned int i = 0; i < numberOfBytes; ++i)
22  {
23  sprintf(hexstr, "%02X", (unsigned char)((const char*)binaryBuffer)[i]);
24  if(i)
25  dest += resultDelimiter;
26  dest += hexstr;
27  }
28  return resultPreamble + dest;
29 } // end binaryToHexString
30 
31 //==============================================================================
35 std::string BinaryStringMacros::binaryNumberToHexString(
36  const std::string& binaryBuffer,
37  const std::string& resultPreamble /*"0x"*/,
38  const std::string& resultDelimiter /*" "*/)
39 {
40  return binaryNumberToHexString(
41  &binaryBuffer[0], binaryBuffer.size(), resultPreamble, resultDelimiter);
42 } // end binaryNumberToHexString()
43 
44 //==============================================================================
48 std::string BinaryStringMacros::binaryNumberToHexString(
49  const void* binaryBuffer,
50  unsigned int numberOfBytes,
51  const std::string& resultPreamble /*"0x"*/,
52  const std::string& resultDelimiter /*" "*/)
53 {
54  std::string dest;
55  dest.reserve(numberOfBytes * 2 + resultDelimiter.size() * (numberOfBytes / 8) +
56  resultPreamble.size());
57  char hexstr[3];
58 
59  dest += resultPreamble;
60 
61  unsigned int j = 0;
62  for(; j + 8 < numberOfBytes; j += 8)
63  {
64  if(j)
65  dest += resultDelimiter;
66  for(unsigned int k = 0; k < 8; ++k)
67  {
68  sprintf(hexstr,
69  "%02X",
70  (unsigned char)((const char*)binaryBuffer)[7 - k + j * 8]);
71  dest += hexstr;
72  }
73  }
74  for(unsigned int k = numberOfBytes - 1; k >= j; --k)
75  {
76  sprintf(hexstr, "%02X", (unsigned char)((const char*)binaryBuffer)[k]);
77  dest += hexstr;
78  if(k == 0)
79  break; // to handle unsigned numbers when j is 0
80  }
81 
82  return dest;
83 } // end binaryNumberToHexString()
84 
85 //==============================================================================
88 void BinaryStringMacros::insertValueInBinaryString(std::string& binaryBuffer,
89  const std::string& value,
90  unsigned int bitIndex /* = 0 */)
91 {
92  std::string dataType = StringMacros::getNumberType(value);
93  if(dataType == "nan")
94  {
95  __SS__ << "String value must be a valid number! Value was " << value << __E__;
96  __SS_THROW__;
97  }
98 
99  if(dataType == "double")
100  {
101  double v;
102  if(!StringMacros::getNumber<double>(value, v))
103  {
104  __SS__ << "String double value must be a valid number! Value was " << value
105  << __E__;
106  __SS_THROW__;
107  }
108  BinaryStringMacros::insertValueInBinaryString<double>(binaryBuffer, v, bitIndex);
109  }
110  else // assume unsigned long long
111  {
112  unsigned long long v;
113  if(!StringMacros::getNumber<unsigned long long>(value, v))
114  {
115  __SS__ << "String unsigned long long value must be a valid number! Value was "
116  << value << __E__;
117  __SS_THROW__;
118  }
119  BinaryStringMacros::insertValueInBinaryString<unsigned long long>(
120  binaryBuffer, v, bitIndex);
121  }
122 } // end insertValueInBinaryString()
123 
124 //==============================================================================
128 void BinaryStringMacros::extractValueFromBinaryString(const void* binaryBufferVoid,
129  unsigned int bufferNumberOfBytes,
130  void* valueVoid,
131  unsigned int valueNumberOfBits,
132  unsigned int bitIndex /* = 0 */)
133 {
134  //__COUTV__(bufferNumberOfBytes);
135 
136  //__COUTV__(valueNumberOfBits);
137 
138  if(valueNumberOfBits == 0)
139  {
140  __SS__ << "Can not extract value of size 0!" << __E__;
141  __SS_THROW__;
142  }
143 
144  if(bitIndex + valueNumberOfBits > bufferNumberOfBytes * 8)
145  {
146  __SS__ << "Can not extract value of size " << valueNumberOfBits
147  << ", at position " << bitIndex << ", from buffer of size "
148  << bufferNumberOfBytes * 8 << "." << __E__;
149  __SS_THROW__;
150  }
151 
152  unsigned char* value = (unsigned char*)valueVoid;
153  const unsigned char* binaryBuffer = (const unsigned char*)binaryBufferVoid;
154  unsigned int byteOffset = bitIndex / 8;
155  unsigned int bitOffset = bitIndex % 8;
156  unsigned int bitsLeft = valueNumberOfBits;
157 
158  // unsigned int valueBytes = (valueNumberOfBits / 8) + ((valueNumberOfBits % 8) ? 1 : 0);
159 
160  unsigned int valuei = 0;
161 
162  while(bitsLeft) // copy whole bytes
163  {
164  // __COUT__ << "bitsLeft=" << bitsLeft <<
165  // " byteOffset=" << byteOffset <<
166  // " bitOffset=" << bitOffset <<
167  // " valuei=" << valuei <<
168  // __E__;
169 
170  // each byte is partial of buffer[n] + buffer[n+1] overlapping by bitOffset
171  value[valuei] = binaryBuffer[byteOffset] >> bitOffset;
172  if(bitOffset)
173  value[valuei] |= binaryBuffer[byteOffset + 1] << (8 - bitOffset);
174 
175  if(bitsLeft > 7)
176  {
177  bitsLeft -= 8;
178  ++valuei;
179  ++byteOffset;
180  }
181  else // only a partial byte left
182  {
183  unsigned char keepMask = ((unsigned char)(-1)) >> (8 - bitsLeft);
184  value[valuei] &= keepMask;
185  bitsLeft = 0;
186  }
187 
188  // __COUT__ << "value: " <<
189  // BinaryStringMacros::binaryToHexString(
190  // (char *)value,valueBytes,"0x"," ") << __E__;
191  }
192 
193  // __COUT__ << "value: " <<
194  // BinaryStringMacros::binaryToHexString(
195  // (char *)value,valueBytes,"0x"," ") << __E__;
196 
197 } // end extractValueFromBinaryString()
198 
199 //==============================================================================
203 void BinaryStringMacros::extractValueFromBinaryString(const std::string& binaryBuffer,
204  std::string& value,
205  unsigned int valueNumberOfBits,
206  unsigned int bitIndex /* = 0 */)
207 {
208  value.resize((valueNumberOfBits / 8) + ((valueNumberOfBits % 8) ? 1 : 0));
210  &binaryBuffer[0], binaryBuffer.size(), &value[0], valueNumberOfBits, bitIndex);
211 } // end extractValueFromBinaryString()
static std::string binaryStringToHexString(const void *binaryBuffer, unsigned int numberOfBytes, const std::string &resultPreamble="", const std::string &resultDelimiter="")
static void extractValueFromBinaryString(const std::string &binaryBuffer, T &value, unsigned int bitIndex=0)
static void insertValueInBinaryString(std::string &binaryBuffer, T value, unsigned int bitIndex=0)
static std::string getNumberType(const std::string &stringToCheck)
Note: before call consider use of stringToCheck = StringMacros::convertEnvironmentVariables(stringToC...