/* ============================================================================== This file is part of the JUCETICE project - Copyright 2009 by Lucio Asnaghi. JUCETICE is based around the JUCE library - "Jules' Utility Class Extensions" Copyright 2007 by Julian Storer. ------------------------------------------------------------------------------ JUCE and JUCETICE can be redistributed and/or modified under the terms of the GNU General Public License, as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. JUCE and JUCETICE are distributed in the hope that they will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with JUCE and JUCETICE; if not, visit www.gnu.org/licenses or write to Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ============================================================================== This file is based around Niall Moody's OSC/UDP library, but was modified to be more independent and modularized, using the best practices from JUCE. ============================================================================== */ #ifdef WIN32 #include #else #include #endif BEGIN_JUCE_NAMESPACE //------------------------------------------------------------------------------ OpenSoundMessage::OpenSoundMessage() : OpenSoundBase(), bufferSize(0), outgoingSize(0), buffer(0) { typeTag = ","; } //------------------------------------------------------------------------------ OpenSoundMessage::OpenSoundMessage(char *data, const int size) : OpenSoundBase(), bufferSize(0), outgoingSize(0), buffer(0) { int i; GetTheBytes tempBytes; int32 tempint; float *tempf; String tempstr; //This represents which part of the Message we're currently reading from. int currentSection = 0; int currentTag = 1; //Because Type Tags start with ','. for(i=0;i= static_cast(typeTag.length())) break; else if(typeTag[currentTag] == 'f') { tempBytes.a = data[i]; ++i; tempBytes.b = data[i]; ++i; tempBytes.c = data[i]; ++i; tempBytes.d = data[i]; tempint = ntohl(*(reinterpret_cast(&tempBytes))); tempf = reinterpret_cast(&tempint); floatArray.add (*tempf); ++currentTag; } else if(typeTag[currentTag] == 'i') { tempBytes.a = data[i]; ++i; tempBytes.b = data[i]; ++i; tempBytes.c = data[i]; ++i; tempBytes.d = data[i]; tempint = ntohl(*(reinterpret_cast(&tempBytes))); intArray.add (tempint); ++currentTag; } else if(typeTag[currentTag] == 's') { tempstr = ""; while(data[i] != 0) { tempstr += data[i]; ++i; } //@TODO //Not sure with this, it was //tempstr[tempstr.length()] = static_cast(NULL); //Terminator. tempstr = tempstr.replaceCharacter (tempstr.getLastCharacter(), static_cast(NULL)); //Terminator. stringArray.add (tempstr); //Handle any padding bytes. while((i%4) != 0) ++i; ++currentTag; } } } } //------------------------------------------------------------------------------ OpenSoundMessage::~OpenSoundMessage() { if(buffer) { delete [] buffer; buffer = 0; } } //------------------------------------------------------------------------------ int32 OpenSoundMessage::getSize() { int32 i; int32 tempint; outgoingSize = 0; if((address.length()+1)%4) { //Because we need space for the padding bytes. tempint = (4 - ((address.length()+1)%4)); outgoingSize += address.length() + 1; outgoingSize += tempint; } else outgoingSize += address.length() + 1; //+1 = Null terminator. if((typeTag.length()+1)%4) { //Because we need space for the padding bytes. tempint = (4 - ((typeTag.length()+1)%4)); outgoingSize += typeTag.length() + 1; outgoingSize += tempint; } else outgoingSize += typeTag.length() + 1; //+1 = Null terminator. outgoingSize += intArray.size() * sizeof(int32); outgoingSize += floatArray.size() * sizeof(float); for(i=0;i(stringArray.size());++i) { if((stringArray[i].length()+1)%4) { //Because we need space for the padding bytes. tempint = (4 - ((stringArray[i].length()+1)%4)); outgoingSize += stringArray[i].length() + 1; outgoingSize += tempint; } else outgoingSize += stringArray[i].length() + 1; //+1 = Null terminator. } if(outgoingSize > bufferSize) { bufferSize = outgoingSize; if(buffer) { delete [] buffer; buffer = 0; } buffer = new char[bufferSize]; } return outgoingSize; } //------------------------------------------------------------------------------ char *OpenSoundMessage::getData() { int32 addressCount = 0; int32 typeTagCount = 0; int32 intCount = 0; int32 floatCount = 0; int32 stringCount = 0; int32 currentTypeTag = 1; int32 i, j; GetTheBytes *tempBytes; int32 tempInt; float tempFloat; int32 addressLength = static_cast(address.length()); int32 typeTagLength = static_cast(typeTag.length()); int32 stringLength; if(!buffer) return 0; for(i=0;i(NULL); ++addressCount; //Add any packing bytes. while(addressCount%4) { ++i; buffer[i] = static_cast(NULL); ++addressCount; } } } //If we're currently writing the type tag to the buffer. else if(typeTagCount < (typeTagLength + 1)) { buffer[i] = typeTag[typeTagCount]; ++typeTagCount; if(typeTagCount == typeTagLength) { ++i; buffer[i] = static_cast(NULL); ++typeTagCount; //Add any packing bytes. while(typeTagCount%4) { ++i; buffer[i] = static_cast(NULL); ++typeTagCount; } } } //If we're currently writing part of the data to the buffer. else if(currentTypeTag < typeTagLength) { //Determine what kind of data we should be writing to the buffer. switch(typeTag[currentTypeTag]) { //If we're writing an integer to the buffer. case 'i': tempInt = htonl(intArray[intCount]); tempBytes = reinterpret_cast(&tempInt); buffer[i] = tempBytes->a; ++i; buffer[i] = tempBytes->b; ++i; buffer[i] = tempBytes->c; ++i; buffer[i] = tempBytes->d; ++intCount; break; //If we're writing a float to the buffer. case 'f': { tempFloat = floatArray[floatCount]; int32* const _i((int32*)&tempFloat); tempInt = htonl(*_i); tempBytes = reinterpret_cast(&tempInt); buffer[i] = tempBytes->a; ++i; buffer[i] = tempBytes->b; ++i; buffer[i] = tempBytes->c; ++i; buffer[i] = tempBytes->d; ++floatCount; break; } //If we're writing an OSC String to the buffer. case 's': stringLength = static_cast(stringArray[stringCount].length()); for(j=1;j(NULL); //Add any packing bytes. while(j%4) { ++i; buffer[i] = static_cast(NULL); ++j; } ++stringCount; break; } //Move on to the next tag in the message's type tag list. ++currentTypeTag; } } i = i; return buffer; } //------------------------------------------------------------------------------ void OpenSoundMessage::clearMessage() { outgoingSize = 0; typeTag = ","; intArray.clear(); floatArray.clear(); stringArray.clear(); } //------------------------------------------------------------------------------ void OpenSoundMessage::setAddress(const String& val) { address = val; } //------------------------------------------------------------------------------ void OpenSoundMessage::addInt32(const int32 val) { typeTag += 'i'; intArray.add (val); } //------------------------------------------------------------------------------ void OpenSoundMessage::addFloat32(const float val) { typeTag += 'f'; floatArray.add (val); } //------------------------------------------------------------------------------ void OpenSoundMessage::addOscString(const String& val) { typeTag += 's'; stringArray.add (val); } //------------------------------------------------------------------------------ bool OpenSoundMessage::isMessage(char *data, const int size) { int i; bool retval = false; //All OSC Messages start with the OSC address, which always starts with '/'. if(data[0] == '/') { for(i=1;i