1 #include "otsdaq-core/Macros/StringMacros.h"
17 bool StringMacros::wildCardMatch(
const std::string& needle,
const std::string& haystack,
18 unsigned int* priorityIndex)
26 if(needle.size() == 0)
28 if(priorityIndex) *priorityIndex = 1;
35 if(priorityIndex) *priorityIndex = 5;
40 if(needle == haystack)
42 if(priorityIndex) *priorityIndex = 1;
47 if(needle[needle.size()-1] ==
'*' &&
48 needle.substr(0,needle.size()-1) ==
49 haystack.substr(0,needle.size()-1))
51 if(priorityIndex) *priorityIndex = 2;
56 if(needle[0] ==
'*' && needle.substr(1) ==
57 haystack.substr(haystack.size() - (needle.size()-1)))
59 if(priorityIndex) *priorityIndex = 3;
64 if(needle[0] ==
'*' &&
65 needle[needle.size()-1] ==
'*' &&
66 std::string::npos != haystack.find(needle.substr(1,needle.size()-2)))
68 if(priorityIndex) *priorityIndex = 4;
73 if(priorityIndex) *priorityIndex = 0;
78 if(priorityIndex) *priorityIndex = 0;
86 bool StringMacros::inWildCardSet(
const std::string needle,
const std::set<std::string>& haystack)
88 for(
const auto& haystackString : haystack)
90 if(StringMacros::wildCardMatch(haystackString,needle))
return true;
97 std::string StringMacros::decodeURIComponent(
const std::string &data)
99 std::string decodeURIString(data.size(),0);
101 for(
unsigned int i=0;i<data.size();++i,++j)
107 decodeURIString[j] += (data[i+1]-55)*16;
109 decodeURIString[j] += (data[i+1]-48)*16;
113 decodeURIString[j] += (data[i+2]-55);
115 decodeURIString[j] += (data[i+2]-48);
120 decodeURIString[j] = data[i];
122 decodeURIString.resize(j);
123 return decodeURIString;
131 std::string StringMacros::convertEnvironmentVariables(
const std::string& data)
133 size_t begin = data.find(
"$");
134 if(begin != std::string::npos)
137 std::string envVariable;
138 std::string converted = data;
140 if(data[begin+1] ==
'{')
142 end = data.find(
"}",begin+2);
143 envVariable = data.substr(begin+2, end-begin-2);
149 for(end = begin+1; end < data.size(); ++end)
150 if(!((data[end] >=
'0' && data[end] <=
'9') ||
151 (data[end] >=
'A' && data[end] <=
'Z') ||
152 (data[end] >=
'a' && data[end] <=
'z') ||
153 data[end] ==
'-' || data[end] ==
'_' ||
154 data[end] ==
'.' || data[end] ==
':'))
156 envVariable = data.substr(begin+1, end-begin-1);
160 char *envResult = getenv(envVariable.c_str());
165 return convertEnvironmentVariables(converted.replace(begin,end-begin,envResult));
170 (
"The environmental variable '" + envVariable +
171 "' is not set! Please make sure you set it before continuing!") << std::endl;
185 bool StringMacros::isNumber(
const std::string& s)
188 std::vector<std::string> numbers;
189 std::vector<char> ops;
191 StringMacros::getVectorFromString(s,numbers,
192 std::set<char>({
'+',
'-',
'*',
'/'}),
193 std::set<char>({
' ',
'\t',
'\n',
'\r'}),
199 for(
const auto& number:numbers)
201 if(number.size() == 0)
continue;
203 if(number.find(
"0x") == 0)
206 for(
unsigned int i=2;i<number.size();++i)
208 if(!((number[i] >=
'0' && number[i] <=
'9') ||
209 (number[i] >=
'A' && number[i] <=
'F') ||
210 (number[i] >=
'a' && number[i] <=
'f')
219 else if(number[0] ==
'b')
223 for(
unsigned int i=1;i<number.size();++i)
225 if(!((number[i] >=
'0' && number[i] <=
'1')
236 for(
unsigned int i=0;i<number.size();++i)
237 if(!((number[i] >=
'0' && number[i] <=
'9') ||
256 std::string StringMacros::validateValueForDefaultStringDataType(
const std::string& value,
257 bool doConvertEnvironmentVariables)
260 return doConvertEnvironmentVariables?
261 StringMacros::convertEnvironmentVariables(value):
264 catch(
const std::runtime_error& e)
266 __SS__ <<
"Failed to validate value for default string data type. " << __E__ << e.what() << __E__;
274 void StringMacros::getSetFromString(
const std::string& inputString,
275 std::set<std::string>& setToReturn,
const std::set<char>& delimiter,
276 const std::set<char>& whitespace)
283 for(;j<inputString.size();++j)
284 if((whitespace.find(inputString[j]) != whitespace.end() ||
285 delimiter.find(inputString[j]) != delimiter.end())
288 else if((whitespace.find(inputString[j]) != whitespace.end() ||
289 delimiter.find(inputString[j]) != delimiter.end())
295 setToReturn.emplace(inputString.substr(i,j-i));
302 setToReturn.emplace(inputString.substr(i,j-i));
314 void StringMacros::getVectorFromString(
const std::string& inputString,
315 std::vector<std::string>& listToReturn,
const std::set<char>& delimiter,
316 const std::set<char>& whitespace, std::vector<char>* listOfDelimiters)
320 std::set<char>::iterator delimeterSearchIt;
328 for(;j<inputString.size();++j)
332 delimeterSearchIt = delimiter.find(inputString[j]);
333 isDelimiter = delimeterSearchIt != delimiter.end();
337 if((whitespace.find(inputString[j]) != whitespace.end() ||
341 else if((whitespace.find(inputString[j]) != whitespace.end() ||
348 if(listOfDelimiters && listToReturn.size())
349 listOfDelimiters->push_back(lastDelimiter);
350 listToReturn.push_back(inputString.substr(i,j-i));
358 lastDelimiter = *delimeterSearchIt;
363 if(listOfDelimiters && listToReturn.size())
364 listOfDelimiters->push_back(lastDelimiter);
365 listToReturn.push_back(inputString.substr(i,j-i));
369 if(listOfDelimiters && listToReturn.size() - 1 != listOfDelimiters->size())
371 __SS__ <<
"There is a mismatch in delimiters to entries (should be one less delimiter): " <<
372 listOfDelimiters->size() <<
373 " vs " << listToReturn.size() << __E__ <<
375 StringMacros::vectorToString(listToReturn) << __E__ <<
377 StringMacros::vectorToString(*listOfDelimiters) << __E__;
387 void StringMacros::getMapFromString(
const std::string& inputString,
388 std::map<std::string,std::string>& mapToReturn,
389 const std::set<char>& pairPairDelimiter,
const std::set<char>& nameValueDelimiter,
390 const std::set<char>& whitespace)
396 bool needValue =
false;
400 for(;j<inputString.size();++j)
403 if((whitespace.find(inputString[j]) != whitespace.end() ||
404 pairPairDelimiter.find(inputString[j]) != pairPairDelimiter.end())
407 else if((whitespace.find(inputString[j]) != whitespace.end() ||
408 nameValueDelimiter.find(inputString[j]) != nameValueDelimiter.end())
414 name = inputString.substr(i,j-i);
424 if((whitespace.find(inputString[j]) != whitespace.end() ||
425 nameValueDelimiter.find(inputString[j]) != nameValueDelimiter.end())
428 else if((whitespace.find(inputString[j]) != whitespace.end() ||
429 pairPairDelimiter.find(inputString[j]) != pairPairDelimiter.end())
435 auto emplaceReturn = mapToReturn.emplace(std::pair<std::string,std::string>(
437 validateValueForDefaultStringDataType(
438 inputString.substr(i,j-i))
441 if(!emplaceReturn.second)
443 __COUT__ <<
"Ignoring repetitive value ('" << inputString.substr(i,j-i) <<
444 "') and keeping current value ('" << emplaceReturn.first->second <<
"'). " << __E__;
456 auto emplaceReturn = mapToReturn.emplace(std::pair<std::string,std::string>(
458 validateValueForDefaultStringDataType(
459 inputString.substr(i,j-i))
462 if(!emplaceReturn.second)
464 __COUT__ <<
"Ignoring repetitive value ('" << inputString.substr(i,j-i) <<
465 "') and keeping current value ('" << emplaceReturn.first->second <<
"'). " << __E__;
469 catch(
const std::runtime_error &e)
471 __SS__ <<
"Error while extracting a map from the string '" <<
472 inputString <<
"'... is it a valid map?" << __E__ << e.what() << __E__;
479 std::string StringMacros::mapToString(
const std::map<std::string,uint8_t>& mapToReturn,
480 const std::string& primaryDelimeter,
const std::string& secondaryDelimeter)
482 std::stringstream ss;
484 for(
auto& mapPair:mapToReturn)
486 if(first) first =
false;
487 else ss << primaryDelimeter;
488 ss << mapPair.first << secondaryDelimeter << (
unsigned int)mapPair.second;
495 std::string StringMacros::setToString(
const std::set<uint8_t>& setToReturn,
const std::string& delimeter)
497 std::stringstream ss;
499 for(
auto& setValue:setToReturn)
501 if(first) first =
false;
502 else ss << delimeter;
503 ss << (
unsigned int)setValue;
510 std::string StringMacros::vectorToString(
const std::vector<uint8_t>& setToReturn,
const std::string& delimeter)
512 std::stringstream ss;
514 for(
auto& setValue:setToReturn)
516 if(first) first =
false;
517 else ss << delimeter;
518 ss << (
unsigned int)setValue;
532 std::string StringMacros::demangleTypeName(
const char* name)
537 std::unique_ptr<char, void(*)(void*)> res {
538 abi::__cxa_demangle(name, NULL, NULL, &status),
542 return (status==0) ? res.get() : name ;
545 #else //does nothing if not g++
549 std::string StringMacros::demangleTypeName(
const char* name)