323 lines
8.5 KiB
C#
323 lines
8.5 KiB
C#
using System;
|
|
namespace DMX2
|
|
{
|
|
public class OSCMessage
|
|
{
|
|
|
|
public enum OSCType
|
|
{
|
|
Int32,
|
|
Float32,
|
|
String,
|
|
Blob
|
|
}
|
|
|
|
|
|
public abstract class OSCArg
|
|
{
|
|
protected OSCArg() { }
|
|
public abstract OSCType Type { get; }
|
|
public virtual string GetString() { throw new System.NotImplementedException(); }
|
|
public virtual float GetFloat() { throw new System.NotImplementedException(); }
|
|
public virtual int GetInt() { throw new System.NotImplementedException(); }
|
|
public virtual byte[] GetBlob() { throw new System.NotImplementedException(); }
|
|
}
|
|
|
|
private class OSCStringArg : OSCArg
|
|
{
|
|
string _s;
|
|
public override OSCType Type
|
|
{
|
|
get
|
|
{
|
|
return OSCType.String;
|
|
}
|
|
}
|
|
public OSCStringArg(string s)
|
|
{
|
|
_s = s;
|
|
}
|
|
public override string GetString()
|
|
{
|
|
return _s;
|
|
}
|
|
public override float GetFloat()
|
|
{
|
|
float f;
|
|
if (float.TryParse(_s, out f)) return f;
|
|
return 0.0f;
|
|
}
|
|
public override int GetInt()
|
|
{
|
|
return (int)GetFloat();
|
|
}
|
|
}
|
|
private class OSCIntArg : OSCArg
|
|
{
|
|
int _i;
|
|
public override OSCType Type
|
|
{
|
|
get
|
|
{
|
|
return OSCType.Int32;
|
|
}
|
|
}
|
|
public OSCIntArg(int i)
|
|
{
|
|
_i = i;
|
|
}
|
|
public override int GetInt()
|
|
{
|
|
return _i;
|
|
}
|
|
public override float GetFloat()
|
|
{
|
|
return (float)_i;
|
|
}
|
|
public override string GetString()
|
|
{
|
|
return _i.ToString();
|
|
}
|
|
|
|
}
|
|
private class OSCFloatArg : OSCArg
|
|
{
|
|
float _f;
|
|
public override OSCType Type
|
|
{
|
|
get
|
|
{
|
|
return OSCType.Float32;
|
|
}
|
|
}
|
|
public OSCFloatArg(float f)
|
|
{
|
|
_f = f;
|
|
}
|
|
public override int GetInt()
|
|
{
|
|
return (int)(_f);
|
|
}
|
|
public override float GetFloat()
|
|
{
|
|
return _f;
|
|
}
|
|
public override string GetString()
|
|
{
|
|
return _f.ToString();
|
|
}
|
|
|
|
}
|
|
private class OSCBlobArg : OSCArg
|
|
{
|
|
byte[] _b;
|
|
public override OSCType Type
|
|
{
|
|
get
|
|
{
|
|
return OSCType.Blob;
|
|
}
|
|
}
|
|
public OSCBlobArg(byte[] b)
|
|
{
|
|
_b = b;
|
|
}
|
|
public override byte[] GetBlob()
|
|
{
|
|
return _b;
|
|
}
|
|
|
|
}
|
|
|
|
static string DecodeString(byte[] b, ref int pos)
|
|
{
|
|
int end = Array.IndexOf<byte>(b, 0, pos);
|
|
if (end == -1) end = b.Length;
|
|
string ret = System.Text.Encoding.ASCII.GetString(b, pos, end - pos);
|
|
pos = (end / 4 + 1) * 4;
|
|
return ret;
|
|
}
|
|
|
|
static float DecodeFloat(byte[] b, ref int pos)
|
|
{
|
|
if (BitConverter.IsLittleEndian)
|
|
Array.Reverse(b, pos, 4);
|
|
float ret = BitConverter.ToSingle(b, pos);
|
|
pos += 4;
|
|
return ret;
|
|
}
|
|
|
|
static int DecodeInt(byte[] b, ref int pos)
|
|
{
|
|
if (BitConverter.IsLittleEndian)
|
|
Array.Reverse(b, pos, 4);
|
|
int ret = BitConverter.ToInt32(b, pos);
|
|
pos += 4;
|
|
return ret;
|
|
}
|
|
|
|
public OSCMessage(byte[] bmsg)
|
|
{
|
|
int pos = 0;
|
|
Address = DecodeString(bmsg, ref pos);
|
|
string typestring = DecodeString(bmsg, ref pos);
|
|
|
|
args = new OSCArg[typestring.Length - 1];
|
|
|
|
int idx = 0;
|
|
foreach (char c in typestring)
|
|
{
|
|
switch (c)
|
|
{
|
|
case 'f':
|
|
args[idx++] = new OSCFloatArg(DecodeFloat(bmsg, ref pos));
|
|
break;
|
|
case 's':
|
|
args[idx++] = new OSCStringArg(DecodeString(bmsg, ref pos));
|
|
break;
|
|
case 'i':
|
|
args[idx++] = new OSCIntArg(DecodeInt(bmsg, ref pos));
|
|
break;
|
|
case 'b':
|
|
int len = DecodeInt(bmsg, ref pos) * 4;
|
|
byte[] b = new byte[len];
|
|
bmsg.CopyTo(b, 0);
|
|
pos += len;
|
|
args[idx++] = new OSCBlobArg(b);
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
public string Address
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
OSCArg[] args;
|
|
|
|
public OSCArg[] Args
|
|
{
|
|
get
|
|
{
|
|
return args;
|
|
}
|
|
}
|
|
|
|
|
|
// Construction de message
|
|
public OSCMessage(string _address)
|
|
{
|
|
Address = _address;
|
|
}
|
|
|
|
void AddArg(OSCArg arg)
|
|
{
|
|
if (args == null)
|
|
{
|
|
args = new OSCArg[1];
|
|
}
|
|
else
|
|
{
|
|
OSCArg[] na = new OSCArg[args.Length + 1];
|
|
args.CopyTo(na, 0);
|
|
args = na;
|
|
}
|
|
args[args.Length - 1] = arg;
|
|
}
|
|
|
|
public void AddString(string arg)
|
|
{
|
|
AddArg(new OSCStringArg(arg));
|
|
}
|
|
|
|
public void AddInt(int arg)
|
|
{
|
|
AddArg(new OSCIntArg(arg));
|
|
}
|
|
public void AddFloat(float arg)
|
|
{
|
|
AddArg(new OSCFloatArg(arg));
|
|
}
|
|
|
|
public byte[] Encode()
|
|
{
|
|
int len = System.Text.ASCIIEncoding.ASCII.GetByteCount(Address) / 4 + 1;
|
|
string typestring = ",";
|
|
foreach (var arg in args)
|
|
{
|
|
switch (arg.Type)
|
|
{
|
|
case OSCType.Int32:
|
|
len += 1;
|
|
typestring += "i";
|
|
break;
|
|
case OSCType.Float32:
|
|
len += 1;
|
|
typestring += "f";
|
|
break;
|
|
case OSCType.String:
|
|
len += System.Text.ASCIIEncoding.ASCII.GetByteCount(arg.GetString()) / 4 + 1;
|
|
typestring += "s";
|
|
break;
|
|
}
|
|
}
|
|
|
|
len += typestring.Length / 4 + 1;
|
|
byte[] res = new byte[len * 4];
|
|
int pos = 0;
|
|
EncodeString(res, ref pos, Address);
|
|
EncodeString(res, ref pos, typestring);
|
|
foreach (var arg in args)
|
|
{
|
|
switch (arg.Type)
|
|
{
|
|
case OSCType.Int32:
|
|
EncodeInt(res, ref pos, arg.GetInt());
|
|
break;
|
|
case OSCType.Float32:
|
|
EncodeFloat(res, ref pos, arg.GetFloat());
|
|
break;
|
|
case OSCType.String:
|
|
EncodeString(res, ref pos, arg.GetString());
|
|
break;
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
void EncodeString(byte[] buff, ref int pos, string s)
|
|
{
|
|
pos +=
|
|
System.Text.ASCIIEncoding.ASCII.GetBytes(
|
|
s, 0, s.Length, buff, pos);
|
|
do
|
|
{
|
|
buff[pos++] = 0;
|
|
} while (pos % 4 != 0);
|
|
}
|
|
|
|
void EncodeInt(byte[] res, ref int pos, int i)
|
|
{
|
|
byte[] buff = BitConverter.GetBytes(i);
|
|
if (BitConverter.IsLittleEndian)
|
|
Array.Reverse(buff);
|
|
buff.CopyTo(res, pos);
|
|
pos += 4;
|
|
}
|
|
|
|
void EncodeFloat(byte[] res, ref int pos, float f)
|
|
{
|
|
byte[] buff = BitConverter.GetBytes(f);
|
|
if (BitConverter.IsLittleEndian)
|
|
Array.Reverse(buff);
|
|
buff.CopyTo(res, pos);
|
|
pos += 4;
|
|
}
|
|
}
|
|
|
|
}
|