support OSC-string

Dependents:   OSCtoCVConverter

Fork of OSC by Toby Harris

Revision:
2:507dea4cc97a
Parent:
1:63b72e393989
Child:
3:f4118f0bc1ab
--- a/mbedOSC.cpp	Fri Jul 26 22:10:20 2013 +0000
+++ b/mbedOSC.cpp	Sun Aug 02 09:56:26 2015 +0000
@@ -1,150 +1,209 @@
 /*
  mbedOSC.cpp 
 */                    
+
+#pragma O3
+#pragma Otime
    
 #include "mbed.h"
 #include "mbedOSC.h"
 #include "stdarg.h"
+#include <string.h>
 
 OSCMessage::OSCMessage() {
  // Initialize host address and port by default (as if this where the receiver message):
  //    host=new Host(IpAddr(10, 0, 0, 1), DEFAULT_RECEIVE_PORT, NULL);
 }
 
-void OSCMessage::setPort(uint16_t _port){
+inline size_t strlength(const char *s) 
+{
+    size_t len = 0;
+    
+    for (;;) 
+    {
+        unsigned x = *(unsigned*)s;
+        if ((x & 0xFF) == 0) return len;
+        if ((x & 0xFF00) == 0) return len + 1;
+        if ((x & 0xFF0000) == 0) return len + 2;
+        if ((x & 0xFF000000) == 0) return len + 3;
+        s += 4, len += 4;
+    }
+}
+
+void OSCMessage::setPort(uint16_t _port) {
+    
      host.setPort(_port);
 }
 
 
-void OSCMessage::setIp(uint8_t *_ip){
+void OSCMessage::setIp(uint8_t *_ip) {
+    
     host.setIp(IpAddr(_ip[0], _ip[1], _ip[2], _ip[3]));
 }
 
 
 
-void OSCMessage::setIp(    uint8_t _ip1,
+void OSCMessage::setIp( uint8_t _ip1,
                         uint8_t _ip2,
                         uint8_t _ip3,
-                        uint8_t _ip4 ){
+                        uint8_t _ip4 ) {
     
     host.setIp(IpAddr(_ip1, _ip2, _ip3, _ip4));
 }
 
-const IpAddr& OSCMessage::getIp(){
+const IpAddr& OSCMessage::getIp() {
+    
     return host.getIp();
 }
 
 
- const int& OSCMessage::getPort(){
+const int& OSCMessage::getPort() {
+     
     return host.getPort();
 }
 
 
-
 uint8_t    OSCMessage::getAddressNum(){
     
     return addressNum;
 }
 
 
-uint8_t    OSCMessage::getArgNum(){
+uint8_t    OSCMessage::getArgNum() {
     
     return argNum;
 }
 
 
-
-char * OSCMessage::getAddress(uint8_t _index){
-    if(_index>MAX_ADDRESS) _index=MAX_ADDRESS-1;
+char * OSCMessage::getAddress(uint8_t _index) {
+    
+    if (_index > MAX_ADDRESS) {
+        
+        _index = (MAX_ADDRESS - 1);
+    }
+     
     return address[_index];
     
 }
 
 
-
-char * OSCMessage::getTopAddress(){
+char * OSCMessage::getTopAddress() {
     
     return getAddress(0);
     
 }
 
 
-char * OSCMessage::getSubAddress(){
+char * OSCMessage::getSubAddress() {
     
     return getAddress(1);
     
 }
 
 
-char  OSCMessage::getTypeTag(uint8_t _index){
-    if(_index>MAX_ARG) _index=MAX_ARG-1;
+char  OSCMessage::getTypeTag(uint8_t _index) {
+    
+    if (_index > MAX_ARG) {
+        
+      _index = MAX_ARG-1;  
+    }
+    
     return typeTag[_index];
 }
 
 
-int32_t OSCMessage::getArgInt(uint8_t _index){
+int32_t OSCMessage::getArgInt(uint8_t _index) {
     int32_t *value;
-    if(_index > argNum) _index=argNum;
+    
+    if (_index > argNum) {
+        
+        _index = argNum;  
+    }
+    
     value = (int32_t *)arg[_index]; // cast to int32_t
+    
     return *value;
 }
 
 
-double OSCMessage::getArgFloat(uint8_t _index){
+double OSCMessage::getArgFloat(uint8_t _index) {
     float *value;
-    if(_index > argNum) _index=argNum;
+    
+    if (_index > argNum) {
+        
+        _index=argNum;  
+    }
+    
     value = (float *)arg[_index]; // cast to float not double for correct parsing on mbed!
+    
     return *value;
 }
 
 
-void OSCMessage::setTopAddress(char *_address){
-    address[0]=_address;
-    address[1]=0;
-    addressNum=1; // Note: this "erases" the subaddress! (is this a good idea?)
+void OSCMessage::setTopAddress(char *_address) {
+    
+    address[0] = _address;
+    address[1] = 0;
+    addressNum = 1; // Note: this "erases" the subaddress! (is this a good idea?)
 }
 
 
-void OSCMessage::setSubAddress(char *_address){
-    address[1]=_address;
-    addressNum=2; // Note: this assumes the top address was already set!
+void OSCMessage::setSubAddress(char *_address) {
+    
+    address[1] = _address;
+    addressNum = 2; // Note: this assumes the top address was already set!
 }
 
 
 
-void OSCMessage::setAddress(char *_topAddress,char *_subAddress){
+void OSCMessage::setAddress(char *_topAddress,char *_subAddress) {
+    
     setTopAddress(_topAddress);
     setSubAddress(_subAddress);
-    addressNum=2; // (unnecessary...)
+    
+    addressNum = 2; // (unnecessary...)
 }
 
 
-void OSCMessage::setAddress(uint8_t _index, char *_address){
-    if(_index>MAX_ADDRESS) _index=MAX_ADDRESS-1;
-    address[_index]=_address;
-    addressNum=_index+1;
+void OSCMessage::setAddress(uint8_t _index, char *_address) {
+    
+    if (_index>MAX_ADDRESS) {
+      
+      _index = (MAX_ADDRESS - 1);  
+    }
+    
+    address[_index] = _address;
+    addressNum = (_index + 1);
 }
 
 
 
-void OSCMessage::setArgs(char *types,...){
+void OSCMessage::setArgs(char *types,...) {
     
     va_list argList;
     
-    argNum = strlen(types);
-    if(argNum>MAX_ARG) argNum=MAX_ARG-1;
+    argNum = strlength(types);
+    
+    if (argNum > MAX_ARG) {
+        
+        argNum = MAX_ARG - 1;
+    } 
     
     va_start( argList, types );
-    for(uint8_t i=0 ; i < argNum ; i++){
+    
+    for (uint8_t i = 0 ; i < argNum ; ++i) {
         
-        typeTag[i]=types[i];
+        typeTag[i] = types[i];
         
         switch(types[i]) {
             case 'i':
-                arg[i]=(uint32_t *)va_arg(argList, uint32_t *);
+                arg[i] = (uint32_t *)va_arg(argList, int32_t *);
                 break;
             case 'f':
-                arg[i]=va_arg(argList, double *);
+                arg[i] = va_arg(argList, float *);
+                break;
+            case 's':
+                arg[i] = va_arg(argList, char *);
                 break;
         }   
     }
@@ -155,233 +214,271 @@
 // ================================================================================================================================================
 //The class define an object wrapping the UDP functions to send and receive OSC messages
 
-OSCClass::OSCClass(){
+OSCClass::OSCClass() {
+    
     udpRec.setOnEvent(this, &OSCClass::onUDPSocketEvent);
     newMessage=false;
 }
 
-OSCClass::~OSCClass(){
+OSCClass::~OSCClass() {
+    
     udpSend.resetOnEvent();
     udpRec.close();
 }
 
-OSCClass::OSCClass(OSCMessage *_mes){
+OSCClass::OSCClass(OSCMessage *_mes) {
+    
     udpRec.setOnEvent(this, &OSCClass::onUDPSocketEvent);
     receiverMessage = _mes; // note: receiverMessage MUST be a pointer to the message, because we will modify things in it
-    newMessage=false;
+    newMessage = false;
 }
 
-void OSCClass::begin()
-{    
+void OSCClass::begin() {    
   // setup receiver udp socket:
   udpRec.bind(receiverMessage->host);
 }
 
 
-void OSCClass::begin(uint16_t _recievePort)
-{
+void OSCClass::begin(uint16_t _recievePort) {
+    
   receiverMessage->host.setPort(_recievePort);
   // setup receiver udp socket:
   udpRec.bind(receiverMessage->host);
 }
 
 
-void OSCClass::setReceiveMessage(OSCMessage *_mes){
+void OSCClass::setReceiveMessage(OSCMessage *_mes) {
+    
     receiverMessage = _mes;
 }
 
-void OSCClass::onUDPSocketEvent(UDPSocketEvent e)
-{
-  switch(e)
-  {
-  case UDPSOCKET_READABLE: //The only event for now
-    //char buf[256] = {0};
-    Host auxhost;
-    buflength = udpRec.recvfrom( rcvBuff, 256, &auxhost ); // QUESTION: auxhost should be equal to the receiver host I guess...
-    if ( buflength > 0 ) {
+void OSCClass::onUDPSocketEvent(UDPSocketEvent e) {
+    
+  switch(e) {
+      
+      case UDPSOCKET_READABLE: //The only event for now
+        //char buf[256] = {0};
+            Host auxhost;
+            buflength = udpRec.recvfrom( rcvBuff, 128, &auxhost ); // QUESTION: auxhost should be equal to the receiver host I guess...
+            if ( buflength > 0 ) {
       //printf("\r\nFrom %d.%d.%d.%d:\r\n", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3]);   
-      decodePacket(receiverMessage); // convert to OSC message, and save it in receiverMessage
-      newMessage=true;
+                decodePacket(receiverMessage); // convert to OSC message, and save it in receiverMessage
+                newMessage = true;
       
-      messageReceivedCallback.call();
-    }
-  break;
-  }
+                messageReceivedCallback.call();
+            }
+            
+            break;
+        }
 }
 
 /*
  Decode UDP packet and save it in the OSCMessage structure
  */
 void OSCClass::decodePacket( OSCMessage *_mes) {
-    
+    int i, j;
     //uint16_t    lenBuff;
     uint8_t        d;    
-    uint8_t        messagePos=0;    
-    uint8_t        adrCount=0;
-    uint8_t        adrMesPos=0;    
-    uint8_t        packetCount=0;
-    uint8_t        packetPos=4;
+    uint8_t        messagePos = 0;    
+    uint8_t        adrCount = 0;
+    uint8_t        adrMesPos = 0;    
+    uint8_t        packetCount = 0;
+    uint8_t        packetPos = 4;
     
     
     //W5100.writeSn(socketNo, SnIR, SnIR::RECV);
     //lenBuff=recvfrom(socketNo, rcvBuff, 1, receiverMessage->ip, &receiverMessage->port);    
     
-    receiverMessage->address[0]=tempAddress[0];
+    receiverMessage->address[0] = tempAddress[0];
 
     //(1) address process start =========================================
-    do{
-        d=rcvBuff[messagePos];
-
+    do {
+        d = rcvBuff[messagePos];
         
-        if( (d=='/') && (messagePos>0) ){
+        if ( (d == '/') && (messagePos > 0) ) {
 
-            if(adrCount<MAX_ADDRESS){
-                tempAddress[adrCount][adrMesPos]=0;
+            if (adrCount < MAX_ADDRESS) {
+                
+                tempAddress[adrCount][adrMesPos] = 0;
 
-                adrCount++;
-                adrMesPos=0;
+                ++adrCount;
+                adrMesPos = 0;
 
-                receiverMessage->address[adrCount]=tempAddress[adrCount];
+                receiverMessage->address[adrCount] = tempAddress[adrCount];
             }
 
         }
         
-        if(adrCount<MAX_ADDRESS){
-        //Added this in to remove the slashes out of final output
-        if(d!='/'){
-        tempAddress[adrCount][adrMesPos]=d;            
+        if (adrCount < MAX_ADDRESS) {
+            //Added this in to remove the slashes out of final output
+            if (d != '/') {
+                
+                tempAddress[adrCount][adrMesPos]=d;            
     
-        if(packetCount>3)  {
-            packetCount=0;
-            packetPos+=4;
+                if (packetCount > 3) {
+                    
+                    packetCount = 0;
+                    packetPos += 4;
+                }
+        
+                ++adrMesPos;
+            }
         }
         
-        adrMesPos++;
-        }
-        }
-        messagePos++;
-        packetCount++;
+        ++messagePos;
+        ++packetCount;
         
-    }while(d!=0);
+    } while(d != 0);
 
     
-    if(adrCount<MAX_ADDRESS) adrCount++;
-    receiverMessage->addressNum=adrCount;
+    if (adrCount < MAX_ADDRESS) {
+        ++adrCount;  
+    }
     
-    messagePos=packetPos;
+    receiverMessage->addressNum = adrCount;
+    
+    messagePos = packetPos;
 
     //(2) type tag process starts =========================================
-    packetCount=0;
-    packetPos+=4;
+    packetCount = 0;
+    packetPos += 4;
 
-    uint8_t  typeTagPos=0;
-    uint8_t     tempArgNum=0;
+    uint8_t  typeTagPos = 0;
+    uint8_t  tempArgNum = 0;
 
-    while(rcvBuff[messagePos]!=0 ){
+    while(rcvBuff[messagePos] != 0) {
             
-        if(rcvBuff[messagePos] != ',') {
-        
-                if(typeTagPos<MAX_ARG){
-                    receiverMessage->typeTag[tempArgNum]=rcvBuff[messagePos];
-                    tempArgNum++;
-                }
-                typeTagPos++;
+        if (rcvBuff[messagePos] != ',') {
+            
+            if (typeTagPos < MAX_ARG) {
+                    
+                receiverMessage->typeTag[tempArgNum] = rcvBuff[messagePos];
+                ++tempArgNum;
+            }
                 
-            }
-        
-        packetCount++;
-        
-        if(packetCount>3)  {
-            packetCount=0;
-            packetPos+=4;
+            ++typeTagPos;
+                
         }
         
-        messagePos++;
+        ++packetCount;
+        
+        if (packetCount > 3) {
+            
+            packetCount = 0;
+            packetPos += 4;
+        }
+        
+        ++messagePos;
     }
     
-    receiverMessage->argNum=tempArgNum;
+    receiverMessage->argNum = tempArgNum;
 
-    messagePos=packetPos;
+    messagePos = packetPos;
 
     //(3) tempArg process starts =========================================
-    for(int i=0;i<tempArgNum;i++){
+    for (i = 0; i < tempArgNum; ++i) {
         
-        adrMesPos=3;
+        adrMesPos = 3;
 
-        receiverMessage->arg[i]=tempArg[i];
+        receiverMessage->arg[i] = tempArg[i];
     
-        for(int j=0;j<4;j++){
+        for (j = 0; j < 4; ++j) {
 
-            tempArg[i][adrMesPos]=rcvBuff[messagePos];
+            tempArg[i][adrMesPos] = rcvBuff[messagePos];
 
-            messagePos++;
-            adrMesPos--;
+            ++messagePos;
+            --adrMesPos;
         }
     
     }
-
-
 }
 
 
 
-OSCMessage * OSCClass::getMessage(){
-    newMessage=false; // this indicate the user READ the message
+OSCMessage * OSCClass::getMessage() {
+    
+    newMessage = false; // this indicate the user READ the message
     return receiverMessage;
 }
 
 
-void OSCClass::sendOsc( OSCMessage *_mes )
-{
+void OSCClass::sendOsc( OSCMessage *_mes ) {
+    int i, j;
     uint8_t lengthEnd;
     uint8_t lengthStart;    
     char  buff[128];
+    bool strCheck = false;
     
     sendContainer = _mes;
     
-    //&#12496;&#12483;&#12501;&#12449;&#21021;&#26399;&#20516;
-    buff[0]=0;
+    buff[0] = '\0';
     
     //1) Add name spaces:
-    for(int i=0;i<sendContainer->addressNum;i++){
+    for (i = 0; i < sendContainer->addressNum; ++i) {
         
-        strcat(buff,sendContainer->address[i]); // note: an address is for instance: "/test" (including the "/")
-        
+        strcat(buff, sendContainer->address[i]); // note: an address is for instance: "/test" (including the "/")
     }
 
     // pad with 0s to align in multiples of 4:
-    lengthStart=strlen(buff);
-    lengthEnd=lengthStart+(4-(lengthStart%4));
-    for(int i=lengthStart ; i<lengthEnd; i++){
-        buff[i]=0;  
+    lengthStart = strlength(buff);
+    
+    lengthEnd = lengthStart + (4 - (lengthStart % 4));
+    
+    for (i = lengthStart; i < lengthEnd; ++i) {
+        
+        buff[i] = '\0';  
     }
 
-    lengthStart=lengthEnd;
+    lengthStart = lengthEnd;
     
     //2) Add TypeTag:
-    buff[lengthEnd++]=','; // Note: type tag is for instance: ",if"
-    for(int i=0;i<sendContainer->argNum;i++){
-        buff[lengthEnd++]=sendContainer->typeTag[i];
+    buff[lengthEnd++] = ','; // Note: type tag is for instance: ",if"
+    
+    for (i = 0; i < sendContainer->argNum; ++i) {
+        
+        buff[lengthEnd++] = sendContainer->typeTag[i];
+        
+        if (sendContainer->typeTag[i] == 's') {
+            
+            strCheck = true;
+        }
     }
     
     // pad with 0s to align in multiples of 4:
-    lengthStart=lengthEnd;
-    lengthEnd=lengthStart+(4-(lengthStart%4));
-    for(int i=lengthStart ; i<lengthEnd; i++){
-        buff[i]=0;
+    lengthStart = lengthEnd;
+    
+    lengthEnd = lengthStart + (4 - (lengthStart % 4));
+    
+    for (i = lengthStart; i < lengthEnd; ++i) {
+        
+        buff[i] = '\0';
     }
     
     //3) add argument values (Note: here only big endian):
     uint8_t *v;
-    for(int i=0;i<sendContainer->argNum;i++){
-        uint8_t valuePos=3;
-        v=(uint8_t *)sendContainer->arg[i];
-
-        buff[lengthEnd++]=v[valuePos--];
-        buff[lengthEnd++]=v[valuePos--];
-        buff[lengthEnd++]=v[valuePos--];
-        buff[lengthEnd++]=v[valuePos]; 
+    
+    for (i = 0; i < sendContainer->argNum; ++i) {
         
+        if (!strCheck) {
+            
+            v = (uint8_t *)&sendContainer->arg[i];
+            
+            buff[lengthEnd++] = v[3];
+            buff[lengthEnd++] = v[2];
+            buff[lengthEnd++] = v[1];
+            buff[lengthEnd++] = v[0];
+            
+        } else {
+            
+            v = (uint8_t *)sendContainer->arg[i];
+            
+            for (j = 0; j < 16; ++j) {    
+                
+                buff[lengthEnd++] = v[j];
+            }
+            
+            strCheck = false;
+        }
     }
     
     //4) Send udp packet: