|
|
@ -219,6 +219,136 @@ bool isMatchingOscType(unsigned int msgType, unsigned int listenerTypeField) |
|
|
|
return (listenerTypeField & msgType); |
|
|
|
} |
|
|
|
|
|
|
|
/* Checks if an incoming OSC messages address matches a given pattern.
|
|
|
|
* Also handles OSC wildcards! */ |
|
|
|
bool isMatchingOSCAddress(const char* address, const char* pattern) |
|
|
|
{ |
|
|
|
//If no wildcards in pattern, do a simple strcmp to save time
|
|
|
|
if (!containsOscWildcard(pattern)) |
|
|
|
{ |
|
|
|
if (strcmp(address, pattern) == 0) return true; |
|
|
|
else return false; |
|
|
|
} |
|
|
|
|
|
|
|
std::string chars; |
|
|
|
|
|
|
|
while (*address != '\0' && *pattern != '\0') |
|
|
|
{ |
|
|
|
switch (*pattern) |
|
|
|
{ |
|
|
|
case '?': //exactly one character
|
|
|
|
if (*address == '/') return false; //'?' does not match beyond '/'
|
|
|
|
address++; |
|
|
|
pattern++; |
|
|
|
break; |
|
|
|
case '*': //zero or more chars
|
|
|
|
pattern++; |
|
|
|
if (isMatchingOSCAddress(address, pattern)) return true; //'*' matches "no char"
|
|
|
|
while (*address != '\0' && *address != '/') |
|
|
|
{ //shift address one char and check again (recursion)
|
|
|
|
address++; |
|
|
|
if (isMatchingOSCAddress(address, pattern)) return true; |
|
|
|
} |
|
|
|
return false; |
|
|
|
break; |
|
|
|
case '[': //Match one character from list (or range of) chars like [asdf] or [a-f] or [!0-9]
|
|
|
|
pattern++; |
|
|
|
while (*pattern != '\0' && |
|
|
|
*pattern != ']' && |
|
|
|
*pattern != '/') |
|
|
|
{ |
|
|
|
if (*pattern == '-') //range of chars
|
|
|
|
{ |
|
|
|
pattern++; |
|
|
|
char c = chars.back() + 1; |
|
|
|
if (*pattern == ']' || *pattern == '/' || *pattern == '\0') c = *pattern; |
|
|
|
while (c != *pattern) |
|
|
|
{ |
|
|
|
chars.push_back(c); |
|
|
|
c++; |
|
|
|
} |
|
|
|
} |
|
|
|
chars.push_back(*pattern); |
|
|
|
pattern++; |
|
|
|
} |
|
|
|
if (chars.at(0) == '!') //negated list or range of chars
|
|
|
|
{ |
|
|
|
chars.erase(chars.begin()); |
|
|
|
if (chars.find(*address) != std::string::npos) return false; |
|
|
|
} |
|
|
|
else if (chars.find(*address) == std::string::npos) return false; |
|
|
|
chars.clear(); |
|
|
|
if (*pattern == ']') pattern++; |
|
|
|
address++; |
|
|
|
break; |
|
|
|
case '{': //list of strings (comma separated like {asd,fghj,etc}
|
|
|
|
bool result; |
|
|
|
result = false; |
|
|
|
pattern++; |
|
|
|
while (!result && |
|
|
|
*pattern != '\0' && |
|
|
|
*pattern != '}' && |
|
|
|
*pattern != '/') |
|
|
|
{ |
|
|
|
while (*pattern != '\0' && |
|
|
|
*pattern != ',' && |
|
|
|
*pattern != '}' && |
|
|
|
*pattern != '/') |
|
|
|
{ |
|
|
|
chars.push_back(*pattern); |
|
|
|
pattern++; |
|
|
|
} |
|
|
|
if (chars.compare(0, chars.length(), address, chars.length()) == 0) |
|
|
|
{ |
|
|
|
result = true; |
|
|
|
address += chars.length(); |
|
|
|
} |
|
|
|
chars.clear(); |
|
|
|
pattern++; |
|
|
|
} |
|
|
|
if (!result) return false; |
|
|
|
while (*pattern != '\0' && |
|
|
|
*pattern != '}' && |
|
|
|
*pattern != '/') |
|
|
|
{ |
|
|
|
pattern++; |
|
|
|
} |
|
|
|
if (*pattern == '}') pattern++; |
|
|
|
break; |
|
|
|
default: //Just a character, no wildcard here
|
|
|
|
if (*pattern == *address) |
|
|
|
{ |
|
|
|
address++; |
|
|
|
pattern++; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
return false; |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (*pattern != *address) return false; //Only match if both strings end here.
|
|
|
|
|
|
|
|
return true; //No earlier 'return false' triggered, so we got a match!
|
|
|
|
} |
|
|
|
|
|
|
|
bool containsOscWildcard(const char* pattern) |
|
|
|
{ |
|
|
|
while (*pattern != '\0') |
|
|
|
{ |
|
|
|
if (*pattern == '?' || |
|
|
|
*pattern == '*' || |
|
|
|
*pattern == '[' || |
|
|
|
*pattern == ']' || |
|
|
|
*pattern == '{' || |
|
|
|
*pattern == '}') return true; |
|
|
|
pattern++; |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
int handleOscMsg(const osc::ReceivedMessage& m) |
|
|
|
{ |
|
|
|
int ret = 0; |
|
|
@ -241,7 +371,7 @@ int handleOscMsg(const osc::ReceivedMessage& m) |
|
|
|
for (UINT i = 0; i < listeners.size(); i++) |
|
|
|
{ |
|
|
|
//Check if incoming OSC address matches current listener entry
|
|
|
|
if (listeners[i].address.compare(m.AddressPattern()) == 0) //TODO: Implement OSC Pattern Wildcards
|
|
|
|
if ( isMatchingOSCAddress(m.AddressPattern(), listeners[i].address.c_str()) ) |
|
|
|
{ |
|
|
|
//Check payload type
|
|
|
|
if (m.ArgumentCount() == 0) { |
|
|
|