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