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