aboutsummaryrefslogtreecommitdiff
path: root/OSC/dumpOSC.c
diff options
context:
space:
mode:
Diffstat (limited to 'OSC/dumpOSC.c')
-rw-r--r--OSC/dumpOSC.c992
1 files changed, 0 insertions, 992 deletions
diff --git a/OSC/dumpOSC.c b/OSC/dumpOSC.c
deleted file mode 100644
index 979a546..0000000
--- a/OSC/dumpOSC.c
+++ /dev/null
@@ -1,992 +0,0 @@
-/*
-Copyright (c) 1992,1993,1994,1995,1996,1997,2000.
-The Regents of the University of California (Regents).
-All Rights Reserved.
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for educational, research, and not-for-profit purposes, without
-fee and without a signed licensing agreement, is hereby granted, provided that
-the above copyright notice, this paragraph and the following two paragraphs
-appear in all copies, modifications, and distributions. Contact The Office of
-Technology Licensing, UC Berkeley, 2150 Shattuck Avenue, Suite 510, Berkeley,
-CA 94720-1620, (510) 643-7201, for commercial licensing opportunities.
-
-Written by Matt Wright and Adrian Freed, The Center for New Music and Audio
-Technologies, University of California, Berkeley.
-
- IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
- SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
- ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
- REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING
- DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
- REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
- ENHANCEMENTS, OR MODIFICATIONS.
-*/
-
- /*
-
- dumpOSC.c
- server that displays OpenSoundControl messages sent to it
- for debugging client udp and UNIX protocol
-
- by Matt Wright, 6/3/97
- modified from dumpSC.c, by Matt Wright and Adrian Freed
-
- version 0.2: Added "-silent" option a.k.a. "-quiet"
-
- version 0.3: Incorporated patches from Nicola Bernardini to make
- things Linux-friendly. Also added ntohl() in the right places
- to support little-endian architectures.
-
-
-
- compile:
- cc -o dumpOSC dumpOSC.c
-
- to-do:
-
- More robustness in saying exactly what's wrong with ill-formed
- messages. (If they don't make sense, show exactly what was
- received.)
-
- Time-based features: print time-received for each packet
-
- Clean up to separate OSC parsing code from socket/select stuff
-
- pd
- -------------
- -- tweaks for Win32 www.zeggz.com/raf 13-April-2002
-
-*/
-
-#include "m_pd.h"
-//#include "m_imp.h"
-#include "s_stuff.h"
-//#include "x_osc.h"
-
-/* declarations */
-
-// typedef void (*t_fdpollfn)(void *ptr, int fd);
-void sys_addpollfn(int fd, t_fdpollfn fn, void *ptr);
-
-
-#if defined(__sgi) || defined(__linux) || defined(WIN32) || defined(MACOSX)
-
-#ifdef WIN32
- #include "OSC-common.h"
- #include <winsock2.h>
- #include <string.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <ctype.h>
- #include <signal.h>
-#else
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <netinet/in.h>
- #include <rpc/rpc.h>
- #include <sys/socket.h>
- #include <sys/un.h>
- #include <sys/times.h>
- #include <sys/param.h>
- #include <sys/time.h>
- #include <sys/ioctl.h>
- #include <ctype.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <pwd.h>
- #include <signal.h>
- #include <grp.h>
- #include <sys/file.h>
- //#include <sys/prctl.h>
-
- #ifdef NEED_SCHEDCTL_AND_LOCK
- #include <sys/schedctl.h>
- #include <sys/lock.h>
- #endif
-#endif
-
-
-char *htm_error_string;
-typedef int Boolean;
-typedef void *OBJ;
-
-typedef struct ClientAddressStruct {
- struct sockaddr_in cl_addr;
- int clilen;
- int sockfd;
-} *ClientAddr;
-
-typedef unsigned long long osc_time_t;
-
-Boolean ShowBytes = FALSE;
-Boolean Silent = FALSE;
-
-/* Declarations */
-#ifndef WIN32
-static int unixinitudp(int chan);
-#endif
-
-static int initudp(int chan);
-static void closeudp(int sockfd);
-Boolean ClientReply(int packetsize, void *packet, int socketfd,
- void *clientaddresspointer, int clientaddressbufferlength);
-void sgi_CleanExit(void);
-Boolean sgi_HaveToQuit(void);
-int RegisterPollingDevice(int fd, void (*callbackfunction)(int , void *), void *dummy);
-static void catch_sigint();
-static int Synthmessage(char *m, int n, void *clientdesc, int clientdesclength, int fd) ;
-char *DataAfterAlignedString(char *string, char *boundary) ;
-Boolean IsNiceString(char *string, char *boundary) ;
-void complain(char *s, ...);
-
-#define MAXMESG 32768
-static char mbuf[MAXMESG];
-
-/* ----------------------------- dumpOSC ------------------------- */
-
-#define MAXOUTAT 50
-
-static t_class *dumpOSC_class;
-
-typedef struct _dumpOSC
-{
- t_object x_obj;
- t_outlet *x_msgout;
- t_outlet *x_connectout;
- t_atom x_outat[MAXOUTAT];
- int x_outatc;
- t_binbuf *x_b;
- int x_connectsocket;
- int x_nconnections;
- int x_udp;
- struct sockaddr_in x_server;
- int x_clilen;
-} t_dumpOSC;
-
-void dumpOSC_ParsePacket(t_dumpOSC *x, char *buf, int n, ClientAddr returnAddr);
-Boolean dumpOSC_SendReply(char *buf, int n, void *clientDesc, int clientDescLenght, int fd);
-static void dumpOSC_Smessage(t_dumpOSC *x, char *address, void *v, int n, ClientAddr returnAddr);
-static void dumpOSC_PrintTypeTaggedArgs(t_dumpOSC *x, void *v, int n);
-static void dumpOSC_PrintHeuristicallyTypeGuessedArgs(t_dumpOSC *x, void *v, int n, int skipComma);
-
-static void dumpOSC_read(t_dumpOSC *x, int sockfd) {
- int clilen = x->x_clilen;
- int n;
- struct ClientAddressStruct ras;
- ClientAddr ra = &ras;
-
- //catchupflag= FALSE;
-
-/* if (ShowBytes) { */
-/* int i; */
-/* printf("%d byte message:\n", n); */
-/* for (i = 0; i < n; ++i) { */
-/* printf(" %x (%c)\t", m[i], m[i]); */
-/* if (i%4 == 3) printf("\n"); */
-/* } */
-/* printf("\n"); */
-/* } */
-
- // return catchupflag;
- //struct sockaddr_in x->x_server;
- //while( (n = recvfrom(sockfd, mbuf, MAXMESG, 0, &cl_addr, &clilen)) >0)
- // while((
- #ifdef WIN32
- if ((n = recvfrom(sockfd, mbuf, MAXMESG, 0, (SOCKADDR*)&x->x_server, &clilen)) >0)
- #else
- if ((n = recvfrom(sockfd, mbuf, MAXMESG, 0, (struct sockaddr *)&x->x_server, &clilen)) >0)
- #endif
- {
- //int r;
- ras.cl_addr = *((struct sockaddr_in *) &x->x_server);
- ras.clilen = x->x_clilen;
- ras.sockfd = x->x_connectsocket;
-
- #ifdef DEBUG
- printf("dumpOSC_read: received UDP packet of length %d\n", n);
- #endif
-
- if(!dumpOSC_SendReply(mbuf, n, &x->x_server, clilen, sockfd))
- {
- dumpOSC_ParsePacket(x, mbuf, n, ra);
- }
- //r = Synthmessage(mbuf, n, &x->x_server, clilen, sockfd);
- //post ("%d", r);
- //outlet_anything(x->x_msgout, at[msg].a_w.w_symbol,
- // emsg-msg-1, at + msg + 1);
- // outlet_list(x->x_msgout, 0, n, mbuf);
- //if( sgi_HaveToQuit()) goto out;
- //if(r>0) goto back;
- //clilen = maxclilen;
- }
-}
-
-static void *dumpOSC_new(t_symbol *compatflag,
- t_floatarg fportno) {
- t_dumpOSC *x;
- struct sockaddr_in server;
- int clilen=sizeof(server);
- int sockfd;
- int portno=fportno;
- int udp = 1;
-
- //x->x_b = binbuf_new();
- //x->x_outat = binbuf_getvec(x->x_b);
-
- //{{raf}} pointer not valid yet...moving this down
- //x->x_outatc = 0; {{raf}}
-
- /* create a socket */
- if ((sockfd = socket(AF_INET, (udp ? SOCK_DGRAM : SOCK_STREAM), 0)) == -1)
- {
- sys_sockerror("socket");
- return (0);
- }
-
- server.sin_family = AF_INET;
- server.sin_addr.s_addr = INADDR_ANY;
- /* assign server port number */
- server.sin_port = htons((u_short)portno);
- /* name the socket */
- if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0)
- {
- sys_sockerror("bind");
- sys_closesocket(sockfd);
- return (0);
- }
-
- x = (t_dumpOSC *)pd_new(dumpOSC_class);
- x->x_outatc = 0; // {{raf}} now pointer is valid (less invalid)
-
- x->x_msgout = outlet_new(&x->x_obj, &s_anything);
-
- // if (udp) /* datagram protocol */
- {
-
- sys_addpollfn(sockfd, (t_fdpollfn)dumpOSC_read, x);
- x->x_connectout = 0;
- }
- // else /* streaming protocol */
- /* { */
- /* if (listen(sockfd, 5) < 0) */
- /* { */
- /* sys_sockerror("listen"); */
- /* sys_closesocket(sockfd); */
- /* sockfd = -1; */
- /* } */
- /* else */
- /* { */
- /* sys_addpollfn(sockfd, (t_fdpollfn)dumpOSC_connectpoll, x); */
- /* x->x_connectout = outlet_new(&x->x_obj, &s_float); */
- /* } */
- /* } */
-
- x->x_connectsocket = sockfd;
- x->x_server = server;
- x->x_clilen = clilen;
- x->x_nconnections = 0;
- x->x_udp = udp;
-
- return (x);
-}
-
-static void dumpOSC_free(t_dumpOSC *x)
-{
- /* LATER make me clean up open connections */
- if (x->x_connectsocket >= 0)
- {
- sys_rmpollfn(x->x_connectsocket);
- sys_closesocket(x->x_connectsocket);
- }
-}
-
-#ifdef WIN32
-OSC_API void dumpOSC_setup(void)
-#else
-void dumpOSC_setup(void)
-#endif
-{
- dumpOSC_class = class_new(gensym("dumpOSC"),
- (t_newmethod)dumpOSC_new, (t_method)dumpOSC_free,
- sizeof(t_dumpOSC), CLASS_NOINLET, A_DEFFLOAT, A_DEFFLOAT,
- A_DEFSYM, 0);
- class_sethelpsymbol(dumpOSC_class, gensym("OSC/dumpOSC-help.pd"));
-}
-
-
-#ifndef WIN32
- #define UNIXDG_PATH "/tmp/htm"
- #define UNIXDG_TMP "/tmp/htm.XXXXXX"
- static int unixinitudp(int chan)
- {
- struct sockaddr_un serv_addr;
- int sockfd;
-
- if((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
- return sockfd;
-
- bzero((char *)&serv_addr, sizeof(serv_addr));
- serv_addr.sun_family = AF_UNIX;
- strcpy(serv_addr.sun_path, UNIXDG_PATH);
- sprintf(serv_addr.sun_path+strlen(serv_addr.sun_path), "%d", chan);
- unlink(serv_addr.sun_path);
- if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr.sun_family)+strlen(serv_addr.sun_path)) < 0)
- {
- perror("unable to bind\n");
- return -1;
- }
-
- fcntl(sockfd, F_SETFL, FNDELAY);
- return sockfd;
- }
-#endif // #ifndef WIN32
-
-
-
-static int initudp(int chan)
-{
-
-#ifdef WIN32
- struct sockaddr_in serv_addr;
- unsigned int sockfd;
- ULONG nonBlocking = (ULONG) TRUE;
-
- if( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) != INVALID_SOCKET ) {
- ZeroMemory((char *)&serv_addr, sizeof(serv_addr));
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
- serv_addr.sin_port = htons(chan);
- if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) >= 0) {
- // set for non-blocking mode
- if(ioctlsocket(sockfd, FIONBIO, &nonBlocking) == SOCKET_ERROR) {
- perror("unable to set non-blocking\n");
- return -1;
- }
- }
- else { perror("unable to bind\n"); return -1; }
- }
- return (sockfd == INVALID_SOCKET ? -1 : (int)sockfd);
-#else
- struct sockaddr_in serv_addr;
- int sockfd;
-
- if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
- return sockfd;
-
- bzero((char *)&serv_addr, sizeof(serv_addr));
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
- serv_addr.sin_port = htons(chan);
-
- if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
- {
- perror("unable to bind\n");
- return -1;
- }
-
- fcntl(sockfd, F_SETFL, FNDELAY);
- return sockfd;
-#endif
-}
-
-
-
-
-
-
-
-
-static void closeudp(int sockfd) {
- #ifdef WIN32
- closesocket(sockfd);
- #else
- close(sockfd);
- #endif
-}
-
-static Boolean catchupflag=FALSE;
-Boolean ClientReply(int packetsize, void *packet, int socketfd,
- void *clientaddresspointer, int clientaddressbufferlength)
-{
- if(!clientaddresspointer) return FALSE;
- catchupflag= TRUE;
- return packetsize==sendto(socketfd, packet, packetsize, 0, clientaddresspointer, clientaddressbufferlength);
-}
-
-static Boolean exitflag= FALSE;
-void sgi_CleanExit(void) {
- exitflag = TRUE;
-}
-
-Boolean sgi_HaveToQuit(void) {
- return exitflag;
-}
-
-
-/* file descriptor poll table */
-static int npolldevs =0;
-typedef struct polldev
-{
- int fd;
- void (*callbackfunction)(int , void *);
- void *dummy;
-} polldev;
-#define TABMAX 8
-static polldev polldevs[TABMAX];
-
-
-/* Register a device (referred to by a file descriptor that the caller
- should have already successfully obtained from a system call) to be
- polled as real-time constraints allowed.
-
- When a select(2) call indicates activity on the file descriptor, the
- callback function is called with the file descripter as first
- argument and the given dummy argument (presumably a pointer to the
- instance variables associated with the device).
-*/
-int RegisterPollingDevice(int fd, void (*callbackfunction)(int , void *), void *dummy)
-{
- if(npolldevs<TABMAX)
- {
- polldevs[npolldevs].fd = fd;
- polldevs[npolldevs].callbackfunction = callbackfunction;
- polldevs[npolldevs].dummy = dummy;
- }
- else return -1;
- return npolldevs++;
-}
-
-static int caught_sigint;
-
-static void catch_sigint() {
- caught_sigint = 1;
-}
-static int sockfd, usockfd;
-
-
-void PrintClientAddr(ClientAddr CA) {
- unsigned long addr = CA->cl_addr.sin_addr.s_addr;
- printf("Client address %p:\n", CA);
- printf(" clilen %d, sockfd %d\n", CA->clilen, CA->sockfd);
- printf(" sin_family %d, sin_port %d\n", CA->cl_addr.sin_family,
- CA->cl_addr.sin_port);
- printf(" address: (%x) %s\n", addr, inet_ntoa(CA->cl_addr.sin_addr));
-
- printf(" sin_zero = \"%c%c%c%c%c%c%c%c\"\n",
- CA->cl_addr.sin_zero[0],
- CA->cl_addr.sin_zero[1],
- CA->cl_addr.sin_zero[2],
- CA->cl_addr.sin_zero[3],
- CA->cl_addr.sin_zero[4],
- CA->cl_addr.sin_zero[5],
- CA->cl_addr.sin_zero[6],
- CA->cl_addr.sin_zero[7]);
-
- printf("\n");
-}
-
-//*******************
-
-void WriteTime(char* dst, osc_time_t osctime)
-{
- *(int32_t*)dst = htonl((int32_t)(osctime >> 32));
- *(int32_t*)(dst+4) = htonl((int32_t)osctime);
-}
-
-void WriteMode(char* dst)
-{
- *(int32_t*)dst = htonl(0);
-}
-
-osc_time_t ReadTime(const char* src)
-{
- osc_time_t osctime = ntohl(*(int32_t*)src);
- return (osctime << 32) + ntohl(*(int32_t*)(src+4));
-}
-
-double TimeToSeconds(osc_time_t osctime)
-{
- return (double)osctime * 2.3283064365386962890625e-10 /* 1/2^32 */;
-}
-
-int timeRound(double x)
-{
- return x >= 0.0 ? x+0.5 : x-0.5;
-}
-/*
-void WriteLogicalTime(char* dst)
-{
- static double startTime = -1.0;
- double sTime;
-
- // Initialisierung der Startzeit.
- // Knnte effizienter (ohne 'if') auch irgendwo vorher passieren.
- // Knnte wahrscheinlich auch 0.0 sein.
- if (startTime < 0.0) {
- startTime = clock_getlogicaltime();
- }
-
- sTime = clock_gettimesince(startTime) * 0.001;
- *(int32_t*)dst = hton'K l((int32_t)sTime);
- *(int32_t*)(dst+4) = htonl((int32_t)(4294967296.0 * sTime));
-}
-*/
-
-void WriteLogicalTime(char* dst)
-{
- double sTime = clock_gettimesince(19230720) / 1000.0;
- double tau = sTime - timeRound(sTime);
-
- //fprintf(stderr, "sSec = %f tau = %f\n", sTime, tau);
-
- *(int32_t*)dst = htonl((int32_t)(sTime));
- *(int32_t*)(dst+4) = htonl((int32_t)(4294967296 * tau));
-}
-
-Boolean dumpOSC_SendReply(char *buf, int n, void *clientDesc, int clientDescLenght, int fd)
-{
- if((n == 24) && (strcmp(buf, "#time") == 0))
- {
- osc_time_t t0, t1, t2;
- double dt0, dt1, dt2;
-
- WriteMode(buf+6);
-
- t0 = ReadTime(buf+8);
-
- WriteLogicalTime(buf+16);
- t1 = ReadTime(buf+16); // reverse
- dt0 = TimeToSeconds(t0); // client time
- dt1 = TimeToSeconds(t1); // server time
-
- // fprintf(stderr, "%f\t%f\t%f\n", dt0, dt1, dt0 - dt1);
-
- sendto(fd, buf, n, 0, (struct sockaddr *)clientDesc, clientDescLenght);
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
-
-//**********************
-
-void dumpOSC_ParsePacket(t_dumpOSC *x, char *buf, int n, ClientAddr returnAddr) {
- // t_dumpOSC *x;
- int size, messageLen, i;
- char *messageName;
- char *args;
-
- //#ifdef PRINTADDRS
- #ifdef DEBUG
- //PrintClientAddr(returnAddr);
- #endif
-
-
- if ((n%4) != 0) {
- complain("SynthControl packet size (%d) not a multiple of 4 bytes: dropping", n);
- return;
- }
-
- if ((n >= 8) && (strncmp(buf, "#bundle", 8) == 0)) {
- /* This is a bundle message. */
- #ifdef DEBUG
- printf("dumpOSC_ParsePacket: bundle msg: bundles not yet supported\n");
- #endif
-
- if (n < 16) {
- complain("Bundle message too small (%d bytes) for time tag", n);
- return;
- }
-
- /* Print the time tag */
- #ifdef DEBUG
- printf("[ %lx%08lx\n", ntohl(*((unsigned long *)(buf+8))), ntohl(*((unsigned long *)(buf+12))));
- #endif
-
- /* Note: if we wanted to actually use the time tag as a little-endian
- 64-bit int, we'd have to word-swap the two 32-bit halves of it */
-
- i = 16; /* Skip "#group\0" and time tag */
-
- while(i<n) {
- size = ntohl(*((int *) (buf + i)));
- if ((size % 4) != 0) {
- complain("Bad size count %d in bundle (not a multiple of 4)", size);
- return;
- }
- if ((size + i + 4) > n) {
- complain("Bad size count %d in bundle (only %d bytes left in entire bundle)",
- size, n-i-4);
- return;
- }
-
- /* Recursively handle element of bundle */
- dumpOSC_ParsePacket(x, buf+i+4, size, returnAddr);
- i += 4 + size;
- }
-
- if (i != n) {
- complain("This can't happen");
- }
- #ifdef DEBUG
- printf("]\n");
- #endif
-
- }
- else if ((n == 24) && (strcmp(buf, "#time") == 0))
- {
- complain("Time message: %s\n :).\n", htm_error_string);
- return;
-
- }
- else
- {
- /* This is not a bundle message */
-
- messageName = buf;
- args = DataAfterAlignedString(messageName, buf+n);
- if (args == 0) {
- complain("Bad message name string: %s\nDropping entire message.\n",
- htm_error_string);
- return;
- }
- messageLen = args-messageName;
- dumpOSC_Smessage(x, messageName, (void *)args, n-messageLen, returnAddr);
- }
-}
-
-#define SMALLEST_POSITIVE_FLOAT 0.000001f
-
-static void dumpOSC_Smessage(t_dumpOSC *x, char *address, void *v, int n, ClientAddr returnAddr) {
- char *chars = v;
- t_atom at;
- //t_atom myargv[50];
-
- int myargc = x->x_outatc;
- t_atom* mya = x->x_outat;
- int myi;
-
-#ifdef DEBUG
- printf("%s ", address);
-#endif
-
- // ztoln+cvt from envgen.c, ggee-0.18 ..
- // outlet_anything's 'symbol' gets set to address
- // so we dont need to append address to the atomlist
- /*
- SETSYMBOL(mya,gensym(address));myargc++;
- x->x_outatc = myargc;
- */
-
- if (n != 0) {
- if (chars[0] == ',') {
- if (chars[1] != ',') {
- /* This message begins with a type-tag string */
- dumpOSC_PrintTypeTaggedArgs(x, v, n);
- } else {
- /* Double comma means an escaped real comma, not a type string */
- dumpOSC_PrintHeuristicallyTypeGuessedArgs(x, v, n, 1);
- }
- } else {
- dumpOSC_PrintHeuristicallyTypeGuessedArgs(x, v, n, 0);
- }
- }
-
- outlet_anything(x->x_msgout,gensym(address),x->x_outatc,(t_atom*)&x->x_outat);
- x->x_outatc = 0;
-#ifdef DEBUG
- printf("\n");
-#endif
- fflush(stdout); /* Added for Sami 5/21/98 */
-}
-
-static void dumpOSC_PrintTypeTaggedArgs(t_dumpOSC *x, void *v, int n) {
- char *typeTags, *thisType;
- char *p;
-
- int myargc = x->x_outatc;
- t_atom* mya = x->x_outat;
- int myi;
-
- typeTags = v;
-
- if (!IsNiceString(typeTags, typeTags+n)) {
- /* No null-termination, so maybe it wasn't a type tag
- string after all */
- dumpOSC_PrintHeuristicallyTypeGuessedArgs(x, v, n, 0);
- return;
- }
-
- p = DataAfterAlignedString(typeTags, typeTags+n);
-
-
- for (thisType = typeTags + 1; *thisType != 0; ++thisType) {
- switch (*thisType) {
- case 'i': case 'r': case 'm': case 'c':
-#ifdef DEBUG
- //post("integer: %d", ntohl(*((int *) p)));
-#endif
- /* Martin Peach fix for negative floats:
- * was: SETFLOAT(mya+myargc,ntohl(*((int *) p)));
- * now is:
- */
- SETFLOAT(mya+myargc,(signed)ntohl(*((int *) p)));
- myargc++;
-
- p += 4;
- break;
-
- case 'f': {
- int i = ntohl(*((int *) p));
- float *floatp = ((float *) (&i));
-#ifdef DEBUG
- post("float: %f", *floatp);
-#endif
- SETFLOAT(mya+myargc,*floatp);
- myargc++;
-
- p += 4;
- }
- break;
-
- case 'h': case 't':
-#ifdef DEBUG
- printf("[A 64-bit int] ");
-#endif
- post("[A 64-bit int] not implemented");
-
- p += 8;
- break;
-
- case 'd':
-#ifdef DEBUG
- printf("[A 64-bit float] ");
-#endif
- post("[A 64-bit float] not implemented");
-
- p += 8;
- break;
-
- case 's': case 'S':
- if (!IsNiceString(p, typeTags+n)) {
- post("Type tag said this arg is a string but it's not!\n");
- return;
- } else {
-#ifdef DEBUG
- post("string: \"%s\"", p);
-#endif
- SETSYMBOL(mya+myargc,gensym(p));
- myargc++;
- //outlet_list(x->x_msgout, 0,sizeof(p), p);
- //outlet_anything(x->x_msgout, 0, sizeof(p), p);
- p = DataAfterAlignedString(p, typeTags+n);
- // append to output vector ..
- }
- break;
-
- case 'T':
-#ifdef DEBUG
- printf("[True] ");
-#endif
- SETFLOAT(mya+myargc,1.);
- myargc++;
- break;
- case 'F':
-#ifdef DEBUG
- printf("[False] ");
-#endif
- SETFLOAT(mya+myargc,0.);
- myargc++;
- break;
- case 'N':
-#ifdef DEBUG
- printf("[Nil]");
-#endif
- post("sendOSC: [Nil] not implemented");
- break;
- case 'I':
-#ifdef DEBUG
- printf("[Infinitum]");
-#endif
- post("sendOSC: [Infinitum] not implemented");
- break;
-
- default:
- post("sendOSC: [Unrecognized type tag %c]", *thisType);
- // return;
- }
- }
- x->x_outatc = myargc;
-}
-
-static void dumpOSC_PrintHeuristicallyTypeGuessedArgs(t_dumpOSC *x, void *v, int n, int skipComma) {
- int i, thisi;
- float thisf;
- int *ints;
- char *chars;
- char *string, *nextString;
-
- int myargc= x->x_outatc;
- t_atom* mya = x->x_outat;
- int myi;
-
-
- /* Go through the arguments 32 bits at a time */
- ints = v;
- chars = v;
-
- for (i = 0; i<n/4; ) {
- string = &chars[i*4];
- thisi = ntohl(ints[i]);
- /* Reinterpret the (potentially byte-reversed) thisi as a float */
- thisf = *(((float *) (&thisi)));
-
- if (thisi >= -1000 && thisi <= 1000000) {
-#ifdef DEBUG
- printf("%d ", thisi);
-#endif
- // append to output vector ..
- SETFLOAT(mya+myargc,(t_float) (thisi));
- myargc++;
- // outlet_float(x->x_msgout, thisi);
- i++;
- } else if (thisf >= -1000.f && thisf <= 1000000.f &&
- (thisf <=0.0f || thisf >= SMALLEST_POSITIVE_FLOAT)) {
-#ifdef DEBUG
- printf("%f ", thisf);
-#endif
- // append to output vector ..
- SETFLOAT(mya+myargc,thisf);
- myargc++;
- //outlet_float(x->x_msgout, thisf);
- i++;
- } else if (IsNiceString(string, chars+n)) {
- nextString = DataAfterAlignedString(string, chars+n);
-#ifdef DEBUG
- printf("\"%s\" ", (i == 0 && skipComma) ? string +1 : string);
-#endif
- // append to output vector ..
- SETSYMBOL(mya+myargc,gensym(string));
- myargc++;
- //outlet_symbol(x->x_msgout, gensym((i == 0 && skipComma) ? string +1 : string));
- i += (nextString-string) / 4;
- } else {
- // unhandled .. ;)
-#ifdef DEBUG
- printf("0x%x xx", ints[i]);
-#endif
- i++;
- }
- x->x_outatc = myargc;
- }
-}
-
-
-#define STRING_ALIGN_PAD 4
-
-char *DataAfterAlignedString(char *string, char *boundary)
-{
- /* The argument is a block of data beginning with a string. The
- string has (presumably) been padded with extra null characters
- so that the overall length is a multiple of STRING_ALIGN_PAD
- bytes. Return a pointer to the next byte after the null
- byte(s). The boundary argument points to the character after
- the last valid character in the buffer---if the string hasn't
- ended by there, something's wrong.
-
- If the data looks wrong, return 0, and set htm_error_string */
-
- int i;
-
- if ((boundary - string) %4 != 0) {
- fprintf(stderr, "Internal error: DataAfterAlignedString: bad boundary\n");
- return 0;
- }
-
- for (i = 0; string[i] != '\0'; i++) {
- if (string + i >= boundary) {
- htm_error_string = "DataAfterAlignedString: Unreasonably long string";
- return 0;
- }
- }
-
- /* Now string[i] is the first null character */
- i++;
-
- for (; (i % STRING_ALIGN_PAD) != 0; i++) {
- if (string + i >= boundary) {
- htm_error_string = "DataAfterAlignedString: Unreasonably long string";
- return 0;
- }
- if (string[i] != '\0') {
- htm_error_string = "DataAfterAlignedString: Incorrectly padded string.";
- return 0;
- }
- }
-
- return string+i;
-}
-
-Boolean IsNiceString(char *string, char *boundary)
-{
- /* Arguments same as DataAfterAlignedString(). Is the given "string"
- really a string? I.e., is it a sequence of isprint() characters
- terminated with 1-4 null characters to align on a 4-byte boundary? */
-
- int i;
-
- if ((boundary - string) %4 != 0) {
- fprintf(stderr, "Internal error: IsNiceString: bad boundary\n");
- return 0;
- }
-
- for (i = 0; string[i] != '\0'; i++) {
- if (!isprint(string[i])) return FALSE;
- if (string + i >= boundary) return FALSE;
- }
-
- /* If we made it this far, it's a null-terminated sequence of printing characters
- in the given boundary. Now we just make sure it's null padded... */
-
- /* Now string[i] is the first null character */
- i++;
- for (; (i % STRING_ALIGN_PAD) != 0; i++) {
- if (string[i] != '\0') return FALSE;
- }
-
- return TRUE;
-}
-
-
-
-
-
-
-
-
-
-#include <stdarg.h>
-void complain(char *s, ...) {
- va_list ap;
- va_start(ap, s);
- fprintf(stderr, "*** ERROR: ");
- vfprintf(stderr, s, ap);
- fprintf(stderr, "\n");
- va_end(ap);
-}
-
-#endif /* __sgi or LINUX or WIN32 */