Ejemplo n.º 1
0
void OSCAcceptPacket(OSCPacketBuffer packet) {
    if ((packet->n % 4) != 0) {
	OSCProblem("OSC packet size (%d bytes) not a multiple of 4.", packet->n);
	DropPacket(packet);
	return;
    }

#ifdef DEBUG
    printf("OSCAcceptPacket(OSCPacketBuffer %p, buf %p, size %d)\n", 
	   packet, packet->buf, packet->n);
#endif

    /* If the packet came from the user, it's return address is OK. */
    packet->returnAddrOK = TRUE;

    InsertBundleOrMessage(packet->buf, packet->n, packet, OSCTT_Immediately());

#ifdef PARANOID
    if (packet->refcount == 0) {
	if (freePackets != packet) {
	    fatal_error("OSCAcceptPacket: packet refcount 0, but it's not the head of the free list!");
	}
    }
#endif

    OSCInvokeAllMessagesThatAreReady(globals.lastTimeTag);
}
Ejemplo n.º 2
0
static void ParseBundle(queuedData *qd) {
    /* A queued bundle has been removed from the scheduler queue, and now it's
       time to parse all the stuff inside it and schedule the enclosed
       messages and bundles.  Once all the contents of the bundle have been
       parsed and scheduled, we trash the bundle, decrementing the packet
       count and freeing the QD. */

    int size;
    int i = 0;

    if (qd->type != BUNDLE) {
        fatal_error("This can't happen: bundle isn't a bundle!");
    }

    while (i < qd->data.bundle.length) {
	size = *((int *) (qd->data.bundle.bytes + i));
	if ((size % 4) != 0) {
	    OSCProblem("Bad size count %d in bundle (not a multiple of 4).", size);
	    DropBundle(qd->data.bundle.bytes, qd->data.bundle.length, qd->myPacket);
	    goto bag;
	}
	if ((size + i + 4) > qd->data.bundle.length) {
	    OSCProblem("Bad size count %d in bundle (only %d bytes left in entire bundle).",
		     size, qd->data.bundle.length-i-4);
	    DropBundle(qd->data.bundle.bytes, qd->data.bundle.length, qd->myPacket);
	    goto bag;	
	}
	
	/* Recursively handle element of bundle */
	InsertBundleOrMessage(qd->data.bundle.bytes+i+4, size, qd->myPacket, qd->timetag);
	i += 4 + size;
    }

    if (i != qd->data.bundle.length) {
	fatal_error("This can't happen: internal logic error parsing bundle");
    }

bag:
    /* If we got here successfully, we've added to the packet's reference count for
       each message or subbundle by calling InsertBundleOrMessage(), so we remove the one
       reference for bundle that we just parsed.  If we got here by "goto bag", there's a
       problem with the bundle so we also want to lose the reference count. */

    PacketRemoveRef(qd->myPacket);
    FreeQD(qd);
}
Ejemplo n.º 3
0
callbackList OSCDispatchMessage(char *pattern) {
    callbackListEnds result;

    if (pattern[0] != '/') {
        OSCProblem("Invalid address \"%s\" does not begin with /", pattern);
        return 0;
    }

    result = DispatchSubMessage(pattern+1, OSCTopLevelContainer);

    return result.begin;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
Boolean OSCGetAddressString(char *target, int maxLength, OSCcontainer c) {
    int lenNeeded;

    if (maxLength <= 1) return FALSE;

    lenNeeded = gasHelp(target, maxLength-1, c) + 1; /* -1, +1 are for null char. */
    if (lenNeeded > maxLength) {
	OSCProblem("Address string too long (room for %d chars; need %d)",
		   maxLength, lenNeeded);
	target[0] = '\0';
	return FALSE;
    }
    return TRUE;
}
Ejemplo n.º 6
0
static Boolean ParseMessage(queuedData *qd) {
    /* Fill in all the information we'll need to execute the message as
       quickly as possible when the time comes.  This means figuring out where
       the address ends and the arguments begin, and also pattern matching the
       address to find the callbacks associated with it.

       The message may be something we have to invoke now, or it may be some
       message scheduled for the future that's just waiting on the queue; this
       procedure doesn't care.  */


    char *args; 	/* char * so we can do pointer subtraction */
    int messageLen;
    char *DAAS_errormsg;


    if (qd->type != MESSAGE) {
        fatal_error("This can't happen: message isn't a message!");
    }

    args = OSCDataAfterAlignedString(qd->data.message.messageName, 
				     qd->data.message.messageName+qd->data.message.length,
				     &DAAS_errormsg);

    if (args == 0) {
	OSCProblem("Bad message name string: %s\n", DAAS_errormsg);
	DropMessage(qd->data.message.messageName, qd->data.message.length, qd->myPacket);
	return FALSE;
    }

    qd->data.message.args = args;
    messageLen = args - qd->data.message.messageName;
    qd->data.message.argLength = qd->data.message.length - messageLen;

    qd->data.message.callbacks = OSCDispatchMessage(qd->data.message.messageName);

    if (qd->data.message.callbacks == 0) {
	OSCWarning("Message pattern \"%s\" did not correspond to any address in the synth.",
		   qd->data.message.messageName);
	return FALSE;
    }

    return TRUE;
}
Ejemplo n.º 7
0
OSCcontainer OSCNewContainer(Name name, OSCcontainer parent,
                             struct OSCContainerQueryResponseInfoStruct *QueryResponseInfo) {
    OSCcontainer me;

    me = AllocContainer();
    if (me == 0) return 0;

    if (strchr(name, '/') != NULL) {
	OSCProblem("Container name \"%s\" contains a slash --- not good.",
		   name);
	return 0;
    }
	
    me->parent = parent;
    AddSubContainer(me->parent, me, name);
    me->numChildren = 0;
    me->numMethods = 0;
    me->QueryResponseInfo = (*QueryResponseInfo);
    return me;
}
Ejemplo n.º 8
0
static void InsertBundleOrMessage(char *buf, int n, OSCPacketBuffer packet, OSCTimeTag enclosingTimeTag) {
    Boolean IsBundle;
    queuedData *qd;

    /* We add the reference first thing so in case any of the upcoming
       potential failure situations come we can call PacketRemoveRef, thereby
       freeing the packet if necessary. */
    PacketAddRef(packet);

#ifdef PARANOID
    if ((n % 4) != 0) {
	OSCProblem("OSC message or bundle size (%d bytes) not a multiple of 4.", n);
	DropMessage(buf, n, packet)
	PacketRemoveRef(packet);
	return;
    }
#endif

    if ((n >= 8) && (strncmp(buf, "#bundle", 8) == 0)) {
	IsBundle = TRUE;

	if (n < 16) {
	    OSCProblem("Bundle message too small (%d bytes) for time tag.", n);
	    DropBundle(buf, n, packet);
	    PacketRemoveRef(packet);
	    return;
	}
    } else {
	IsBundle = FALSE;
    }


    qd = AllocQD();

    if (qd == 0) {
	OSCProblem("Not enough memory for queued data!");
	DropBundle(buf, n, packet);
	PacketRemoveRef(packet);
	return;
    }

    qd->myPacket = packet;
    qd->type = IsBundle ? BUNDLE : MESSAGE;

    if (IsBundle) {
	/* Be careful of 8-byte alignment when copying the time tag.  Here's a good
	   way to get a bus error when buf happens not to be 8-byte aligned:
	   qd->timetag = *((OSCTimeTag *)(buf+8));
	*/
	memcpy(&(qd->timetag), buf+8, sizeof(OSCTimeTag));

	if (OSCTT_Compare(qd->timetag, enclosingTimeTag) < 0) {
	    OSCProblem("Time tag of sub-bundle is before time tag of enclosing bundle.");
	    DropBundle(buf, n, packet);
	    PacketRemoveRef(packet);
	    FreeQD(qd);
	    return;
	}
	qd->data.bundle.bytes = buf + 16;
	qd->data.bundle.length = n - 16;
    } else {
        qd->timetag = enclosingTimeTag;
	qd->data.message.messageName = buf;
	qd->data.message.length = n;
	qd->data.message.callbacks = NOT_DISPATCHED_YET;
    }

    OSCQueueInsert(globals.TheQueue, (OSCSchedulableObject) qd);
}