Beispiel #1
0
ssize_t lo_validate_arg(lo_type type, void *data, ssize_t size)
{
    if (size < 0) {
        return -1;
    }
    switch (type) {
    case LO_TRUE:
    case LO_FALSE:
    case LO_NIL:
    case LO_INFINITUM:
        return 0;

    case LO_INT32:
    case LO_FLOAT:
    case LO_MIDI:
    case LO_CHAR:
        return size >= 4 ? 4 : -LO_ESIZE;

    case LO_INT64:
    case LO_TIMETAG:
    case LO_DOUBLE:
        return size >= 8 ? 8 : -LO_ESIZE;

    case LO_STRING:
    case LO_SYMBOL:
        return lo_validate_string((char *) data, size);

    case LO_BLOB:
        return lo_validate_blob((lo_blob) data, size);

    default:
        return -LO_EINVALIDTYPE;
    }
    return -LO_INT_ERR;
}
Beispiel #2
0
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;
}
Beispiel #3
0
lo_message lo_message_deserialise(void *data, size_t size, int *result)
{
    lo_message msg = NULL;
    char *types = NULL, *ptr = NULL;
    int i = 0, argc = 0, remain = size, res = 0, len;

    if (remain <= 0) {
        res = LO_ESIZE;
        goto fail;
    }

    msg = malloc(sizeof(struct _lo_message));
    if (!msg) {
        res = LO_EALLOC;
        goto fail;
    }

    msg->types = NULL;
    msg->typelen = 0;
    msg->typesize = 0;
    msg->data = NULL;
    msg->datalen = 0;
    msg->datasize = 0;
    msg->source = NULL;
    msg->argv = NULL;
    msg->ts = LO_TT_IMMEDIATE;
    msg->refcount = 0;

    // path
    len = lo_validate_string(data, remain);
    if (len < 0) {
        res = LO_EINVALIDPATH;  // invalid path string
        goto fail;
    }
    remain -= len;

    // types
    if (remain <= 0) {
        res = LO_ENOTYPE;       // no type tag string
        goto fail;
    }
    types = (char *) data + len;
    len = lo_validate_string(types, remain);
    if (len < 0) {
        res = LO_EINVALIDTYPE;  // invalid type tag string
        goto fail;
    }
    if (types[0] != ',') {
        res = LO_EBADTYPE;      // type tag string missing initial comma
        goto fail;
    }
    remain -= len;

    msg->typelen = strlen(types);
    msg->typesize = len;
    msg->types = malloc(msg->typesize);
    if (NULL == msg->types) {
        res = LO_EALLOC;
        goto fail;
    }
    memcpy(msg->types, types, msg->typesize);

    // args
    msg->data = malloc(remain);
    if (NULL == msg->data) {
        res = LO_EALLOC;
        goto fail;
    }
    memcpy(msg->data, types + len, remain);
    msg->datalen = msg->datasize = remain;
    ptr = msg->data;

    ++types;
    argc = msg->typelen - 1;
    if (argc) {
        msg->argv = calloc(argc, sizeof(lo_arg *));
        if (NULL == msg->argv) {
            res = LO_EALLOC;
            goto fail;
        }
    }

    for (i = 0; remain >= 0 && i < argc; ++i) {
        len = lo_validate_arg((lo_type) types[i], ptr, remain);
        if (len < 0) {
            res = LO_EINVALIDARG;       // invalid argument
            goto fail;
        }
        lo_arg_host_endian((lo_type) types[i], ptr);
        msg->argv[i] = len ? (lo_arg *) ptr : NULL;
        remain -= len;
        ptr += len;
    }
    if (0 != remain || i != argc) {
        res = LO_ESIZE;         // size/argument mismatch
        goto fail;
    }

    if (result) {
        *result = res;
    }
    return msg;

  fail:
    if (msg) {
        lo_message_free(msg);
    }
    if (result) {
        *result = res;
    }
    return NULL;
}
Beispiel #4
0
char *lo_get_path(void *data, ssize_t size)
{
    ssize_t result = lo_validate_string(data, size);
    return (result >= 4) ? (char *) data : NULL;
}
Beispiel #5
0
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;
}