private static OscMessage parseMessage(byte[] msg)
{
int index = 0;
string address = null;
char[] types = new char[0];
List<object> arguments = new List<object>();
List<object> mainArray = arguments; // used as a reference when we are parsing arrays to get the main array back
// Get address
address = getAddress(msg, index);
index += msg.FirstIndexAfter(address.Length, x => x == ',');
if (index % 4 != 0)
throw new Exception("Misaligned OSC Packet data. Address string is not padded correctly and does not align to 4 byte interval");
// Get type tags
types = getTypes(msg, index);
index += types.Length;
while (index % 4 != 0)
index++;
bool commaParsed = false;
foreach (char type in types)
{
// skip leading comma
if (type == ',' && !commaParsed)
{
commaParsed = true;
continue;
}
switch(type)
{
case ('\0'):
break;
case('i'):
int intVal = getInt(msg, index);
arguments.Add(intVal);
index += 4;
break;
case('f'):
float floatVal = getFloat(msg, index);
arguments.Add(floatVal);
index += 4;
break;
case('s'):
string stringVal = getString(msg, index);
arguments.Add(stringVal);
index += stringVal.Length;
break;
case('b'):
byte[] blob = getBlob(msg, index);
arguments.Add(blob);
index += 4 + blob.Length;
break;
case ('h'):
Int64 hval = getLong(msg, index);
arguments.Add(hval);
index += 8;
break;
case ('t'):
UInt64 sval = getULong(msg, index);
arguments.Add(new Timetag(sval));
index += 8;
break;
case ('d'):
double dval = getDouble(msg, index);
arguments.Add(dval);
index += 8;
break;
case ('S'):
string SymbolVal = getString(msg, index);
arguments.Add(new Symbol(SymbolVal));
index += SymbolVal.Length;
break;
case ('c'):
char cval = getChar(msg, index);
arguments.Add(cval);
index += 4;
break;
case ('r'):
RGBA rgbaval = getRGBA(msg, index);
arguments.Add(rgbaval);
index += 4;
break;
case ('m'):
Midi midival = getMidi(msg, index);
arguments.Add(midival);
index += 4;
break;
case ('T'):
arguments.Add(true);
break;
case ('F'):
arguments.Add(false);
break;
case ('N'):
arguments.Add(null);
break;
case ('I'):
arguments.Add(double.PositiveInfinity);
break;
case ('['):
if (arguments != mainArray)
throw new Exception("SharopOSC does not support nested arrays");
arguments = new List<object>(); // make arguments point to a new object array
break;
case (']'):
mainArray.Add(arguments); // add the array to the main array
arguments = mainArray; // make arguments point back to the main array
break;
default:
throw new Exception("OSC type tag '" + type + "' is unknown.");
}
while (index % 4 != 0)
index++;
}
return new OscMessage(address, arguments.ToArray());
}