modded version CNMAT/OSC https://github.com/CNMAT/OSC

Dependents:   CVtoOSCConverter

Fork of osc-cnmat by Asperius van Hansen

Revision:
1:18009e3041ea
Child:
2:61caa2495215
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OSCMessage.h	Fri May 16 22:10:49 2014 +0000
@@ -0,0 +1,330 @@
+/*
+ Written by Yotam Mann, The Center for New Music and Audio Technologies,
+ University of California, Berkeley.  Copyright (c) 2012, The Regents of
+ the University of California (Regents).
+ 
+ Permission to use, copy, modify, distribute, and distribute modified versions
+ of this software and its documentation without fee and without a signed
+ licensing agreement, is hereby granted, provided that the above copyright
+ notice, this paragraph and the following two paragraphs appear in all copies,
+ modifications, and distributions.
+ 
+ IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+ OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+ BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+ REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+ HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ 
+ For bug reports and feature requests please email me at yotam@cnmat.berkeley.edu
+ */
+
+#ifndef OSCMESSAGE_h
+#define OSCMESSAGE_h
+
+#include "OSCData.h"
+//#include <Print.h>
+
+
+class OSCMessage
+{
+    
+private:
+    
+    //friends
+    friend class OSCBundle;
+
+
+/*=============================================================================
+    PRIVATE VARIABLES
+=============================================================================*/
+
+    //the address
+    char * address;
+
+    //the data
+    OSCData ** data;
+
+    //the number of OSCData in the data array
+    int dataCount;
+
+    //error codes for potential runtime problems
+    OSCErrorCode error;
+    
+/*=============================================================================
+    DECODING INCOMING BYTES
+ =============================================================================*/
+    
+    //the decoding states for incoming bytes
+    enum DecodeState {
+        STANDBY,
+        ADDRESS,
+        ADDRESS_PADDING,
+        TYPES,
+        TYPES_PADDING,
+        DATA,
+        DATA_PADDING,
+        DONE,
+    } decodeState;
+    
+    //stores incoming bytes until they can be decoded
+    uint8_t * incomingBuffer;
+    int incomingBufferSize; // how many bytes are stored
+    int incomingBufferFree; // how many bytes are allocated but unused
+    
+    //adds a byte to the buffer
+    void addToIncomingBuffer(uint8_t);
+    //clears the incoming buffer
+    void clearIncomingBuffer();
+    
+    //decoding function
+    void decode(uint8_t);
+    void decodeAddress();
+    void decodeType(uint8_t);
+    void decodeData(uint8_t);
+
+/*=============================================================================
+    HELPER FUNCTIONS
+=============================================================================*/
+
+    void setupMessage();
+
+    //compares the OSCData's type char to a test char
+    bool testType(int position, char type);
+
+    //returns the number of bytes to pad to make it 4-bit aligned
+    //  int padSize(int bytes);
+    
+public:
+
+    //returns the OSCData at that position
+    OSCData * getOSCData(int);
+
+/*=============================================================================
+    CONSTRUCTORS / DESTRUCTOR
+=============================================================================*/
+    
+    //new constructor needs an address
+    OSCMessage (const char * _address);
+    //no address
+    //placeholder since it's invalide OSC
+    OSCMessage();
+    
+    //can optionally accept all of the data after the address
+    //OSCMessage(const char * _address, char * types, ... );
+    //created from another OSCMessage
+    OSCMessage (OSCMessage *);
+
+    //DESTRUCTOR
+    ~OSCMessage();
+
+    //empties all of the data
+    void empty();
+
+/*=============================================================================
+    SETTING  DATA
+=============================================================================*/
+
+    //returns the OSCMessage so that multiple 'add's can be strung together
+    template <typename T> 
+    OSCMessage& add(T datum){
+        //make a piece of data
+        OSCData * d = new OSCData(datum);
+        //check if it has any errors
+        if (d->error == ALLOCFAILED){
+            error = ALLOCFAILED;
+        } else {
+            //resize the data array
+            OSCData ** dataMem = (OSCData **) realloc(data, sizeof(OSCData *) * (dataCount + 1));
+            if (dataMem == NULL){
+                error = ALLOCFAILED;
+            } else {
+                data = dataMem;
+                //add data to the end of the array
+                data[dataCount] = d;
+                //increment the data size
+                dataCount++;
+            }
+        }
+        return *this;
+    }
+    
+    //blob specific add
+    OSCMessage& add(uint8_t * blob, int length){
+        //make a piece of data
+        OSCData * d = new OSCData(blob, length);
+        //check if it has any errors
+        if (d->error == ALLOCFAILED){
+            error = ALLOCFAILED;
+        } else {
+            //resize the data array
+            OSCData ** dataMem = (OSCData **) realloc(data, sizeof(OSCData *) * (dataCount + 1));
+            if (dataMem == NULL){
+                error = ALLOCFAILED;
+            } else {
+                data = dataMem;
+                //add data to the end of the array
+                data[dataCount] = d;
+                //increment the data size
+                dataCount++;
+            }
+        }
+        return *this;
+    }
+
+    //sets the data at a position
+    template <typename T> 
+    void set(int position, T datum){
+        if (position < dataCount){
+            //replace the OSCData with a new one
+            OSCData * oldDatum = getOSCData(position);
+            //destroy the old one
+            delete oldDatum;
+            //make a new one
+            OSCData * newDatum = new OSCData(datum);
+            //test if there was an error
+            if (newDatum->error == ALLOCFAILED){
+                error = ALLOCFAILED;
+            } else {
+                //otherwise, put it in the data array
+                data[position] = newDatum;
+            }
+        } else if (position == (dataCount)){
+            //add the data to the end
+            add(datum);
+        } else {
+            //else out of bounds error
+            error = INDEX_OUT_OF_BOUNDS;
+        }
+    }
+    
+    //blob specific setter
+    void set(int position, uint8_t * blob, int length){
+        if (position < dataCount){
+            //replace the OSCData with a new one
+            OSCData * oldDatum = getOSCData(position);
+            //destroy the old one
+            delete oldDatum;
+            //make a new one
+            OSCData * newDatum = new OSCData(blob, length);
+            //test if there was an error
+            if (newDatum->error == ALLOCFAILED){
+                error = ALLOCFAILED;
+            } else {
+                //otherwise, put it in the data array
+                data[position] = newDatum;
+            }
+        } else if (position == (dataCount)){
+            //add the data to the end
+            add(blob, length);
+        } else {
+            //else out of bounds error
+            error = INDEX_OUT_OF_BOUNDS;
+        }
+    }
+    
+    void setAddress(const char *);
+
+/*=============================================================================
+    GETTING DATA
+
+    getters take a position as an argument
+=============================================================================*/
+
+    int32_t getInt(int);
+    uint64_t getTime(int);
+
+    float getFloat(int);
+    double getDouble(int);
+    bool getBoolean(int);
+
+    //return the copied string's length
+    int getString(int, char *, int);
+    //returns the number of unsigned int8's copied into the buffer
+    int getBlob(int, uint8_t *, int);
+
+    //returns the number of bytes of the data at that position
+    int getDataLength(int);
+
+    //returns the type at the position
+    char getType(int);
+
+    //put the address in the buffer
+    int getAddress(char * buffer, int offset = 0);
+    int getAddress(char * buffer, int offset, int len);
+    
+    // TODO: int getAddressLength(int offset = 0);
+    
+
+/*=============================================================================
+    TESTING DATA
+
+    testers take a position as an argument
+=============================================================================*/
+
+    bool isInt(int);
+    bool isFloat(int);
+    bool isBlob(int);
+    bool isChar(int);
+    bool isString(int);
+    bool isDouble(int);
+    bool isBoolean(int);
+    bool isTime(int);
+        
+/*=============================================================================
+    PATTERN MATCHING
+=============================================================================*/
+    
+    //match the pattern against the address
+    //returns true only for a complete match
+    bool fullMatch( const char * pattern, int = 0);
+    
+    //returns the number of characters matched in the address
+    int match( const char * pattern, int = 0);
+    
+    //calls the function with the message as the arg if it was a full match
+    bool dispatch(const char * pattern, void (*callback)(OSCMessage &), int = 0);
+    
+    //like dispatch, but allows for partial matches
+    //the address match offset is sent as an argument to the callback
+    //also room for an option address offset to allow for multiple nested routes
+    bool route(const char * pattern, void (*callback)(OSCMessage &, int), int = 0);
+    
+
+
+/*=============================================================================
+    SIZE
+=============================================================================*/
+    
+    //the number of data that the message contains
+    int size();
+    
+    //computes the number of bytes the OSCMessage occupies if everything is 32-bit aligned
+    int bytes();
+    
+/*=============================================================================
+    TRANSMISSION
+ =============================================================================*/
+    
+    //send the message
+//    void send(Print &p);
+    
+    //fill the message from a byte stream
+    void fill(uint8_t);
+    void fill(uint8_t *, int);
+        
+/*=============================================================================
+    ERROR
+=============================================================================*/
+
+    bool hasError();
+
+    OSCErrorCode getError();
+
+};
+
+#endif
\ No newline at end of file