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; }
OSCMethod OSCNewMethod(Name name, OSCcontainer me, methodCallback callback, void *context, struct OSCMethodQueryResponseInfoStruct *QueryResponseInfo) { char addr[LONG_ADDR_SIZE]; OSCMethod m; #ifdef DEBUG printf("OSCNewMethod(name %s, container %p, callback %p, context %p)\n", name, me, callback, context); #endif if (strchr(name, '/') != NULL) { OSCProblem("Method name \"%s\" contains a slash --- not good.", name); return 0; } if (me->numMethods >= MAX_METHODS_PER_CONTAINER) { addr[0] = '\0'; OSCGetAddressString(addr, LONG_ADDR_SIZE, me); OSCProblem("OSCNewMethod: container %s already has %d methods; can't add another\n" "Change MAX_METHODS_PER_CONTAINER in OSC-address-space.c and recompile.", addr, me->numMethods); return 0; } m = AllocMethod(); if (!m) return 0; m->callback = callback; m->context = context; m->QueryResponseInfo = *QueryResponseInfo; me->methodNames[me->numMethods] = name; me->methods[me->numMethods] = m; ++(me->numMethods); return m; }
static void PrintHelp(OSCcontainer c) { char addr[BIG_ADDRESS]; char aliasNames[1000]; int i, j, numAliases; if (OSCGetAddressString(addr, BIG_ADDRESS, c) == FALSE) { printf(" /.../%s", ContainerName(c)); } else { printf(" %s", addr); } numAliases = ContainerAliases(c, aliasNames); if (numAliases > 0) { printf(" (%d aliases:%s)", numAliases, aliasNames); } printf("\n"); for (i = 0; i < c->numMethods; ++i) { printf(" %s%s: %s\n", addr, c->methodNames[i], c->methods[i]->QueryResponseInfo.description); } /* Forgive this quadratic kludge: */ for (i = 0; i < c->numChildren; ++i) { for (j = 0; j < i; ++j) { if (c->children[j] == c->children[i]) { /* c->children[i] is just an alias to c->children[j], which we already printed, so ignore it. */ goto SkipAlias; } } PrintHelp(c->children[i]); SkipAlias: } }
void SetUpAddrSpace(void) { OSCcontainer foo, goo, hunkydory; char addr[100]; struct OSCContainerQueryResponseInfoStruct cqinfo; struct OSCMethodQueryResponseInfoStruct QueryResponseInfo; printf("Getting address of top-level container\n"); if (OSCGetAddressString(addr, 100, OSCTopLevelContainer) == FALSE) { printf("OSCGetAddressString returned FALSE!\n"); } printf("It's \"%s\"\n", addr); printf("Printing whole address space before we put anything in it\n"); OSCPrintWholeAddressSpace(); OSCInitContainerQueryResponseInfo(&cqinfo); cqinfo.comment = "Foo!"; if ((foo = OSCNewContainer("foo", OSCTopLevelContainer, &cqinfo)) == 0) { printf("OSCNewContainer returned FALSE!\n"); return; } printf("Printing whole address space after we register /foo/\n"); OSCPrintWholeAddressSpace(); printf("Trying to get address of /foo/ in a 4 char array\n"); if (OSCGetAddressString(addr, 4, foo) == FALSE) { printf("Good---OSCGetAddressString returned FALSE\n"); } else { printf("OSCGetAddressString returned TRUE!!!\n"); } printf("Trying to get address of /foo/ in a 5 char array\n"); if (OSCGetAddressString(addr, 5, foo) == FALSE) { printf("Good---OSCGetAddressString returned FALSE\n"); } else { printf("OSCGetAddressString returned TRUE!!!\n"); } printf("Trying to get address of /foo/ in a 6 char array\n"); if (OSCGetAddressString(addr, 6, foo) == FALSE) { printf("OSCGetAddressString returned FALSE!!!\n"); } else { printf("Good---OSCGetAddressString returned TRUE. Addr is %s\n", addr); } printf("Trying to get address of /foo/ in a 100 char array\n"); if (OSCGetAddressString(addr, 100, foo) == FALSE) { printf("OSCGetAddressString returned FALSE!\n"); } printf("It's \"%s\"\n", addr); OSCInitContainerQueryResponseInfo(&cqinfo); cqinfo.comment = "Everything's just Hunky-Dory!"; if ((hunkydory = OSCNewContainer("hunkydory", foo, &cqinfo)) == 0) { printf("OSCNewContainer returned 0!\n"); return; } printf("Trying to get address of /foo/hunkydory/ in a 100 char array\n"); if (OSCGetAddressString(addr, 100, hunkydory) == FALSE) { printf("OSCGetAddressString returned FALSE!\n"); } printf("It's \"%s\"\n", addr); OSCInitContainerQueryResponseInfo(&cqinfo); cqinfo.comment = "Goo is goopy."; if ((goo = OSCNewContainer("goo", OSCTopLevelContainer, &cqinfo)) == 0) { printf("OSCNewContainer returned 0!\n"); return; } OSCInitMethodQueryResponseInfo(&QueryResponseInfo); QueryResponseInfo.description = "Get drunk in a bar"; if (OSCNewMethod("bar", foo, BarCallback, (void *) 100, &QueryResponseInfo) == 0) { printf("OSCNewMethod returned 0!\n"); return; } QueryResponseInfo.description = "Latvia is very far"; if (OSCNewMethod("far", goo, FarCallback, (void *) 7, &QueryResponseInfo) == 0) { printf("OSCAddMethod returned 0!\n"); return; } printf("Printing whole address space after we register everything\n"); OSCPrintWholeAddressSpace(); printf("Now register some aliases\n"); if (OSCAddContainerAlias(goo, "slime") == FALSE) { printf("OSCAddContainerAlias returned FALSE!\n"); } if (OSCAddContainerAlias(goo, "schmutz") == FALSE) { printf("OSCAddContainerAlias returned FALSE!\n"); } if (OSCAddContainerAlias(goo, "spooge") == FALSE) { printf("OSCAddContainerAlias returned FALSE!\n"); } if (OSCAddContainerAlias(goo, "glurpies") == FALSE) { printf("OSCAddContainerAlias returned FALSE!\n"); } printf("Printing whole address space after registering aliases\n"); OSCPrintWholeAddressSpace(); printf("Finished registering the address space!\n\n\n"); }