(uncpomplete) port of the cnmat osc library for Arduino/Teensy. Upstream url: https://github.com/CNMAT/OSC
(uncpomplete) port of the cnmat osc library for Arduino/Teensy. Upstream url: https://github.com/CNMAT/OSC
Compiles, but not Tested in any kind. OSCMessage::send(); and OSCBundle::send() don't work/are commented out due to Platform specifics I first have to figure out.
Diff: OSCMatch.c
- Revision:
- 1:18009e3041ea
diff -r 36705c54059a -r 18009e3041ea OSCMatch.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OSCMatch.c Fri May 16 22:10:49 2014 +0000 @@ -0,0 +1,307 @@ +#define OSC_MATCH_ENABLE_2STARS 1 +#define OSC_MATCH_ENABLE_NSTARS 1 +/* + Written by John MacCallum, The Center for New Music and Audio Technologies, + University of California, Berkeley. Copyright (c) 2009, The Regents of + the University of California (Regents). + Permission to use, copy, modify, distribute, and distribute modified versions + of this software and its documentation without fee and without a signed + licensing agreement, is hereby granted, provided that the above copyright + notice, this paragraph and the following two paragraphs appear in all copies, + modifications, and distributions. + + IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, + SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING + OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS + BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED + HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE + MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ +#include <string.h> +#include "OSCMatch.h" + +static int osc_match_star(const char *pattern, const char *address); +static int osc_match_star_r(const char *pattern, const char *address); +static int osc_match_single_char(const char *pattern, const char *address); +static int osc_match_bracket(const char *pattern, const char *address); +static int osc_match_curly_brace(const char *pattern, const char *address); + +int osc_match(const char *pattern, const char *address, int *pattern_offset, int *address_offset) +{ + if(!strcmp(pattern, address)){ + *pattern_offset = strlen(pattern); + *address_offset = strlen(address); + return OSC_MATCH_ADDRESS_COMPLETE | OSC_MATCH_PATTERN_COMPLETE; + } + + const char *pattern_start; + const char *address_start; + + pattern_start = pattern; + address_start = address; + + *pattern_offset = 0; + *address_offset = 0; + + while(*address != '\0' && *pattern != '\0'){ + if(*pattern == '*'){ + if(!osc_match_star(pattern, address)){ + return 0; + } + while(*pattern != '/' && *pattern != '\0'){ + pattern++; + } + while(*address != '/' && *address != '\0'){ + address++; + } + }else if(*address == '*'){ + while(*pattern != '/' && *pattern != '\0'){ + pattern++; + } + while(*address != '/' && *address != '\0'){ + address++; + } + }else{ + int n = 0; + if(!(n = osc_match_single_char(pattern, address))){ + return 0; + } + if(*pattern == '['){ + while(*pattern != ']'){ + pattern++; + } + pattern++; + address++; + }else if(*pattern == '{'){ + while(*pattern != '}'){ + pattern++; + } + pattern++; + address += n; + }else{ + pattern++; + address++; + } + } + } + + *pattern_offset = pattern - pattern_start; + *address_offset = address - address_start; + + int r = 0; + + if(*address == '\0') { + r |= OSC_MATCH_ADDRESS_COMPLETE; + } + + if(*pattern == '\0') { + r |= OSC_MATCH_PATTERN_COMPLETE; + } + + return r; +} + +static int osc_match_star(const char *pattern, const char *address) +{ + const char *address_start = address; + const char *pattern_start = pattern; + int num_stars = 0; + if(*address == '\0') { return 0; } + while(*address != '/' && *address != '\0'){ + address++; + } + while(*pattern != '/' && *pattern != '\0'){ + if(*pattern == '*'){ + num_stars++; + } + pattern++; + } + pattern--; + address--; + switch(num_stars){ + case 1: + { + const char *pp = pattern, *aa = address; + while(*pp != '*'){ + if(!(osc_match_single_char(pp, aa))){ + return 0; + } + if(*pp == ']' || *pp == '}'){ + while(*pp != '[' && *pp != '{'){ + pp--; + } + } + pp--; + aa--; + } + } + break; + case 2: +#if (OSC_MATCH_ENABLE_2STARS == 1) + { + const char *pp = pattern, *aa = address; + while(*pp != '*'){ + if(!(osc_match_single_char(pp, aa))){ + return 0; + } + if(*pp == ']' || *pp == '}'){ + while(*pp != '[' && *pp != '{'){ + pp--; + } + } + pp--; + aa--; + } + aa++; // we want to start one character forward to allow the star to match nothing + const char *star2 = pp; + const char *test = aa; + int i = 0; + while(test > address_start){ + pp = star2 - 1; + aa = test - 1; + i++; + while(*pp != '*'){ + if(!osc_match_single_char(pp, aa)){ + break; + } + if(*pp == ']' || *pp == '}'){ + while(*pp != '[' && *pp != '{'){ + pp--; + } + } + pp--; + aa--; + } + if(pp == pattern_start){ + return 1; + } + test--; + } + return 0; + } + break; +#else + return 0; +#endif + default: +#if (OSC_MATCH_ENABLE_NSTARS == 1) + return osc_match_star_r(pattern_start, address_start); + break; +#else + return 0; +#endif + } + return 1; +} + +#if (OSC_MATCH_ENABLE_NSTARS == 1) +static int osc_match_star_r(const char *pattern, const char *address) +{ + if(*address == '/' || *address == '\0'){ + if(*pattern == '/' || *pattern == '\0' || (*pattern == '*' && ((*(pattern + 1) == '/') || *(pattern + 1) == '\0'))){ + return 1; + }else{ + return 0; + } + } + if(*pattern == '*'){ + if(osc_match_star_r(pattern + 1, address)){ + return 1; + }else{ + return osc_match_star_r(pattern, address + 1); + } + }else{ + if(!osc_match_single_char(pattern, address)){ + return 0; + } + if(*pattern == '[' || *pattern == '{'){ + while(*pattern != ']' && *pattern != '}'){ + pattern++; + } + } + return osc_match_star_r(pattern + 1, address + 1); + } +} +#endif + +static int osc_match_single_char(const char *pattern, const char *address) +{ + switch(*pattern){ + case '[': + return osc_match_bracket(pattern, address); + case ']': + while(*pattern != '['){ + pattern--; + } + return osc_match_bracket(pattern, address); + case '{': + return osc_match_curly_brace(pattern, address); + case '}': + while(*pattern != '{'){ + pattern--; + } + return osc_match_curly_brace(pattern, address); + case '?': + return 1; + default: + if(*pattern == *address){ + return 1; + }else{ + return 0; + } + } + return 0; +} + +static int osc_match_bracket(const char *pattern, const char *address) +{ + pattern++; + int val = 1; + if(*pattern == '!'){ + pattern++; + val = 0; + } + int matched = !val; + while(*pattern != ']' && *pattern != '\0'){ + // the character we're on now is the beginning of a range + if(*(pattern + 1) == '-'){ + if(*address >= *pattern && *address <= *(pattern + 2)){ + matched = val; + break; + }else{ + pattern += 3; + } + }else{ + // just test the character + if(*pattern == *address){ + matched = val; + break; + } + pattern++; + } + } + return matched; +} + +static int osc_match_curly_brace(const char *pattern, const char *address) +{ + pattern++; + const char *ptr = pattern; + while(*ptr != '}' && *ptr != '\0' && *ptr != '/'){ + while(*ptr != '}' && *ptr != '\0' && *ptr != '/' && *ptr != ','){ + ptr++; + } + int n = ptr - pattern; + if(!strncmp(pattern, address, n)){ + return n; + }else{ + ptr++; + pattern = ptr; + } + } + return 0; +} \ No newline at end of file