using System; using System.Collections; using System.Text; namespace OSC.NET { /// /// OSCPacket /// abstract public class OSCPacket { protected string address; protected byte[] binaryData; protected ArrayList values; public string Address { get { return address; } set { // TODO: validate address = value; } } public byte[] BinaryData { get { pack(); return binaryData; } } public ArrayList Values { get { return (ArrayList)values.Clone(); } } public OSCPacket() { this.values = new ArrayList(); } public static OSCPacket Unpack(byte[] bytes) { int start = 0; return Unpack(bytes, ref start, bytes.Length); } public static OSCPacket Unpack(byte[] bytes, ref int start, int end) { if (bytes[start] == '#') return OSCBundle.Unpack(bytes, ref start, end); else return OSCMessage.Unpack(bytes, ref start); } abstract public void Append(object value); abstract public bool IsBundle(); protected static void addBytes(ArrayList data, byte[] bytes) { foreach (byte b in bytes) { data.Add(b); } } protected static byte[] packDouble(double value) { byte[] data = BitConverter.GetBytes(value); if (BitConverter.IsLittleEndian) data = swapEndian(data); return data; } protected static byte[] packFloat(float value) { byte[] data = BitConverter.GetBytes(value); if (BitConverter.IsLittleEndian) data = swapEndian(data); return data; } protected static byte[] packInt(int value) { byte[] data = BitConverter.GetBytes(value); if (BitConverter.IsLittleEndian) data = swapEndian(data); return data; } protected static byte[] packLong(long value) { byte[] data = BitConverter.GetBytes(value); if (BitConverter.IsLittleEndian) data = swapEndian(data); return data; } protected static byte[] packString(string value) { return System.Text.Encoding.ASCII.GetBytes(value); } protected static void padNull(ArrayList data) { byte zero = 0; int pad = 4 - (data.Count % 4); for (int i = 0; i < pad; i++) { data.Add(zero); } } protected static byte[] swapEndian(byte[] data) { byte[] swapped = new byte[data.Length]; for (int i = data.Length - 1, j = 0; i >= 0; i--, j++) { swapped[j] = data[i]; } return swapped; } protected static double unpackDouble(byte[] bytes, ref int start) { byte[] data = new byte[8]; for (int i = 0; i < 8; i++, start++) data[i] = bytes[start]; if (BitConverter.IsLittleEndian) data = swapEndian(data); return BitConverter.ToDouble(data, 0); } protected static float unpackFloat(byte[] bytes, ref int start) { byte[] data = new byte[4]; for (int i = 0; i < 4; i++, start++) data[i] = bytes[start]; if (BitConverter.IsLittleEndian) data = swapEndian(data); return BitConverter.ToSingle(data, 0); } protected static int unpackInt(byte[] bytes, ref int start) { byte[] data = new byte[4]; for (int i = 0; i < 4; i++, start++) data[i] = bytes[start]; if (BitConverter.IsLittleEndian) data = swapEndian(data); return BitConverter.ToInt32(data, 0); } protected static long unpackLong(byte[] bytes, ref int start) { byte[] data = new byte[8]; for (int i = 0; i < 8; i++, start++) data[i] = bytes[start]; if (BitConverter.IsLittleEndian) data = swapEndian(data); return BitConverter.ToInt64(data, 0); } protected static string unpackString(byte[] bytes, ref int start) { int count = 0; for (int index = start; bytes[index] != 0; index++, count++) ; string s = Encoding.ASCII.GetString(bytes, start, count); start += count + 1; start = (start + 3) / 4 * 4; return s; } abstract protected void pack(); } }