Added OSC address wildcard support
This commit is contained in:
parent
670c1f7ff4
commit
a6992a45c8
@ -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) {
|
||||
|
@ -26,6 +26,8 @@ extern "C" DLLEXPORT int removeListener(LPCSTR address);
|
||||
extern "C" DLLEXPORT char* getStringData(char* targetString, unsigned int targetSize, unsigned int StringID);
|
||||
int handleOscMsg(const osc::ReceivedMessage& m);
|
||||
bool isMatchingOscType(unsigned int msgType, unsigned int listenerTypeField);
|
||||
bool isMatchingOSCAddress(const char* address, const char* pattern);
|
||||
bool containsOscWildcard(const char* pattern);
|
||||
unsigned int getOscType(osc::ReceivedMessage::const_iterator arg);
|
||||
void removeStoredString(int stringId);
|
||||
int addStoredString(std::string theString);
|
||||
|
Loading…
x
Reference in New Issue
Block a user