You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
335 lines
6.9 KiB
335 lines
6.9 KiB
|
|
#include "OSCData.h" |
|
|
|
|
|
osctime_t zerotime = {0,0}; |
|
/*============================================================================= |
|
CONSTRUCTORS |
|
|
|
overloaded methods for each of the types which will |
|
set the type flag, the size (in bytes), and the data |
|
=============================================================================*/ |
|
|
|
|
|
OSCData::OSCData(const char * s){ |
|
error = OSC_OK; |
|
type = 's'; |
|
bytes = (strlen(s) + 1); |
|
//own the data |
|
char * mem = (char *) malloc(bytes); |
|
if (mem == NULL){ |
|
error = ALLOCFAILED; |
|
} else { |
|
strcpy(mem, s); |
|
data.s = mem; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
OSCData::OSCData(int32_t i){ |
|
error = OSC_OK; |
|
type = 'i'; |
|
bytes = 4; |
|
data.i = i; |
|
} |
|
#ifndef ESPxx |
|
OSCData::OSCData(int i){ |
|
error = OSC_OK; |
|
type = 'i'; |
|
bytes = 4; |
|
data.i = i; |
|
} |
|
#endif |
|
OSCData::OSCData(unsigned int i){ |
|
error = OSC_OK; |
|
type = 'i'; |
|
bytes = 4; |
|
data.i = i; |
|
} |
|
#if defined(__SAM3X8E__) |
|
OSCData::OSCData(int16_t i){ |
|
error = OSC_OK; |
|
type = 'i'; |
|
bytes = 4; |
|
data.i = i; |
|
} |
|
#endif |
|
|
|
OSCData::OSCData(float f){ |
|
error = OSC_OK; |
|
type = 'f'; |
|
bytes = 4; |
|
data.f = f; |
|
} |
|
|
|
OSCData::OSCData(osctime_t t){ |
|
error = OSC_OK; |
|
type = 't'; |
|
bytes = 8; |
|
data.time = t; |
|
} |
|
OSCData::OSCData(boolean b){ |
|
error = OSC_OK; |
|
type = b?'T':'F'; |
|
bytes = 0; |
|
} |
|
|
|
|
|
OSCData::OSCData(double d){ |
|
error = OSC_OK; |
|
bytes = sizeof(double); |
|
//if it's not 8 bytes it's not a true double |
|
if (bytes == 8){ |
|
type = 'd'; |
|
data.d = d; |
|
} else { |
|
type = 'f'; |
|
data.f = d; |
|
} |
|
} |
|
|
|
OSCData::OSCData(uint8_t * b, int len){ |
|
error = OSC_OK; |
|
type = 'b'; |
|
bytes = len + 4; |
|
//add the size to the front of the blob |
|
uint32_t len32 = (uint32_t) len; |
|
//make sure the length is endian-safe |
|
len32 = BigEndian(len32); |
|
uint8_t * lenPtr = (uint8_t *) (& len32); |
|
//own the data |
|
if(bytes>0) |
|
{ |
|
|
|
uint8_t * mem = (uint8_t * ) malloc(bytes); |
|
if (mem == NULL){ |
|
error = ALLOCFAILED; |
|
} else { |
|
//copy over the blob length |
|
memcpy(mem, lenPtr, 4); |
|
//copy over the blob data |
|
memcpy(mem + 4, b, len); |
|
data.b = mem; |
|
} |
|
} |
|
else |
|
data.b = 0; |
|
} |
|
|
|
OSCData::OSCData (OSCData * datum){ |
|
error = OSC_OK; |
|
type = datum->type; |
|
bytes = datum->bytes; |
|
if ( (type == 'i') || (type == 'f') || (type == 'd') || (type == 't') |
|
|| (type == 'h') || (type == 'c') || (type == 'r') || (type == 'm') |
|
) |
|
{ |
|
data = datum->data; |
|
} else if ((type == 's') || (type == 'b')){ |
|
//allocate a new piece of memory |
|
uint8_t * mem = (uint8_t * ) malloc(bytes); |
|
if (mem == NULL){ |
|
error = ALLOCFAILED; |
|
} else { |
|
//copy over the blob length |
|
memcpy(mem, datum->data.b, bytes); |
|
data.b = mem; |
|
} |
|
} |
|
} |
|
|
|
//DESTRUCTOR |
|
OSCData::~OSCData(){ |
|
//if there are no bytes, there is nothing to free |
|
if (bytes>0){ |
|
//if the data is of type 's' or 'b', need to free that memory |
|
if (type == 's'){ |
|
free(data.s); |
|
}else if( type == 'b'){ |
|
free(data.b); |
|
} |
|
} |
|
} |
|
|
|
//sets just the type as a message placeholder |
|
//no data |
|
OSCData::OSCData(char t){ |
|
error = (t == 'T' || t == 'F') ? OSC_OK : INVALID_OSC; |
|
type = t; |
|
bytes = 0; |
|
} |
|
|
|
/*============================================================================= |
|
GETTERS |
|
|
|
perform a safety check to make sure the data type matches the request |
|
otherwise returns NULL |
|
=============================================================================*/ |
|
|
|
int32_t OSCData::getInt(){ |
|
if (type == 'i'){ |
|
return data.i; |
|
} else { |
|
#ifndef ESPxx |
|
return (int32_t)NULL; |
|
#else |
|
return -1; |
|
#endif |
|
} |
|
} |
|
osctime_t OSCData::getTime(){ |
|
if (type == 't'){ |
|
return data.time; |
|
} else { |
|
|
|
return zerotime; |
|
} |
|
} |
|
float OSCData::getFloat(){ |
|
if (type == 'f'){ |
|
return data.f; |
|
} else { |
|
#ifndef ESPxx |
|
return (float)NULL; |
|
#else |
|
return -1; |
|
#endif |
|
} |
|
} |
|
|
|
double OSCData::getDouble(){ |
|
if (type == 'd'){ |
|
return data.d; |
|
} else { |
|
#ifndef ESPxx |
|
return (double)NULL; |
|
#else |
|
return -1; |
|
#endif |
|
} |
|
} |
|
bool OSCData::getBoolean(){ |
|
if (type == 'T'){ |
|
return true; |
|
} else if (type=='F'){ |
|
return false; |
|
} |
|
else |
|
#ifndef ESPxx |
|
return NULL; |
|
#else |
|
return -1; |
|
#endif |
|
} |
|
|
|
|
|
// no-safety-check straightforward way to fill the passed buffer |
|
// with the received string |
|
int OSCData::getString(char * strBuffer){ |
|
if (type == 's'){ |
|
strncpy(strBuffer, data.s, bytes); |
|
return bytes; |
|
} else { |
|
#ifndef ESPxx |
|
return (int)NULL; |
|
#else |
|
return -1; |
|
#endif |
|
} |
|
} |
|
|
|
// it's possible to pass strBuffer's size as argument (length) |
|
// in order to check that it won't be overflown |
|
int OSCData::getString(char * strBuffer, int length){ |
|
if (type == 's' && bytes <= length){ |
|
strncpy(strBuffer, data.s, bytes); |
|
return bytes; |
|
} else { |
|
#ifndef ESPxx |
|
return (int)NULL; |
|
#else |
|
return -1; |
|
#endif |
|
} |
|
} |
|
|
|
// Here we can get only a part of the string |
|
int OSCData::getString(char * strBuffer, int length, int offset, int size) |
|
{ |
|
int maxLen = bytes - offset; |
|
if (type == 's' && maxLen >= 0 && size <= maxLen && size <= length){ |
|
strncpy(strBuffer, data.s + offset, size); |
|
return size; |
|
} else { |
|
#ifndef ESPxx |
|
return (int)NULL; |
|
#else |
|
return -1; |
|
#endif |
|
} |
|
} |
|
|
|
// no-safety-check straightforward way to fill the passed buffer |
|
// with the contents of the received blob |
|
int OSCData::getBlob(uint8_t * blobBuffer){ |
|
// read the blob length |
|
int blobLength = getBlobLength(); |
|
|
|
if (type == 'b'){ |
|
memcpy(blobBuffer, data.b + 4, blobLength); |
|
return blobLength; |
|
} else { |
|
#ifndef ESPxx |
|
return (int)NULL; |
|
#else |
|
return -1; |
|
#endif |
|
} |
|
} |
|
|
|
// it's possible to pass blobBuffer's size as argument (length) |
|
// in order to check that it won't be overflown |
|
int OSCData::getBlob(uint8_t * blobBuffer, int length){ |
|
//jump over the first 4 bytes which encode the length |
|
int blobLength = bytes-4; |
|
if (type == 'b' && blobLength <= length){ |
|
memcpy(blobBuffer, data.b + 4, blobLength); |
|
return blobLength; |
|
} else { |
|
#ifndef ESPxx |
|
return (int)NULL; |
|
#else |
|
return -1; |
|
#endif |
|
} |
|
} |
|
|
|
// Here we can get only a part of the blob |
|
int OSCData::getBlob(uint8_t * blobBuffer, int length, int offset, int size){ |
|
//jump over the first 4 bytes which encode the length |
|
int blobLength = bytes-4-offset; |
|
if (type == 'b' && blobLength >= 0 && size <= blobLength && size <= length){ |
|
memcpy(blobBuffer, data.b + 4 + offset, size); |
|
return size; |
|
} else { |
|
#ifndef ESPxx |
|
return (int)NULL; |
|
#else |
|
return -1; |
|
#endif |
|
} |
|
} |
|
|
|
const uint8_t* OSCData::getBlob() { |
|
return type == 'b' ? data.b + 4 : NULL; |
|
} |
|
|
|
int OSCData::getBlobLength(){ |
|
if (type == 'b'){ |
|
//jump over the first 4 bytes which encode the length |
|
return bytes-4; |
|
} |
|
return -1; |
|
}
|
|
|