diff --git a/src/Generation/Generator/Renderer/Internal/Parameter/CallbackParameters.cs b/src/Generation/Generator/Renderer/Internal/Parameter/CallbackParameters.cs index 5db16351d..0ada82832 100644 --- a/src/Generation/Generator/Renderer/Internal/Parameter/CallbackParameters.cs +++ b/src/Generation/Generator/Renderer/Internal/Parameter/CallbackParameters.cs @@ -25,6 +25,8 @@ internal static class CallbackParameters new Parameter.PointerArray(), new Parameter.PointerGLibArray(), new Parameter.PointerGLibPtrArray(), + new Parameter.Long(), //Must be before primitive value type + new Parameter.UnsignedLong(), //Must be before primitive value type new Parameter.PrimitiveValueType(), new Parameter.PrimitiveValueTypeAlias(), new Parameter.PrimitiveValueTypeArray(), diff --git a/src/Generation/Generator/Renderer/Internal/Parameter/Converter/Long.cs b/src/Generation/Generator/Renderer/Internal/Parameter/Converter/Long.cs new file mode 100644 index 000000000..b1055f050 --- /dev/null +++ b/src/Generation/Generator/Renderer/Internal/Parameter/Converter/Long.cs @@ -0,0 +1,44 @@ +using System; + +namespace Generator.Renderer.Internal.Parameter; + +internal class Long : ParameterConverter +{ + public bool Supports(GirModel.AnyType anyType) + { + return anyType.Is(); + } + + public RenderableParameter Convert(GirModel.Parameter parameter) + { + // If the parameter is both nullable and optional this implies a parameter type like 'int **' and possibly + // ownership transfer (this combination does not currently occur for any functions). + if (parameter is { Nullable: true, Optional: true }) + throw new System.NotImplementedException($"{parameter.AnyTypeOrVarArgs} - Long value type with nullable=true and optional=true not yet supported"); + + // Nullable-only parameters likely have incorrect annotations and should be marked optional instead. + if (parameter.Nullable) + Log.Information($"Long value type '{parameter.Name}' with nullable=true is likely an incorrect annotation"); + + // The caller-allocates flag is not meaningful for primitive types (https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/446) + if (parameter.CallerAllocates) + Log.Information($"Long value type '{parameter.Name}' with caller-allocates=true is an incorrect annotation"); + + return new RenderableParameter( + Attribute: string.Empty, + Direction: GetDirection(parameter), + NullableTypeName: "CLong", + Name: Model.Parameter.GetName(parameter) + ); + } + + private static string GetDirection(GirModel.Parameter parameter) => parameter switch + { + // - Optional inout and out types are just exposed as non-nullable ref / out parameters which the user can ignore if desired. + { Direction: GirModel.Direction.In, IsPointer: true } => ParameterDirection.Ref(), + { Direction: GirModel.Direction.InOut } => ParameterDirection.Ref(), + { Direction: GirModel.Direction.Out } => ParameterDirection.Out(), + { Direction: GirModel.Direction.In } => ParameterDirection.In(), + _ => throw new Exception($"Can't figure out direction for internal long value type parameter {parameter}.") + }; +} diff --git a/src/Generation/Generator/Renderer/Internal/Parameter/Converter/UnsignedLong.cs b/src/Generation/Generator/Renderer/Internal/Parameter/Converter/UnsignedLong.cs new file mode 100644 index 000000000..d5396f0e1 --- /dev/null +++ b/src/Generation/Generator/Renderer/Internal/Parameter/Converter/UnsignedLong.cs @@ -0,0 +1,44 @@ +using System; + +namespace Generator.Renderer.Internal.Parameter; + +internal class UnsignedLong : ParameterConverter +{ + public bool Supports(GirModel.AnyType anyType) + { + return anyType.Is(); + } + + public RenderableParameter Convert(GirModel.Parameter parameter) + { + // If the parameter is both nullable and optional this implies a parameter type like 'int **' and possibly + // ownership transfer (this combination does not currently occur for any functions). + if (parameter is { Nullable: true, Optional: true }) + throw new System.NotImplementedException($"{parameter.AnyTypeOrVarArgs} - Unsigned long value type with nullable=true and optional=true not yet supported"); + + // Nullable-only parameters likely have incorrect annotations and should be marked optional instead. + if (parameter.Nullable) + Log.Information($"Unsigned long value type '{parameter.Name}' with nullable=true is likely an incorrect annotation"); + + // The caller-allocates flag is not meaningful for primitive types (https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/446) + if (parameter.CallerAllocates) + Log.Information($"Unsigned long value type '{parameter.Name}' with caller-allocates=true is an incorrect annotation"); + + return new RenderableParameter( + Attribute: string.Empty, + Direction: GetDirection(parameter), + NullableTypeName: "CULong", + Name: Model.Parameter.GetName(parameter) + ); + } + + private static string GetDirection(GirModel.Parameter parameter) => parameter switch + { + // - Optional inout and out types are just exposed as non-nullable ref / out parameters which the user can ignore if desired. + { Direction: GirModel.Direction.In, IsPointer: true } => ParameterDirection.Ref(), + { Direction: GirModel.Direction.InOut } => ParameterDirection.Ref(), + { Direction: GirModel.Direction.Out } => ParameterDirection.Out(), + { Direction: GirModel.Direction.In } => ParameterDirection.In(), + _ => throw new Exception($"Can't figure out direction for internal unsigned long value type parameter {parameter}.") + }; +} diff --git a/src/Generation/Generator/Renderer/Internal/Parameter/Parameters.cs b/src/Generation/Generator/Renderer/Internal/Parameter/Parameters.cs index d09afe6ac..144b0c531 100644 --- a/src/Generation/Generator/Renderer/Internal/Parameter/Parameters.cs +++ b/src/Generation/Generator/Renderer/Internal/Parameter/Parameters.cs @@ -30,6 +30,8 @@ internal static class Parameters new Parameter.PointerArray(), new Parameter.PointerGLibArray(), new Parameter.PointerGLibPtrArray(), + new Parameter.Long(), //Must be before primitive value type + new Parameter.UnsignedLong(), //Must be before primitive value type new Parameter.PrimitiveValueType(), new Parameter.PrimitiveValueTypeAlias(), new Parameter.PrimitiveValueTypeArray(), diff --git a/src/Generation/Generator/Renderer/Internal/ParameterToManagedExpression/Converter/Long.cs b/src/Generation/Generator/Renderer/Internal/ParameterToManagedExpression/Converter/Long.cs new file mode 100644 index 000000000..eb69e0b5e --- /dev/null +++ b/src/Generation/Generator/Renderer/Internal/ParameterToManagedExpression/Converter/Long.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; + +namespace Generator.Renderer.Internal.ParameterToManagedExpressions; + +internal class Long : ToManagedParameterConverter +{ + public bool Supports(GirModel.AnyType type) + => type.Is(); + + public void Initialize(ParameterToManagedData parameterData, IEnumerable parameters) + { + switch (parameterData.Parameter) + { + case { Direction: GirModel.Direction.In, IsPointer: false }: + Direct(parameterData); + break; + default: + throw new NotImplementedException($"This kind of internal long value type (pointed: {parameterData.Parameter.IsPointer}, direction: {parameterData.Parameter.Direction} can't be converted to managed currently."); + } + } + + private static void Direct(ParameterToManagedData parameterData) + { + var variableName = Model.Parameter.GetName(parameterData.Parameter); + + parameterData.SetSignatureName(() => variableName); + parameterData.SetCallName(() => $"{variableName}.Value"); + } +} diff --git a/src/Generation/Generator/Renderer/Internal/ParameterToManagedExpression/Converter/UnsignedLong.cs b/src/Generation/Generator/Renderer/Internal/ParameterToManagedExpression/Converter/UnsignedLong.cs new file mode 100644 index 000000000..97e667229 --- /dev/null +++ b/src/Generation/Generator/Renderer/Internal/ParameterToManagedExpression/Converter/UnsignedLong.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; + +namespace Generator.Renderer.Internal.ParameterToManagedExpressions; + +internal class UnsignedLong : ToManagedParameterConverter +{ + public bool Supports(GirModel.AnyType type) + => type.Is(); + + public void Initialize(ParameterToManagedData parameterData, IEnumerable parameters) + { + switch (parameterData.Parameter) + { + case { Direction: GirModel.Direction.In, IsPointer: false }: + Direct(parameterData); + break; + default: + throw new NotImplementedException($"This kind of internal unsigned long value type (pointed: {parameterData.Parameter.IsPointer}, direction: {parameterData.Parameter.Direction} can't be converted to managed currently."); + } + } + + private static void Direct(ParameterToManagedData parameterData) + { + var variableName = Model.Parameter.GetName(parameterData.Parameter); + + parameterData.SetSignatureName(() => variableName); + parameterData.SetCallName(() => $"{variableName}.Value"); + } +} diff --git a/src/Generation/Generator/Renderer/Internal/ParameterToManagedExpression/ParameterToManagedExpression.cs b/src/Generation/Generator/Renderer/Internal/ParameterToManagedExpression/ParameterToManagedExpression.cs index dc4b5c151..c02d67e18 100644 --- a/src/Generation/Generator/Renderer/Internal/ParameterToManagedExpression/ParameterToManagedExpression.cs +++ b/src/Generation/Generator/Renderer/Internal/ParameterToManagedExpression/ParameterToManagedExpression.cs @@ -19,6 +19,8 @@ internal static class ParameterToManagedExpression new ParameterToManagedExpressions.PlatformStringArray(), new ParameterToManagedExpressions.Pointer(), new ParameterToManagedExpressions.PointerAlias(), + new ParameterToManagedExpressions.Long(), //Must be before primitive value type + new ParameterToManagedExpressions.UnsignedLong(), //Must be before primitive value type new ParameterToManagedExpressions.PrimitiveValueType(), new ParameterToManagedExpressions.PrimitiveValueTypeAlias(), new ParameterToManagedExpressions.PrimitiveValueTypeArray(), diff --git a/src/Generation/Generator/Renderer/Internal/ReturnType/Converter/Long.cs b/src/Generation/Generator/Renderer/Internal/ReturnType/Converter/Long.cs new file mode 100644 index 000000000..b8b12d08b --- /dev/null +++ b/src/Generation/Generator/Renderer/Internal/ReturnType/Converter/Long.cs @@ -0,0 +1,18 @@ +namespace Generator.Renderer.Internal.ReturnType; + +internal class Long : ReturnTypeConverter +{ + public bool Supports(GirModel.ReturnType returnType) + { + return returnType.AnyType.Is(); + } + + public RenderableReturnType Convert(GirModel.ReturnType returnType) + { + var nullableTypeName = returnType.IsPointer + ? Model.Type.Pointer + : "CLong"; + + return new RenderableReturnType(nullableTypeName); + } +} diff --git a/src/Generation/Generator/Renderer/Internal/ReturnType/Converter/UnsignedLong.cs b/src/Generation/Generator/Renderer/Internal/ReturnType/Converter/UnsignedLong.cs new file mode 100644 index 000000000..02c52fc3b --- /dev/null +++ b/src/Generation/Generator/Renderer/Internal/ReturnType/Converter/UnsignedLong.cs @@ -0,0 +1,18 @@ +namespace Generator.Renderer.Internal.ReturnType; + +internal class UnsignedLong : ReturnTypeConverter +{ + public bool Supports(GirModel.ReturnType returnType) + { + return returnType.AnyType.Is(); + } + + public RenderableReturnType Convert(GirModel.ReturnType returnType) + { + var nullableTypeName = returnType.IsPointer + ? Model.Type.Pointer + : "CULong"; + + return new RenderableReturnType(nullableTypeName); + } +} diff --git a/src/Generation/Generator/Renderer/Internal/ReturnType/ReturnTypeRenderer.cs b/src/Generation/Generator/Renderer/Internal/ReturnType/ReturnTypeRenderer.cs index aca66c52a..6f16a6835 100644 --- a/src/Generation/Generator/Renderer/Internal/ReturnType/ReturnTypeRenderer.cs +++ b/src/Generation/Generator/Renderer/Internal/ReturnType/ReturnTypeRenderer.cs @@ -19,6 +19,8 @@ internal static class ReturnTypeRenderer new ReturnType.PlatformStringArray(), new ReturnType.Pointer(), new ReturnType.PointerAlias(), + new ReturnType.Long(), //Must be before primitive value type + new ReturnType.UnsignedLong(), //Must be before primitive value type new ReturnType.PrimitiveValueType(), new ReturnType.PrimitiveValueTypeAlias(), new ReturnType.PrimitiveValueTypeArray(), diff --git a/src/Generation/Generator/Renderer/Internal/ReturnType/ReturnTypeRendererCallback.cs b/src/Generation/Generator/Renderer/Internal/ReturnType/ReturnTypeRendererCallback.cs index c988a6c98..cdc5998b9 100644 --- a/src/Generation/Generator/Renderer/Internal/ReturnType/ReturnTypeRendererCallback.cs +++ b/src/Generation/Generator/Renderer/Internal/ReturnType/ReturnTypeRendererCallback.cs @@ -18,6 +18,8 @@ internal static class ReturnTypeRendererCallback new ReturnType.PlatformStringInCallback(), new ReturnType.PlatformStringArrayInCallback(), new ReturnType.Pointer(), + new ReturnType.Long(), + new ReturnType.UnsignedLong(), new ReturnType.PrimitiveValueType(), new ReturnType.PrimitiveValueTypeAlias(), new ReturnType.PrimitiveValueTypeArray(), diff --git a/src/Generation/Generator/Renderer/Internal/ReturnTypeToNativeExpression/Converter/Long.cs b/src/Generation/Generator/Renderer/Internal/ReturnTypeToNativeExpression/Converter/Long.cs new file mode 100644 index 000000000..a85d2d855 --- /dev/null +++ b/src/Generation/Generator/Renderer/Internal/ReturnTypeToNativeExpression/Converter/Long.cs @@ -0,0 +1,10 @@ +namespace Generator.Renderer.Internal.ReturnTypeToNativeExpressions; + +internal class Long : ReturnTypeConverter +{ + public bool Supports(GirModel.AnyType type) + => type.Is(); + + public string GetString(GirModel.ReturnType returnType, string fromVariableName) + => $"new CLong(checked((nint){fromVariableName}))"; +} diff --git a/src/Generation/Generator/Renderer/Internal/ReturnTypeToNativeExpression/Converter/UnsignedLong.cs b/src/Generation/Generator/Renderer/Internal/ReturnTypeToNativeExpression/Converter/UnsignedLong.cs new file mode 100644 index 000000000..d12586849 --- /dev/null +++ b/src/Generation/Generator/Renderer/Internal/ReturnTypeToNativeExpression/Converter/UnsignedLong.cs @@ -0,0 +1,10 @@ +namespace Generator.Renderer.Internal.ReturnTypeToNativeExpressions; + +internal class UnsigendLong : ReturnTypeConverter +{ + public bool Supports(GirModel.AnyType type) + => type.Is(); + + public string GetString(GirModel.ReturnType returnType, string fromVariableName) + => $"new CULong(checked((nuint){fromVariableName}))"; +} diff --git a/src/Generation/Generator/Renderer/Internal/ReturnTypeToNativeExpression/ReturnTypeToNativeExpression.cs b/src/Generation/Generator/Renderer/Internal/ReturnTypeToNativeExpression/ReturnTypeToNativeExpression.cs index 524cf98fc..1ec15ad88 100644 --- a/src/Generation/Generator/Renderer/Internal/ReturnTypeToNativeExpression/ReturnTypeToNativeExpression.cs +++ b/src/Generation/Generator/Renderer/Internal/ReturnTypeToNativeExpression/ReturnTypeToNativeExpression.cs @@ -14,6 +14,8 @@ internal static class ReturnTypeToNativeExpression new ReturnTypeToNativeExpressions.OpaqueTypedRecord(), new ReturnTypeToNativeExpressions.OpaqueUntypedRecord(), new ReturnTypeToNativeExpressions.Pointer(), + new ReturnTypeToNativeExpressions.Long(), //Must be before Primitive value type + new ReturnTypeToNativeExpressions.UnsigendLong(), //Must be before primitive value type new ReturnTypeToNativeExpressions.PrimitiveValueType(), new ReturnTypeToNativeExpressions.PrimitiveValueTypeAlias(), new ReturnTypeToNativeExpressions.TypedRecord(), diff --git a/src/Generation/Generator/Renderer/Public/Field/Converter/Long.cs b/src/Generation/Generator/Renderer/Public/Field/Converter/Long.cs index 2c07f6f35..e16c5f4d7 100644 --- a/src/Generation/Generator/Renderer/Public/Field/Converter/Long.cs +++ b/src/Generation/Generator/Renderer/Public/Field/Converter/Long.cs @@ -26,7 +26,7 @@ private static string GetNullableTypeName(GirModel.Field field) private static string SetExpression(GirModel.Record record, GirModel.Field field) { - return $"Handle.Set{Model.Field.GetName(field)}(new CLong((nint)value))"; + return $"Handle.Set{Model.Field.GetName(field)}(new CLong(checked((nint)value)))"; } private static string GetExpression(GirModel.Record record, GirModel.Field field) diff --git a/src/Generation/Generator/Renderer/Public/Field/Converter/UnsignedLong.cs b/src/Generation/Generator/Renderer/Public/Field/Converter/UnsignedLong.cs index cb6d1e575..44f335bd4 100644 --- a/src/Generation/Generator/Renderer/Public/Field/Converter/UnsignedLong.cs +++ b/src/Generation/Generator/Renderer/Public/Field/Converter/UnsignedLong.cs @@ -26,7 +26,7 @@ private static string GetNullableTypeName(GirModel.Field field) private static string SetExpression(GirModel.Record record, GirModel.Field field) { - return $"Handle.Set{Model.Field.GetName(field)}(new CULong((nuint)value))"; + return $"Handle.Set{Model.Field.GetName(field)}(new CULong(checked((nuint)value)))"; } private static string GetExpression(GirModel.Record record, GirModel.Field field) diff --git a/src/Generation/Generator/Renderer/Public/ParameterToNativeExpression/Converter/Long.cs b/src/Generation/Generator/Renderer/Public/ParameterToNativeExpression/Converter/Long.cs new file mode 100644 index 000000000..dce7942a0 --- /dev/null +++ b/src/Generation/Generator/Renderer/Public/ParameterToNativeExpression/Converter/Long.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; + +namespace Generator.Renderer.Public.ParameterToNativeExpressions; + +internal class Long : ToNativeParameterConverter +{ + public bool Supports(GirModel.AnyType type) + => type.Is(); + + public void Initialize(ParameterToNativeData parameter, IEnumerable _) + { + //Array length parameters are handled as part of the corresponding array converters + if (parameter.IsArrayLengthParameter) + return; + + switch (parameter.Parameter) + { + case { IsPointer: false, Direction: GirModel.Direction.In }: + Direct(parameter); + break; + default: + throw new NotImplementedException($"{parameter.Parameter.AnyTypeOrVarArgs}: This long value type can not yet be converted to native"); + } + } + + private static void Direct(ParameterToNativeData parameter) + { + var parameterName = Model.Parameter.GetName(parameter.Parameter); + parameter.SetSignatureName(() => parameterName); + parameter.SetCallName(() => $"new CLong(checked((nint) {parameterName}))"); + } +} diff --git a/src/Generation/Generator/Renderer/Public/ParameterToNativeExpression/Converter/UnsignedLong.cs b/src/Generation/Generator/Renderer/Public/ParameterToNativeExpression/Converter/UnsignedLong.cs new file mode 100644 index 000000000..7b4a47c2c --- /dev/null +++ b/src/Generation/Generator/Renderer/Public/ParameterToNativeExpression/Converter/UnsignedLong.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; + +namespace Generator.Renderer.Public.ParameterToNativeExpressions; + +internal class UnsignedLong : ToNativeParameterConverter +{ + public bool Supports(GirModel.AnyType type) + => type.Is(); + + public void Initialize(ParameterToNativeData parameter, IEnumerable _) + { + //Array length parameters are handled as part of the corresponding array converters + if (parameter.IsArrayLengthParameter) + return; + + switch (parameter.Parameter) + { + case { IsPointer: false, Direction: GirModel.Direction.In }: + Direct(parameter); + break; + default: + throw new NotImplementedException($"{parameter.Parameter.AnyTypeOrVarArgs}: This unsigned long value type can not yet be converted to native"); + } + } + + private static void Direct(ParameterToNativeData parameter) + { + var parameterName = Model.Parameter.GetName(parameter.Parameter); + parameter.SetSignatureName(() => parameterName); + parameter.SetCallName(() => $"new CULong(checked((nuint) {parameterName}))"); + } +} diff --git a/src/Generation/Generator/Renderer/Public/ParameterToNativeExpression/ParameterToNativeExpression.cs b/src/Generation/Generator/Renderer/Public/ParameterToNativeExpression/ParameterToNativeExpression.cs index 79b43a3af..07267737b 100644 --- a/src/Generation/Generator/Renderer/Public/ParameterToNativeExpression/ParameterToNativeExpression.cs +++ b/src/Generation/Generator/Renderer/Public/ParameterToNativeExpression/ParameterToNativeExpression.cs @@ -25,6 +25,8 @@ internal static class ParameterToNativeExpression new ParameterToNativeExpressions.PlatformStringArray(), new ParameterToNativeExpressions.Pointer(), new ParameterToNativeExpressions.PointerAlias(), + new ParameterToNativeExpressions.Long(), //Must be before primitive value type + new ParameterToNativeExpressions.UnsignedLong(), //Must be before primitive value type new ParameterToNativeExpressions.PrimitiveValueType(), new ParameterToNativeExpressions.PrimitiveValueTypeAlias(), new ParameterToNativeExpressions.PrimitiveValueTypeArray(), diff --git a/src/Generation/Generator/Renderer/Public/ReturnTypeToManagedExpression/Converter/Long.cs b/src/Generation/Generator/Renderer/Public/ReturnTypeToManagedExpression/Converter/Long.cs new file mode 100644 index 000000000..e340e885e --- /dev/null +++ b/src/Generation/Generator/Renderer/Public/ReturnTypeToManagedExpression/Converter/Long.cs @@ -0,0 +1,14 @@ +using GirModel; + +namespace Generator.Renderer.Public.ReturnTypeToManagedExpressions; + +internal class Long : ReturnTypeConverter +{ + public bool Supports(AnyType type) + => type.Is(); + + public string GetString(GirModel.ReturnType returnType, string fromVariableName) + => returnType.IsPointer + ? fromVariableName + : $"{fromVariableName}.Value"; +} diff --git a/src/Generation/Generator/Renderer/Public/ReturnTypeToManagedExpression/Converter/UnsignedLong.cs b/src/Generation/Generator/Renderer/Public/ReturnTypeToManagedExpression/Converter/UnsignedLong.cs new file mode 100644 index 000000000..73391bdc2 --- /dev/null +++ b/src/Generation/Generator/Renderer/Public/ReturnTypeToManagedExpression/Converter/UnsignedLong.cs @@ -0,0 +1,14 @@ +using GirModel; + +namespace Generator.Renderer.Public.ReturnTypeToManagedExpressions; + +internal class UnsignedLong : ReturnTypeConverter +{ + public bool Supports(AnyType type) + => type.Is(); + + public string GetString(GirModel.ReturnType returnType, string fromVariableName) + => returnType.IsPointer + ? fromVariableName + : $"{fromVariableName}.Value"; +} diff --git a/src/Generation/Generator/Renderer/Public/ReturnTypeToManagedExpression/ReturnTypeToManagedExpression.cs b/src/Generation/Generator/Renderer/Public/ReturnTypeToManagedExpression/ReturnTypeToManagedExpression.cs index ecd42300b..2c695666f 100644 --- a/src/Generation/Generator/Renderer/Public/ReturnTypeToManagedExpression/ReturnTypeToManagedExpression.cs +++ b/src/Generation/Generator/Renderer/Public/ReturnTypeToManagedExpression/ReturnTypeToManagedExpression.cs @@ -17,6 +17,8 @@ internal static class ReturnTypeToManagedExpression new ReturnTypeToManagedExpressions.PlatformStringArray(), new ReturnTypeToManagedExpressions.Pointer(), new ReturnTypeToManagedExpressions.PointerAlias(), + new ReturnTypeToManagedExpressions.Long(), //Must be before primitive value type + new ReturnTypeToManagedExpressions.UnsignedLong(), //Must be before primitive value type new ReturnTypeToManagedExpressions.PrimitiveValueType(), new ReturnTypeToManagedExpressions.PrimitiveValueTypeAlias(), new ReturnTypeToManagedExpressions.PrimitiveValueTypeArray(), diff --git a/src/Libs/GObject-2.0/Public/Object.Signals.cs b/src/Libs/GObject-2.0/Public/Object.Signals.cs index ad925a37e..fe7bb11c4 100644 --- a/src/Libs/GObject-2.0/Public/Object.Signals.cs +++ b/src/Libs/GObject-2.0/Public/Object.Signals.cs @@ -1,18 +1,19 @@ using System; using System.Collections.Generic; +using System.Runtime.InteropServices; namespace GObject; public partial class Object { - private readonly Dictionary<(SignalDefinition, Delegate), (ulong, Closure)> _signalStore = new(); + private readonly Dictionary<(SignalDefinition, Delegate), (CULong, Closure)> _signalStore = new(); internal void SignalConnectClosure(SignalDefinition signalDefinition, Delegate callback, Closure closure, bool after, string? detail) { var detailQuark = GLib.Functions.QuarkFromString(detail); var handlerId = Internal.Functions.SignalConnectClosureById(Handle, signalDefinition.Id, detailQuark, closure.Handle, after); - if (handlerId == 0) + if (handlerId.Value == 0) throw new Exception($"Could not connect to event {signalDefinition.ManagedName}"); _signalStore[(signalDefinition, callback)] = (handlerId, closure); diff --git a/src/Native/GirTestLib/girtest-long-record-tester.c b/src/Native/GirTestLib/girtest-long-record-tester.c deleted file mode 100644 index 7f09cc612..000000000 --- a/src/Native/GirTestLib/girtest-long-record-tester.c +++ /dev/null @@ -1,17 +0,0 @@ -#include "girtest-long-record-tester.h" - -/** - * GirTestLongRecordTester: - * - * Test records with long fields - */ - -gsize girtest_long_record_tester_get_sizeof_l(GirTestLongRecordTester* record) -{ - return sizeof(record->l); -} - -gsize girtest_long_record_tester_get_sizeof_ul(GirTestLongRecordTester* record) -{ - return sizeof(record->ul); -} \ No newline at end of file diff --git a/src/Native/GirTestLib/girtest-long-record-tester.h b/src/Native/GirTestLib/girtest-long-record-tester.h deleted file mode 100644 index 0c5c187dc..000000000 --- a/src/Native/GirTestLib/girtest-long-record-tester.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include - -G_BEGIN_DECLS - -typedef struct _GirTestLongRecordTester GirTestLongRecordTester; - -struct _GirTestLongRecordTester -{ - long l; - unsigned long ul; -}; - -gsize girtest_long_record_tester_get_sizeof_l(GirTestLongRecordTester* record); -gsize girtest_long_record_tester_get_sizeof_ul(GirTestLongRecordTester* record); -G_END_DECLS \ No newline at end of file diff --git a/src/Native/GirTestLib/girtest-long-tester.c b/src/Native/GirTestLib/girtest-long-tester.c new file mode 100644 index 000000000..1ebe81313 --- /dev/null +++ b/src/Native/GirTestLib/girtest-long-tester.c @@ -0,0 +1,52 @@ +#include "girtest-long-tester.h" + +/** + * GirTestLongTester: + * + * Test records with long fields + */ + +gsize girtest_long_tester_get_sizeof_l(GirTestLongTester* record) +{ + return sizeof(record->l); +} + +glong girtest_long_tester_get_max_long_value() +{ + return LONG_MAX; +} + +gboolean girtest_long_tester_is_max_long_value(glong value) +{ + if(value == LONG_MAX) + return TRUE; + + return FALSE; +} + +glong girtest_long_tester_get_min_long_value() +{ + return LONG_MIN; +} + +gboolean girtest_long_tester_is_min_long_value(glong value) +{ + if(value == LONG_MIN) + return TRUE; + + return FALSE; +} + +/** + * girtest_long_tester_run_callback: + * @value: The long value which should be passed to the callback + * @callback: (scope call): a function that is called receives a long and should return a long + * + * Calls the callback and returns the data from the callback. + * + * Returns: The result of the callback. + **/ +glong girtest_long_tester_run_callback(glong value, GirTestLongCallback callback) +{ + return callback(value); +} \ No newline at end of file diff --git a/src/Native/GirTestLib/girtest-long-tester.h b/src/Native/GirTestLib/girtest-long-tester.h new file mode 100644 index 000000000..abb5056da --- /dev/null +++ b/src/Native/GirTestLib/girtest-long-tester.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +G_BEGIN_DECLS + +typedef glong (*GirTestLongCallback) (glong val); + +typedef struct _GirTestLongTester GirTestLongTester; + +struct _GirTestLongTester +{ + long l; +}; + +gsize girtest_long_tester_get_sizeof_l(GirTestLongTester* record); +glong girtest_long_tester_get_max_long_value(); +glong girtest_long_tester_get_min_long_value(); +gboolean girtest_long_tester_is_max_long_value(glong value); +gboolean girtest_long_tester_is_min_long_value(glong value); +glong girtest_long_tester_run_callback(glong value, GirTestLongCallback callback); +G_END_DECLS \ No newline at end of file diff --git a/src/Native/GirTestLib/girtest-ulong-tester.c b/src/Native/GirTestLib/girtest-ulong-tester.c new file mode 100644 index 000000000..ffb7c1096 --- /dev/null +++ b/src/Native/GirTestLib/girtest-ulong-tester.c @@ -0,0 +1,39 @@ +#include "girtest-ulong-tester.h" + +/** + * GirTestULongTester: + * + * Test records with unsigned long fields + */ + +gsize girtest_ulong_tester_get_sizeof_ul(GirTestULongTester* record) +{ + return sizeof(record->ul); +} + +gulong girtest_ulong_tester_get_max_unsigned_long_value() +{ + return ULONG_MAX; +} + +gboolean girtest_ulong_tester_is_max_unsigned_long_value(gulong value) +{ + if(value == ULONG_MAX) + return TRUE; + + return FALSE; +} + +/** + * girtest_ulong_tester_run_callback: + * @value: The long value which should be passed to the callback + * @callback: (scope call): a function that is called receives a ulong and should return a ulong + * + * Calls the callback and returns the data from the callback. + * + * Returns: The result of the callback. + **/ +gulong girtest_ulong_tester_run_callback(gulong value, GirTestULongCallback callback) +{ + return callback(value); +} \ No newline at end of file diff --git a/src/Native/GirTestLib/girtest-ulong-tester.h b/src/Native/GirTestLib/girtest-ulong-tester.h new file mode 100644 index 000000000..143aca1fa --- /dev/null +++ b/src/Native/GirTestLib/girtest-ulong-tester.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +G_BEGIN_DECLS + +typedef gulong (*GirTestULongCallback) (gulong val); + +typedef struct _GirTestULongTester GirTestULongTester; + +struct _GirTestULongTester +{ + unsigned long ul; +}; + +gsize girtest_ulong_tester_get_sizeof_ul(GirTestULongTester* record); +gulong girtest_ulong_tester_get_max_unsigned_long_value(); +gboolean girtest_ulong_tester_is_max_unsigned_long_value(gulong value); +gulong girtest_ulong_tester_run_callback(gulong value, GirTestULongCallback callback); +G_END_DECLS \ No newline at end of file diff --git a/src/Native/GirTestLib/girtest.h b/src/Native/GirTestLib/girtest.h index c976c6e17..28592e425 100644 --- a/src/Native/GirTestLib/girtest.h +++ b/src/Native/GirTestLib/girtest.h @@ -10,7 +10,7 @@ #include "girtest-enum-tester.h" #include "girtest-error-tester.h" #include "girtest-integer-array-tester.h" -#include "girtest-long-record-tester.h" +#include "girtest-long-tester.h" #include "girtest-opaque-typed-record-tester.h" #include "girtest-opaque-untyped-record-tester.h" #include "girtest-platform-string-array-null-terminated-tester.h" @@ -21,6 +21,7 @@ #include "girtest-signal-tester.h" #include "girtest-string-array-tester.h" #include "girtest-string-tester.h" +#include "girtest-ulong-tester.h" #include "girtest-typed-record-tester.h" #include "girtest-untyped-record-tester.h" #include "girtest-utf8-string-array-null-terminated-tester.h" diff --git a/src/Native/GirTestLib/meson.build b/src/Native/GirTestLib/meson.build index 02894a2d9..3c2a0e9f9 100644 --- a/src/Native/GirTestLib/meson.build +++ b/src/Native/GirTestLib/meson.build @@ -13,7 +13,7 @@ header_files = [ 'girtest-enum-tester.h', 'girtest-error-tester.h', 'girtest-integer-array-tester.h', - 'girtest-long-record-tester.h', + 'girtest-long-tester.h', 'girtest-opaque-typed-record-tester.h', 'girtest-opaque-untyped-record-tester.h', 'girtest-platform-string-array-null-terminated-tester.h', @@ -25,6 +25,7 @@ header_files = [ 'girtest-string-array-tester.h', 'girtest-string-tester.h', 'girtest-typed-record-tester.h', + 'girtest-ulong-tester.h', 'girtest-untyped-record-tester.h', 'girtest-utf8-string-array-null-terminated-tester.h', 'data/girtest-executor.h', @@ -40,7 +41,7 @@ source_files = [ 'girtest-enum-tester.c', 'girtest-error-tester.c', 'girtest-integer-array-tester.c', - 'girtest-long-record-tester.c', + 'girtest-long-tester.c', 'girtest-opaque-typed-record-tester.c', 'girtest-opaque-untyped-record-tester.c', 'girtest-platform-string-array-null-terminated-tester.c', @@ -52,6 +53,7 @@ source_files = [ 'girtest-string-array-tester.c', 'girtest-string-tester.c', 'girtest-typed-record-tester.c', + 'girtest-ulong-tester.c', 'girtest-untyped-record-tester.c', 'girtest-utf8-string-array-null-terminated-tester.c', 'data/girtest-executor.c', diff --git a/src/Tests/Libs/GirTest-0.1.Tests/LongRecordTest.cs b/src/Tests/Libs/GirTest-0.1.Tests/LongRecordTest.cs deleted file mode 100644 index 10c20ca52..000000000 --- a/src/Tests/Libs/GirTest-0.1.Tests/LongRecordTest.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using FluentAssertions; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace GirTest.Tests; - -[TestClass, TestCategory("BindingTest")] -public class LongRecordTest : Test -{ - [TestMethod] - public void ShouldUseCLongCULongInInternalStructData() - { - var data = new GirTest.Internal.LongRecordTesterData(); - data.Ul.Should().BeOfType(); - data.L.Should().BeOfType(); - } - - [TestMethod] - public unsafe void GetSizeOfLShouldBeSizeOfCLong() - { - var sizeOfCLong = sizeof(CLong); - var obj = new LongRecordTester(); - obj.GetSizeofL().Should().Be((nuint) sizeOfCLong); - } - - [DataTestMethod] - [DataRow(long.MaxValue)] - [DataRow(long.MinValue)] - public void ShouldHandleMaxMinLongValue(long value) - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || !Environment.Is64BitOperatingSystem) - Assert.Inconclusive("Only supported on 64 Bit Unix operating Systems"); - - var obj = new LongRecordTester { L = value }; - obj.L.Should().Be(value); - } - - [DataTestMethod] - [DataRow(int.MaxValue)] - [DataRow(int.MinValue)] - public void ShouldHandleMaxMinIntValue(int value) - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitOperatingSystem) - Assert.Inconclusive("Only supported on windows or 32 bit unix operating Systems"); - - var obj = new LongRecordTester { L = value }; - obj.L.Should().Be(value); - } - - [DataTestMethod] - [DataRow(long.MaxValue)] - [DataRow(long.MinValue)] - public void ShouldThrowIfValueExceedsIntegerSize(long value) - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitOperatingSystem) - Assert.Inconclusive("Only supported on windows or 32 bit unix operating Systems"); - - var obj = new LongRecordTester(); - var act = () => obj.L = value; - act.Should().Throw(); - } - - [TestMethod] - public unsafe void GetSizeOfULShouldBeSizeOfCULong() - { - var sizeOfCULong = sizeof(CULong); - var obj = new LongRecordTester(); - obj.GetSizeofUl().Should().Be((nuint) sizeOfCULong); - } - - [DataTestMethod] - [DataRow(ulong.MaxValue)] - [DataRow(ulong.MinValue)] - public void ShouldHandleMaxMinULongValue(ulong value) - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || !Environment.Is64BitOperatingSystem) - Assert.Inconclusive("Only supported on 64 Bit Unix operating Systems"); - - var obj = new LongRecordTester { Ul = value }; - obj.Ul.Should().Be(value); - } - - [DataTestMethod] - [DataRow(uint.MaxValue)] - [DataRow(uint.MinValue)] - public void ShouldHandleMaxMinUIntValue(uint value) - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitOperatingSystem) - Assert.Inconclusive("Only supported on windows or 32 bit unix operating Systems"); - - var obj = new LongRecordTester { Ul = value }; - obj.Ul.Should().Be(value); - } - - [TestMethod] - public void ShouldThrowIfValueExceedsUnsignedIntegerSize() - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitOperatingSystem) - Assert.Inconclusive("Only supported on windows or 32 bit unix operating Systems"); - - var obj = new LongRecordTester(); - var act = () => obj.Ul = ulong.MaxValue; - act.Should().Throw(); - } -} diff --git a/src/Tests/Libs/GirTest-0.1.Tests/LongTest.cs b/src/Tests/Libs/GirTest-0.1.Tests/LongTest.cs new file mode 100644 index 000000000..61de83cd7 --- /dev/null +++ b/src/Tests/Libs/GirTest-0.1.Tests/LongTest.cs @@ -0,0 +1,186 @@ +using System; +using System.Runtime.InteropServices; +using FluentAssertions; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace GirTest.Tests; + +[TestClass, TestCategory("BindingTest")] +public class LongTest : Test +{ + [TestMethod] + public void ShouldUseCLongInInternalStructData() + { + var data = new GirTest.Internal.LongTesterData(); + data.L.Should().BeOfType(); + } + + [TestMethod] + public unsafe void GetSizeOfLShouldBeSizeOfCLong() + { + var sizeOfCLong = sizeof(CLong); + var obj = new LongTester(); + obj.GetSizeofL().Should().Be((nuint) sizeOfCLong); + } + + [DataTestMethod] + [DataRow(long.MaxValue)] + [DataRow(long.MinValue)] + public void ShouldHandleMaxMinLongValue(long value) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || !Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on 64 Bit Unix operating Systems"); + + var obj = new LongTester { L = value }; + obj.L.Should().Be(value); + } + + [DataTestMethod] + [DataRow(int.MaxValue)] + [DataRow(int.MinValue)] + public void ShouldHandleMaxMinIntValue(int value) + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on windows or 32 bit unix operating Systems"); + + var obj = new LongTester { L = value }; + obj.L.Should().Be(value); + } + + [DataTestMethod] + [DataRow(long.MaxValue)] + [DataRow(long.MinValue)] + public void ShouldThrowIfValueExceedsIntegerSize(long value) + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on windows or 32 bit unix operating Systems"); + + var obj = new LongTester(); + var act = () => obj.L = value; + act.Should().Throw(); + } + + [TestMethod] + public void ReturnsMaxLongValueOn64BitUnix() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || !Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on 64 Bit Unix operating Systems"); + + LongTester.GetMaxLongValue().Should().Be(long.MaxValue); + } + + [TestMethod] + public void ReturnsMaxLongValueOnWindows() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on windows or 32 bit unix operating Systems"); + + LongTester.GetMaxLongValue().Should().Be(int.MaxValue); + } + + [TestMethod] + public void ReturnsMinLongValueOn64BitUnix() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || !Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on 64 Bit Unix operating Systems"); + + LongTester.GetMinLongValue().Should().Be(long.MinValue); + } + + [TestMethod] + public void ReturnsMinLongValueOnWindows() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on windows or 32 bit unix operating Systems"); + + LongTester.GetMinLongValue().Should().Be(int.MinValue); + } + + [TestMethod] + public void SetsMaxLongValueOn64BitUnix() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || !Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on 64 Bit Unix operating Systems"); + + LongTester.IsMaxLongValue(long.MaxValue).Should().BeTrue(); + } + + [TestMethod] + public void SetsMaxLongValueOnWindows() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on windows or 32 bit unix operating Systems"); + + LongTester.IsMaxLongValue(int.MaxValue).Should().BeTrue(); + } + + [TestMethod] + public void SetsMinLongValueOn64BitUnix() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || !Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on 64 Bit Unix operating Systems"); + + LongTester.IsMinLongValue(long.MinValue).Should().BeTrue(); + } + + [TestMethod] + public void SetsMinLongValueOnWindows() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on windows or 32 bit unix operating Systems"); + + LongTester.IsMinLongValue(int.MinValue).Should().BeTrue(); + } + + [TestMethod] + public void ThrowsOverflowExceptionIfLongMinValueIsPassedOnWindows() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on windows or 32 bit unix operating Systems"); + + var action = () => LongTester.IsMinLongValue(long.MinValue).Should().BeTrue(); + action.Should().Throw(); + } + + [TestMethod] + public void ThrowsOverflowExceptionIfLongMaxValueIsPassedOnWindows() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on windows or 32 bit unix operating Systems"); + + var action = () => LongTester.IsMaxLongValue(long.MaxValue).Should().BeTrue(); + action.Should().Throw(); + } + + [DataTestMethod] + [DataRow(long.MaxValue)] + [DataRow(long.MinValue)] + public void CanPassLongValueThroughCallbackOn64BitUnix(long value) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || !Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on 64 Bit Unix operating Systems"); + + long Callback(long val) + { + return val; + } + + LongTester.RunCallback(value, Callback).Should().Be(value); + } + + [DataTestMethod] + [DataRow(int.MaxValue)] + [DataRow(int.MinValue)] + public void CanPassIntValueThroughCallbackOnWindows(int value) + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on windows or 32 bit unix operating Systems"); + + long Callback(long val) + { + return val; + } + + LongTester.RunCallback(value, Callback).Should().Be(value); + } +} diff --git a/src/Tests/Libs/GirTest-0.1.Tests/ULongTest.cs b/src/Tests/Libs/GirTest-0.1.Tests/ULongTest.cs new file mode 100644 index 000000000..1717a3b0d --- /dev/null +++ b/src/Tests/Libs/GirTest-0.1.Tests/ULongTest.cs @@ -0,0 +1,138 @@ +using System; +using System.Runtime.InteropServices; +using FluentAssertions; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace GirTest.Tests; + +[TestClass, TestCategory("BindingTest")] +public class ULongTest : Test +{ + [TestMethod] + public void ShouldUseCULongInInternalStructData() + { + var data = new GirTest.Internal.ULongTesterData(); + data.Ul.Should().BeOfType(); + } + + [TestMethod] + public unsafe void GetSizeOfLShouldBeSizeOfCULong() + { + var sizeOfCULong = sizeof(CULong); + var obj = new ULongTester(); + obj.GetSizeofUl().Should().Be((nuint) sizeOfCULong); + } + + [DataTestMethod] + [DataRow(ulong.MaxValue)] + [DataRow(ulong.MinValue)] + public void ShouldHandleMaxULongValue(ulong value) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || !Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on 64 Bit Unix operating Systems"); + + var obj = new ULongTester { Ul = value }; + obj.Ul.Should().Be(value); + } + + [DataTestMethod] + [DataRow(uint.MaxValue)] + [DataRow(uint.MinValue)] + public void ShouldHandleMaxMinUIntValue(uint value) + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on windows or 32 bit unix operating Systems"); + + var obj = new ULongTester { Ul = value }; + obj.Ul.Should().Be(value); + } + + [TestMethod] + public void ShouldThrowIfValueExceedsUIntegerSize() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on windows or 32 bit unix operating Systems"); + + var obj = new ULongTester(); + var act = () => obj.Ul = ulong.MaxValue; + act.Should().Throw(); + } + + [TestMethod] + public void ReturnsMaxULongValueOn64BitUnix() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || !Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on 64 Bit Unix operating Systems"); + + ULongTester.GetMaxUnsignedLongValue().Should().Be(ulong.MaxValue); + } + + [TestMethod] + public void ReturnsMaxULongValueOnWindows() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on windows or 32 bit unix operating Systems"); + + ULongTester.GetMaxUnsignedLongValue().Should().Be(uint.MaxValue); + } + + [TestMethod] + public void SetsMaxULongValueOn64BitUnix() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || !Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on 64 Bit Unix operating Systems"); + + ULongTester.IsMaxUnsignedLongValue(ulong.MaxValue).Should().BeTrue(); + } + + [TestMethod] + public void SetsMaxULongValueOnWindows() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on windows or 32 bit unix operating Systems"); + + ULongTester.IsMaxUnsignedLongValue(uint.MaxValue).Should().BeTrue(); + } + + [TestMethod] + public void ThrowsOverflowExceptionIfULongMaxValueIsPassedOnWindows() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on windows or 32 bit unix operating Systems"); + + var action = () => ULongTester.IsMaxUnsignedLongValue(ulong.MaxValue).Should().BeTrue(); + action.Should().Throw(); + } + + [DataTestMethod] + [DataRow(ulong.MaxValue)] + [DataRow(ulong.MinValue)] + public void CanPassULongValueThroughCallbackOn64BitUnix(ulong value) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || !Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on 64 Bit Unix operating Systems"); + + ulong Callback(ulong val) + { + return val; + } + + ULongTester.RunCallback(value, Callback).Should().Be(value); + } + + [DataTestMethod] + [DataRow(uint.MaxValue)] + [DataRow(uint.MinValue)] + public void CanPassIntValueThroughCallbackOnWindows(uint value) + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on windows or 32 bit unix operating Systems"); + + ulong Callback(ulong val) + { + return val; + } + + ULongTester.RunCallback(value, Callback).Should().Be(value); + } +}