From a522b0bc7e0816ad56f393e818e05ddd4133476e Mon Sep 17 00:00:00 2001 From: Cassandra de la Cruz-Munoz Date: Sat, 21 Oct 2023 09:14:35 -0400 Subject: [PATCH] feat!: change accessing mechanism for OscArguments --- Exceptions/InvalidDataTypeException.cs | 18 +++++ OscArgument.cs | 107 ++++++++++++++++++++++--- OscMessage.cs | 3 +- OscReceiver.cs | 6 +- 4 files changed, 118 insertions(+), 16 deletions(-) create mode 100644 Exceptions/InvalidDataTypeException.cs diff --git a/Exceptions/InvalidDataTypeException.cs b/Exceptions/InvalidDataTypeException.cs new file mode 100644 index 0000000..e3b20aa --- /dev/null +++ b/Exceptions/InvalidDataTypeException.cs @@ -0,0 +1,18 @@ +using System; + +namespace godotOscSharp +{ + public class InvalidDataTypeException : ArgumentException + { + public InvalidDataTypeException(): base() {} + public InvalidDataTypeException(String message): base(message) {} + public InvalidDataTypeException(Char expected, Char actual): base($"Invalid data type: Received '{actual}', expected '{expected}'.") {} + public InvalidDataTypeException(String expected, Char actual): base($"Invalid data type: Received '{actual}', expected '{expected}'.") {} + public InvalidDataTypeException(Char expected, Char actual, Exception inner): base($"Invalid data type: Received '{actual}', expected '{expected}'.", inner) {} + public InvalidDataTypeException(String expected, Char actual, Exception inner): base($"Invalid data type: Received '{actual}', expected '{expected}'.", inner) {} + public InvalidDataTypeException(String address, int index, String name, Char expected, Char actual): base($"{address}[{index}] {name} has invalid data type. Received '{actual}', expected '{expected}'.") {} + public InvalidDataTypeException(String address, int index, String name, Char expected, Char actual, Exception inner): base($"{address}[{index}] {name} has invalid data type. Received '{actual}', expected '{expected}'.", inner) {} + public InvalidDataTypeException(OscAddress address, int index, String name, Char expected, Char actual): base($"{address.ToString()}[{index}] {name} has invalid data type. Received '{actual}', expected '{expected}'.") {} + public InvalidDataTypeException(OscAddress address, int index, String name, Char expected, Char actual, Exception inner): base($"{address.ToString()}[{index}] {name} has invalid data type. Received '{actual}', expected '{expected}'.", inner) {} + } +} diff --git a/OscArgument.cs b/OscArgument.cs index 5a94bde..c09f8fe 100644 --- a/OscArgument.cs +++ b/OscArgument.cs @@ -18,6 +18,8 @@ using System; +#nullable enable + namespace godotOscSharp { // A class that represents a DWord @@ -25,10 +27,30 @@ namespace godotOscSharp { // The value of the DWord as an unsigned integer public char Type { get; } - public object Value { get; } + private object? Value { get; } + + public static OscArgument CreateFromParams(object? value, char type) + { + switch (type) { + case 'i': + case 'f': + case 's': + case 'h': + case 'd': + return new OscArgument(value, type); + case 'T': + return new OscArgument(true, type); + case 'F': + return new OscArgument(false, type); + case 'N': + return new OscArgument(null, type); + default: + throw new ArgumentException($"Invalid argument type: {type}"); + } + } // The constructor that takes an unsigned integer as the value - public OscArgument(object value, char type) + private OscArgument(object? value, char type) { Value = value; Type = type; @@ -38,7 +60,7 @@ namespace godotOscSharp public static OscArgument Parse(byte[] data, ref int index, char type) { // Use BitConverter to get the unsigned integer from the bytes at the given index in little-endian order - object value = null; + object? value = null; var start = index; switch (type) { case 'i': @@ -78,23 +100,82 @@ namespace godotOscSharp value = null; break; } - - // Increment the index by 4 bytes - - // Return a new DWord instance with the value return new OscArgument(value, type); } + public Int32 GetAsInt32() + { + if (Type != 'i') { + throw new InvalidDataTypeException('i', Type); + } + return (Int32)Value!; + } + + public float GetAsFloat() + { + if (Type != 'f') { + throw new InvalidDataTypeException('f', Type); + } + return (float)Value!; + } + + public String GetAsString() { + if (Type != 's') + { + throw new InvalidDataTypeException('s', Type); + } + return (String)Value!; + } + + public Int64 GetAsInt64() + { + if (Type != 'h') + { + throw new InvalidDataTypeException('h', Type); + } + return (Int64)Value!; + } + + public Double GetAsDouble() + { + if (Type != 'd') + { + throw new InvalidDataTypeException('d', Type); + } + return (Double)Value!; + } + + public bool GetAsBool() { + switch (Type) + { + case 'T': + return true; + case 'F': + return false; + default: + throw new InvalidDataTypeException("{T, F}", Type); + } + } + + public object? GetAsNull() + { + if (Type != 'N') + { + throw new InvalidDataTypeException('N', Type); + } + return null; + } + public byte[] ToBytes() { switch (Type) { case 'i': - return BitConverter.GetBytes((int)Value); + return BitConverter.GetBytes((int)Value!); case 'f': - return BitConverter.GetBytes((float)Value); + return BitConverter.GetBytes((float)Value!); case 's': var result = new System.Collections.Generic.List(); - result.AddRange(System.Text.Encoding.ASCII.GetBytes((string)Value)); + result.AddRange(System.Text.Encoding.ASCII.GetBytes((string)Value!)); result.Add(0); var padding = 4 - (result.Count % 4); for (int i = 0; i < padding; i++) @@ -103,16 +184,16 @@ namespace godotOscSharp } return result.ToArray(); case 'h': - return BitConverter.GetBytes((long)Value); + return BitConverter.GetBytes((long)Value!); case 'd': - return BitConverter.GetBytes((double)Value); + return BitConverter.GetBytes((double)Value!); } return new byte[0]; } public override string ToString() { - return Value.ToString(); + return Value?.ToString()!; } } } diff --git a/OscMessage.cs b/OscMessage.cs index 2ee73c2..e806b4f 100644 --- a/OscMessage.cs +++ b/OscMessage.cs @@ -33,6 +33,7 @@ namespace godotOscSharp public OscMessage(OscAddress address) { Address = address; + Data = new List(); } public OscMessage(OscAddress address, List data) @@ -94,4 +95,4 @@ namespace godotOscSharp return result.ToArray(); } } -} \ No newline at end of file +} diff --git a/OscReceiver.cs b/OscReceiver.cs index 98d4472..db214af 100644 --- a/OscReceiver.cs +++ b/OscReceiver.cs @@ -21,6 +21,8 @@ using System.Net; using System.Net.Sockets; using System.Threading; +#nullable enable + namespace godotOscSharp { // A class that represents an OSC receiver @@ -83,10 +85,10 @@ namespace godotOscSharp } // An event that occurs when a message is received - public event EventHandler MessageReceived; + public event EventHandler? MessageReceived; // An event that occurs when an error is received - public event EventHandler ErrorReceived; + public event EventHandler? ErrorReceived; } // A class that contains the data for the message received event