Ibiltari Nora / OSC
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers OSCData.cpp Source File

OSCData.cpp

00001 
00002 #include "OSCData.h"
00003 
00004 
00005 osctime_t zerotime = {0,0};
00006 /*=============================================================================
00007     CONSTRUCTORS
00008 
00009     overloaded methods for each of the types which will
00010     set the type flag, the size (in bytes), and the data
00011 =============================================================================*/
00012 
00013 
00014 OSCData::OSCData(const char * s){
00015     error = OSC_OK;
00016     type = 's';
00017     bytes = (strlen(s) + 1);
00018     //own the data
00019     char * mem = (char *) malloc(bytes);
00020     if (mem == NULL){
00021         error = ALLOCFAILED;
00022     } else {
00023         strcpy(mem, s);
00024         data.s = mem;
00025     }
00026 }
00027 
00028 
00029 
00030 
00031 OSCData::OSCData(int i){
00032     error = OSC_OK;
00033     type = 'i';
00034     bytes = 4;
00035     data.i = i;
00036 }
00037 OSCData::OSCData(long int i){
00038     error = OSC_OK;
00039     type = 'i';
00040     bytes = 4;
00041     data.i = i;
00042 }
00043 
00044 OSCData::OSCData(unsigned int i){
00045     error = OSC_OK;
00046     type = 'i';
00047     bytes = 4;
00048     data.i = i;
00049 }
00050 
00051 
00052 OSCData::OSCData(float f){
00053     error = OSC_OK;
00054     type = 'f';
00055     bytes = 4;
00056     data.f = f;
00057 }
00058 
00059 
00060 OSCData::OSCData(bool b){
00061     error = OSC_OK;
00062     type = b?'T':'F';
00063     bytes = 0;
00064 }
00065 
00066 
00067 OSCData::OSCData(double d){
00068     error = OSC_OK;
00069     bytes = sizeof(double);
00070     //if it's not 8 bytes it's not a true double
00071     if (bytes == 8){
00072         type = 'd';
00073         data.d = d;
00074     } else {
00075         type = 'f';
00076         data.f = d;
00077     }
00078 }
00079 
00080 
00081 OSCData::OSCData(uint8_t * b, int len){
00082     error = OSC_OK;
00083     type = 'b';
00084     bytes = len + 4;
00085     //add the size to the front of the blob
00086     uint32_t len32 = (uint32_t) len;
00087     //make sure the length is endian-safe
00088     len32 = BigEndian(len32);
00089     uint8_t * lenPtr = (uint8_t *) (& len32);
00090     //own the data
00091     if(bytes>0)
00092     {
00093 
00094         uint8_t * mem = (uint8_t * ) malloc(bytes);
00095         if (mem == NULL){
00096             error = ALLOCFAILED;
00097         } else {
00098             //copy over the blob length
00099             memcpy(mem, lenPtr, 4);
00100             //copy over the blob data
00101             memcpy(mem + 4, b, len);
00102             data.b = mem;
00103         }
00104     }
00105     else
00106         data.b = 0;
00107 }
00108 
00109 OSCData::OSCData (OSCData * datum){
00110     error = OSC_OK;
00111     type = datum->type;
00112     bytes = datum->bytes;
00113     if ( (type == 'i') || (type == 'f') || (type == 'd') || (type == 't')
00114         || (type == 'h') || (type == 'c') || (type == 'r') || (type == 'm')
00115         )
00116     {
00117         data = datum->data;
00118     }  else if ((type == 's') || (type == 'b')){
00119         //allocate a new piece of memory
00120         uint8_t * mem = (uint8_t * ) malloc(bytes);
00121         if (mem == NULL){
00122             error = ALLOCFAILED;
00123         } else {
00124             //copy over the blob length
00125             memcpy(mem, datum->data.b, bytes);
00126             data.b = mem;
00127         }
00128     }
00129 }
00130 
00131 //DESTRUCTOR
00132 OSCData::~OSCData(){
00133 
00134     //if there are no bytes, there is nothing to free
00135     if (bytes>0){
00136         //if the data is of type 's' or 'b', need to free that memory
00137         if (type == 's'){
00138             free(data.s);
00139         }else if( type == 'b'){
00140             free(data.b);
00141         }
00142     }
00143 
00144 }
00145 
00146 //sets just the type as a message placeholder
00147 //no data
00148 OSCData::OSCData(char t){
00149     error = INVALID_OSC;
00150     type = t;
00151     bytes = 0;
00152 }
00153 
00154 /*=============================================================================
00155     GETTERS
00156 
00157     perform a safety check to make sure the data type matches the request
00158     otherwise returns NULL
00159 =============================================================================*/
00160 
00161 int32_t OSCData::getInt(){
00162     if (type == 'i'){
00163         return data.i;
00164     } else {
00165         return -1;
00166     }
00167 }
00168 
00169 osctime_t OSCData::getTime(){
00170     if (type == 't'){
00171         return data.time;
00172     } else {
00173 
00174         return zerotime;
00175     }
00176 }
00177 
00178 float OSCData::getFloat(){
00179     if (type == 'f'){
00180         return data.f;
00181     } else {
00182         return -1;
00183     }
00184 }
00185 
00186 double OSCData::getDouble(){
00187     if (type == 'd'){
00188         return data.d;
00189     } else {
00190         return -1;
00191     }
00192 }
00193 bool OSCData::getBoolean(){
00194     if (type == 'T'){
00195         return true;
00196     } else if (type=='F'){
00197         return false;
00198     }else{
00199         return -1;
00200     }
00201 
00202 
00203 }
00204 
00205 
00206 // no-safety-check straightforward way to fill the passed buffer
00207 // with the received string
00208 int OSCData::getString(char * strBuffer){
00209     if (type == 's'){
00210         strncpy(strBuffer, data.s, bytes);
00211         return bytes;
00212     } else {
00213         return -1;
00214     }
00215 }
00216 
00217 // it's possible to pass strBuffer's size as argument (length)
00218 // in order to check that it won't be overflown
00219 int OSCData::getString(char * strBuffer, int length){
00220     if (type == 's' && bytes <= length){
00221         strncpy(strBuffer, data.s, bytes);
00222         return bytes;
00223     } else {
00224         return -1;
00225     }
00226 }
00227 
00228 // Here we can get only a part of the blob
00229 int OSCData::getString(char * strBuffer, int length, int offset, int size){
00230     if (type == 's' && size <= bytes && size <= length){
00231         strncpy(strBuffer, data.s + offset, size);
00232         return size;
00233     } else {
00234         return -1;
00235     }
00236 }
00237 
00238 // no-safety-check straightforward way to fill the passed buffer
00239 // with the contents of the received blob
00240 int OSCData::getBlob(uint8_t * blobBuffer){
00241     // read the blob length
00242     int blobLength =  getBlobLength();
00243 
00244     if (type == 'b'){
00245         memcpy(blobBuffer, data.b + 4, blobLength);
00246         return blobLength;
00247     } else {
00248         return -1;
00249     }
00250 }
00251 
00252 // it's possible to pass blobBuffer's size as argument (length)
00253 // in order to check that it won't be overflown
00254 int OSCData::getBlob(uint8_t * blobBuffer, int length){
00255     //jump over the first 4 bytes which encode the length
00256     int blobLength =  bytes-4;
00257     if (type == 'b' && blobLength <= length){
00258         memcpy(blobBuffer, data.b + 4, blobLength);
00259         return blobLength;
00260     } else {
00261         return -1;
00262     }
00263 }
00264 
00265 // Here we can get only a part of the blob
00266 int OSCData::getBlob(uint8_t * blobBuffer, int length, int offset, int size){
00267     //jump over the first 4 bytes which encode the length
00268     int blobLength =  bytes-4;
00269     if (type == 'b' && size <= blobLength && size <= length){
00270         memcpy(blobBuffer, data.b + 4 + offset, size);
00271         return size;
00272     } else {
00273         return -1;
00274     }
00275 }
00276 
00277 
00278 
00279 int OSCData::getBlobLength(){
00280   if (type == 'b'){
00281     //jump over the first 4 bytes which encode the length
00282     return bytes-4;
00283   }
00284   return -1;
00285 }
00286