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);
|
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 handleOscMsg(const osc::ReceivedMessage& m)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -241,7 +371,7 @@ int handleOscMsg(const osc::ReceivedMessage& m)
|
|||||||
for (UINT i = 0; i < listeners.size(); i++)
|
for (UINT i = 0; i < listeners.size(); i++)
|
||||||
{
|
{
|
||||||
//Check if incoming OSC address matches current listener entry
|
//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
|
//Check payload type
|
||||||
if (m.ArgumentCount() == 0) {
|
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);
|
extern "C" DLLEXPORT char* getStringData(char* targetString, unsigned int targetSize, unsigned int StringID);
|
||||||
int handleOscMsg(const osc::ReceivedMessage& m);
|
int handleOscMsg(const osc::ReceivedMessage& m);
|
||||||
bool isMatchingOscType(unsigned int msgType, unsigned int listenerTypeField);
|
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);
|
unsigned int getOscType(osc::ReceivedMessage::const_iterator arg);
|
||||||
void removeStoredString(int stringId);
|
void removeStoredString(int stringId);
|
||||||
int addStoredString(std::string theString);
|
int addStoredString(std::string theString);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user