コード例 #1
0
ファイル: message.c プロジェクト: foogywoo/drone
void lo_arg_host_endian(lo_type type, void *data)
{
    switch (type) {
    case LO_INT32:
    case LO_FLOAT:
    case LO_BLOB:
    case LO_CHAR:
	*(int32_t *)data = lo_otoh32(*(int32_t *)data);
	break;

    case LO_INT64:
    case LO_TIMETAG:
    case LO_DOUBLE:
	*(int64_t *)data = lo_otoh64(*(int64_t *)data);
	break;

    case LO_STRING:
    case LO_SYMBOL:
    case LO_MIDI:
    case LO_TRUE:
    case LO_FALSE:
    case LO_NIL:
    case LO_INFINITUM:
	/* these are fine */
	break;

    default:
	fprintf(stderr, "liblo warning: unhandled OSC type '%c' at %s:%d\n",
		type, __FILE__, __LINE__);
	break;
    }
}
コード例 #2
0
ファイル: message.c プロジェクト: tnayuki/OSC2OpenDMXUSB
ssize_t lo_validate_blob(void *data, ssize_t size)
{
    ssize_t i, end, len;
    uint32_t dsize;
    char *pos = (char *) data;

    if (size < 0) {
        return -LO_ESIZE;       // invalid size
    }
    dsize = lo_otoh32(*(uint32_t *) data);
    if (dsize > LO_MAX_MSG_SIZE) {      // avoid int overflow in next step
        return -LO_ESIZE;
    }
    end = sizeof(uint32_t) + dsize;     // end of data
    len = 4 * ((end + 3) / 4);  // full padded size
    if (len > size) {
        return -LO_ESIZE;       // would overflow buffer
    }
    for (i = end; i < len; ++i) {
        if (pos[i] != '\0') {
            return -LO_EPAD;    // non-zero char found in pad area
        }
    }
    return len;
}
コード例 #3
0
ファイル: message.c プロジェクト: tnayuki/OSC2OpenDMXUSB
ssize_t lo_validate_bundle(void *data, ssize_t size)
{
    ssize_t len = 0, remain = size;
    char *pos = data;
    ssize_t elem_len;

    len = lo_validate_string(data, size);
    if (len < 0) {
        return -LO_ESIZE;       // invalid size
    }
    if (0 != strcmp(data, "#bundle")) {
        return -LO_EINVALIDBUND;        // not a bundle
    }
    pos += len;
    remain -= len;

    // time tag
    if (remain < 8) {
        return -LO_ESIZE;
    }
    pos += 8;
    remain -= 8;

    while (remain >= 4) {
        elem_len = lo_otoh32(*((uint32_t *) pos));
        pos += 4;
        remain -= 4;
        if (elem_len > remain) {
            return -LO_ESIZE;
        }
        pos += elem_len;
        remain -= elem_len;
    }
    if (0 != remain) {
        return -LO_ESIZE;
    }
    return size;
}
コード例 #4
0
ファイル: message.c プロジェクト: foogywoo/drone
void lo_arg_pp_internal(lo_type type, void *data, int bigendian)
{
    lo_pcast32 val32;
    lo_pcast64 val64;
    int size;
    int i;

    size = lo_arg_size(type, data);
    if (size == 4 || type == LO_BLOB) {
	if (bigendian) {
	    val32.nl = lo_otoh32(*(int32_t *)data);
	} else {
	    val32.nl = *(int32_t *)data;
	}
    } else if (size == 8) {
	if (bigendian) {
	    val64.nl = lo_otoh64(*(int64_t *)data);
	} else {
	    val64.nl = *(int64_t *)data;
	}
    }

    switch (type) {
    case LO_INT32:
	printf("%d", val32.i);
	break;
    
    case LO_FLOAT:
	printf("%f", val32.f);
	break;

    case LO_STRING:
	printf("\"%s\"", (char *)data);
	break;

    case LO_BLOB:
	printf("[");
	if (val32.i > 12) {
	    printf("%d byte blob", val32.i);
	} else {
	    printf("%db ", val32.i);
	    for (i=0; i<val32.i; i++) {
		printf("0x%02x", *((char *)(data) + 4 + i));
		if (i+1 < val32.i) printf(" ");
	    }
	}
	printf("]");
	break;

    case LO_INT64:
	printf("%lld", val64.i);
	break;
    
    case LO_TIMETAG:
	printf("%08x.%08x", val64.tt.sec, val64.tt.frac);
	break;
    
    case LO_DOUBLE:
	printf("%f", val64.f);
	break;
    
    case LO_SYMBOL:
	printf("'%s", (char *)data);
	break;

    case LO_CHAR:
	printf("'%c'", (char)val32.c);
	break;

    case LO_MIDI:
	printf("MIDI [");
	for (i=0; i<4; i++) {
	    printf("0x%02x", *((uint8_t *)(data) + i));
	    if (i+1 < 4) printf(" ");
	}
	printf("]");
	break;

    case LO_TRUE:
	printf("#T");
	break;

    case LO_FALSE:
	printf("#F");
	break;

    case LO_NIL:
	printf("Nil");
	break;

    case LO_INFINITUM:
	printf("Infinitum");
	break;

    default:
	fprintf(stderr, "liblo warning: unhandled type: %c\n", type);
	break;
    }
}
コード例 #5
0
ファイル: server.c プロジェクト: foogywoo/drone
int lo_server_recv(lo_server s)
{
    void *data;
    size_t size;
    char *path;
    char *types;
    double sched_time = lo_server_next_event_delay(s);
#ifdef WIN32
    fd_set ps;
    struct timeval stimeout;
    int res;
#else
    struct pollfd ps;
#endif

again:
    if (sched_time > 0.01) {
	if (sched_time > 10.0) {
	    sched_time = 10.0;
	}

#ifdef WIN32
    if(!initWSock()) return 0;

    ps.fd_count = 1;
    ps.fd_array[0] = s->socket;

    stimeout.tv_sec = sched_time;
    stimeout.tv_usec = (sched_time-stimeout.tv_sec)*1.e6;
	res = select(1,&ps,NULL,NULL,&stimeout);
	if(res == SOCKET_ERROR) {
	    return 0;
	}

	if(!res) {
	    sched_time = lo_server_next_event_delay(s);

	    if (sched_time > 0.01) {
		goto again;
	    }

	    return dispatch_queued(s);
	}
#else
	ps.fd = s->socket;
	ps.events = POLLIN | POLLPRI | POLLERR | POLLHUP;
	ps.revents = 0;
	poll(&ps, 1, (int)(sched_time * 1000.0));

	if (ps.revents == POLLERR || ps.revents == POLLHUP) {
	    return 0;
	}

	if (!ps.revents) {
	    sched_time = lo_server_next_event_delay(s);

	    if (sched_time > 0.01) {
		goto again;
	    }

	    return dispatch_queued(s);
	}
#endif
    } else {
	return dispatch_queued(s);
    }
    if (s->protocol == LO_TCP) {
	data = lo_server_recv_raw_stream(s, &size);
    } else {
	data = lo_server_recv_raw(s, &size);
    }

    if (!data) {
	return 0;
    }
    path = data;

    types = data + lo_strsize(path);
    if (!strcmp(path, "#bundle")) {
	char *pos = types;
	uint32_t len;
	lo_timetag ts, now;

	lo_timetag_now(&now);

	ts.sec = lo_otoh32(*((uint32_t *)pos));
	pos += 4;
	ts.frac = lo_otoh32(*((uint32_t *)pos));
	pos += 4;

	while (pos - (char *)data < size) {
	    len = lo_otoh32(*((uint32_t *)pos));
	    pos += 4;
	    /* test for immedaite dispatch */
	    if ((ts.sec == 0 && ts.frac == 1) ||
				lo_timetag_diff(ts, now) <= 0.0) {
		types = pos + lo_strsize(pos);
		dispatch_method(s, pos, types + 1, types + lo_strsize(types));
	    } else {
		queue_data(s, ts, pos, len);
	    }
	    pos += len;
	}

	free(data);

	return size;
    } else if (*types != ',') {
	lo_throw(s, LO_ENOTYPE, "Missing typetag", path);

	return -1;
    }

    dispatch_method(s, path, types+1, data);

    free(data);

    return size;
}
コード例 #6
0
ファイル: server.c プロジェクト: aknuds1/chuck
int lo_server_dispatch_data(lo_server s, void *data, size_t size)
{
    int result = 0;
    char *path = data;
    ssize_t len = lo_validate_string(data, size);
    if (len < 0) {
        lo_throw(s, -len, "Invalid message path", NULL);
        return len;
    }

    if (!strcmp(data, "#bundle")) {
        char *pos;
        int remain;
        uint32_t elem_len;
        lo_timetag ts, now;

        ssize_t bundle_result = lo_validate_bundle(data, size);
        if (bundle_result < 0) {
            lo_throw(s, -bundle_result, "Invalid bundle", NULL);
            return bundle_result;
        }
        pos = (char *)data + len;
        remain = size - len;

        lo_timetag_now(&now);
        ts.sec = lo_otoh32(*((uint32_t *)pos));
        pos += 4;
        ts.frac = lo_otoh32(*((uint32_t *)pos));
        pos += 4;
        remain -= 8;

        while (remain >= 4) {
            lo_message msg;
            elem_len = lo_otoh32(*((uint32_t *)pos));
            pos += 4;
            remain -= 4;
            msg = lo_message_deserialise(pos, elem_len, &result);
            if (!msg) {
                lo_throw(s, result, "Invalid bundle element received", path);
                return -result;
            }

	    // set timetag from bundle
	    msg->ts = ts;

            // test for immediate dispatch
            if ((ts.sec == LO_TT_IMMEDIATE.sec
                 && ts.frac == LO_TT_IMMEDIATE.frac) ||
                                lo_timetag_diff(ts, now) <= 0.0) {
                dispatch_method(s, pos, msg);
                lo_message_free(msg);
            } else {
                queue_data(s, ts, pos, msg);
            }
            pos += elem_len;
            remain -= elem_len;
        }
    } else {
        lo_message msg = lo_message_deserialise(data, size, &result);
        if (NULL == msg) {
            lo_throw(s, result, "Invalid message received", path);
            return -result;
        }
        dispatch_method(s, data, msg);
        lo_message_free(msg);
    }
    return size;
}