123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- #include "OSCBundle.h"
- #include <stdlib.h>
-
- OSCBundle::OSCBundle(osctime_t _timetag){
- setTimetag(_timetag);
- numMessages = 0;
- error = OSC_OK;
- messages = NULL;
- incomingBuffer = NULL;
- incomingBufferSize = 0;
- decodeState = STANDBY;
- }
- OSCBundle::~OSCBundle(){
- for (int i = 0; i < numMessages; i++){
- OSCMessage * msg = getOSCMessage(i);
- delete msg;
- }
- free(messages);
- free(incomingBuffer);
- }
- OSCBundle& OSCBundle::empty(){
- error = OSC_OK;
- for (int i = 0; i < numMessages; i++){
- OSCMessage * msg = getOSCMessage(i);
- delete msg;
- }
- free(messages);
- messages = NULL;
- clearIncomingBuffer();
- numMessages = 0;
- return *this;
- }
- OSCMessage & OSCBundle::add(const char * _address){
- OSCMessage * msg = new OSCMessage(_address);
- if (!msg->hasError()){
-
- OSCMessage ** messageMem = (OSCMessage **) realloc(messages, sizeof(OSCMessage *) * (numMessages + 1));
- if (messageMem != NULL){
- messages = messageMem;
- messages[numMessages] = msg;
- numMessages++;
- } else {
- error = ALLOCFAILED;
- }
- }
- return *msg;
- }
- OSCMessage & OSCBundle::add(){
- OSCMessage * msg = new OSCMessage();
-
- OSCMessage ** messageMem = (OSCMessage **) realloc(messages, sizeof(OSCMessage *) * (numMessages + 1));
- if (messageMem != NULL){
- messages = messageMem;
- messages[numMessages] = msg;
- numMessages++;
- } else {
- error = ALLOCFAILED;
- }
- return *msg;
- }
- OSCMessage & OSCBundle::add(OSCMessage & _msg){
- OSCMessage * msg = new OSCMessage(&_msg);
- if (!msg->hasError()){
-
- OSCMessage ** messageMem = (OSCMessage **) realloc(messages, sizeof(OSCMessage *) * (numMessages + 1));
- if (messageMem != NULL){
- messages = messageMem;
- messages[numMessages] = msg;
- numMessages++;
- } else {
- error = ALLOCFAILED;
- }
- }
- return *msg;
- }
- OSCMessage * OSCBundle::getOSCMessage( char * addr){
- for (int i = 0; i < numMessages; i++){
- OSCMessage * msg = getOSCMessage(i);
- if (msg->fullMatch(addr)){
- return msg;
- }
- }
- return NULL;
- }
- OSCMessage * OSCBundle::getOSCMessage(int pos){
- if (pos < numMessages){
- return messages[pos];
- }
- return NULL;
- }
- bool OSCBundle::dispatch(const char * pattern, void (*callback)(OSCMessage&), int initial_offset){
- bool called = false;
- for (int i = 0; i < numMessages; i++){
- OSCMessage msg = getOSCMessage(i);
- called = msg.dispatch(pattern, callback, initial_offset) || called ;
- }
- return called;
- }
- bool OSCBundle::route(const char * pattern, void (*callback)(OSCMessage&, int), int initial_offset){
- bool called = false;
- for (int i = 0; i < numMessages; i++){
- OSCMessage msg = getOSCMessage(i);
- called = msg.route(pattern, callback, initial_offset) || called;
- }
- return called;
- }
- int OSCBundle::size(){
- return numMessages;
- }
- bool OSCBundle::hasError(){
- bool retError = error != OSC_OK;
-
- for (int i = 0; i < numMessages; i++){
- OSCMessage * msg = getOSCMessage(i);
- retError |= msg->hasError();
- }
- return retError;
- }
- OSCErrorCode OSCBundle::getError(){
- return error;
- }
- OSCBundle& OSCBundle::send(Print &p){
-
- if (hasError()){
- return *this;
- }
-
- static uint8_t header[] = {'#', 'b', 'u', 'n', 'd', 'l', 'e', 0};
- p.write(header, 8);
-
- {
- osctime_t time = timetag;
- uint32_t d = BigEndian(time.seconds);
- uint8_t * ptr = (uint8_t *) &d;
- p.write(ptr, 4);
- d = BigEndian(time.fractionofseconds);
- ptr = (uint8_t *) &d;
- p.write(ptr, 4);
- }
-
- for (int i = 0; i < numMessages; i++){
- OSCMessage * msg = getOSCMessage(i);
- int msgSize = msg->bytes();
-
- uint32_t s32 = BigEndian((uint32_t) msgSize);
- uint8_t * sptr = (uint8_t *) &s32;
-
- p.write(sptr, 4);
- msg->send(p);
- }
- return *this;
- }
- OSCBundle& OSCBundle::fill(uint8_t incomingByte){
- decode(incomingByte);
- return *this;
- }
- OSCBundle& OSCBundle::fill(const uint8_t * incomingBytes, int length){
- while (length--){
- decode(*incomingBytes++);
- }
- return *this;
- }
- void OSCBundle::decodeTimetag(){
-
- setTimetag(incomingBuffer);
-
-
- decodeState = MESSAGE_SIZE;
- clearIncomingBuffer();
- }
- void OSCBundle::decodeHeader(){
- const char * header = "#bundle";
- if (strcmp(header, (char *) incomingBuffer)!=0){
-
- decodeState = STANDBY;
- error = INVALID_OSC;
- } else {
- decodeState = TIMETAG;
- }
- clearIncomingBuffer();
- }
- void OSCBundle::decodeMessage(uint8_t incomingByte){
-
- if (numMessages > 0){
- OSCMessage * lastMessage = messages[numMessages - 1];
-
- lastMessage->fill(incomingByte);
-
- if (incomingBufferSize == incomingMessageSize){
-
- decodeState = MESSAGE_SIZE;
- clearIncomingBuffer();
- } else if (incomingBufferSize > incomingMessageSize){
- error = INVALID_OSC;
- }
- }
- }
- void OSCBundle::decode(uint8_t incomingByte){
- addToIncomingBuffer(incomingByte);
- switch (decodeState){
- case STANDBY:
- if (incomingByte == '#'){
- decodeState = HEADER;
- } else if (incomingByte == '/'){
- add();
- decodeMessage(incomingByte);
- decodeState = MESSAGE;
- }
- break;
- case HEADER:
- if (incomingBufferSize == 8){
- decodeHeader();
- decodeState = TIMETAG;
- }
- break;
- case TIMETAG:
- if (incomingBufferSize == 8){
- decodeTimetag();
- decodeState = MESSAGE_SIZE;
- }
- break;
- case MESSAGE_SIZE:
- if (incomingBufferSize == 4){
-
- int32_t msgSize;
- memcpy(&msgSize, incomingBuffer, 4);
- msgSize = BigEndian(msgSize);
- if (msgSize % 4 != 0 || msgSize == 0){
- error = INVALID_OSC;
- } else {
-
- decodeState = MESSAGE;
- incomingMessageSize = msgSize;
- clearIncomingBuffer();
-
- add();
- }
- }
- break;
- case MESSAGE:
- decodeMessage(incomingByte);
- break;
- }
- }
- void OSCBundle::addToIncomingBuffer(uint8_t incomingByte){
-
- incomingBuffer = (uint8_t *) realloc ( incomingBuffer, incomingBufferSize + 1);
- if (incomingBuffer != NULL){
- incomingBuffer[incomingBufferSize++] = incomingByte;
- } else {
- error = ALLOCFAILED;
- }
- }
- void OSCBundle::clearIncomingBuffer(){
- incomingBufferSize = 0;
- free(incomingBuffer);
- incomingBuffer = NULL;
- }
|