/* * 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. Load more
/* * 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, ...) #else int 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;