1 #include "otsdaq/Macros/StringMacros.h"
19 const std::string& haystack,
20 unsigned int* priorityIndex)
28 if(needle.size() == 0)
44 if(needle == haystack)
52 if(needle[needle.size() - 1] ==
'*' &&
53 needle.substr(0, needle.size() - 1) == haystack.substr(0, needle.size() - 1))
61 if(needle[0] ==
'*' &&
62 needle.substr(1) == haystack.substr(haystack.size() - (needle.size() - 1)))
70 if(needle[0] ==
'*' && needle[needle.size() - 1] ==
'*' &&
71 std::string::npos != haystack.find(needle.substr(1, needle.size() - 2)))
95 const std::set<std::string>& haystack)
97 for(
const auto& haystackString : haystack)
100 if(haystackString.size() && haystackString[0] ==
'!')
117 std::string decodeURIString(data.size(), 0);
119 for(
unsigned int i = 0; i < data.size(); ++i, ++j)
124 if(data[i + 1] >
'9')
125 decodeURIString[j] += (data[i + 1] - 55) * 16;
127 decodeURIString[j] += (data[i + 1] - 48) * 16;
130 if(data[i + 2] >
'9')
131 decodeURIString[j] += (data[i + 2] - 55);
133 decodeURIString[j] += (data[i + 2] - 48);
138 decodeURIString[j] = data[i];
140 decodeURIString.resize(j);
141 return decodeURIString;
145 std::string StringMacros::encodeURIComponent(
const std::string& sourceStr)
147 std::string retStr =
"";
149 for(
const auto& c : sourceStr)
150 if((c >=
'a' && c <=
'z') || (c >=
'A' && c <=
'Z') || (c >=
'0' && c <=
'9'))
154 sprintf(encodeStr,
"%%%2.2X", (uint8_t)c);
164 std::map<char, std::string> replacements = {
172 while(pos < str.size())
174 auto it = replacements.find(str[pos]);
175 if(it != replacements.end())
177 str.replace(pos, 1, it->second);
178 pos += it->second.size();
197 bool allowWhiteSpace )
199 unsigned int ws = -1;
202 for(
unsigned int i = 0; i < inString.length(); i++)
203 if(inString[i] !=
' ')
205 __COUT_TYPE__(TLVL_DEBUG + 30) << __COUT_HDR__ << i <<
". " << inString[i]
206 <<
":" << (int)inString[i] << std::endl;
209 if(inString[i] ==
'\r' || inString[i] ==
'\n' ||
210 inString[i] ==
'\t' ||
213 (inString[i] >
char(126) &&
214 inString[i] <
char(161)))
221 if(i + 2 < inString.size() && inString[i] == char(0xE2) &&
222 inString[i + 1] == char(0x80) &&
246 sprintf(htmlTmp,
"&#%3.3d", inString[i]);
248 i, std::string(htmlTmp));
266 "        ");
268 i, std::string(htmlTmp));
276 sprintf(htmlTmp,
"	");
278 i, std::string(htmlTmp));
290 inString.erase(i, 1);
293 __COUT_TYPE__(TLVL_DEBUG + 31) << __COUT_HDR__ << inString << std::endl;
297 __COUT_TYPE__(TLVL_DEBUG + 31) << __COUT_HDR__ << inString << std::endl;
300 if(inString[i] ==
'\"' || inString[i] ==
'\'')
303 (inString[i] ==
'\'')
306 inString.replace(i + 5, 1, 1,
';');
310 else if(inString[i] ==
'&')
312 inString.insert(i,
"&");
313 inString.replace(i + 4, 1, 1,
';');
316 else if(inString[i] ==
'<' || inString[i] ==
'>')
323 inString.replace(i + 3, 1, 1,
';');
326 else if(inString[i] >=
char(161) &&
327 inString[i] <=
char(255))
329 sprintf(htmlTmp,
"&#%3.3d", inString[i]);
330 inString.insert(i, std::string(htmlTmp));
331 inString.replace(i + 5, 1, 1,
';');
335 __COUT_TYPE__(TLVL_DEBUG + 30) << __COUT_HDR__ << inString << std::endl;
339 else if(allowWhiteSpace)
347 inString.insert(i,
" ");
350 inString.insert(i,
" ");
351 inString.replace(i + 5, 1, 1,
';');
356 __COUT_TYPE__(TLVL_DEBUG + 30)
357 << __COUT_HDR__ << inString.size() <<
" " << ws << std::endl;
361 __COUT_TYPE__(TLVL_DEBUG + 30)
362 << __COUT_HDR__ << inString.size() <<
" " << inString << std::endl;
368 if(ws == (
unsigned int)-1)
370 return inString.substr(0, ws + 1);
380 size_t begin = data.find(
"$");
381 if(begin != std::string::npos)
384 std::string envVariable;
385 std::string converted = data;
387 while(begin && begin != std::string::npos &&
388 converted[begin - 1] ==
391 converted.replace(begin - 1, 1,
"");
392 begin = data.find(
"$", begin + 1);
393 if(begin == std::string::npos)
395 __COUT_TYPE__(TLVL_DEBUG + 50)
397 <<
"Only found escaped $'s that will not be converted: " << converted
403 if(data[begin + 1] ==
'{')
405 end = data.find(
"}", begin + 2);
406 envVariable = data.substr(begin + 2, end - begin - 2);
412 for(end = begin + 1; end < data.size(); ++end)
413 if(!((data[end] >=
'0' && data[end] <=
'9') ||
414 (data[end] >=
'A' && data[end] <=
'Z') ||
415 (data[end] >=
'a' && data[end] <=
'z') || data[end] ==
'-' ||
416 data[end] ==
'_' || data[end] ==
'.' || data[end] ==
':'))
418 envVariable = data.substr(begin + 1, end - begin - 1);
420 __COUTVS__(50, data);
421 __COUTVS__(50, envVariable);
422 char* envResult = __ENV__(envVariable.c_str());
428 converted.replace(begin, end - begin, envResult));
432 __SS__ << (
"The environmental variable '" + envVariable +
433 "' is not set! Please make sure you set it before continuing!")
439 __COUT_TYPE__(TLVL_DEBUG + 50) << __COUT_HDR__ <<
"Result: " << data << __E__;
451 std::vector<std::string> numbers;
452 std::vector<char> ops;
460 std::set<char>({
'+',
'-',
'*',
'/'}),
461 std::set<char>({
' ',
'\t',
'\n',
'\r'}),
467 for(
const auto& number : numbers)
469 if(number.size() == 0)
472 if(number.find(
"0x") == 0)
475 for(
unsigned int i = 2; i < number.size(); ++i)
477 if(!((number[i] >=
'0' && number[i] <=
'9') ||
478 (number[i] >=
'A' && number[i] <=
'F') ||
479 (number[i] >=
'a' && number[i] <=
'f')))
487 else if(number[0] ==
'b')
491 for(
unsigned int i = 1; i < number.size(); ++i)
493 if(!((number[i] >=
'0' && number[i] <=
'1')))
503 for(
unsigned int i = 0; i < number.size(); ++i)
504 if(!((number[i] >=
'0' && number[i] <=
'9') || number[i] ==
'.' ||
505 number[i] ==
'+' || number[i] ==
'-'))
528 std::vector<std::string> numbers;
529 std::vector<char> ops;
531 bool hasDecimal =
false;
536 std::set<char>({
'+',
'-',
'*',
'/'}),
537 std::set<char>({
' ',
'\t',
'\n',
'\r'}),
543 for(
const auto& number : numbers)
545 if(number.size() == 0)
548 if(number.find(
"0x") == 0)
551 for(
unsigned int i = 2; i < number.size(); ++i)
553 if(!((number[i] >=
'0' && number[i] <=
'9') ||
554 (number[i] >=
'A' && number[i] <=
'F') ||
555 (number[i] >=
'a' && number[i] <=
'f')))
563 else if(number[0] ==
'b')
567 for(
unsigned int i = 1; i < number.size(); ++i)
569 if(!((number[i] >=
'0' && number[i] <=
'1')))
579 for(
unsigned int i = 0; i < number.size(); ++i)
580 if(!((number[i] >=
'0' && number[i] <=
'9') || number[i] ==
'.' ||
581 number[i] ==
'+' || number[i] ==
'-'))
583 else if(number[i] ==
'.')
596 return "unsigned long long";
609 __COUT_ERR__ <<
"Invalid empty bool string " << s << __E__;
614 if(s.find(
"1") != std::string::npos || s ==
"true" || s ==
"True" || s ==
"TRUE")
621 if(s.find(
"0") != std::string::npos || s ==
"false" || s ==
"False" || s ==
"FALSE")
627 __COUT_ERR__ <<
"Invalid bool string " << s << __E__;
638 time_t timestamp(strtol(linuxTimeInSeconds.c_str(), 0, 10));
648 std::string retValue(30,
'\0');
651 ::localtime_r(&linuxTimeInSeconds, &tmstruct);
652 ::strftime(&retValue[0], 30,
"%c %Z", &tmstruct);
653 retValue.resize(strlen(retValue.c_str()));
665 std::stringstream ss;
666 int days = t / 60 / 60 / 24;
669 ss << days <<
" day" << (days > 1 ?
"s" :
"") <<
", ";
670 t -= days * 60 * 60 * 24;
674 ss << std::setw(2) << std::setfill(
'0') << (t / 60 / 60) <<
":" << std::setw(2)
675 << std::setfill(
'0') << ((t % (60 * 60)) / 60) <<
":" << std::setw(2)
676 << std::setfill(
'0') << (t % 60);
684 const std::string& value,
bool doConvertEnvironmentVariables)
687 return doConvertEnvironmentVariables
691 catch(
const std::runtime_error& e)
693 __SS__ <<
"Failed to validate value for default string data type. " << __E__
694 << e.what() << __E__;
703 std::set<std::string>& setToReturn,
704 const std::set<char>& delimiter,
705 const std::set<char>& whitespace)
712 for(; j < inputString.size(); ++j)
713 if((whitespace.find(inputString[j]) !=
715 delimiter.find(inputString[j]) != delimiter.end()) &&
718 else if((whitespace.find(inputString[j]) !=
721 delimiter.find(inputString[j]) != delimiter.end()) &&
727 setToReturn.emplace(inputString.substr(i, j - i));
734 setToReturn.emplace(inputString.substr(i, j - i));
750 std::vector<std::string>& listToReturn,
751 const std::set<char>& delimiter,
752 const std::set<char>& whitespace,
753 std::vector<char>* listOfDelimiters,
754 bool decodeURIComponents)
759 std::set<char>::iterator delimeterSearchIt;
760 char lastDelimiter = 0;
769 for(; c < inputString.size(); ++c)
773 delimeterSearchIt = delimiter.find(inputString[c]);
774 isDelimiter = delimeterSearchIt != delimiter.end();
779 if(whitespace.find(inputString[c]) !=
788 else if(whitespace.find(inputString[c]) != whitespace.end() &&
798 if(listOfDelimiters && listToReturn.size())
805 listOfDelimiters->push_back(lastDelimiter);
808 inputString.substr(i, j - i))
809 : inputString.substr(i, j - i));
819 lastDelimiter = *delimeterSearchIt;
828 if(listOfDelimiters && listToReturn.size())
834 listOfDelimiters->push_back(lastDelimiter);
837 inputString.substr(i, j - i))
838 : inputString.substr(i, j - i));
842 if(listOfDelimiters && listToReturn.size() - 1 != listOfDelimiters->size() &&
843 listToReturn.size() != listOfDelimiters->size())
845 __SS__ <<
"There is a mismatch in delimiters to entries (should be equal or one "
847 << listOfDelimiters->size() <<
" vs " << listToReturn.size() << __E__
869 const std::string& inputString,
870 const std::set<char>& delimiter,
871 const std::set<char>& whitespace,
872 std::vector<char>* listOfDelimiters,
873 bool decodeURIComponents)
875 std::vector<std::string> listToReturn;
882 decodeURIComponents);
891 std::map<std::string, std::string>& mapToReturn,
892 const std::set<char>& pairPairDelimiter,
893 const std::set<char>& nameValueDelimiter,
894 const std::set<char>& whitespace)
900 bool needValue =
false;
904 for(; j < inputString.size(); ++j)
907 if((whitespace.find(inputString[j]) !=
909 pairPairDelimiter.find(inputString[j]) != pairPairDelimiter.end()) &&
912 else if((whitespace.find(inputString[j]) !=
915 nameValueDelimiter.find(inputString[j]) !=
916 nameValueDelimiter.end()) &&
922 name = inputString.substr(i, j - i);
932 if((whitespace.find(inputString[j]) !=
934 nameValueDelimiter.find(inputString[j]) != nameValueDelimiter.end()) &&
937 else if(whitespace.find(inputString[j]) !=
940 pairPairDelimiter.find(inputString[j]) !=
941 pairPairDelimiter.end())
948 mapToReturn.emplace(std::pair<std::string, std::string>(
951 inputString.substr(i, j - i))
954 if(!emplaceReturn.second)
956 __COUT__ <<
"Ignoring repetitive value ('"
957 << inputString.substr(i, j - i)
958 <<
"') and keeping current value ('"
959 << emplaceReturn.first->second <<
"'). " << __E__;
972 mapToReturn.emplace(std::pair<std::string, std::string>(
975 inputString.substr(i, j - i))
978 if(!emplaceReturn.second)
980 __COUT__ <<
"Ignoring repetitive value ('" << inputString.substr(i, j - i)
981 <<
"') and keeping current value ('" << emplaceReturn.first->second
986 catch(
const std::runtime_error& e)
988 __SS__ <<
"Error while extracting a map from the string '" << inputString
989 <<
"'... is it a valid map?" << __E__ << e.what() << __E__;
996 const std::string& primaryDelimeter,
997 const std::string& secondaryDelimeter)
999 std::stringstream ss;
1001 for(
auto& mapPair : mapToReturn)
1006 ss << primaryDelimeter;
1007 ss << mapPair.first << secondaryDelimeter << (
unsigned int)mapPair.second;
1015 const std::string& delimeter)
1017 std::stringstream ss;
1019 for(
auto& setValue : setToReturn)
1025 ss << (
unsigned int)setValue;
1033 const std::string& delimeter)
1035 std::stringstream ss;
1037 if(delimeter ==
"\n")
1039 for(
auto& setValue : setToReturn)
1045 ss << (
unsigned int)setValue;
1061 std::vector<std::string>& commonChunksToReturn,
1062 std::vector<std::string>& wildcardStringsToReturn,
1063 unsigned int& fixedWildcardLength)
1065 fixedWildcardLength = 0;
1089 std::pair<
unsigned int ,
unsigned int > wildcardBounds(
1090 std::make_pair(-1, 0));
1093 for(
unsigned int n = 1; n < haystack.size(); ++n)
1094 for(
unsigned int i = 0, j = 0;
1095 i < haystack[0].length() && j < haystack[n].length();
1098 if(i < wildcardBounds.first)
1100 if(haystack[0][i] != haystack[n][j])
1102 wildcardBounds.first = i;
1112 for(
unsigned int n = 1; n < haystack.size(); ++n)
1113 for(
int i = haystack[0].length() - 1, j = haystack[n].length() - 1;
1114 i >= (int)wildcardBounds.first && j >= (
int)wildcardBounds.first;
1117 if(i > (
int)wildcardBounds.second)
1119 if(haystack[0][i] != haystack[n][j])
1121 wildcardBounds.second = i + 1;
1132 commonChunksToReturn.push_back(haystack[0].substr(0, wildcardBounds.first));
1134 if(wildcardBounds.first != (
unsigned int)-1)
1137 for(
int i = (wildcardBounds.first + wildcardBounds.second) / 2 + 1;
1138 i < (int)wildcardBounds.second;
1140 if(haystack[0][wildcardBounds.first] == haystack[0][i] &&
1141 haystack[0].substr(wildcardBounds.first, wildcardBounds.second - i) ==
1142 haystack[0].substr(i, wildcardBounds.second - i))
1144 std::string multiWildcardString =
1145 haystack[0].substr(i, wildcardBounds.second - i);
1146 __COUT__ <<
"Multi-wildcard found: " << multiWildcardString << __E__;
1148 std::vector<
unsigned int > wildCardInstances;
1150 wildCardInstances.push_back(wildcardBounds.first);
1152 unsigned int offset =
1153 wildCardInstances[0] + multiWildcardString.size() + 1;
1154 std::string middleString = haystack[0].substr(offset, (i - 1) - offset);
1155 __COUTV__(middleString);
1159 while((k = middleString.find(multiWildcardString)) != std::string::npos)
1161 __COUT__ <<
"Multi-wildcard found at " << k << __E__;
1163 wildCardInstances.push_back(offset + k);
1166 middleString.substr(k + multiWildcardString.size() + 1);
1167 offset += k + multiWildcardString.size() + 1;
1168 __COUTV__(middleString);
1172 wildCardInstances.push_back(i);
1174 for(
unsigned int w = 0; w < wildCardInstances.size() - 1; ++w)
1176 commonChunksToReturn.push_back(haystack[0].substr(
1177 wildCardInstances[w] + wildCardInstances.size(),
1178 wildCardInstances[w + 1] -
1179 (wildCardInstances[w] + wildCardInstances.size())));
1185 for(
unsigned int i = 0; i < commonChunksToReturn[0].size(); ++i)
1186 if(commonChunksToReturn[0][commonChunksToReturn[0].size() - 1 - i] ==
'0')
1187 ++fixedWildcardLength;
1192 for(
unsigned int c = 0; c < commonChunksToReturn.size(); ++c)
1194 unsigned int cnt = 0;
1195 for(
unsigned int i = 0; i < commonChunksToReturn[c].size(); ++i)
1196 if(commonChunksToReturn[c][commonChunksToReturn[c].size() - 1 - i] ==
'0')
1201 if(fixedWildcardLength < cnt)
1202 fixedWildcardLength = cnt;
1203 else if(fixedWildcardLength > cnt)
1205 __SS__ <<
"Invalid fixed length found, please simplify indexing between "
1206 "these common chunks: "
1213 if(fixedWildcardLength)
1214 for(
unsigned int c = 0; c < commonChunksToReturn.size(); ++c)
1215 commonChunksToReturn[c] = commonChunksToReturn[c].substr(
1216 0, commonChunksToReturn[c].size() - fixedWildcardLength);
1219 commonChunksToReturn.push_back(haystack[0].substr(wildcardBounds.second));
1225 unsigned int ioff = fixedWildcardLength;
1226 bool wildcardsNeeded =
false;
1228 for(
unsigned int n = 0; n < haystack.size(); ++n)
1230 std::string wildcard =
"";
1232 i = ioff + commonChunksToReturn[0].size();
1234 if(commonChunksToReturn.size() == 1)
1235 wildcard = haystack[n].substr(i);
1237 for(
unsigned int c = 1; c < commonChunksToReturn.size(); ++c)
1239 if(c == commonChunksToReturn.size() - 1)
1240 k = haystack[n].rfind(commonChunksToReturn[c]);
1242 k = haystack[n].find(commonChunksToReturn[c], i + 1);
1251 wildcard = haystack[n].substr(i, k - i);
1252 if(fixedWildcardLength && n == 0)
1253 fixedWildcardLength += wildcard.size();
1260 wildcard != haystack[n].substr(i, k - i))
1262 __SS__ <<
"Invalid wildcard! for name[" << n <<
"] = " << haystack[n]
1263 <<
" - the extraction algorithm is confused, please simplify "
1264 "your naming convention."
1273 wildcardsNeeded =
true;
1274 wildcardStringsToReturn.push_back(wildcard);
1281 if(wildcardStringsToReturn.size() != haystack.size())
1283 __SS__ <<
"There was a problem during common chunk extraction!" << __E__;
1287 return wildcardsNeeded;
1296 const std::string& rhs)
const
1302 for(
unsigned int i = 0; i < lhs.size() && i < rhs.size(); ++i)
1305 if((lhs[i] >=
'A' && lhs[i] <=
'Z' && rhs[i] >=
'A' && rhs[i] <=
'Z') ||
1306 (lhs[i] >=
'a' && lhs[i] <=
'z' && rhs[i] >=
'a' && rhs[i] <=
'z'))
1308 if(lhs[i] == rhs[i])
1310 return (lhs[i] < rhs[i]);
1313 else if(lhs[i] >=
'A' && lhs[i] <=
'Z')
1315 if(lhs[i] + 32 == rhs[i])
1317 return (lhs[i] + 32 < rhs[i]);
1319 else if(rhs[i] >=
'A' && rhs[i] <=
'Z')
1321 if(lhs[i] == rhs[i] + 32)
1323 return (lhs[i] < rhs[i] + 32);
1327 if(lhs[i] == rhs[i])
1329 return (lhs[i] < rhs[i]);
1334 return lhs.size() < rhs.size();
1344 std::array<char, 128> buffer;
1346 std::shared_ptr<FILE> pipe(popen(cmd,
"r"), pclose);
1348 __THROW__(
"popen() failed!");
1349 while(!feof(pipe.get()))
1351 if(fgets(buffer.data(), 128, pipe.get()) !=
nullptr)
1352 result += buffer.data();
1363 #include <execinfo.h>
1367 __SS__ <<
"ots::stackTrace:\n";
1373 size = backtrace(array, 10);
1377 char** messages = backtrace_symbols(array, size);
1381 for(
unsigned int i = 1; i < size && messages != NULL; ++i)
1394 char *mangled_name = 0, *offset_begin = 0, *offset_end = 0;
1397 for(
char* p = messages[i]; *p; ++p)
1415 if(mangled_name && offset_begin && offset_end && mangled_name < offset_begin)
1417 *mangled_name++ =
'\0';
1418 *offset_begin++ =
'\0';
1419 *offset_end++ =
'\0';
1422 char* real_name = abi::__cxa_demangle(mangled_name, 0, 0, &status);
1427 ss <<
"[" << i <<
"] " << messages[i] <<
" : " << real_name <<
"+"
1428 << offset_begin << offset_end << std::endl;
1433 ss <<
"[" << i <<
"] " << messages[i] <<
" : " << mangled_name <<
"+"
1434 << offset_begin << offset_end << std::endl;
1441 ss <<
"[" << i <<
"] " << messages[i] << std::endl;
1460 const std::string& location,
1461 const unsigned int& line)
1463 char* environmentVariablePtr = getenv(name);
1464 if(!environmentVariablePtr)
1466 __SS__ <<
"Environment variable '$" << name <<
"' not defined at " << location
1467 <<
":" << line << __E__;
1471 return environmentVariablePtr;
1478 const std::string& field,
1479 uint32_t occurrence,
1481 size_t* returnFindPos ,
1482 const std::string& valueField ,
1483 const std::string& quoteType )
1486 *returnFindPos = std::string::npos;
1488 __COUTVS__(41, xml);
1490 size_t lo, findpos = after, hi;
1491 for(uint32_t i = 0; i <= occurrence; ++i)
1493 bool anyFound =
false;
1495 xml.find(
"<" + field,
1496 findpos)) != std::string::npos &&
1497 findpos + 1 + field.size() < xml.size())
1499 __COUT_TYPE__(TLVL_DEBUG + 40)
1500 << __COUT_HDR__ <<
"find: ---- '<" << field <<
" findpos=" << findpos
1501 <<
"findpos " << findpos <<
" " << xml[findpos] <<
" "
1502 << xml[findpos + 1 + field.size()] <<
" "
1503 << (int)xml[findpos + 1 + field.size()] << __E__;
1511 if((quoteType ==
">" && xml[findpos] ==
'>') || xml[findpos] ==
' ' ||
1512 xml[findpos] ==
'\n' || xml[findpos] ==
'\t')
1521 __COUT_TYPE__(TLVL_DEBUG + 40)
1522 << __COUT_HDR__ <<
"Field '" << field <<
"' not found" << __E__;
1527 lo = xml.find(valueField + quoteType, findpos) + valueField.size() + quoteType.size();
1529 if(TTEST(40) && quoteType.size())
1531 __COUT_TYPE__(TLVL_DEBUG + 40)
1532 << __COUT_HDR__ <<
"Neighbors of field '" << field <<
"' and value '"
1533 << valueField <<
"' w/quote = " << quoteType << __E__;
1534 for(
size_t i = lo - valueField.size(); i < lo + 10 && i < xml.size(); ++i)
1535 __COUT_TYPE__(TLVL_DEBUG + 40)
1536 << __COUT_HDR__ <<
"xml[" << i <<
"] " << xml[i] <<
" vs " << quoteType
1537 <<
" ? " << (int)xml[i] <<
" vs " << (
int)quoteType[0] << __E__;
1541 quoteType ==
">" ?
"<" : quoteType,
1542 lo)) == std::string::npos)
1544 __COUT_TYPE__(TLVL_DEBUG + 40)
1545 << __COUT_HDR__ <<
"Value closing not found" << __E__;
1550 *returnFindPos = findpos - (1 + field.size());
1552 __COUT_TYPE__(TLVL_DEBUG + 40)
1553 << __COUT_HDR__ <<
"after: " << after <<
", findpos: " << findpos
1554 <<
", hi/lo: " << hi <<
"/" << lo <<
", size: " << xml.size() << __E__;
1555 __COUTVS__(40, xml.substr(lo, hi - lo));
1556 return xml.substr(lo, hi - lo);
1563 const std::string& field,
1564 uint32_t occurrence,
1566 size_t* returnFindPos ,
1567 const std::string& valueField ,
1568 const std::string& quoteType )
1571 *returnFindPos = std::string::npos;
1573 __COUTVS__(41, xml);
1575 size_t lo = 0, hi, findpos = before;
1576 for(uint32_t i = 0; i <= occurrence; ++i)
1578 bool anyFound =
false;
1580 xml.rfind(
"<" + field,
1581 findpos)) != std::string::npos &&
1582 findpos + 1 + field.size() < xml.size())
1584 __COUT_TYPE__(TLVL_DEBUG + 40)
1585 << __COUT_HDR__ <<
"rfind: ---- '<" << field <<
" findpos=" << findpos
1586 <<
" " << xml[findpos] <<
" " << xml[findpos + 1 + field.size()] <<
" "
1587 << (int)xml[findpos + 1 + field.size()] << __E__;
1589 findpos += 1 + field.size();
1592 if((quoteType ==
">" && xml[findpos] ==
'>') || xml[findpos] ==
' ' ||
1593 xml[findpos] ==
'\n' || xml[findpos] ==
'\t')
1599 findpos -= 1 + field.size() + 1;
1603 __COUT_TYPE__(TLVL_DEBUG + 40)
1604 << __COUT_HDR__ <<
"Field '" << field <<
"' not found" << __E__;
1609 lo = xml.find(valueField + quoteType, findpos) + valueField.size() + quoteType.size();
1611 if(TTEST(40) && quoteType.size())
1613 __COUT_TYPE__(TLVL_DEBUG + 40) << __COUT_HDR__ <<
"Neighbors?" << __E__;
1614 for(
size_t i = findpos; i < lo + 10 && i < xml.size(); ++i)
1615 __COUT_TYPE__(TLVL_DEBUG + 40)
1616 << __COUT_HDR__ <<
"xml[" << i <<
"] " << xml[i] <<
" vs " << quoteType
1617 <<
" ? " << (int)xml[i] <<
" vs " << (
int)quoteType[0] << __E__;
1621 quoteType ==
">" ?
"<" : quoteType,
1622 lo)) == std::string::npos)
1624 __COUT_TYPE__(TLVL_DEBUG + 40)
1625 << __COUT_HDR__ <<
"Value closing not found" << __E__;
1631 findpos - (1 + field.size());
1633 __COUT_TYPE__(TLVL_DEBUG + 40)
1634 << __COUT_HDR__ <<
"before: " << before <<
", findpos: " << findpos
1635 <<
", hi/lo: " << hi <<
"/" << lo <<
", size: " << xml.size() << __E__;
1636 __COUTVS__(40, xml.substr(lo, hi - lo));
1637 return xml.substr(lo, hi - lo);
1652 std::unique_ptr<char, void (*)(
void*)> res{
1653 abi::__cxa_demangle(name, NULL, NULL, &status), std::free};
1655 return (status == 0) ? res.get() : name;
bool operator()(const std::string &lhs, const std::string &rhs) const
<get string in order ignoring letter case
static std::string getTimestampString(const std::string &linuxTimeInSeconds)
static std::string extractXmlField(const std::string &xml, const std::string &field, uint32_t occurrence, size_t after, size_t *returnFindPos=nullptr, const std::string &valueField="value=", const std::string "eType="'")
static void getVectorFromString(const std::string &inputString, std::vector< std::string > &listToReturn, const std::set< char > &delimiter={',', '|', '&'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'}, std::vector< char > *listOfDelimiters=0, bool decodeURIComponents=false)
static std::string exec(const char *cmd)
static void getSetFromString(const std::string &inputString, std::set< std::string > &setToReturn, const std::set< char > &delimiter={',', '|', '&'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'})
static std::string setToString(const std::set< T > &setToReturn, const std::string &delimeter=", ")
setToString ~
static T validateValueForDefaultStringDataType(const std::string &value, bool doConvertEnvironmentVariables=true)
static char * otsGetEnvironmentVarable(const char *name, const std::string &location, const unsigned int &line)
static std::string escapeString(std::string inString, bool allowWhiteSpace=false)
static void sanitizeForSQL(std::string &data)
StringMacros::sanitizeForSQL.
static std::string vectorToString(const std::vector< T > &setToReturn, const std::string &delimeter=", ")
vectorToString ~
static std::string convertEnvironmentVariables(const std::string &data)
static std::string getNumberType(const std::string &stringToCheck)
Note: before call consider use of stringToCheck = StringMacros::convertEnvironmentVariables(stringToC...
static std::string demangleTypeName(const char *name)
static std::string rextractXmlField(const std::string &xml, const std::string &field, uint32_t occurrence, size_t before, size_t *returnFindPos=nullptr, const std::string &valueField="value=", const std::string "eType="'")
static bool extractCommonChunks(const std::vector< std::string > &haystack, std::vector< std::string > &commonChunksToReturn, std::vector< std::string > &wildcardStrings, unsigned int &fixedWildcardLength)
static bool inWildCardSet(const std::string &needle, const std::set< std::string > &haystack)
static bool isNumber(const std::string &stringToCheck)
Note: before call consider use of stringToCheck = StringMacros::convertEnvironmentVariables(stringToC...
static std::string mapToString(const std::map< std::string, T > &mapToReturn, const std::string &primaryDelimeter=", ", const std::string &secondaryDelimeter=": ")
static void getMapFromString(const std::string &inputString, std::map< S, T > &mapToReturn, const std::set< char > &pairPairDelimiter={',', '|', '&'}, const std::set< char > &nameValueDelimiter={'=', ':'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'})
getMapFromString ~
static std::string getTimeDurationString(const time_t durationInSeconds=time(0))
static bool wildCardMatch(const std::string &needle, const std::string &haystack, unsigned int *priorityIndex=0)
static std::string decodeURIComponent(const std::string &data)
static std::string stackTrace(void)
static bool getNumber(const std::string &s, T &retValue)