diff --git a/CHANGELIST.md b/CHANGELIST.md
index 0c1d18d3..457bedf7 100644
--- a/CHANGELIST.md
+++ b/CHANGELIST.md
@@ -25,6 +25,7 @@
- Add tests around ProcessingTool
- Add BaseExecutionContext tests
- Add currently unused Input type
+- Split Input type into typed classes
### 3.2.4 (2024-11-24)
diff --git a/MPF.ExecutionContexts.Test/InputTests.cs b/MPF.ExecutionContexts.Test/InputTests.cs
index 6838ec1a..cd722e16 100644
--- a/MPF.ExecutionContexts.Test/InputTests.cs
+++ b/MPF.ExecutionContexts.Test/InputTests.cs
@@ -1,441 +1,332 @@
+using MPF.ExecutionContexts.Data;
using Xunit;
namespace MPF.ExecutionContexts.Test
{
public class InputTests
{
- #region ProcessAsFlag
+ #region FlagInput
[Theory]
- // Invalid type
- [InlineData(InputType.None, "flag", new string[] { "flag" }, 0, false)]
- [InlineData(InputType.Boolean, "flag", new string[] { "flag" }, 0, false)]
- [InlineData(InputType.Int8, "flag", new string[] { "flag" }, 0, false)]
- [InlineData(InputType.UInt8, "flag", new string[] { "flag" }, 0, false)]
- [InlineData(InputType.Int16, "flag", new string[] { "flag" }, 0, false)]
- [InlineData(InputType.UInt16, "flag", new string[] { "flag" }, 0, false)]
- [InlineData(InputType.Int32, "flag", new string[] { "flag" }, 0, false)]
- [InlineData(InputType.UInt32, "flag", new string[] { "flag" }, 0, false)]
- [InlineData(InputType.Int64, "flag", new string[] { "flag" }, 0, false)]
- [InlineData(InputType.UInt64, "flag", new string[] { "flag" }, 0, false)]
- [InlineData(InputType.String, "flag", new string[] { "flag" }, 0, false)]
// Invalid parts
- [InlineData(InputType.Flag, "flag", new string[0], 0, false)]
+ [InlineData("flag", new string[0], 0, false, false)]
// Invalid index
- [InlineData(InputType.Flag, "flag", new string[] { "flag" }, -1, false)]
- [InlineData(InputType.Flag, "flag", new string[] { "flag" }, 1, false)]
+ [InlineData("flag", new string[] { "flag" }, -1, false, false)]
+ [InlineData("flag", new string[] { "flag" }, 1, false, false)]
// Invalid name
- [InlineData(InputType.Flag, "flag", new string[] { "" }, 0, false)]
- [InlineData(InputType.Flag, "flag", new string[] { "flag2" }, 0, false)]
+ [InlineData("flag", new string[] { "" }, 0, false, false)]
+ [InlineData("flag", new string[] { "flag2" }, 0, false, false)]
// Valid
- [InlineData(InputType.Flag, "flag", new string[] { "flag" }, 0, true)]
- public void ProcessAsFlagTest(InputType type, string name, string[] parts, int index, bool expected)
+ [InlineData("flag", new string[] { "flag" }, 0, true, true)]
+ public void FlagInputTest(string name, string[] parts, int index, bool success, bool expected)
{
- Input input = new Input(type, name);
- bool actual = input.ProcessAsFlag(parts, ref index);
- Assert.Equal(expected, actual);
+ FlagInput input = new FlagInput(name);
+ bool actual = input.Process(parts, ref index);
+
+ Assert.Equal(success, actual);
+ Assert.Equal(expected, input.Value);
}
#endregion
- #region ProcessAsBoolean
+ #region BooleanInput
[Theory]
- // Invalid type
- [InlineData(InputType.None, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Flag, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int8, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt8, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int16, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt16, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int32, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt32, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int64, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt64, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.String, "flag", true, new string[] { "flag" }, 0, null)]
// Invalid parts
- [InlineData(InputType.Boolean, "flag", true, new string[0], 0, null)]
+ [InlineData("flag", true, new string[0], 0, false, null)]
// Invalid index
- [InlineData(InputType.Boolean, "flag", true, new string[] { "flag" }, -1, null)]
- [InlineData(InputType.Boolean, "flag", true, new string[] { "flag" }, 1, null)]
+ [InlineData("flag", true, new string[] { "flag" }, -1, false, null)]
+ [InlineData("flag", true, new string[] { "flag" }, 1, false, null)]
// Invalid name
- [InlineData(InputType.Boolean, "flag", true, new string[] { "" }, 0, null)]
- [InlineData(InputType.Boolean, "flag", true, new string[] { "flag2" }, 0, null)]
+ [InlineData("flag", true, new string[] { "" }, 0, false, null)]
+ [InlineData("flag", true, new string[] { "flag2" }, 0, false, null)]
// Valid name, no following
- [InlineData(InputType.Boolean, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Boolean, "flag", false, new string[] { "flag" }, 0, true)]
+ [InlineData("flag", true, new string[] { "flag" }, 0, false, null)]
+ [InlineData("flag", false, new string[] { "flag" }, 0, true, true)]
// Valid name, invalid following
- [InlineData(InputType.Boolean, "flag", true, new string[] { "flag", "invalid" }, 0, null)]
- [InlineData(InputType.Boolean, "flag", false, new string[] { "flag", "invalid" }, 0, true)]
+ [InlineData("flag", true, new string[] { "flag", "invalid" }, 0, false, null)]
+ [InlineData("flag", false, new string[] { "flag", "invalid" }, 0, true, true)]
// Valid name, valid following
- [InlineData(InputType.Boolean, "flag", true, new string[] { "flag", "true" }, 0, true)]
- [InlineData(InputType.Boolean, "flag", true, new string[] { "flag", "false" }, 0, false)]
- public void ProcessAsBooleanTest(InputType type, string name, bool required, string[] parts, int index, bool? expected)
+ [InlineData("flag", true, new string[] { "flag", "true" }, 0, true, true)]
+ [InlineData("flag", true, new string[] { "flag", "false" }, 0, true, false)]
+ public void BooleanInputTest(string name, bool required, string[] parts, int index, bool success, bool? expected)
{
- Input input = new Input(type, name, required);
- bool? actual = input.ProcessAsBoolean(parts, ref index);
- Assert.Equal(expected, actual);
+ BooleanInput input = new BooleanInput(name, required);
+ bool actual = input.Process(parts, ref index);
+
+ Assert.Equal(success, actual);
+ Assert.Equal(expected, input.Value);
}
#endregion
- #region ProcessAsInt8
+ #region Int8Input
[Theory]
- // Invalid type
- [InlineData(InputType.None, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Flag, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Boolean, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt8, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int16, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt16, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int32, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt32, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int64, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt64, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.String, "flag", true, new string[] { "flag" }, 0, null)]
// Invalid parts
- [InlineData(InputType.Int8, "flag", true, new string[0], 0, null)]
+ [InlineData("flag", true, new string[0], 0, false, null)]
// Invalid index
- [InlineData(InputType.Int8, "flag", true, new string[] { "flag" }, -1, null)]
- [InlineData(InputType.Int8, "flag", true, new string[] { "flag" }, 1, null)]
+ [InlineData("flag", true, new string[] { "flag" }, -1, false, null)]
+ [InlineData("flag", true, new string[] { "flag" }, 1, false, null)]
// Invalid name
- [InlineData(InputType.Int8, "flag", true, new string[] { "" }, 0, null)]
- [InlineData(InputType.Int8, "flag", true, new string[] { "flag2" }, 0, null)]
+ [InlineData("flag", true, new string[] { "" }, 0, false, null)]
+ [InlineData("flag", true, new string[] { "flag2" }, 0, false, null)]
// Valid name, no following
- [InlineData(InputType.Int8, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int8, "flag", false, new string[] { "flag" }, 0, sbyte.MinValue)]
+ [InlineData("flag", true, new string[] { "flag" }, 0, false, null)]
+ [InlineData("flag", false, new string[] { "flag" }, 0, true, sbyte.MinValue)]
// Valid name, invalid following
- [InlineData(InputType.Int8, "flag", true, new string[] { "flag", "invalid" }, 0, null)]
- [InlineData(InputType.Int8, "flag", false, new string[] { "flag", "invalid" }, 0, sbyte.MinValue)]
+ [InlineData("flag", true, new string[] { "flag", "invalid" }, 0, false, null)]
+ [InlineData("flag", false, new string[] { "flag", "invalid" }, 0, true, sbyte.MinValue)]
// Valid name, valid following
- [InlineData(InputType.Int8, "flag", true, new string[] { "flag", "1" }, 0, (sbyte)1)]
- [InlineData(InputType.Int8, "flag", true, new string[] { "flag", "-1" }, 0, (sbyte)-1)]
- public void ProcessAsInt8Test(InputType type, string name, bool required, string[] parts, int index, sbyte? expected)
+ [InlineData("flag", true, new string[] { "flag", "1" }, 0, true, (sbyte)1)]
+ [InlineData("flag", true, new string[] { "flag", "-1" }, 0, true, (sbyte)-1)]
+ public void Int8InputTest(string name, bool required, string[] parts, int index, bool success, sbyte? expected)
{
- Input input = new Input(type, name, required);
- sbyte? actual = input.ProcessAsInt8(parts, ref index);
- Assert.Equal(expected, actual);
+ Int8Input input = new Int8Input(name, required);
+ bool actual = input.Process(parts, ref index);
+
+ Assert.Equal(success, actual);
+ Assert.Equal(expected, input.Value);
}
#endregion
- #region ProcessAsUInt8
+ #region UInt8Input
[Theory]
- // Invalid type
- [InlineData(InputType.None, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Flag, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Boolean, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int8, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int16, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt16, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int32, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt32, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int64, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt64, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.String, "flag", true, new string[] { "flag" }, 0, null)]
// Invalid parts
- [InlineData(InputType.UInt8, "flag", true, new string[0], 0, null)]
+ [InlineData("flag", true, new string[0], 0, false, null)]
// Invalid index
- [InlineData(InputType.UInt8, "flag", true, new string[] { "flag" }, -1, null)]
- [InlineData(InputType.UInt8, "flag", true, new string[] { "flag" }, 1, null)]
+ [InlineData("flag", true, new string[] { "flag" }, -1, false, null)]
+ [InlineData("flag", true, new string[] { "flag" }, 1, false, null)]
// Invalid name
- [InlineData(InputType.UInt8, "flag", true, new string[] { "" }, 0, null)]
- [InlineData(InputType.UInt8, "flag", true, new string[] { "flag2" }, 0, null)]
+ [InlineData("flag", true, new string[] { "" }, 0, false, null)]
+ [InlineData("flag", true, new string[] { "flag2" }, 0, false, null)]
// Valid name, no following
- [InlineData(InputType.UInt8, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt8, "flag", false, new string[] { "flag" }, 0, byte.MinValue)]
+ [InlineData("flag", true, new string[] { "flag" }, 0, false, null)]
+ [InlineData("flag", false, new string[] { "flag" }, 0, true, byte.MinValue)]
// Valid name, invalid following
- [InlineData(InputType.UInt8, "flag", true, new string[] { "flag", "invalid" }, 0, null)]
- [InlineData(InputType.UInt8, "flag", false, new string[] { "flag", "invalid" }, 0, byte.MinValue)]
+ [InlineData("flag", true, new string[] { "flag", "invalid" }, 0, false, null)]
+ [InlineData("flag", false, new string[] { "flag", "invalid" }, 0, true, byte.MinValue)]
// Valid name, valid following
- [InlineData(InputType.UInt8, "flag", true, new string[] { "flag", "1" }, 0, (byte)1)]
- public void ProcessAsUInt8Test(InputType type, string name, bool required, string[] parts, int index, byte? expected)
+ [InlineData("flag", true, new string[] { "flag", "1" }, 0, true, (byte)1)]
+ public void UInt8InputTest(string name, bool required, string[] parts, int index, bool success, byte? expected)
{
- Input input = new Input(type, name, required);
- byte? actual = input.ProcessAsUInt8(parts, ref index);
- Assert.Equal(expected, actual);
+ UInt8Input input = new UInt8Input(name, required);
+ bool actual = input.Process(parts, ref index);
+
+ Assert.Equal(success, actual);
+ Assert.Equal(expected, input.Value);
}
#endregion
- #region ProcessAsInt16
+ #region Int16Input
[Theory]
- // Invalid type
- [InlineData(InputType.None, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Flag, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Boolean, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int8, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt8, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt16, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int32, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt32, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int64, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt64, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.String, "flag", true, new string[] { "flag" }, 0, null)]
// Invalid parts
- [InlineData(InputType.Int16, "flag", true, new string[0], 0, null)]
+ [InlineData("flag", true, new string[0], 0, false, null)]
// Invalid index
- [InlineData(InputType.Int16, "flag", true, new string[] { "flag" }, -1, null)]
- [InlineData(InputType.Int16, "flag", true, new string[] { "flag" }, 1, null)]
+ [InlineData("flag", true, new string[] { "flag" }, -1, false, null)]
+ [InlineData("flag", true, new string[] { "flag" }, 1, false, null)]
// Invalid name
- [InlineData(InputType.Int16, "flag", true, new string[] { "" }, 0, null)]
- [InlineData(InputType.Int16, "flag", true, new string[] { "flag2" }, 0, null)]
+ [InlineData("flag", true, new string[] { "" }, 0, false, null)]
+ [InlineData("flag", true, new string[] { "flag2" }, 0, false, null)]
// Valid name, no following
- [InlineData(InputType.Int16, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int16, "flag", false, new string[] { "flag" }, 0, short.MinValue)]
+ [InlineData("flag", true, new string[] { "flag" }, 0, false, null)]
+ [InlineData("flag", false, new string[] { "flag" }, 0, true, short.MinValue)]
// Valid name, invalid following
- [InlineData(InputType.Int16, "flag", true, new string[] { "flag", "invalid" }, 0, null)]
- [InlineData(InputType.Int16, "flag", false, new string[] { "flag", "invalid" }, 0, short.MinValue)]
+ [InlineData("flag", true, new string[] { "flag", "invalid" }, 0, false, null)]
+ [InlineData("flag", false, new string[] { "flag", "invalid" }, 0, true, short.MinValue)]
// Valid name, valid following
- [InlineData(InputType.Int16, "flag", true, new string[] { "flag", "1" }, 0, (short)1)]
- [InlineData(InputType.Int16, "flag", true, new string[] { "flag", "-1" }, 0, (short)-1)]
- public void ProcessAsInt16Test(InputType type, string name, bool required, string[] parts, int index, short? expected)
+ [InlineData("flag", true, new string[] { "flag", "1" }, 0, true, (short)1)]
+ [InlineData("flag", true, new string[] { "flag", "-1" }, 0, true, (short)-1)]
+ public void Int16InputTest(string name, bool required, string[] parts, int index, bool success, short? expected)
{
- Input input = new Input(type, name, required);
- short? actual = input.ProcessAsInt16(parts, ref index);
- Assert.Equal(expected, actual);
+ Int16Input input = new Int16Input(name, required);
+ bool actual = input.Process(parts, ref index);
+
+ Assert.Equal(success, actual);
+ Assert.Equal(expected, input.Value);
}
#endregion
- #region ProcessAsUInt16
+ #region UInt16Input
[Theory]
- // Invalid type
- [InlineData(InputType.None, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Flag, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Boolean, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int8, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt8, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int16, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int32, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt32, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int64, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt64, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.String, "flag", true, new string[] { "flag" }, 0, null)]
// Invalid parts
- [InlineData(InputType.UInt16, "flag", true, new string[0], 0, null)]
+ [InlineData("flag", true, new string[0], 0, false, null)]
// Invalid index
- [InlineData(InputType.UInt16, "flag", true, new string[] { "flag" }, -1, null)]
- [InlineData(InputType.UInt16, "flag", true, new string[] { "flag" }, 1, null)]
+ [InlineData("flag", true, new string[] { "flag" }, -1, false, null)]
+ [InlineData("flag", true, new string[] { "flag" }, 1, false, null)]
// Invalid name
- [InlineData(InputType.UInt16, "flag", true, new string[] { "" }, 0, null)]
- [InlineData(InputType.UInt16, "flag", true, new string[] { "flag2" }, 0, null)]
+ [InlineData("flag", true, new string[] { "" }, 0, false, null)]
+ [InlineData("flag", true, new string[] { "flag2" }, 0, false, null)]
// Valid name, no following
- [InlineData(InputType.UInt16, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt16, "flag", false, new string[] { "flag" }, 0, ushort.MinValue)]
+ [InlineData("flag", true, new string[] { "flag" }, 0, false, null)]
+ [InlineData("flag", false, new string[] { "flag" }, 0, true, ushort.MinValue)]
// Valid name, invalid following
- [InlineData(InputType.UInt16, "flag", true, new string[] { "flag", "invalid" }, 0, null)]
- [InlineData(InputType.UInt16, "flag", false, new string[] { "flag", "invalid" }, 0, ushort.MinValue)]
+ [InlineData("flag", true, new string[] { "flag", "invalid" }, 0, false, null)]
+ [InlineData("flag", false, new string[] { "flag", "invalid" }, 0, true, ushort.MinValue)]
// Valid name, valid following
- [InlineData(InputType.UInt16, "flag", true, new string[] { "flag", "1" }, 0, (ushort)1)]
- public void ProcessAsUInt16Test(InputType type, string name, bool required, string[] parts, int index, ushort? expected)
+ [InlineData("flag", true, new string[] { "flag", "1" }, 0, true, (ushort)1)]
+ public void UInt16InputTest(string name, bool required, string[] parts, int index, bool success, ushort? expected)
{
- Input input = new Input(type, name, required);
- ushort? actual = input.ProcessAsUInt16(parts, ref index);
- Assert.Equal(expected, actual);
+ UInt16Input input = new UInt16Input(name, required);
+ bool actual = input.Process(parts, ref index);
+
+ Assert.Equal(success, actual);
+ Assert.Equal(expected, input.Value);
}
#endregion
- #region ProcessAsInt32
+ #region Int32Input
[Theory]
- // Invalid type
- [InlineData(InputType.None, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Flag, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Boolean, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int8, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt8, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int16, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt16, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt32, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int64, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt64, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.String, "flag", true, new string[] { "flag" }, 0, null)]
// Invalid parts
- [InlineData(InputType.Int32, "flag", true, new string[0], 0, null)]
+ [InlineData("flag", true, new string[0], 0, false, null)]
// Invalid index
- [InlineData(InputType.Int32, "flag", true, new string[] { "flag" }, -1, null)]
- [InlineData(InputType.Int32, "flag", true, new string[] { "flag" }, 1, null)]
+ [InlineData("flag", true, new string[] { "flag" }, -1, false, null)]
+ [InlineData("flag", true, new string[] { "flag" }, 1, false, null)]
// Invalid name
- [InlineData(InputType.Int32, "flag", true, new string[] { "" }, 0, null)]
- [InlineData(InputType.Int32, "flag", true, new string[] { "flag2" }, 0, null)]
+ [InlineData("flag", true, new string[] { "" }, 0, false, null)]
+ [InlineData("flag", true, new string[] { "flag2" }, 0, false, null)]
// Valid name, no following
- [InlineData(InputType.Int32, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int32, "flag", false, new string[] { "flag" }, 0, int.MinValue)]
+ [InlineData("flag", true, new string[] { "flag" }, 0, false, null)]
+ [InlineData("flag", false, new string[] { "flag" }, 0, true, int.MinValue)]
// Valid name, invalid following
- [InlineData(InputType.Int32, "flag", true, new string[] { "flag", "invalid" }, 0, null)]
- [InlineData(InputType.Int32, "flag", false, new string[] { "flag", "invalid" }, 0, int.MinValue)]
+ [InlineData("flag", true, new string[] { "flag", "invalid" }, 0, false, null)]
+ [InlineData("flag", false, new string[] { "flag", "invalid" }, 0, true, int.MinValue)]
// Valid name, valid following
- [InlineData(InputType.Int32, "flag", true, new string[] { "flag", "1" }, 0, (int)1)]
- [InlineData(InputType.Int32, "flag", true, new string[] { "flag", "-1" }, 0, (int)-1)]
- public void ProcessAsInt32Test(InputType type, string name, bool required, string[] parts, int index, int? expected)
+ [InlineData("flag", true, new string[] { "flag", "1" }, 0, true, (int)1)]
+ [InlineData("flag", true, new string[] { "flag", "-1" }, 0, true, (int)-1)]
+ public void Int32InputTest(string name, bool required, string[] parts, int index, bool success, int? expected)
{
- Input input = new Input(type, name, required);
- int? actual = input.ProcessAsInt32(parts, ref index);
- Assert.Equal(expected, actual);
+ Int32Input input = new Int32Input(name, required);
+ bool actual = input.Process(parts, ref index);
+
+ Assert.Equal(success, actual);
+ Assert.Equal(expected, input.Value);
}
#endregion
- #region ProcessAsUInt32
+ #region UInt32Input
[Theory]
- // Invalid type
- [InlineData(InputType.None, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Flag, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Boolean, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int8, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt8, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int16, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt16, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int32, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int64, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt64, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.String, "flag", true, new string[] { "flag" }, 0, null)]
// Invalid parts
- [InlineData(InputType.UInt32, "flag", true, new string[0], 0, null)]
+ [InlineData("flag", true, new string[0], 0, false, null)]
// Invalid index
- [InlineData(InputType.UInt32, "flag", true, new string[] { "flag" }, -1, null)]
- [InlineData(InputType.UInt32, "flag", true, new string[] { "flag" }, 1, null)]
+ [InlineData("flag", true, new string[] { "flag" }, -1, false, null)]
+ [InlineData("flag", true, new string[] { "flag" }, 1, false, null)]
// Invalid name
- [InlineData(InputType.UInt32, "flag", true, new string[] { "" }, 0, null)]
- [InlineData(InputType.UInt32, "flag", true, new string[] { "flag2" }, 0, null)]
+ [InlineData("flag", true, new string[] { "" }, 0, false, null)]
+ [InlineData("flag", true, new string[] { "flag2" }, 0, false, null)]
// Valid name, no following
- [InlineData(InputType.UInt32, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt32, "flag", false, new string[] { "flag" }, 0, uint.MinValue)]
+ [InlineData("flag", true, new string[] { "flag" }, 0, false, null)]
+ [InlineData("flag", false, new string[] { "flag" }, 0, true, uint.MinValue)]
// Valid name, invalid following
- [InlineData(InputType.UInt32, "flag", true, new string[] { "flag", "invalid" }, 0, null)]
- [InlineData(InputType.UInt32, "flag", false, new string[] { "flag", "invalid" }, 0, uint.MinValue)]
+ [InlineData("flag", true, new string[] { "flag", "invalid" }, 0, false, null)]
+ [InlineData("flag", false, new string[] { "flag", "invalid" }, 0, true, uint.MinValue)]
// Valid name, valid following
- [InlineData(InputType.UInt32, "flag", true, new string[] { "flag", "1" }, 0, (uint)1)]
- public void ProcessAsUInt32Test(InputType type, string name, bool required, string[] parts, int index, uint? expected)
+ [InlineData("flag", true, new string[] { "flag", "1" }, 0, true, (uint)1)]
+ public void UInt32InputTest(string name, bool required, string[] parts, int index, bool success, uint? expected)
{
- Input input = new Input(type, name, required);
- uint? actual = input.ProcessAsUInt32(parts, ref index);
- Assert.Equal(expected, actual);
+ UInt32Input input = new UInt32Input(name, required);
+ bool actual = input.Process(parts, ref index);
+
+ Assert.Equal(success, actual);
+ Assert.Equal(expected, input.Value);
}
#endregion
- #region ProcessAsInt64
+ #region Int64Input
[Theory]
- // Invalid type
- [InlineData(InputType.None, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Flag, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Boolean, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int8, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt8, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int16, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt16, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int32, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt32, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt64, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.String, "flag", true, new string[] { "flag" }, 0, null)]
// Invalid parts
- [InlineData(InputType.Int64, "flag", true, new string[0], 0, null)]
+ [InlineData("flag", true, new string[0], 0, false, null)]
// Invalid index
- [InlineData(InputType.Int64, "flag", true, new string[] { "flag" }, -1, null)]
- [InlineData(InputType.Int64, "flag", true, new string[] { "flag" }, 1, null)]
+ [InlineData("flag", true, new string[] { "flag" }, -1, false, null)]
+ [InlineData("flag", true, new string[] { "flag" }, 1, false, null)]
// Invalid name
- [InlineData(InputType.Int64, "flag", true, new string[] { "" }, 0, null)]
- [InlineData(InputType.Int64, "flag", true, new string[] { "flag2" }, 0, null)]
+ [InlineData("flag", true, new string[] { "" }, 0, false, null)]
+ [InlineData("flag", true, new string[] { "flag2" }, 0, false, null)]
// Valid name, no following
- [InlineData(InputType.Int64, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int64, "flag", false, new string[] { "flag" }, 0, long.MinValue)]
+ [InlineData("flag", true, new string[] { "flag" }, 0, false, null)]
+ [InlineData("flag", false, new string[] { "flag" }, 0, true, long.MinValue)]
// Valid name, invalid following
- [InlineData(InputType.Int64, "flag", true, new string[] { "flag", "invalid" }, 0, null)]
- [InlineData(InputType.Int64, "flag", false, new string[] { "flag", "invalid" }, 0, long.MinValue)]
+ [InlineData("flag", true, new string[] { "flag", "invalid" }, 0, false, null)]
+ [InlineData("flag", false, new string[] { "flag", "invalid" }, 0, true, long.MinValue)]
// Valid name, valid following
- [InlineData(InputType.Int64, "flag", true, new string[] { "flag", "1" }, 0, (long)1)]
- [InlineData(InputType.Int64, "flag", true, new string[] { "flag", "-1" }, 0, (long)-1)]
- public void ProcessAsInt64Test(InputType type, string name, bool required, string[] parts, int index, long? expected)
+ [InlineData("flag", true, new string[] { "flag", "1" }, 0, true, (long)1)]
+ [InlineData("flag", true, new string[] { "flag", "-1" }, 0, true, (long)-1)]
+ public void Int64InputTest(string name, bool required, string[] parts, int index, bool success, long? expected)
{
- Input input = new Input(type, name, required);
- long? actual = input.ProcessAsInt64(parts, ref index);
- Assert.Equal(expected, actual);
+ Int64Input input = new Int64Input(name, required);
+ bool actual = input.Process(parts, ref index);
+
+ Assert.Equal(success, actual);
+ Assert.Equal(expected, input.Value);
}
#endregion
- #region ProcessAsUInt64
+ #region UInt64Input
[Theory]
- // Invalid type
- [InlineData(InputType.None, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Flag, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Boolean, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int8, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt8, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int16, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt16, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int32, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt32, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int64, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.String, "flag", true, new string[] { "flag" }, 0, null)]
// Invalid parts
- [InlineData(InputType.UInt64, "flag", true, new string[0], 0, null)]
+ [InlineData("flag", true, new string[0], 0, false, null)]
// Invalid index
- [InlineData(InputType.UInt64, "flag", true, new string[] { "flag" }, -1, null)]
- [InlineData(InputType.UInt64, "flag", true, new string[] { "flag" }, 1, null)]
+ [InlineData("flag", true, new string[] { "flag" }, -1, false, null)]
+ [InlineData("flag", true, new string[] { "flag" }, 1, false, null)]
// Invalid name
- [InlineData(InputType.UInt64, "flag", true, new string[] { "" }, 0, null)]
- [InlineData(InputType.UInt64, "flag", true, new string[] { "flag2" }, 0, null)]
+ [InlineData("flag", true, new string[] { "" }, 0, false, null)]
+ [InlineData("flag", true, new string[] { "flag2" }, 0, false, null)]
// Valid name, no following
- [InlineData(InputType.UInt64, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt64, "flag", false, new string[] { "flag" }, 0, ulong.MinValue)]
+ [InlineData("flag", true, new string[] { "flag" }, 0, false, null)]
+ [InlineData("flag", false, new string[] { "flag" }, 0, true, ulong.MinValue)]
// Valid name, invalid following
- [InlineData(InputType.UInt64, "flag", true, new string[] { "flag", "invalid" }, 0, null)]
- [InlineData(InputType.UInt64, "flag", false, new string[] { "flag", "invalid" }, 0, ulong.MinValue)]
+ [InlineData("flag", true, new string[] { "flag", "invalid" }, 0, false, null)]
+ [InlineData("flag", false, new string[] { "flag", "invalid" }, 0, true, ulong.MinValue)]
// Valid name, valid following
- [InlineData(InputType.UInt64, "flag", true, new string[] { "flag", "1" }, 0, (ulong)1)]
- public void ProcessAsUInt64Test(InputType type, string name, bool required, string[] parts, int index, ulong? expected)
+ [InlineData("flag", true, new string[] { "flag", "1" }, 0, true, (ulong)1)]
+ public void UInt64InputTest(string name, bool required, string[] parts, int index, bool success, ulong? expected)
{
- Input input = new Input(type, name, required);
- ulong? actual = input.ProcessAsUInt64(parts, ref index);
- Assert.Equal(expected, actual);
+ UInt64Input input = new UInt64Input(name, required);
+ bool actual = input.Process(parts, ref index);
+
+ Assert.Equal(success, actual);
+ Assert.Equal(expected, input.Value);
}
#endregion
- #region ProcessAsString
+ #region StringInput
[Theory]
- // Invalid type
- [InlineData(InputType.None, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Flag, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Boolean, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int8, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt8, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int16, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt16, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int32, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt32, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.Int64, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.UInt64, "flag", true, new string[] { "flag" }, 0, null)]
// Invalid parts
- [InlineData(InputType.String, "flag", true, new string[0], 0, null)]
+ [InlineData("flag", true, new string[0], 0, false, null)]
// Invalid index
- [InlineData(InputType.String, "flag", true, new string[] { "flag" }, -1, null)]
- [InlineData(InputType.String, "flag", true, new string[] { "flag" }, 1, null)]
+ [InlineData("flag", true, new string[] { "flag" }, -1, false, null)]
+ [InlineData("flag", true, new string[] { "flag" }, 1, false, null)]
// Invalid name
- [InlineData(InputType.String, "flag", true, new string[] { "" }, 0, null)]
- [InlineData(InputType.String, "flag", true, new string[] { "flag2" }, 0, null)]
+ [InlineData("flag", true, new string[] { "" }, 0, false, null)]
+ [InlineData("flag", true, new string[] { "flag2" }, 0, false, null)]
// Valid name, no following
- [InlineData(InputType.String, "flag", true, new string[] { "flag" }, 0, null)]
- [InlineData(InputType.String, "flag", false, new string[] { "flag" }, 0, "")]
+ [InlineData("flag", true, new string[] { "flag" }, 0, false, null)]
+ [InlineData("flag", false, new string[] { "flag" }, 0, true, "")]
// Valid name, following
- [InlineData(InputType.String, "flag", true, new string[] { "flag", "value" }, 0, "value")]
- public void ProcessAsString(InputType type, string name, bool required, string[] parts, int index, string? expected)
+ [InlineData("flag", true, new string[] { "flag", "value" }, 0, true, "value")]
+ public void StringInputTest(string name, bool required, string[] parts, int index, bool success, string? expected)
{
- Input input = new Input(type, name, required);
- string? actual = input.ProcessAsString(parts, ref index);
- Assert.Equal(expected, actual);
+ StringInput input = new StringInput(name, required);
+ bool actual = input.Process(parts, ref index);
+
+ Assert.Equal(success, actual);
+ Assert.Equal(expected, input.Value);
}
#endregion
diff --git a/MPF.ExecutionContexts/Data/BooleanInput.cs b/MPF.ExecutionContexts/Data/BooleanInput.cs
new file mode 100644
index 00000000..a78e7a94
--- /dev/null
+++ b/MPF.ExecutionContexts/Data/BooleanInput.cs
@@ -0,0 +1,61 @@
+namespace MPF.ExecutionContexts.Data
+{
+ ///
+ /// Represents a boolean flag with an optional trailing value
+ ///
+ public class BooleanInput : Input
+ {
+ #region Constructors
+
+ ///
+ public BooleanInput(string name)
+ : base(name) { }
+
+ ///
+ public BooleanInput(string name, bool required)
+ : base(name, required) { }
+
+ ///
+ public BooleanInput(string shortName, string longName)
+ : base(shortName, longName) { }
+
+ ///
+ public BooleanInput(string shortName, string longName, bool required)
+ : base(shortName, longName, required) { }
+
+ #endregion
+
+ ///
+ public override bool Process(string[] parts, ref int index)
+ {
+ // Check the parts array
+ if (parts.Length == 0)
+ return false;
+
+ // Check the index
+ if (index < 0 || index >= parts.Length)
+ return false;
+
+ // Check the name
+ if (parts[index] != Name && (_longName != null && parts[index] != _longName))
+ return false;
+
+ // Ensure the value exists
+ if (!DoesExist(parts, index + 1))
+ {
+ Value = _required ? null : true;
+ return !_required;
+ }
+
+ // If the next value is valid
+ if (!bool.TryParse(parts[index + 1], out bool value))
+ {
+ Value = _required ? null : true;
+ return !_required;
+ }
+
+ index++;
+ return value;
+ }
+ }
+}
\ No newline at end of file
diff --git a/MPF.ExecutionContexts/Data/FlagInput.cs b/MPF.ExecutionContexts/Data/FlagInput.cs
new file mode 100644
index 00000000..664b5627
--- /dev/null
+++ b/MPF.ExecutionContexts/Data/FlagInput.cs
@@ -0,0 +1,47 @@
+namespace MPF.ExecutionContexts.Data
+{
+ ///
+ /// Represents a boolean flag without a trailing value
+ ///
+ public class FlagInput : Input
+ {
+ #region Constructors
+
+ ///
+ public FlagInput(string name)
+ : base(name) { }
+
+ ///
+ public FlagInput(string name, bool required)
+ : base(name, required) { }
+
+ ///
+ public FlagInput(string shortName, string longName)
+ : base(shortName, longName) { }
+
+ ///
+ public FlagInput(string shortName, string longName, bool required)
+ : base(shortName, longName, required) { }
+
+ #endregion
+
+ ///
+ public override bool Process(string[] parts, ref int index)
+ {
+ // Check the parts array
+ if (parts.Length == 0)
+ return false;
+
+ // Check the index
+ if (index < 0 || index >= parts.Length)
+ return false;
+
+ // Check the name
+ if (parts[index] != Name && (_longName != null && parts[index] != _longName))
+ return false;
+
+ Value = true;
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/MPF.ExecutionContexts/Data/Input.cs b/MPF.ExecutionContexts/Data/Input.cs
new file mode 100644
index 00000000..7b6c3af9
--- /dev/null
+++ b/MPF.ExecutionContexts/Data/Input.cs
@@ -0,0 +1,208 @@
+using System;
+
+namespace MPF.ExecutionContexts.Data
+{
+ ///
+ /// Represents a single input for an execution context
+ ///
+ public abstract class Input
+ {
+ #region Properties
+
+ ///
+ /// Primary name for the input
+ ///
+ public readonly string Name;
+
+ ///
+ /// Verbose name for the input
+ ///
+ protected readonly string? _longName;
+
+ ///
+ /// Indicates if the value following is required or not
+ ///
+ protected readonly bool _required;
+
+ #endregion
+
+ #region Constructors
+
+ /// Flag name / value
+ public Input(string name)
+ {
+ Name = name;
+ _longName = null;
+ _required = true;
+ }
+
+ /// Flag name / value
+ /// Indicates if a following value is required
+ public Input(string name, bool required)
+ {
+ Name = name;
+ _longName = null;
+ _required = required;
+ }
+
+ /// Flag name / value
+ /// Verbose flag name / value
+ public Input(string shortName, string longName)
+ {
+ Name = shortName;
+ _longName = longName;
+ _required = true;
+ }
+
+ /// Flag name / value
+ /// Verbose flag name / value
+ /// Indicates if a following value is required
+ public Input(string shortName, string longName, bool required)
+ {
+ Name = shortName;
+ _longName = longName;
+ _required = required;
+ }
+
+ #endregion
+
+ #region Helpers
+
+ ///
+ /// Returns whether or not the selected item exists
+ ///
+ /// Parts array to be referenced
+ /// Current index
+ /// True if the next item exists, false otherwise
+ internal static bool DoesExist(string[] parts, int index)
+ => index >= 0 && index < parts.Length;
+
+ ///
+ /// Get the trimmed value and multiplication factor from a value
+ ///
+ /// String value to treat as suffixed number
+ /// Trimmed value and multiplication factor
+ internal static string ExtractFactorFromValue(string value, out long factor)
+ {
+ value = value.Trim('"');
+ factor = 1;
+
+ // Characters
+ if (value.EndsWith("c", StringComparison.Ordinal))
+ {
+ factor = 1;
+ value = value.TrimEnd('c');
+ }
+
+ // Words
+ else if (value.EndsWith("w", StringComparison.Ordinal))
+ {
+ factor = 2;
+ value = value.TrimEnd('w');
+ }
+
+ // Double Words
+ else if (value.EndsWith("d", StringComparison.Ordinal))
+ {
+ factor = 4;
+ value = value.TrimEnd('d');
+ }
+
+ // Quad Words
+ else if (value.EndsWith("q", StringComparison.Ordinal))
+ {
+ factor = 8;
+ value = value.TrimEnd('q');
+ }
+
+ // Kilobytes
+ else if (value.EndsWith("k", StringComparison.Ordinal))
+ {
+ factor = 1024;
+ value = value.TrimEnd('k');
+ }
+
+ // Megabytes
+ else if (value.EndsWith("M", StringComparison.Ordinal))
+ {
+ factor = 1024 * 1024;
+ value = value.TrimEnd('M');
+ }
+
+ // Gigabytes
+ else if (value.EndsWith("G", StringComparison.Ordinal))
+ {
+ factor = 1024 * 1024 * 1024;
+ value = value.TrimEnd('G');
+ }
+
+ return value;
+ }
+
+ ///
+ /// Removes a leading 0x if it exists, case insensitive
+ ///
+ /// String with removed leading 0x
+ ///
+ internal static string RemoveHexIdentifier(string value)
+ {
+ if (value.Length <= 2)
+ return value;
+ if (value[0] != '0')
+ return value;
+ if (value[1] != 'x' && value[1] != 'X')
+ return value;
+
+ return value.Substring(2);
+ }
+
+ #endregion
+ }
+
+ ///
+ /// Represents a single input for an execution context
+ ///
+ public abstract class Input : Input
+ {
+ #region Properties
+
+ ///
+ /// Represents the last value stored
+ ///
+ public T? Value { get; protected set; }
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ public Input(string name)
+ : base(name) { }
+
+ ///
+ public Input(string name, bool required)
+ : base(name, required) { }
+
+ ///
+ public Input(string shortName, string longName)
+ : base(shortName, longName) { }
+
+ ///
+ public Input(string shortName, string longName, bool required)
+ : base(shortName, longName, required) { }
+
+ #endregion
+
+ #region Processors
+
+ ///
+ /// Process the current index, if possible
+ ///
+ /// Parts array to be referenced
+ /// Reference to the position in the parts
+ /// True if a value could be determined, false otherwise
+ public abstract bool Process(string[] parts, ref int index);
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/MPF.ExecutionContexts/Data/Int16Input.cs b/MPF.ExecutionContexts/Data/Int16Input.cs
new file mode 100644
index 00000000..601407ab
--- /dev/null
+++ b/MPF.ExecutionContexts/Data/Int16Input.cs
@@ -0,0 +1,83 @@
+using System.Globalization;
+
+namespace MPF.ExecutionContexts.Data
+{
+ ///
+ /// Represents an Int16 flag with an optional trailing value
+ ///
+ public class Int16Input : Input
+ {
+ #region Constructors
+
+ ///
+ public Int16Input(string name)
+ : base(name) { }
+
+ ///
+ public Int16Input(string name, bool required)
+ : base(name, required) { }
+
+ ///
+ public Int16Input(string shortName, string longName)
+ : base(shortName, longName) { }
+
+ ///
+ public Int16Input(string shortName, string longName, bool required)
+ : base(shortName, longName, required) { }
+
+ #endregion
+
+ ///
+ public override bool Process(string[] parts, ref int index)
+ {
+ // Check the parts array
+ if (parts.Length == 0)
+ return false;
+
+ // Check the index
+ if (index < 0 || index >= parts.Length)
+ return false;
+
+ // Check the name
+ if (parts[index] != Name && (_longName != null && parts[index] != _longName))
+ return false;
+
+ // Ensure the value exists
+ if (!DoesExist(parts, index + 1))
+ {
+ Value = _required ? null : short.MinValue;
+ return !_required;
+ }
+
+ // If the next value is valid
+ if (short.TryParse(parts[index + 1], out short value))
+ {
+ index++;
+ Value = value;
+ return true;
+ }
+
+ // Try to process as a formatted string
+ string baseVal = ExtractFactorFromValue(parts[index + 1], out long factor);
+ if (short.TryParse(baseVal, out value))
+ {
+ index++;
+ Value = (short)(value * factor);
+ return true;
+ }
+
+ // Try to process as a hex string
+ string hexValue = RemoveHexIdentifier(baseVal);
+ if (short.TryParse(hexValue, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out value))
+ {
+ index++;
+ Value = (short)(value * factor);
+ return true;
+ }
+
+ // Return value based on required flag
+ Value = _required ? null : short.MinValue;
+ return !_required;
+ }
+ }
+}
\ No newline at end of file
diff --git a/MPF.ExecutionContexts/Data/Int32Input.cs b/MPF.ExecutionContexts/Data/Int32Input.cs
new file mode 100644
index 00000000..7ff2b96e
--- /dev/null
+++ b/MPF.ExecutionContexts/Data/Int32Input.cs
@@ -0,0 +1,83 @@
+using System.Globalization;
+
+namespace MPF.ExecutionContexts.Data
+{
+ ///
+ /// Represents an Int32 flag with an optional trailing value
+ ///
+ public class Int32Input : Input
+ {
+ #region Constructors
+
+ ///
+ public Int32Input(string name)
+ : base(name) { }
+
+ ///
+ public Int32Input(string name, bool required)
+ : base(name, required) { }
+
+ ///
+ public Int32Input(string shortName, string longName)
+ : base(shortName, longName) { }
+
+ ///
+ public Int32Input(string shortName, string longName, bool required)
+ : base(shortName, longName, required) { }
+
+ #endregion
+
+ ///
+ public override bool Process(string[] parts, ref int index)
+ {
+ // Check the parts array
+ if (parts.Length == 0)
+ return false;
+
+ // Check the index
+ if (index < 0 || index >= parts.Length)
+ return false;
+
+ // Check the name
+ if (parts[index] != Name && (_longName != null && parts[index] != _longName))
+ return false;
+
+ // Ensure the value exists
+ if (!DoesExist(parts, index + 1))
+ {
+ Value = _required ? null : int.MinValue;
+ return !_required;
+ }
+
+ // If the next value is valid
+ if (int.TryParse(parts[index + 1], out int value))
+ {
+ index++;
+ Value = value;
+ return true;
+ }
+
+ // Try to process as a formatted string
+ string baseVal = ExtractFactorFromValue(parts[index + 1], out long factor);
+ if (int.TryParse(baseVal, out value))
+ {
+ index++;
+ Value = (int)(value * factor);
+ return true;
+ }
+
+ // Try to process as a hex string
+ string hexValue = RemoveHexIdentifier(baseVal);
+ if (int.TryParse(hexValue, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out value))
+ {
+ index++;
+ Value = (int)(value * factor);
+ return true;
+ }
+
+ // Return value based on required flag
+ Value = _required ? null : int.MinValue;
+ return !_required;
+ }
+ }
+}
\ No newline at end of file
diff --git a/MPF.ExecutionContexts/Data/Int64Input.cs b/MPF.ExecutionContexts/Data/Int64Input.cs
new file mode 100644
index 00000000..3d0baf59
--- /dev/null
+++ b/MPF.ExecutionContexts/Data/Int64Input.cs
@@ -0,0 +1,83 @@
+using System.Globalization;
+
+namespace MPF.ExecutionContexts.Data
+{
+ ///
+ /// Represents an Int64 flag with an optional trailing value
+ ///
+ public class Int64Input : Input
+ {
+ #region Constructors
+
+ ///
+ public Int64Input(string name)
+ : base(name) { }
+
+ ///
+ public Int64Input(string name, bool required)
+ : base(name, required) { }
+
+ ///
+ public Int64Input(string shortName, string longName)
+ : base(shortName, longName) { }
+
+ ///
+ public Int64Input(string shortName, string longName, bool required)
+ : base(shortName, longName, required) { }
+
+ #endregion
+
+ ///
+ public override bool Process(string[] parts, ref int index)
+ {
+ // Check the parts array
+ if (parts.Length == 0)
+ return false;
+
+ // Check the index
+ if (index < 0 || index >= parts.Length)
+ return false;
+
+ // Check the name
+ if (parts[index] != Name && (_longName != null && parts[index] != _longName))
+ return false;
+
+ // Ensure the value exists
+ if (!DoesExist(parts, index + 1))
+ {
+ Value = _required ? null : long.MinValue;
+ return !_required;
+ }
+
+ // If the next value is valid
+ if (long.TryParse(parts[index + 1], out long value))
+ {
+ index++;
+ Value = value;
+ return true;
+ }
+
+ // Try to process as a formatted string
+ string baseVal = ExtractFactorFromValue(parts[index + 1], out long factor);
+ if (long.TryParse(baseVal, out value))
+ {
+ index++;
+ Value = (long)(value * factor);
+ return true;
+ }
+
+ // Try to process as a hex string
+ string hexValue = RemoveHexIdentifier(baseVal);
+ if (long.TryParse(hexValue, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out value))
+ {
+ index++;
+ Value = (long)(value * factor);
+ return true;
+ }
+
+ // Return value based on required flag
+ Value = _required ? null : long.MinValue;
+ return !_required;
+ }
+ }
+}
\ No newline at end of file
diff --git a/MPF.ExecutionContexts/Data/Int8Input.cs b/MPF.ExecutionContexts/Data/Int8Input.cs
new file mode 100644
index 00000000..2c3c18bf
--- /dev/null
+++ b/MPF.ExecutionContexts/Data/Int8Input.cs
@@ -0,0 +1,83 @@
+using System.Globalization;
+
+namespace MPF.ExecutionContexts.Data
+{
+ ///
+ /// Represents an Int8 flag with an optional trailing value
+ ///
+ public class Int8Input : Input
+ {
+ #region Constructors
+
+ ///
+ public Int8Input(string name)
+ : base(name) { }
+
+ ///
+ public Int8Input(string name, bool required)
+ : base(name, required) { }
+
+ ///
+ public Int8Input(string shortName, string longName)
+ : base(shortName, longName) { }
+
+ ///
+ public Int8Input(string shortName, string longName, bool required)
+ : base(shortName, longName, required) { }
+
+ #endregion
+
+ ///
+ public override bool Process(string[] parts, ref int index)
+ {
+ // Check the parts array
+ if (parts.Length == 0)
+ return false;
+
+ // Check the index
+ if (index < 0 || index >= parts.Length)
+ return false;
+
+ // Check the name
+ if (parts[index] != Name && (_longName != null && parts[index] != _longName))
+ return false;
+
+ // Ensure the value exists
+ if (!DoesExist(parts, index + 1))
+ {
+ Value = _required ? null : sbyte.MinValue;
+ return !_required;
+ }
+
+ // If the next value is valid
+ if (sbyte.TryParse(parts[index + 1], out sbyte value))
+ {
+ index++;
+ Value = value;
+ return true;
+ }
+
+ // Try to process as a formatted string
+ string baseVal = ExtractFactorFromValue(parts[index + 1], out long factor);
+ if (sbyte.TryParse(baseVal, out value))
+ {
+ index++;
+ Value = (sbyte)(value * factor);
+ return true;
+ }
+
+ // Try to process as a hex string
+ string hexValue = RemoveHexIdentifier(baseVal);
+ if (sbyte.TryParse(hexValue, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out value))
+ {
+ index++;
+ Value = (sbyte)(value * factor);
+ return true;
+ }
+
+ // Return value based on required flag
+ Value = _required ? null : sbyte.MinValue;
+ return !_required;
+ }
+ }
+}
\ No newline at end of file
diff --git a/MPF.ExecutionContexts/Data/StringInput.cs b/MPF.ExecutionContexts/Data/StringInput.cs
new file mode 100644
index 00000000..bfd6585f
--- /dev/null
+++ b/MPF.ExecutionContexts/Data/StringInput.cs
@@ -0,0 +1,55 @@
+namespace MPF.ExecutionContexts.Data
+{
+ ///
+ /// Represents a string flag with an optional trailing value
+ ///
+ public class StringInput : Input
+ {
+ #region Constructors
+
+ ///
+ public StringInput(string name)
+ : base(name) { }
+
+ ///
+ public StringInput(string name, bool required)
+ : base(name, required) { }
+
+ ///
+ public StringInput(string shortName, string longName)
+ : base(shortName, longName) { }
+
+ ///
+ public StringInput(string shortName, string longName, bool required)
+ : base(shortName, longName, required) { }
+
+ #endregion
+
+ ///
+ public override bool Process(string[] parts, ref int index)
+ {
+ // Check the parts array
+ if (parts.Length == 0)
+ return false;
+
+ // Check the index
+ if (index < 0 || index >= parts.Length)
+ return false;
+
+ // Check the name
+ if (parts[index] != Name && (_longName != null && parts[index] != _longName))
+ return false;
+
+ // Ensure the value exists
+ if (!DoesExist(parts, index + 1))
+ {
+ Value = _required ? null : string.Empty;
+ return !_required;
+ }
+
+ index++;
+ Value = parts[index];
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/MPF.ExecutionContexts/Data/UInt16Input.cs b/MPF.ExecutionContexts/Data/UInt16Input.cs
new file mode 100644
index 00000000..8f05988e
--- /dev/null
+++ b/MPF.ExecutionContexts/Data/UInt16Input.cs
@@ -0,0 +1,83 @@
+using System.Globalization;
+
+namespace MPF.ExecutionContexts.Data
+{
+ ///
+ /// Represents an UInt16 flag with an optional trailing value
+ ///
+ public class UInt16Input : Input
+ {
+ #region Constructors
+
+ ///
+ public UInt16Input(string name)
+ : base(name) { }
+
+ ///
+ public UInt16Input(string name, bool required)
+ : base(name, required) { }
+
+ ///
+ public UInt16Input(string shortName, string longName)
+ : base(shortName, longName) { }
+
+ ///
+ public UInt16Input(string shortName, string longName, bool required)
+ : base(shortName, longName, required) { }
+
+ #endregion
+
+ ///
+ public override bool Process(string[] parts, ref int index)
+ {
+ // Check the parts array
+ if (parts.Length == 0)
+ return false;
+
+ // Check the index
+ if (index < 0 || index >= parts.Length)
+ return false;
+
+ // Check the name
+ if (parts[index] != Name && (_longName != null && parts[index] != _longName))
+ return false;
+
+ // Ensure the value exists
+ if (!DoesExist(parts, index + 1))
+ {
+ Value = _required ? null : ushort.MinValue;
+ return !_required;
+ }
+
+ // If the next value is valid
+ if (ushort.TryParse(parts[index + 1], out ushort value))
+ {
+ index++;
+ Value = value;
+ return true;
+ }
+
+ // Try to process as a formatted string
+ string baseVal = ExtractFactorFromValue(parts[index + 1], out long factor);
+ if (ushort.TryParse(baseVal, out value))
+ {
+ index++;
+ Value = (ushort)(value * factor);
+ return true;
+ }
+
+ // Try to process as a hex string
+ string hexValue = RemoveHexIdentifier(baseVal);
+ if (ushort.TryParse(hexValue, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out value))
+ {
+ index++;
+ Value = (ushort)(value * factor);
+ return true;
+ }
+
+ // Return value based on required flag
+ Value = _required ? null : ushort.MinValue;
+ return !_required;
+ }
+ }
+}
\ No newline at end of file
diff --git a/MPF.ExecutionContexts/Data/UInt32Input.cs b/MPF.ExecutionContexts/Data/UInt32Input.cs
new file mode 100644
index 00000000..c6afb746
--- /dev/null
+++ b/MPF.ExecutionContexts/Data/UInt32Input.cs
@@ -0,0 +1,83 @@
+using System.Globalization;
+
+namespace MPF.ExecutionContexts.Data
+{
+ ///
+ /// Represents an UInt32 flag with an optional trailing value
+ ///
+ public class UInt32Input : Input
+ {
+ #region Constructors
+
+ ///
+ public UInt32Input(string name)
+ : base(name) { }
+
+ ///
+ public UInt32Input(string name, bool required)
+ : base(name, required) { }
+
+ ///
+ public UInt32Input(string shortName, string longName)
+ : base(shortName, longName) { }
+
+ ///
+ public UInt32Input(string shortName, string longName, bool required)
+ : base(shortName, longName, required) { }
+
+ #endregion
+
+ ///
+ public override bool Process(string[] parts, ref int index)
+ {
+ // Check the parts array
+ if (parts.Length == 0)
+ return false;
+
+ // Check the index
+ if (index < 0 || index >= parts.Length)
+ return false;
+
+ // Check the name
+ if (parts[index] != Name && (_longName != null && parts[index] != _longName))
+ return false;
+
+ // Ensure the value exists
+ if (!DoesExist(parts, index + 1))
+ {
+ Value = _required ? null : uint.MinValue;
+ return !_required;
+ }
+
+ // If the next value is valid
+ if (uint.TryParse(parts[index + 1], out uint value))
+ {
+ index++;
+ Value = value;
+ return true;
+ }
+
+ // Try to process as a formatted string
+ string baseVal = ExtractFactorFromValue(parts[index + 1], out long factor);
+ if (uint.TryParse(baseVal, out value))
+ {
+ index++;
+ Value = (uint)(value * factor);
+ return true;
+ }
+
+ // Try to process as a hex string
+ string hexValue = RemoveHexIdentifier(baseVal);
+ if (uint.TryParse(hexValue, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out value))
+ {
+ index++;
+ Value = (uint)(value * factor);
+ return true;
+ }
+
+ // Return value based on required flag
+ Value = _required ? null : uint.MinValue;
+ return !_required;
+ }
+ }
+}
\ No newline at end of file
diff --git a/MPF.ExecutionContexts/Data/UInt64Input.cs b/MPF.ExecutionContexts/Data/UInt64Input.cs
new file mode 100644
index 00000000..7cfb8801
--- /dev/null
+++ b/MPF.ExecutionContexts/Data/UInt64Input.cs
@@ -0,0 +1,83 @@
+using System.Globalization;
+
+namespace MPF.ExecutionContexts.Data
+{
+ ///
+ /// Represents an UInt64 flag with an optional trailing value
+ ///
+ public class UInt64Input : Input
+ {
+ #region Constructors
+
+ ///
+ public UInt64Input(string name)
+ : base(name) { }
+
+ ///
+ public UInt64Input(string name, bool required)
+ : base(name, required) { }
+
+ ///
+ public UInt64Input(string shortName, string longName)
+ : base(shortName, longName) { }
+
+ ///
+ public UInt64Input(string shortName, string longName, bool required)
+ : base(shortName, longName, required) { }
+
+ #endregion
+
+ ///
+ public override bool Process(string[] parts, ref int index)
+ {
+ // Check the parts array
+ if (parts.Length == 0)
+ return false;
+
+ // Check the index
+ if (index < 0 || index >= parts.Length)
+ return false;
+
+ // Check the name
+ if (parts[index] != Name && (_longName != null && parts[index] != _longName))
+ return false;
+
+ // Ensure the value exists
+ if (!DoesExist(parts, index + 1))
+ {
+ Value = _required ? null : ulong.MinValue;
+ return !_required;
+ }
+
+ // If the next value is valid
+ if (ulong.TryParse(parts[index + 1], out ulong value))
+ {
+ index++;
+ Value = value;
+ return true;
+ }
+
+ // Try to process as a formatted string
+ string baseVal = ExtractFactorFromValue(parts[index + 1], out long factor);
+ if (ulong.TryParse(baseVal, out value))
+ {
+ index++;
+ Value = (ulong)(value * factor);
+ return true;
+ }
+
+ // Try to process as a hex string
+ string hexValue = RemoveHexIdentifier(baseVal);
+ if (ulong.TryParse(hexValue, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out value))
+ {
+ index++;
+ Value = (ulong)(value * factor);
+ return true;
+ }
+
+ // Return value based on required flag
+ Value = _required ? null : ulong.MinValue;
+ return !_required;
+ }
+ }
+}
\ No newline at end of file
diff --git a/MPF.ExecutionContexts/Data/UInt8Input.cs b/MPF.ExecutionContexts/Data/UInt8Input.cs
new file mode 100644
index 00000000..eb847466
--- /dev/null
+++ b/MPF.ExecutionContexts/Data/UInt8Input.cs
@@ -0,0 +1,83 @@
+using System.Globalization;
+
+namespace MPF.ExecutionContexts.Data
+{
+ ///
+ /// Represents an UInt8 flag with an optional trailing value
+ ///
+ public class UInt8Input : Input
+ {
+ #region Constructors
+
+ ///
+ public UInt8Input(string name)
+ : base(name) { }
+
+ ///
+ public UInt8Input(string name, bool required)
+ : base(name, required) { }
+
+ ///
+ public UInt8Input(string shortName, string longName)
+ : base(shortName, longName) { }
+
+ ///
+ public UInt8Input(string shortName, string longName, bool required)
+ : base(shortName, longName, required) { }
+
+ #endregion
+
+ ///
+ public override bool Process(string[] parts, ref int index)
+ {
+ // Check the parts array
+ if (parts.Length == 0)
+ return false;
+
+ // Check the index
+ if (index < 0 || index >= parts.Length)
+ return false;
+
+ // Check the name
+ if (parts[index] != Name && (_longName != null && parts[index] != _longName))
+ return false;
+
+ // Ensure the value exists
+ if (!DoesExist(parts, index + 1))
+ {
+ Value = _required ? null : byte.MinValue;
+ return !_required;
+ }
+
+ // If the next value is valid
+ if (byte.TryParse(parts[index + 1], out byte value))
+ {
+ index++;
+ Value = value;
+ return true;
+ }
+
+ // Try to process as a formatted string
+ string baseVal = ExtractFactorFromValue(parts[index + 1], out long factor);
+ if (byte.TryParse(baseVal, out value))
+ {
+ index++;
+ Value = (byte)(value * factor);
+ return true;
+ }
+
+ // Try to process as a hex string
+ string hexValue = RemoveHexIdentifier(baseVal);
+ if (byte.TryParse(hexValue, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out value))
+ {
+ index++;
+ Value = (byte)(value * factor);
+ return true;
+ }
+
+ // Return value based on required flag
+ Value = _required ? null : byte.MinValue;
+ return !_required;
+ }
+ }
+}
\ No newline at end of file
diff --git a/MPF.ExecutionContexts/Input.cs b/MPF.ExecutionContexts/Input.cs
deleted file mode 100644
index 818c67b6..00000000
--- a/MPF.ExecutionContexts/Input.cs
+++ /dev/null
@@ -1,753 +0,0 @@
-using System;
-using System.Globalization;
-
-namespace MPF.ExecutionContexts
-{
- ///
- /// Indicates the input type
- ///
- public enum InputType
- {
- None,
- Flag,
- Boolean,
- Int8,
- UInt8,
- Int16,
- UInt16,
- Int32,
- UInt32,
- Int64,
- UInt64,
- String,
- }
-
- ///
- /// Represents a single input for an execution context
- ///
- public class Input
- {
- #region Properties
-
- ///
- /// Input type for parsing
- ///
- public readonly InputType InputType;
-
- ///
- /// Primary name for the input
- ///
- public readonly string Name;
-
- ///
- /// Verbose name for the input
- ///
- private readonly string? _longName;
-
- ///
- /// Indicates if the value following is required or not
- ///
- private readonly bool _required;
-
- #endregion
-
- #region Constructors
-
- /// Type of input for parsing
- /// Flag name / value
- public Input(InputType type, string name)
- {
- InputType = type;
- Name = name;
- _longName = null;
- _required = true;
- }
-
- /// Type of input for parsing
- /// Flag name / value
- /// Indicates if a following value is required
- public Input(InputType type, string name, bool required)
- {
- InputType = type;
- Name = name;
- _longName = null;
- _required = required;
- }
-
- /// Type of input for parsing
- /// Flag name / value
- /// Verbose flag name / value
- public Input(InputType type, string shortName, string longName)
- {
- InputType = type;
- Name = shortName;
- _longName = longName;
- _required = true;
- }
-
- /// Type of input for parsing
- /// Flag name / value
- /// Verbose flag name / value
- /// Indicates if a following value is required
- public Input(InputType type, string shortName, string longName, bool required)
- {
- InputType = type;
- Name = shortName;
- _longName = longName;
- _required = required;
- }
-
- #endregion
-
- #region Processors
-
- ///
- /// Process the input as a flag
- ///
- /// Parts array to be referenced
- /// Reference to the position in the parts
- /// True if the flag was set, false otherwise
- public bool ProcessAsFlag(string[] parts, ref int index)
- {
- // Check the input type
- if (InputType != InputType.Flag)
- return false;
-
- // Check the parts array
- if (parts.Length == 0)
- return false;
-
- // Check the index
- if (index < 0 || index >= parts.Length)
- return false;
-
- // Check the name
- if (parts[index] == Name || (_longName != null && parts[index] == _longName))
- return true;
-
- return false;
- }
-
- ///
- /// Process the input as a boolean
- ///
- /// Parts array to be referenced
- /// Reference to the position in the parts
- /// Boolean value if set, null otherwise
- public bool? ProcessAsBoolean(string[] parts, ref int index)
- {
- // Check the input type
- if (InputType != InputType.Boolean)
- return null;
-
- // Check the parts array
- if (parts == null || parts.Length == 0)
- return null;
-
- // Check the index
- if (index < 0 || index >= parts.Length)
- return null;
-
- // Check the name
- if (parts[index] == Name || (_longName != null && parts[index] == _longName))
- {
- // Ensure the value exists
- if (!DoesExist(parts, index + 1))
- return _required ? null : true;
-
- // If the next value is valid
- if (!bool.TryParse(parts[index + 1], out bool value))
- return _required ? null : true;
-
- index++;
- return value;
- }
-
- return null;
- }
-
- ///
- /// Process the input as an Int8
- ///
- /// Parts array to be referenced
- /// Reference to the position in the parts
- /// Int8 value if set, minimum value if not required and missing, null otherwise
- public sbyte? ProcessAsInt8(string[] parts, ref int index)
- {
- // Check the input type
- if (InputType != InputType.Int8)
- return null;
-
- // Check the parts array
- if (parts == null || parts.Length == 0)
- return null;
-
- // Check the index
- if (index < 0 || index >= parts.Length)
- return null;
-
- // Check the name
- if (parts[index] == Name || (_longName != null && parts[index] == _longName))
- {
- // Ensure the value exists
- if (!DoesExist(parts, index + 1))
- return _required ? null : sbyte.MinValue;
-
- // If the next value is valid
- if (sbyte.TryParse(parts[index + 1], out sbyte value))
- {
- index++;
- return value;
- }
-
- // Try to process as a formatted string
- string baseVal = ExtractFactorFromValue(parts[index + 1], out long factor);
- if (sbyte.TryParse(baseVal, out value))
- {
- index++;
- return (sbyte)(value * factor);
- }
-
- // Try to process as a hex string
- string hexValue = RemoveHexIdentifier(baseVal);
- if (sbyte.TryParse(hexValue, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out value))
- {
- index++;
- return (sbyte)(value * factor);
- }
-
- // Return value based on required flag
- return _required ? null : sbyte.MinValue;
- }
-
- return null;
- }
-
- ///
- /// Process the input as a UInt8
- ///
- /// Parts array to be referenced
- /// Reference to the position in the parts
- /// UInt8 value if set, minimum value if not required and missing, null otherwise
- public byte? ProcessAsUInt8(string[] parts, ref int index)
- {
- // Check the input type
- if (InputType != InputType.UInt8)
- return null;
-
- // Check the parts array
- if (parts == null || parts.Length == 0)
- return null;
-
- // Check the index
- if (index < 0 || index >= parts.Length)
- return null;
-
- // Check the name
- if (parts[index] == Name || (_longName != null && parts[index] == _longName))
- {
- // Ensure the value exists
- if (!DoesExist(parts, index + 1))
- return _required ? null : byte.MinValue;
-
- // If the next value is valid
- if (byte.TryParse(parts[index + 1], out byte value))
- {
- index++;
- return value;
- }
-
- // Try to process as a formatted string
- string baseVal = ExtractFactorFromValue(parts[index + 1], out long factor);
- if (byte.TryParse(baseVal, out value))
- {
- index++;
- return (byte)(value * factor);
- }
-
- // Try to process as a hex string
- string hexValue = RemoveHexIdentifier(baseVal);
- if (byte.TryParse(hexValue, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out value))
- {
- index++;
- return (byte)(value * factor);
- }
-
- // Return value based on required flag
- return _required ? null : byte.MinValue;
- }
-
- return null;
- }
-
- ///
- /// Process the input as an Int16
- ///
- /// Parts array to be referenced
- /// Reference to the position in the parts
- /// Int16 value if set, minimum value if not required and missing, null otherwise
- public short? ProcessAsInt16(string[] parts, ref int index)
- {
- // Check the input type
- if (InputType != InputType.Int16)
- return null;
-
- // Check the parts array
- if (parts == null || parts.Length == 0)
- return null;
-
- // Check the index
- if (index < 0 || index >= parts.Length)
- return null;
-
- // Check the name
- if (parts[index] == Name || (_longName != null && parts[index] == _longName))
- {
- // Ensure the value exists
- if (!DoesExist(parts, index + 1))
- return _required ? null : short.MinValue;
-
- // If the next value is valid
- if (short.TryParse(parts[index + 1], out short value))
- {
- index++;
- return value;
- }
-
- // Try to process as a formatted string
- string baseVal = ExtractFactorFromValue(parts[index + 1], out long factor);
- if (short.TryParse(baseVal, out value))
- {
- index++;
- return (short)(value * factor);
- }
-
- // Try to process as a hex string
- string hexValue = RemoveHexIdentifier(baseVal);
- if (short.TryParse(hexValue, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out value))
- {
- index++;
- return (short)(value * factor);
- }
-
- // Return value based on required flag
- return _required ? null : short.MinValue;
- }
-
- return null;
- }
-
- ///
- /// Process the input as a UInt16
- ///
- /// Parts array to be referenced
- /// Reference to the position in the parts
- /// UInt16 value if set, minimum value if not required and missing, null otherwise
- public ushort? ProcessAsUInt16(string[] parts, ref int index)
- {
- // Check the input type
- if (InputType != InputType.UInt16)
- return null;
-
- // Check the parts array
- if (parts == null || parts.Length == 0)
- return null;
-
- // Check the index
- if (index < 0 || index >= parts.Length)
- return null;
-
- // Check the name
- if (parts[index] == Name || (_longName != null && parts[index] == _longName))
- {
- // Ensure the value exists
- if (!DoesExist(parts, index + 1))
- return _required ? null : ushort.MinValue;
-
- // If the next value is valid
- if (ushort.TryParse(parts[index + 1], out ushort value))
- {
- index++;
- return value;
- }
-
- // Try to process as a formatted string
- string baseVal = ExtractFactorFromValue(parts[index + 1], out long factor);
- if (ushort.TryParse(baseVal, out value))
- {
- index++;
- return (ushort)(value * factor);
- }
-
- // Try to process as a hex string
- string hexValue = RemoveHexIdentifier(baseVal);
- if (ushort.TryParse(hexValue, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out value))
- {
- index++;
- return (ushort)(value * factor);
- }
-
- // Return value based on required flag
- return _required ? null : ushort.MinValue;
- }
-
- return null;
- }
-
- ///
- /// Process the input as an Int32
- ///
- /// Parts array to be referenced
- /// Reference to the position in the parts
- /// Int32 value if set, minimum value if not required and missing, null otherwise
- public int? ProcessAsInt32(string[] parts, ref int index)
- {
- // Check the input type
- if (InputType != InputType.Int32)
- return null;
-
- // Check the parts array
- if (parts == null || parts.Length == 0)
- return null;
-
- // Check the index
- if (index < 0 || index >= parts.Length)
- return null;
-
- // Check the name
- if (parts[index] == Name || (_longName != null && parts[index] == _longName))
- {
- // Ensure the value exists
- if (!DoesExist(parts, index + 1))
- return _required ? null : int.MinValue;
-
- // If the next value is valid
- if (int.TryParse(parts[index + 1], out int value))
- {
- index++;
- return value;
- }
-
- // Try to process as a formatted string
- string baseVal = ExtractFactorFromValue(parts[index + 1], out long factor);
- if (int.TryParse(baseVal, out value))
- {
- index++;
- return (int)(value * factor);
- }
-
- // Try to process as a hex string
- string hexValue = RemoveHexIdentifier(baseVal);
- if (int.TryParse(hexValue, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out value))
- {
- index++;
- return (int)(value * factor);
- }
-
- // Return value based on required flag
- return _required ? null : int.MinValue;
- }
-
- return null;
- }
-
- ///
- /// Process the input as a UInt32
- ///
- /// Parts array to be referenced
- /// Reference to the position in the parts
- /// UInt32 value if set, minimum value if not required and missing, null otherwise
- public uint? ProcessAsUInt32(string[] parts, ref int index)
- {
- // Check the input type
- if (InputType != InputType.UInt32)
- return null;
-
- // Check the parts array
- if (parts == null || parts.Length == 0)
- return null;
-
- // Check the index
- if (index < 0 || index >= parts.Length)
- return null;
-
- // Check the name
- if (parts[index] == Name || (_longName != null && parts[index] == _longName))
- {
- // Ensure the value exists
- if (!DoesExist(parts, index + 1))
- return _required ? null : uint.MinValue;
-
- // If the next value is valid
- if (uint.TryParse(parts[index + 1], out uint value))
- {
- index++;
- return value;
- }
-
- // Try to process as a formatted string
- string baseVal = ExtractFactorFromValue(parts[index + 1], out long factor);
- if (uint.TryParse(baseVal, out value))
- {
- index++;
- return (uint)(value * factor);
- }
-
- // Try to process as a hex string
- string hexValue = RemoveHexIdentifier(baseVal);
- if (uint.TryParse(hexValue, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out value))
- {
- index++;
- return (uint)(value * factor);
- }
-
- // Return value based on required flag
- return _required ? null : uint.MinValue;
- }
-
- return null;
- }
-
- ///
- /// Process the input as an Int64
- ///
- /// Parts array to be referenced
- /// Reference to the position in the parts
- /// Int64 value if set, minimum value if not required and missing, null otherwise
- public long? ProcessAsInt64(string[] parts, ref int index)
- {
- // Check the input type
- if (InputType != InputType.Int64)
- return null;
-
- // Check the parts array
- if (parts == null || parts.Length == 0)
- return null;
-
- // Check the index
- if (index < 0 || index >= parts.Length)
- return null;
-
- // Check the name
- if (parts[index] == Name || (_longName != null && parts[index] == _longName))
- {
- // Ensure the value exists
- if (!DoesExist(parts, index + 1))
- return _required ? null : long.MinValue;
-
- // If the next value is valid
- if (long.TryParse(parts[index + 1], out long value))
- {
- index++;
- return value;
- }
-
- // Try to process as a formatted string
- string baseVal = ExtractFactorFromValue(parts[index + 1], out long factor);
- if (long.TryParse(baseVal, out value))
- {
- index++;
- return (long)(value * factor);
- }
-
- // Try to process as a hex string
- string hexValue = RemoveHexIdentifier(baseVal);
- if (long.TryParse(hexValue, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out value))
- {
- index++;
- return (long)(value * factor);
- }
-
- // Return value based on required flag
- return _required ? null : long.MinValue;
- }
-
- return null;
- }
-
- ///
- /// Process the input as a UInt64
- ///
- /// Parts array to be referenced
- /// Reference to the position in the parts
- /// UInt64 value if set, minimum value if not required and missing, null otherwise
- public ulong? ProcessAsUInt64(string[] parts, ref int index)
- {
- // Check the input type
- if (InputType != InputType.UInt64)
- return null;
-
- // Check the parts array
- if (parts == null || parts.Length == 0)
- return null;
-
- // Check the index
- if (index < 0 || index >= parts.Length)
- return null;
-
- // Check the name
- if (parts[index] == Name || (_longName != null && parts[index] == _longName))
- {
- // Ensure the value exists
- if (!DoesExist(parts, index + 1))
- return _required ? null : ulong.MinValue;
-
- // If the next value is valid
- if (ulong.TryParse(parts[index + 1], out ulong value))
- {
- index++;
- return value;
- }
-
- // Try to process as a formatted string
- string baseVal = ExtractFactorFromValue(parts[index + 1], out long factor);
- if (ulong.TryParse(baseVal, out value))
- {
- index++;
- return (ulong)(value * (ulong)factor);
- }
-
- // Try to process as a hex string
- string hexValue = RemoveHexIdentifier(baseVal);
- if (ulong.TryParse(hexValue, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out value))
- {
- index++;
- return (ulong)(value * (ulong)factor);
- }
-
- // Return value based on required flag
- return _required ? null : ulong.MinValue;
- }
-
- return null;
- }
-
- ///
- /// Process the input as a UInt64
- ///
- /// Parts array to be referenced
- /// Reference to the position in the parts
- /// String value if set, empty value if not required and missing, null otherwise
- public string? ProcessAsString(string[] parts, ref int index)
- {
- // Check the input type
- if (InputType != InputType.String)
- return null;
-
- // Check the parts array
- if (parts == null || parts.Length == 0)
- return null;
-
- // Check the index
- if (index < 0 || index >= parts.Length)
- return null;
-
- // Check the name
- if (parts[index] == Name || (_longName != null && parts[index] == _longName))
- {
- // Ensure the value exists
- if (!DoesExist(parts, index + 1))
- return _required ? null : string.Empty;
-
- index++;
- return parts[index];
- }
-
- return null;
- }
-
- #endregion
-
- #region Helpers
-
- ///
- /// Returns whether or not the selected item exists
- ///
- /// Parts array to be referenced
- /// Current index
- /// True if the next item exists, false otherwise
- internal static bool DoesExist(string[] parts, int index)
- => index >= 0 && index < parts.Length;
-
- ///
- /// Get the trimmed value and multiplication factor from a value
- ///
- /// String value to treat as suffixed number
- /// Trimmed value and multiplication factor
- internal static string ExtractFactorFromValue(string value, out long factor)
- {
- value = value.Trim('"');
- factor = 1;
-
- // Characters
- if (value.EndsWith("c", StringComparison.Ordinal))
- {
- factor = 1;
- value = value.TrimEnd('c');
- }
-
- // Words
- else if (value.EndsWith("w", StringComparison.Ordinal))
- {
- factor = 2;
- value = value.TrimEnd('w');
- }
-
- // Double Words
- else if (value.EndsWith("d", StringComparison.Ordinal))
- {
- factor = 4;
- value = value.TrimEnd('d');
- }
-
- // Quad Words
- else if (value.EndsWith("q", StringComparison.Ordinal))
- {
- factor = 8;
- value = value.TrimEnd('q');
- }
-
- // Kilobytes
- else if (value.EndsWith("k", StringComparison.Ordinal))
- {
- factor = 1024;
- value = value.TrimEnd('k');
- }
-
- // Megabytes
- else if (value.EndsWith("M", StringComparison.Ordinal))
- {
- factor = 1024 * 1024;
- value = value.TrimEnd('M');
- }
-
- // Gigabytes
- else if (value.EndsWith("G", StringComparison.Ordinal))
- {
- factor = 1024 * 1024 * 1024;
- value = value.TrimEnd('G');
- }
-
- return value;
- }
-
- ///
- /// Removes a leading 0x if it exists, case insensitive
- ///
- /// String with removed leading 0x
- ///
- internal static string RemoveHexIdentifier(string value)
- {
- if (value.Length <= 2)
- return value;
- if (value[0] != '0')
- return value;
- if (value[1] != 'x' && value[1] != 'X')
- return value;
-
- return value.Substring(2);
- }
-
- #endregion
- }
-}
\ No newline at end of file