extend MQTT integration support
This commit is contained in:
@@ -175,11 +175,14 @@ enum PartType {
|
||||
/** bit flag for @a DataType: numeric type with base class @a NumberDataType. */
|
||||
#define NUM 0x400
|
||||
|
||||
/** bit flag for @a DataType: numeric type with base class @a DateTimeDataType. */
|
||||
#define DAT 0x800
|
||||
|
||||
/** bit flag for @a DataType: special marker for certain types. */
|
||||
#define SPE 0x800
|
||||
#define SPE 0x1000
|
||||
|
||||
/** bit flag for @a DataType: stored duplicate for backwards compatibility, not to be traversed in lists any more. */
|
||||
#define DUP 0x1000
|
||||
#define DUP 0x2000
|
||||
|
||||
/**
|
||||
* Base class for all kinds of data types.
|
||||
@@ -364,7 +367,7 @@ class DateTimeDataType : public DataType {
|
||||
*/
|
||||
DateTimeDataType(const string& id, size_t bitCount, uint16_t flags, unsigned int replacement,
|
||||
bool hasDate, bool hasTime, int16_t resolution)
|
||||
: DataType(id, bitCount, flags, replacement), m_hasDate(hasDate), m_hasTime(hasTime),
|
||||
: DataType(id, bitCount, flags|DAT, replacement), m_hasDate(hasDate), m_hasTime(hasTime),
|
||||
m_resolution(resolution == 0 ? 1 : resolution) {}
|
||||
|
||||
/**
|
||||
|
||||
@@ -118,6 +118,98 @@ void FileReader::tolower(string* str) {
|
||||
transform(str->begin(), str->end(), str->begin(), ::tolower);
|
||||
}
|
||||
|
||||
bool FileReader::matches(const string& input, const string& search, bool ignoreCase, bool searchIsLower) {
|
||||
if (search.empty()) {
|
||||
return true; // empty pattern matches everything
|
||||
}
|
||||
if (ignoreCase) {
|
||||
string inputSub = input;
|
||||
tolower(&inputSub);
|
||||
if (searchIsLower) {
|
||||
return matches(inputSub, search, false, true);
|
||||
}
|
||||
string searchSub = search;
|
||||
tolower(&inputSub);
|
||||
return matches(inputSub, searchSub, false, false);
|
||||
}
|
||||
// walk through alternatives
|
||||
size_t from = 0;
|
||||
bool found = false;
|
||||
do {
|
||||
size_t to = search.find('|', from);
|
||||
if (to == string::npos) {
|
||||
to = search.length();
|
||||
} else {
|
||||
found = true;
|
||||
}
|
||||
if (from==to) {
|
||||
return true; // empty pattern matches everything
|
||||
}
|
||||
size_t nextStart = to+1;
|
||||
bool matchStart = search[from] == '^';
|
||||
if (matchStart) {
|
||||
from++;
|
||||
}
|
||||
bool matchEnd = from<to && search[to-1] == '$';
|
||||
if (matchEnd) {
|
||||
to--;
|
||||
}
|
||||
if (matchEnd && matchStart && from==to) { // pattern is "^$"
|
||||
if (input.empty()) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
string prefix = search.substr(from, to-from);
|
||||
size_t star = prefix.find('*');
|
||||
size_t checkEnd = input.length();
|
||||
if (star != string::npos) {
|
||||
string suffix = prefix.substr(star + 1);
|
||||
prefix = prefix.substr(0, star);
|
||||
if (suffix.empty()) {
|
||||
// empty suffix matches everything
|
||||
} else {
|
||||
if (checkEnd < suffix.length()) {
|
||||
checkEnd = string::npos; // no-match
|
||||
} else {
|
||||
checkEnd -= suffix.length();
|
||||
if (matchEnd) {
|
||||
if (input.find(suffix, checkEnd) == string::npos) {
|
||||
checkEnd = string::npos; // no-match
|
||||
}
|
||||
} else {
|
||||
checkEnd = input.rfind(suffix, checkEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
matchEnd = false; // prefix is no longer required to match at the end
|
||||
} // else: no star, check prefix only
|
||||
if (checkEnd != string::npos) {
|
||||
if (prefix.empty()) {
|
||||
return true; // empty prefix matches everything
|
||||
}
|
||||
if (prefix.length() <= checkEnd) {
|
||||
if (matchStart) {
|
||||
if (input.substr(0, prefix.length()) == prefix && (!matchEnd || prefix.length()==checkEnd)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
string remain = input.substr(0, checkEnd);
|
||||
if (matchEnd) {
|
||||
if (remain.find(prefix, checkEnd-prefix.length()) != string::npos) {
|
||||
return true;
|
||||
}
|
||||
} else if (remain.find(prefix) != string::npos) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} // else: prefix is longer than remainder
|
||||
}
|
||||
}
|
||||
from = nextStart;
|
||||
} while (from < search.length()+(found?1:0));
|
||||
return false;
|
||||
}
|
||||
|
||||
static size_t hashFunction(const string& str) {
|
||||
size_t hash = 0;
|
||||
for (unsigned char c : str) {
|
||||
|
||||
@@ -141,6 +141,20 @@ class FileReader {
|
||||
*/
|
||||
static void tolower(string* str);
|
||||
|
||||
/**
|
||||
* Check the input string against the search pattern.
|
||||
* @param input the input string to check.
|
||||
* @param search the search pattern to match against. May contain alternatives separated by a "|".
|
||||
* Each alternative may
|
||||
* - start with "^" to match the beginning of the input,
|
||||
* - end with "$" to match the end of the input,
|
||||
* - contain a single "*" (between other characters) to match an arbitrary number of characters.
|
||||
* @param ignoreCase true to ignore case differences.
|
||||
* @param searchIsLower true if search is already known to be in lowercase only.
|
||||
* @return true if the input string matches the search pattern.
|
||||
*/
|
||||
static bool matches(const string& input, const string& search, bool ignoreCase = false, bool searchIsLower = false);
|
||||
|
||||
/**
|
||||
* Split the next line(s) from the @a istream into fields.
|
||||
* @param stream the @a istream to read from.
|
||||
|
||||
@@ -615,6 +615,9 @@ bool Message::setPollPriority(size_t priority) {
|
||||
if (m_usedByCondition && (priority == 0 || priority > POLL_PRIORITY_CONDITION)) {
|
||||
usePriority = POLL_PRIORITY_CONDITION;
|
||||
}
|
||||
if (m_pollPriority != usePriority) {
|
||||
time(&m_createTime); // mis-use creation time for this update
|
||||
}
|
||||
bool ret = m_pollPriority == 0 && usePriority > 0;
|
||||
m_pollPriority = usePriority;
|
||||
if (ret || m_pollOrder > g_lastPollOrder+(unsigned int)m_pollPriority) {
|
||||
|
||||
@@ -47,6 +47,50 @@ void verify(bool expectFailMatch, string type, string input,
|
||||
}
|
||||
}
|
||||
|
||||
string matchInputs[] = {
|
||||
// expected result (+=true, -=false), pattern, test strings
|
||||
"+", "", "", ".", "*",
|
||||
"+", "*", ".", "*", "**",
|
||||
"+", "a", "hallo", "a",
|
||||
"-", "a", "hi", "b",
|
||||
"+", "^a", "aber",
|
||||
"-", "^a", "reba",
|
||||
"+", "^a*", "aber",
|
||||
"-", "^a*", "reba",
|
||||
"+", "^*a", "reba",
|
||||
"-", "^*a", "rebx",
|
||||
"+", "a$", "reba",
|
||||
"-", "a$", "aber",
|
||||
"+", "*a$", "reba",
|
||||
"-", "*a$", "aber",
|
||||
"+", "a*$", "aber",
|
||||
"-", "a*$", "xber",
|
||||
"+", "|.", "", ".", "*",
|
||||
"+", ".|", "", ".", "*",
|
||||
"+", "*|", ".", "*", "**",
|
||||
"+", "a|z", "hallo", "a",
|
||||
"-", "a|z", "hi", "b",
|
||||
"+", "^a|z", "aber",
|
||||
"-", "^a|z", "reba",
|
||||
"+", "^a*|z", "aber",
|
||||
"-", "^a*|z", "reba",
|
||||
"+", "^*a|z", "reba",
|
||||
"-", "^*a|z", "rebx",
|
||||
"+", "a$|z", "reba",
|
||||
"-", "a$|z", "aber",
|
||||
"+", "*a$|z", "reba",
|
||||
"-", "*a$|z", "aber",
|
||||
"+", "a*$|z", "aber",
|
||||
"-", "a*$|z", "xber",
|
||||
"+", "a|*", "hi", "b",
|
||||
"+", "^a|e*a", "reba",
|
||||
"+", "^a*|r*a", "reba",
|
||||
"+", "^*a|^r*x$", "rebx",
|
||||
"+", "a$|^*$", "aber",
|
||||
"+", "*a$|^*", "aber",
|
||||
"+", "a*$|*$", "xber",
|
||||
};
|
||||
|
||||
string resultlines[][3] = {
|
||||
{"col 1", "col 2", "col 3"},
|
||||
{"line 2 col 1 de", "line 2 col 2", "line 2 \"col 3\";default of col 3"},
|
||||
@@ -215,6 +259,32 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
return error ? 1 : 0;
|
||||
}
|
||||
|
||||
bool expectResult = true;
|
||||
bool nextPattern = true;
|
||||
string pattern = "";
|
||||
for (auto& str : matchInputs) {
|
||||
if (str == "+" || str == "-") {
|
||||
expectResult = str == "+";
|
||||
nextPattern = true;
|
||||
continue;
|
||||
}
|
||||
if (nextPattern) {
|
||||
pattern = str;
|
||||
nextPattern = false;
|
||||
continue;
|
||||
}
|
||||
bool result = FileReader::matches(str, pattern);
|
||||
cout << "matches(\"" << str << "\", \"" << pattern << "\") = " << (result ? "true" : "false");
|
||||
if (result==expectResult) {
|
||||
cout << ": OK";
|
||||
} else {
|
||||
cout << ": wrong";
|
||||
error = true;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
baseLine = __LINE__+1;
|
||||
istringstream ifs(
|
||||
"col 1.en,col 1.de,col 2,col 3\n"
|
||||
|
||||
Reference in New Issue
Block a user