Esempio n. 1
0
static callbackListEnds DispatchSubMessage(char *pattern, OSCcontainer c) {
    callbackListEnds result;
    char *nextSlash, *restOfPattern;
    char offendingAddr[LONG_ADDR_LEN];
    int i;

    result.begin = result.end = 0;
    nextSlash = NextSlashOrNull(pattern);

    if (*nextSlash == '\0') {
	/* Base case: the pattern names methods of this container. */
	for (i = 0; i < c->numMethods; i++) {
	    if (PatternMatch(pattern, c->methodNames[i])) {
		callbackList node = AllocCallbackListNode(c->methods[i]->callback,
							  c->methods[i]->context,
							  result.begin);
		if (node == 0) {
		    /* Excuse the hairyness of the code to generate the error message. */
		    if (OSCGetAddressString(offendingAddr, 
					    LONG_ADDR_LEN-strlen(c->methodNames[i]),
					    c)) {
			strcat(offendingAddr, c->methodNames[i]);
		    } else {
			strcpy(offendingAddr, c->methodNames[i]);
		    }
			
		    OSCWarning("No memory for callback node; not invoking %s",
			       offendingAddr);
		} else {
		    if (result.end == 0) {
			result.end = node;
		    }
		    result.begin = node;
		}
	    }
	}
    } else {
	/* Recursive case: in the middle of an address, so the job at this 
	   step is to look for containers that match.  We temporarily turn
           the next slash into a null so pattern will be a null-terminated
	   string of the stuff between the slashes. */
	*nextSlash = '\0';
	restOfPattern = nextSlash + 1;

	for (i = 0; i < c->numChildren; ++i) {
	    if (PatternMatch(pattern, c->childrenNames[i])) {
		callbackListEnds subResult =	
		    DispatchSubMessage(restOfPattern, c->children[i]);
		if (result.end == 0) {
		    result = subResult;
		} else {
		    subResult.end->next = result.begin;
		    result.begin = subResult.begin;
		}
	    }
	}
	*nextSlash = '/';
    }
    return result;
}
Esempio n. 2
0
static void routeOSC_doanything(t_routeOSC *x, t_symbol *s, int argc, t_atom *argv)
{
    char    *pattern, *nextSlash;
    int     i, pattern_depth = 0, matchedAnything = 0;
    int     noPath = 0; // nonzero if we are dealing with a simple list (as from a previous [routeOSC])

    pattern = s->s_name;
    if (x->x_verbosity) post("routeOSC_doanything(%p): pattern is %s", x, pattern);
    if (pattern[0] != '/')
    { // make a path '/'. Now s is actually the first item in the arguments list
        pattern = gensym("/")->s_name;
        noPath = 1;
        if (x->x_verbosity)
            post("routeOSC_doanything(%p): message pattern \"%s\" does not begin with /, setting path to %s", x, s->s_name, pattern);
    }

    pattern_depth = routeOSC_count_slashes(pattern);
    if (x->x_verbosity) post("routeOSC_doanything(%p): pattern_depth is %i", x, pattern_depth);
    nextSlash = NextSlashOrNull(pattern+1);
    if (*nextSlash == '\0')
    { /* pattern_depth == 1 */
        /* last level of the address, so we'll output the argument list */
    
        for (i = 0; i < x->x_num; ++i)
        {
            if
            (
                (x->x_prefix_depth[i] <= pattern_depth)
                && (MyPatternMatch(pattern+1, x->x_prefixes[i]+1))
            )
            {
                ++matchedAnything;
                if (noPath)
                { // just a list starting with a symbol
                  // The special symbol is s
                  outlet_anything(x->x_outlets[i], s, argc, argv);
                }
                else // normal OSC path
                {
                    // I hate stupid Max lists with a special first element
                    if (argc == 0)
                    {
                        outlet_bang(x->x_outlets[i]);
                    }
                    else if (argv[0].a_type == A_SYMBOL)
                    {
                        // Promote the symbol that was argv[0] to the special symbol
                        outlet_anything(x->x_outlets[i], argv[0].a_w.w_symbol, argc-1, argv+1);
                    }
                    else if (argc > 1)
                    {
                        // Multiple arguments starting with a number, so naturally we have
                        // to use a special function to output this "list", since it's what
                        // Max originally meant by "list".
                        outlet_list(x->x_outlets[i], 0L, argc, argv);
                    }
                    else
                    {
                        // There was only one argument, and it was a number, so we output it
                        // not as a list
                        if (argv[0].a_type == A_FLOAT)
                        {
                            outlet_float(x->x_outlets[i], argv[0].a_w.w_float);
                        }
                        else
                        {
                            pd_error(x, "* routeOSC: unrecognized atom type!");
                        }
                    }
                }
            }
        }
    }
    else
    {
        /* There's more address after this part, so our output list will begin with
           the next slash.  */
        t_symbol *restOfPattern = 0; /* avoid the gensym unless we have to output */
        char patternBegin[1000];

        /* Get the incoming pattern to match against all our prefixes */

        for (i = 0; i < x->x_num; ++i)
        {
            restOfPattern = 0;
            if (x->x_prefix_depth[i] <= pattern_depth)
            {
                StrCopyUntilNthSlash(patternBegin, pattern+1, x->x_prefix_depth[i]);
                if (x->x_verbosity)
                    post("routeOSC_doanything(%p): (%d) patternBegin is %s", x, i, patternBegin);
                if (MyPatternMatch(patternBegin, x->x_prefixes[i]+1))
                {
                    if (x->x_verbosity)
                        post("routeOSC_doanything(%p): (%d) matched %s depth %d", x, i, x->x_prefixes[i], x->x_prefix_depth[i]);
                    ++matchedAnything;
                    nextSlash = NthSlashOrNull(pattern+1, x->x_prefix_depth[i]);
                    if (x->x_verbosity)
                        post("routeOSC_doanything(%p): (%d) nextSlash %s", x, i, nextSlash);
                    if (restOfPattern == 0) restOfPattern = gensym(nextSlash);
                    outlet_anything(x->x_outlets[i], restOfPattern, argc, argv);
                }
            }
        }
    }

    if (!matchedAnything)
    {
        // output unmatched data on rightmost outlet a la normal 'route' object, jdl 20020908
        outlet_anything(x->x_outlets[x->x_num], s, argc, argv);
    }
}
Esempio n. 3
0
void OSCroute_doanything(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv) {
  char *pattern, *nextSlash;
  int i;
  int matchedAnything;
  // post("*** OSCroute_anything(s %s, argc %ld)", s->s_name, (long) argc);
  
  pattern = s->s_name;
  if (pattern[0] != '/') {
    post("* OSC-route: invalid message pattern %s does not begin with /", s->s_name);
    outlet_anything(x->x_outlets[x->x_num], s, argc, argv);
    return;
  }
  
  matchedAnything = 0;
  
  nextSlash = NextSlashOrNull(pattern+1);
  if (*nextSlash == '\0') {
    /* last level of the address, so we'll output the argument list */
    

#ifdef NULL_IS_DIFFERENT_FROM_BANG
    if (argc==0) {
      post("* OSC-route: why are you matching one level pattern %s with no args?",
	   pattern);
      return;
    }
#endif
    
    for (i = 0; i < x->x_num; ++i) {
      if (MyPatternMatch(pattern+1, x->x_prefixes[i]+1)) {
	++matchedAnything;
	
	// I hate stupid Max lists with a special first element
	if (argc == 0) {
	  outlet_bang(x->x_outlets[i]);
	} else if (argv[0].a_type == A_SYMBOL) {
	  // Promote the symbol that was argv[0] to the special symbol
	  outlet_anything(x->x_outlets[i], argv[0].a_w.w_symbol, argc-1, argv+1);
	} else if (argc > 1) {
	  // Multiple arguments starting with a number, so naturally we have
	  // to use a special function to output this "list", since it's what
	  // Max originally meant by "list".
	  outlet_list(x->x_outlets[i], 0L, argc, argv);
	} else {
	  // There was only one argument, and it was a number, so we output it
	  // not as a list
/* 	  if (argv[0].a_type == A_LONG) { */
	    
/* 	    outlet_int(x->x_outlets[i], argv[0].a_w.w_long); */
	  //	  } else 
	  if (argv[0].a_type == A_FLOAT) {
	    
	    outlet_float(x->x_outlets[i], argv[0].a_w.w_float);
	  } else {
	    post("* OSC-route: unrecognized atom type!");
	  }
	}
      }
    }
  } else {
    /* There's more address after this part, so our output list will begin with
       the next slash.  */
    t_symbol *restOfPattern = 0; /* avoid the gensym unless we have to output */
    char patternBegin[1000];
    
    
    /* Get the first level of the incoming pattern to match against all our prefixes */
    StrCopyUntilSlash(patternBegin, pattern+1);
    
    for (i = 0; i < x->x_num; ++i) {
      if (MyPatternMatch(patternBegin, x->x_prefixes[i]+1)) {
	++matchedAnything;
	if (restOfPattern == 0) {
	  restOfPattern = gensym(nextSlash);
	}
	outlet_anything(x->x_outlets[i], restOfPattern, argc, argv);
      }
    }
  }

  if (x->x_complainmode) {
    if (!matchedAnything) {
      post("* OSC-route: pattern %s did not match any prefixes", pattern);
    }
  }

  // output unmatched data on rightmost outlet a la normal 'route' object, jdl 20020908
  if (!matchedAnything) {
    outlet_anything(x->x_outlets[x->x_num], s, argc, argv);
  }


}