modded version CNMAT/OSC https://github.com/CNMAT/OSC
Fork of osc-cnmat by
Revision 4:107c23eb31b6, committed 2016-02-13
- Comitter:
- casiotone401
- Date:
- Sat Feb 13 11:29:14 2016 +0000
- Parent:
- 3:f58c63b78853
- Commit message:
- OSCMessage::send & OSCBundle::send supports return OSC buffer
Changed in this revision
--- a/OSCBundle.cpp Sat May 17 12:42:29 2014 +0000 +++ b/OSCBundle.cpp Sat Feb 13 11:29:14 2016 +0000 @@ -214,10 +214,51 @@ } }*/ +int OSCBundle::send(uint8_t * bundleBuffer){ + int i, j; + //don't send a bundle with errors + if (hasError()){ + return -1; + } + //write the bundle header + static uint8_t header[] = {'#', 'b', 'u', 'n', 'd', 'l', 'e', 0}; + + int idx = 0; + //p.write(header, 8); + for (i = 0; i < 8; i++){ + bundleBuffer[idx++] = header[i]; + } + //write the timetag + uint64_t t64 = BigEndian(timetag); + uint8_t * tptr = (uint8_t *) &t64; + //p.write(tptr, 8); + for (i = 0; i < 8; i++){ + bundleBuffer[idx++] = tptr[i]; + } + //send the messages + for (i = 0; i < numMessages; i++){ + OSCMessage * msg = getOSCMessage(i); + int msgSize = msg->bytes(); + //turn the message size into a pointer + uint32_t s32 = BigEndian((uint32_t) msgSize); + uint8_t * sptr = (uint8_t *) &s32; + //write the messsage size + //p.write(sptr, 4); + for (j = 0; j < 4; j++){ + bundleBuffer[idx++] = sptr[j]; + } + //msg->send(p); + msg->bundleOffset = idx; + idx = msg->send(bundleBuffer); + } + + return idx; +} + /*============================================================================= FILLING =============================================================================*/ - +/* void OSCBundle::fill(uint8_t incomingByte){ decode(incomingByte); } @@ -226,6 +267,10 @@ while (length--){ decode(*incomingBytes++); } + +*/ +void OSCBundle::fill(uint8_t incomingByte){ + decode(incomingByte); } /*=============================================================================
--- a/OSCBundle.h Sat May 17 12:42:29 2014 +0000 +++ b/OSCBundle.h Sat Feb 13 11:29:14 2016 +0000 @@ -67,7 +67,7 @@ //the size of the incoming message int incomingMessageSize; - + //adds a byte to the buffer void addToIncomingBuffer(uint8_t); //clears the incoming buffer @@ -158,15 +158,15 @@ SENDING =============================================================================*/ - //void send(Print &p); + int send(uint8_t *); /*============================================================================= FILLING =============================================================================*/ - void fill(uint8_t incomingByte); + void fill(uint8_t); - void fill(uint8_t * incomingBytes, int length); + //void fill(uint8_t * incomingBytes, int length); }; -#endif \ No newline at end of file +#endif
--- a/OSCMessage.cpp Sat May 17 12:42:29 2014 +0000 +++ b/OSCMessage.cpp Sat Feb 13 11:29:14 2016 +0000 @@ -26,6 +26,22 @@ #include "OSCMessage.h" #include "OSCMatch.h" +// Fast strlen function http://www.strchr.com/optimized_strlen_function +inline size_t strlengthgth(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; + } +} + /*============================================================================= CONSTRUCTORS / DESTRUCTOR =============================================================================*/ @@ -215,7 +231,6 @@ return testType(position, 't'); } - bool OSCMessage::isFloat(int position){ return testType(position, 'f'); } @@ -347,11 +362,11 @@ if (typePad == 0){ typePad = 4; // to make sure the type string is null terminated } - messageSize+=typePad; + messageSize += typePad; //then the data for (int i = 0; i < dataCount; i++){ OSCData * datum = getOSCData(i); - messageSize+=datum->bytes; + messageSize += datum->bytes; messageSize += padSize(datum->bytes); } return messageSize; @@ -458,6 +473,115 @@ } }*/ + +int OSCMessage::send(uint8_t * messageBuffer){ + int i, j; + //don't send a message with errors + if (hasError()){ + return -1; + } + uint8_t nullChar = '\0'; + //send the address + int addrLen = strlen(address) + 1; + //padding amount + int addrPad = padSize(addrLen); + //write it to the stream + //p.write((uint8_t *) address, addrLen); + int addrIdx = 0; + int idx = 0 + bundleOffset; + + while(addrLen--) { + messageBuffer[idx++] = address[addrIdx++]; + } + //add the padding + while(addrPad--){ + //p.write(nullChar); + messageBuffer[idx++] = nullChar; + } + //add the comma seperator + //p.write((uint8_t) ','); + messageBuffer[idx++] = ','; + //add the types +#ifdef PAULSSUGGESTION + // Paul suggested buffering on the stack + // to improve performance. The problem is this could exhaust the stack + // for long complex messages + { + //uint8_t typstr[dataCount]; + + for (i = 0; i < dataCount; i++){ + //typstr[i] = getType(i); + messageBuffer[idx++] = getType(i); + } + //p.write(typstr,dataCount); + } +#else + for (i = 0; i < dataCount; i++){ + //p.write((uint8_t) getType(i)); + messageBuffer[idx++] = getType(i); + } +#endif + //pad the types + int typePad = padSize(dataCount + 1); // 1 is for the comma + + if (typePad == 0) { + typePad = 4; // This is because the type string has to be null terminated + } + + while(typePad--){ + //p.write(nullChar); + messageBuffer[idx++] = nullChar; + } + //write the data + for (i = 0; i < dataCount; i++) { + + OSCData * datum = getOSCData(i); + + if ((datum->type == 's') || (datum->type == 'b')){ + //p.write(datum->data.b, datum->bytes); + for (j = 0; j < datum->bytes; j++) { + messageBuffer[idx++] = datum->data.b[j]; + } + + int dataPad = padSize(datum->bytes); + while(dataPad--){ + //p.write(nullChar); + messageBuffer[idx++] = nullChar; + } + } else if (datum->type == 'd'){ + double d = BigEndian(datum->data.d); + //uint8_t * ptr = (uint8_t *) &d; + uint8_t * ptr = (uint8_t *) &d; + //p.write(ptr, 8); + for (j = 0; j < 8; j++) { + messageBuffer[idx++] = ptr[j]; + } + } else if (datum->type == 't'){ + uint64_t d = BigEndian(datum->data.l); + //uint8_t * ptr = (uint8_t *) &d; + uint8_t * ptr = (uint8_t *) &d; + //p.write(ptr, 8); + for (j = 0; j < 8; j++) { + messageBuffer[idx++] = ptr[j]; + } + } else if (datum->type == 'T' || datum->type == 'F') { + + } else { // float or int + //uint32_t i = BigEndian(datum->data.i); + uint32_t ui = BigEndian(datum->data.i); + //uint8_t * ptr = (uint8_t *) &i; + uint8_t * ptr = (uint8_t *) &ui; + //p.write(ptr, datum->bytes); + for (j = 0; j < datum->bytes; j++) { + messageBuffer[idx++] = ptr[j]; + } + } + } + + bundleOffset = 0; + return idx; +} + /*============================================================================= FILLING =============================================================================*/ @@ -465,13 +589,13 @@ void OSCMessage::fill(uint8_t incomingByte){ decode(incomingByte); } - +/* void OSCMessage::fill(uint8_t * incomingBytes, int length){ while (length--){ decode(*incomingBytes++); } } - +*/ /*============================================================================= DECODING =============================================================================*/ @@ -578,6 +702,7 @@ break; } } + } //does not validate the incoming OSC for correctness @@ -685,4 +810,4 @@ } incomingBufferSize = 0; -} \ No newline at end of file +}
--- a/OSCMessage.h Sat May 17 12:42:29 2014 +0000 +++ b/OSCMessage.h Sat Feb 13 11:29:14 2016 +0000 @@ -44,6 +44,9 @@ PRIVATE VARIABLES =============================================================================*/ + //buffer array index offset for bundle + uint16_t bundleOffset; + //the address char * address; @@ -312,11 +315,11 @@ =============================================================================*/ //send the message - // void send(Stream &p); + int send(uint8_t *); //fill the message from a byte stream void fill(uint8_t); - void fill(uint8_t *, int); + //void fill(uint8_t *, int); /*============================================================================= ERROR @@ -328,4 +331,4 @@ }; -#endif \ No newline at end of file +#endif