/* The library has four methods for doing pattern matching on address. 'match' and 'fullMatch' are specific to OSCMessages while route and dispatch work on both messages and bundles. OSCMessage: match - matches the message's address pattern against an address. returns the number of characters matched from the address passed in. fullMatch - returns true if the pattern was a complete match against the address OSCMessage && OSCBundle: route - calls a function with the matched OSCMessage(s) and the number of matched characters in the address as the parameters dispatch - calls a function with each OSCMessage which was fully matched by the pattern /////////////////////////////////////////////////////////////////////////////////////////////////// OSC Regular expression pattern matching rules from http://opensoundcontrol.org/spec-1_0 1. '?' in the OSC Address Pattern matches any single character 2. '*' in the OSC Address Pattern matches any sequence of zero or more characters 3. A string of characters in square brackets (e.g., "[string]") in the OSC Address Pattern matches any character in the string. Inside square brackets, the minus sign (-) and exclamation point (!) have special meanings: two characters separated by a minus sign indicates the range of characters between the given two in ASCII collating sequence. An exclamation point at the beginning of a bracketed string negates the sense of the list, meaning that the list matches any character not in the list. 4. A comma-separated list of strings enclosed in curly braces (e.g., "{foo,bar}") in the OSC Address Pattern matches any of the strings in the list. 5. Any other character in an OSC Address Pattern can match only the same character. /////////////////////////////////////////////////////////////////////////////////////////////////// */ #include void setup() { Serial.begin(38400); } void loop(){ //a heavily patterned message address OSCMessage msg0("/{input,output}/[0-2]/[!ab]/*"); //match will traverse as far as it can in the pattern //it returns the number of characters matched from the pattern int patternOffset = msg0.match("/input/1"); if (patternOffset>0){ //string multiple 'match' methods together using the pattern offset parameter to continue matching where it left off //use 'fullMatch' to test if the entire pattern was matched. if(msg0.fullMatch("/c/anything", patternOffset)){ Serial.println("Match: '/input/1/c/anything' against the pattern '/{input,output}/[0-2]/[abc]/*'"); } } //write over the other message address OSCMessage msg1("/partialMatch"); //match will return 0 if it did not reach the end or a '/' if(!msg1.match("/partial")){ Serial.println("No Match: '/partial' against the pattern '/partialMatch'"); } OSCMessage msg2("/output/[0-2]"); //'route' is uses 'match' to allow for partial matches //it invokes the callback with the matched message and the pattern offset as parameters to the callback msg2.route("/output", routeOutput); //'dispatch' uses 'fullMatch' so it does not allow for partial matches //invokes the callback with only one argument which is the matched message msg2.dispatch("/output/1", routeOutputOne); delay(1000); } //called after matching '/output' //the matched message and the number of matched characters as the parameters void routeOutput(OSCMessage &msg, int patternOffset){ Serial.println("Match: '/output'"); //string multiple 'route' methods together using the pattern offset parameter. msg.route("/0", routeZero, patternOffset); } //called after matching '/0' void routeZero(OSCMessage &msg, int addressOffset){ Serial.println("Match: '/output/0'"); } //called after matching '/output/1' void routeOutputOne(OSCMessage &msg){ Serial.println("Match: '/output/1'"); } // // TROUBLESHOOTING: // Because of a bug in the Arduino IDE, it sometimes thinks that the '*' in combination with '/' is the opening or closing of a multiline comment // This can be fixed by escaping the '/' with '\' or using the octal value of '*' which is '\052' // for example: // "/*" == "/\052" == "\/*" //