1083 lines · 22.8 KB · C
RawDownload
/* *  Copyright (C) 2004 Steve Harris * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as *  published by the Free Software Foundation; either version 2.1 of the *  License, or (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU Lesser General Public License for more details. * *  $Id$ */ #include <stdarg.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <math.h> #ifdef WIN32#include <winsock2.h>#include <ws2tcpip.h>#else#include <netinet/in.h>#endif #include "lo_types_internal.h"#include "lo_internal.h"#include "lo.h" #define LO_DEF_TYPE_SIZE 8#define LO_DEF_DATA_SIZE 8 static char lo_numerical_types[] = {    LO_INT32,    LO_FLOAT,    LO_INT64,    LO_DOUBLE,    '\0'}; static char lo_string_types[] = {    LO_STRING,    LO_SYMBOL,    '\0'}; static int lo_message_add_typechar(lo_message m, char t);static void *lo_message_add_data(lo_message m, size_t s);void lo_arg_pp_internal(lo_type type, void *data, int bigendian); // Used for calculating new sizes when expanding message data buffers.// Note that log(x)/0.69315 = log2(x): this simply finds the next// highest power of 2.#if 1#define lo_pow2_over(a,b) \    a = ((b > a) ? (a << ((int)((log(((double)b/(double)a))/0.69315)+1))) : a);#else#define lo_pow2_over(a,b) \    while (b > a) {a *= 2;}#endif lo_message lo_message_new(){    lo_message m = malloc(sizeof(struct _lo_message));    if (!m) {	return m;    }     m->types = calloc(LO_DEF_TYPE_SIZE, sizeof(char));    m->types[0] = ',';    m->types[1] = '\0';    m->typelen = 1;    m->typesize = LO_DEF_TYPE_SIZE;    m->data = NULL;    m->datalen = 0;    m->datasize = 0;    m->source = NULL;    m->argv = NULL;    m->ts = LO_TT_IMMEDIATE;     return m;} void lo_message_free(lo_message m){    if (m) {	free(m->types);	free(m->data);        free(m->argv);    }    free(m);} /* Don't call lo_message_add_varargs_internal directly, use * lo_message_add_varargs, a macro wrapping this function with * appropriate values for file and line */ int lo_message_add_varargs_internal(lo_message msg, const char *types,                                    va_list ap, const char *file, int line){    int count = 0;    int i;    int64_t i64;    float f;    char *s;    lo_blob b;    uint8_t *m;    lo_timetag tt;    double d;	int ret = 0;     while (types && *types) {	count++;    i=0;    i64=0;    f=0;    s=0;    b=0;    m=0;    d=0;	switch (*types++) { 	case LO_INT32:	    i = va_arg(ap, int32_t);	    lo_message_add_int32(msg, i);	    break; 	case LO_FLOAT:	    f = (float)va_arg(ap, double);	    lo_message_add_float(msg, f);	    break; 	case LO_STRING:	    s = va_arg(ap, char *);#ifdef __GNUC__	    if (s == (char *)LO_MARKER_A) {		fprintf(stderr, "liblo error: lo_send or lo_message_add called with "			"invalid string pointer for arg %d, probably arg mismatch\n"		        "at %s:%d, exiting.\n", count, file, line);	    }#endif	    lo_message_add_string(msg, s);	    break; 	case LO_BLOB:	    b = va_arg(ap, lo_blob);	    lo_message_add_blob(msg, b);	    break; 	case LO_INT64:	    i64 = va_arg(ap, int64_t);	    lo_message_add_int64(msg, i64);	    break; 	case LO_TIMETAG:	    tt = va_arg(ap, lo_timetag);	    lo_message_add_timetag(msg, tt);	    break; 	case LO_DOUBLE:	    d = va_arg(ap, double);	    lo_message_add_double(msg, d);	    break; 	case LO_SYMBOL:	    s = va_arg(ap, char *);#ifdef __GNUC__	    if (s == (char *)LO_MARKER_A) {		fprintf(stderr, "liblo error: lo_send or lo_message_add called with "			"invalid symbol pointer for arg %d, probably arg mismatch\n"		        "at %s:%d, exiting.\n", count, file, line);        va_end(ap);        return -2;	    }#endif	    lo_message_add_symbol(msg, s);	    break; 	case LO_CHAR:	    i = va_arg(ap, int);	    lo_message_add_char(msg, i);	    break; 	case LO_MIDI:	    m = va_arg(ap, uint8_t *);	    lo_message_add_midi(msg, m);	    break; 	case LO_TRUE:	    lo_message_add_true(msg);	    break; 	case LO_FALSE:	    lo_message_add_false(msg);	    break; 	case LO_NIL:	    lo_message_add_nil(msg);	    break; 	case LO_INFINITUM:	    lo_message_add_infinitum(msg);	    break; 	default:		ret = -1; // unknown type	    fprintf(stderr, "liblo warning: unknown type '%c' at %s:%d\n",		    *(types-1), file, line);	    break;	}    }#ifdef __GNUC__    i = va_arg(ap, uint32_t);    if (i != LO_MARKER_A) {	ret = -2; // bad format/args	fprintf(stderr, "liblo error: lo_send, lo_message_add, or lo_message_add_varargs called with "			"mismatching types and data at\n%s:%d, exiting.\n", file, line);    va_end(ap);    return ret;    }    i = va_arg(ap, uint32_t);    if (i != LO_MARKER_B) {	ret = -2; // bad format/args	fprintf(stderr, "liblo error: lo_send, lo_message_add, or lo_message_add_varargs called with "			"mismatching types and data at\n%s:%d, exiting.\n", file, line);    }#endif    va_end(ap); 	return ret;} /* Don't call lo_message_add_internal directly, use lo_message_add, * a macro wrapping this function with appropriate values for file and line */ #ifdef __GNUC__int lo_message_add_internal(lo_message msg, const char *file, const int line,                            const char *types, ...)#elseint lo_message_add(lo_message msg, const char *types, ...)#endif{    va_list ap;    int ret = 0; #ifndef __GNUC__    const char *file = "";    const int line = 0;#endif     va_start(ap, types);    ret = lo_message_add_varargs_internal(msg, types, ap, file, line);    // 1.4.1.0 (ge) added matching va_end    va_end(ap); 	return ret;}	int lo_message_add_int32(lo_message m, int32_t a){    lo_pcast32 b;    int32_t *nptr = lo_message_add_data(m, sizeof(a));    if (!nptr) return -1;    b.i = a;     if (lo_message_add_typechar(m, LO_INT32))        return -1;    *nptr = b.nl;    return 0;}    int lo_message_add_float(lo_message m, float a){    lo_pcast32 b;    int32_t *nptr = lo_message_add_data(m, sizeof(a));    if (!nptr) return -1;    b.f = a;     if (lo_message_add_typechar(m, LO_FLOAT))        return -1;    *nptr = b.nl;    return 0;} int lo_message_add_string(lo_message m, const char *a){    const int size = lo_strsize(a);    char *nptr = lo_message_add_data(m, size);    if (!nptr) return -1;     if (lo_message_add_typechar(m, LO_STRING))        return -1;    strncpy(nptr, a, size);    return 0;} int lo_message_add_blob(lo_message m, lo_blob a){    const uint32_t size = lo_blobsize(a);    const uint32_t dsize = lo_blob_datasize(a);    char *nptr = lo_message_add_data(m, size);    if (!nptr) return -1;     if (lo_message_add_typechar(m, LO_BLOB))        return -1;    memset(nptr + size - 4, 0, 4);     memcpy(nptr, &dsize, sizeof(dsize));    memcpy(nptr + sizeof(int32_t), lo_blob_dataptr(a), lo_blob_datasize(a));    return 0;} int lo_message_add_int64(lo_message m, int64_t a){    lo_pcast64 b;    uint64_t *nptr = lo_message_add_data(m, sizeof(a));    if (!nptr) return -1;    b.i = a;     if (lo_message_add_typechar(m, LO_INT64))        return -1;    *nptr = b.nl;    return 0;} int lo_message_add_timetag(lo_message m, lo_timetag a){    lo_pcast64 b;    uint64_t *nptr = lo_message_add_data(m, sizeof(a));    if (!nptr) return -1;    b.tt = a;     if (lo_message_add_typechar(m, LO_TIMETAG))        return -1;    *nptr = b.nl;    return 0;} int lo_message_add_double(lo_message m, double a){    lo_pcast64 b;    uint64_t *nptr = lo_message_add_data(m, sizeof(a));    if (!nptr) return -1;    b.f = a;     if (lo_message_add_typechar(m, LO_DOUBLE))        return -1;    *nptr = b.nl;    return 0;} int lo_message_add_symbol(lo_message m, const char *a){    const int size = lo_strsize(a);    char *nptr = lo_message_add_data(m, size);    if (!nptr) return -1;     if (lo_message_add_typechar(m, LO_SYMBOL))        return -1;    strncpy(nptr, a, size);    return 0;} int lo_message_add_char(lo_message m, char a){    lo_pcast32 b;    int32_t *nptr = lo_message_add_data(m, sizeof(int32_t));    if (!nptr) return -1;     b.c = a;     if (lo_message_add_typechar(m, LO_CHAR))        return -1;    *nptr = b.nl;    return 0;} int lo_message_add_midi(lo_message m, uint8_t a[4]){    char *nptr = lo_message_add_data(m, 4);    if (!nptr) return -1;     if (lo_message_add_typechar(m, LO_MIDI))        return -1;     memcpy(nptr, a, sizeof(uint8_t)*4); // ge: changed uint8_t*4 to avoid ambiguity    return 0;} int lo_message_add_true(lo_message m){    return lo_message_add_typechar(m, LO_TRUE);} int lo_message_add_false(lo_message m){    return lo_message_add_typechar(m, LO_FALSE);} int lo_message_add_nil(lo_message m){    return lo_message_add_typechar(m, LO_NIL);} int lo_message_add_infinitum(lo_message m){    return lo_message_add_typechar(m, LO_INFINITUM);} static int lo_message_add_typechar(lo_message m, char t){    if (m->typelen + 1 >= m->typesize) {        int new_typesize = m->typesize * 2;        char *new_types = 0;        if (!new_typesize)            new_typesize = LO_DEF_TYPE_SIZE;        new_types = realloc(m->types, new_typesize);        if (!new_types) return -1;        m->types = new_types;        m->typesize = new_typesize;    }    m->types[m->typelen] = t;    m->typelen++;    m->types[m->typelen] = '\0';    if (m->argv) {        free(m->argv);        m->argv = NULL;    }    return 0;} static void *lo_message_add_data(lo_message m, size_t s){    uint32_t old_dlen = m->datalen;    int new_datasize = m->datasize;    int new_datalen = m->datalen + s;    void *new_data = 0; 	if (!new_datasize)	    new_datasize = LO_DEF_DATA_SIZE;     lo_pow2_over(new_datasize, new_datalen);	new_data = realloc(m->data, new_datasize);    if (!new_data)        return 0;     m->datalen = new_datalen;    m->datasize = new_datasize;    m->data = new_data;     if (m->argv) {        free(m->argv);        m->argv = NULL;    }     return (void*)((char*)m->data + old_dlen);} int lo_strsize(const char *s){    return 4 * (strlen(s) / 4 + 1);} size_t lo_arg_size(lo_type type, void *data){    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 4;     case LO_INT64:    case LO_TIMETAG:    case LO_DOUBLE:	return 8;     case LO_STRING:    case LO_SYMBOL:	return lo_strsize((char *)data);     case LO_BLOB:	return lo_blobsize((lo_blob)data);     default:	fprintf(stderr, "liblo warning: unhandled OSC type '%c' at %s:%d\n", type, __FILE__, __LINE__);	return 0;    }     return 0;

Lines 1–500 of 1083.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t