From 75cfccace179ffcfe97fca4f8baa62e96ca28270 Mon Sep 17 00:00:00 2001 From: badcel <1218031+badcel@users.noreply.github.com> Date: Wed, 29 May 2024 21:13:19 +0200 Subject: [PATCH 1/3] LongTester: Renamed from LongRecordTester --- .../GirTestLib/girtest-long-record-tester.c | 17 ---------------- .../GirTestLib/girtest-long-record-tester.h | 17 ---------------- src/Native/GirTestLib/girtest-long-tester.c | 17 ++++++++++++++++ src/Native/GirTestLib/girtest-long-tester.h | 17 ++++++++++++++++ src/Native/GirTestLib/girtest.h | 2 +- src/Native/GirTestLib/meson.build | 4 ++-- .../{LongRecordTest.cs => LongTest.cs} | 20 +++++++++---------- 7 files changed, 47 insertions(+), 47 deletions(-) delete mode 100644 src/Native/GirTestLib/girtest-long-record-tester.c delete mode 100644 src/Native/GirTestLib/girtest-long-record-tester.h create mode 100644 src/Native/GirTestLib/girtest-long-tester.c create mode 100644 src/Native/GirTestLib/girtest-long-tester.h rename src/Tests/Libs/GirTest-0.1.Tests/{LongRecordTest.cs => LongTest.cs} (86%) 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..2219c2038 --- /dev/null +++ b/src/Native/GirTestLib/girtest-long-tester.c @@ -0,0 +1,17 @@ +#include "girtest-long-tester.h" + +/** + * GirTestLongTester: + * + * Test records with long fields + */ + +gsize girtest_long_tester_get_sizeof_l(GirTestLongTester* record) +{ + return sizeof(record->l); +} + +gsize girtest_long_tester_get_sizeof_ul(GirTestLongTester* record) +{ + return sizeof(record->ul); +} \ 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..0b5c5f3f7 --- /dev/null +++ b/src/Native/GirTestLib/girtest-long-tester.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +G_BEGIN_DECLS + +typedef struct _GirTestLongTester GirTestLongTester; + +struct _GirTestLongTester +{ + long l; + unsigned long ul; +}; + +gsize girtest_long_tester_get_sizeof_l(GirTestLongTester* record); +gsize girtest_long_tester_get_sizeof_ul(GirTestLongTester* record); +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..3f49c4a81 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" diff --git a/src/Native/GirTestLib/meson.build b/src/Native/GirTestLib/meson.build index 02894a2d9..9858156f5 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', @@ -40,7 +40,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', diff --git a/src/Tests/Libs/GirTest-0.1.Tests/LongRecordTest.cs b/src/Tests/Libs/GirTest-0.1.Tests/LongTest.cs similarity index 86% rename from src/Tests/Libs/GirTest-0.1.Tests/LongRecordTest.cs rename to src/Tests/Libs/GirTest-0.1.Tests/LongTest.cs index 10c20ca52..1a4e3b82a 100644 --- a/src/Tests/Libs/GirTest-0.1.Tests/LongRecordTest.cs +++ b/src/Tests/Libs/GirTest-0.1.Tests/LongTest.cs @@ -6,12 +6,12 @@ namespace GirTest.Tests; [TestClass, TestCategory("BindingTest")] -public class LongRecordTest : Test +public class LongTest : Test { [TestMethod] public void ShouldUseCLongCULongInInternalStructData() { - var data = new GirTest.Internal.LongRecordTesterData(); + var data = new GirTest.Internal.LongTesterData(); data.Ul.Should().BeOfType(); data.L.Should().BeOfType(); } @@ -20,7 +20,7 @@ public void ShouldUseCLongCULongInInternalStructData() public unsafe void GetSizeOfLShouldBeSizeOfCLong() { var sizeOfCLong = sizeof(CLong); - var obj = new LongRecordTester(); + var obj = new LongTester(); obj.GetSizeofL().Should().Be((nuint) sizeOfCLong); } @@ -32,7 +32,7 @@ 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 }; + var obj = new LongTester { L = value }; obj.L.Should().Be(value); } @@ -44,7 +44,7 @@ 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 }; + var obj = new LongTester { L = value }; obj.L.Should().Be(value); } @@ -56,7 +56,7 @@ 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 obj = new LongTester(); var act = () => obj.L = value; act.Should().Throw(); } @@ -65,7 +65,7 @@ public void ShouldThrowIfValueExceedsIntegerSize(long value) public unsafe void GetSizeOfULShouldBeSizeOfCULong() { var sizeOfCULong = sizeof(CULong); - var obj = new LongRecordTester(); + var obj = new LongTester(); obj.GetSizeofUl().Should().Be((nuint) sizeOfCULong); } @@ -77,7 +77,7 @@ 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 }; + var obj = new LongTester { Ul = value }; obj.Ul.Should().Be(value); } @@ -89,7 +89,7 @@ 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 }; + var obj = new LongTester { Ul = value }; obj.Ul.Should().Be(value); } @@ -99,7 +99,7 @@ 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 obj = new LongTester(); var act = () => obj.Ul = ulong.MaxValue; act.Should().Throw(); } From 9d0344df6b317a24391b1b269c2d30008a3c36a0 Mon Sep 17 00:00:00 2001 From: badcel <1218031+badcel@users.noreply.github.com> Date: Wed, 29 May 2024 22:03:31 +0200 Subject: [PATCH 2/3] Long: Test returning and setting long values --- src/Native/GirTestLib/girtest-long-tester.c | 39 ++++- src/Native/GirTestLib/girtest-long-tester.h | 9 +- src/Native/GirTestLib/girtest-ulong-tester.c | 39 +++++ src/Native/GirTestLib/girtest-ulong-tester.h | 20 +++ src/Native/GirTestLib/girtest.h | 1 + src/Native/GirTestLib/meson.build | 2 + src/Tests/Libs/GirTest-0.1.Tests/LongTest.cs | 124 +++++++++++++--- src/Tests/Libs/GirTest-0.1.Tests/ULongTest.cs | 138 ++++++++++++++++++ 8 files changed, 346 insertions(+), 26 deletions(-) create mode 100644 src/Native/GirTestLib/girtest-ulong-tester.c create mode 100644 src/Native/GirTestLib/girtest-ulong-tester.h create mode 100644 src/Tests/Libs/GirTest-0.1.Tests/ULongTest.cs diff --git a/src/Native/GirTestLib/girtest-long-tester.c b/src/Native/GirTestLib/girtest-long-tester.c index 2219c2038..1ebe81313 100644 --- a/src/Native/GirTestLib/girtest-long-tester.c +++ b/src/Native/GirTestLib/girtest-long-tester.c @@ -11,7 +11,42 @@ gsize girtest_long_tester_get_sizeof_l(GirTestLongTester* record) return sizeof(record->l); } -gsize girtest_long_tester_get_sizeof_ul(GirTestLongTester* record) +glong girtest_long_tester_get_max_long_value() { - return sizeof(record->ul); + 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 index 0b5c5f3f7..abb5056da 100644 --- a/src/Native/GirTestLib/girtest-long-tester.h +++ b/src/Native/GirTestLib/girtest-long-tester.h @@ -4,14 +4,19 @@ G_BEGIN_DECLS +typedef glong (*GirTestLongCallback) (glong val); + typedef struct _GirTestLongTester GirTestLongTester; struct _GirTestLongTester { long l; - unsigned long ul; }; gsize girtest_long_tester_get_sizeof_l(GirTestLongTester* record); -gsize girtest_long_tester_get_sizeof_ul(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 3f49c4a81..28592e425 100644 --- a/src/Native/GirTestLib/girtest.h +++ b/src/Native/GirTestLib/girtest.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 9858156f5..3c2a0e9f9 100644 --- a/src/Native/GirTestLib/meson.build +++ b/src/Native/GirTestLib/meson.build @@ -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', @@ -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/LongTest.cs b/src/Tests/Libs/GirTest-0.1.Tests/LongTest.cs index 1a4e3b82a..61de83cd7 100644 --- a/src/Tests/Libs/GirTest-0.1.Tests/LongTest.cs +++ b/src/Tests/Libs/GirTest-0.1.Tests/LongTest.cs @@ -9,10 +9,9 @@ namespace GirTest.Tests; public class LongTest : Test { [TestMethod] - public void ShouldUseCLongCULongInInternalStructData() + public void ShouldUseCLongInInternalStructData() { var data = new GirTest.Internal.LongTesterData(); - data.Ul.Should().BeOfType(); data.L.Should().BeOfType(); } @@ -62,45 +61,126 @@ public void ShouldThrowIfValueExceedsIntegerSize(long value) } [TestMethod] - public unsafe void GetSizeOfULShouldBeSizeOfCULong() + public void ReturnsMaxLongValueOn64BitUnix() { - var sizeOfCULong = sizeof(CULong); - var obj = new LongTester(); - obj.GetSizeofUl().Should().Be((nuint) sizeOfCULong); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || !Environment.Is64BitOperatingSystem) + Assert.Inconclusive("Only supported on 64 Bit Unix operating Systems"); + + LongTester.GetMaxLongValue().Should().Be(long.MaxValue); } - [DataTestMethod] - [DataRow(ulong.MaxValue)] - [DataRow(ulong.MinValue)] - public void ShouldHandleMaxMinULongValue(ulong value) + [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"); - var obj = new LongTester { Ul = value }; - obj.Ul.Should().Be(value); + LongTester.GetMinLongValue().Should().Be(long.MinValue); } - [DataTestMethod] - [DataRow(uint.MaxValue)] - [DataRow(uint.MinValue)] - public void ShouldHandleMaxMinUIntValue(uint value) + [TestMethod] + public void ReturnsMinLongValueOnWindows() { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitOperatingSystem) Assert.Inconclusive("Only supported on windows or 32 bit unix operating Systems"); - var obj = new LongTester { Ul = value }; - obj.Ul.Should().Be(value); + 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 ShouldThrowIfValueExceedsUnsignedIntegerSize() + public void SetsMaxLongValueOnWindows() { 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.Ul = ulong.MaxValue; - act.Should().Throw(); + 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); + } +} From d6fec7c26e95f77bffc31d1a117ca41144c5e718 Mon Sep 17 00:00:00 2001 From: badcel <1218031+badcel@users.noreply.github.com> Date: Thu, 30 May 2024 18:34:14 +0200 Subject: [PATCH 3/3] Long: Use CLong / CULong as internal paramter / return type The size of long on windows is always 32 bit. On 64 bit unix systems it is 64 bit. CLong / CULong has the same behavior so it must be used to communicate with native code. --- .../Internal/Parameter/CallbackParameters.cs | 2 + .../Internal/Parameter/Converter/Long.cs | 44 +++++++++++++++++++ .../Parameter/Converter/UnsignedLong.cs | 44 +++++++++++++++++++ .../Renderer/Internal/Parameter/Parameters.cs | 2 + .../Converter/Long.cs | 30 +++++++++++++ .../Converter/UnsignedLong.cs | 30 +++++++++++++ .../ParameterToManagedExpression.cs | 2 + .../Internal/ReturnType/Converter/Long.cs | 18 ++++++++ .../ReturnType/Converter/UnsignedLong.cs | 18 ++++++++ .../Internal/ReturnType/ReturnTypeRenderer.cs | 2 + .../ReturnType/ReturnTypeRendererCallback.cs | 2 + .../Converter/Long.cs | 10 +++++ .../Converter/UnsignedLong.cs | 10 +++++ .../ReturnTypeToNativeExpression.cs | 2 + .../Renderer/Public/Field/Converter/Long.cs | 2 +- .../Public/Field/Converter/UnsignedLong.cs | 2 +- .../Converter/Long.cs | 33 ++++++++++++++ .../Converter/UnsignedLong.cs | 33 ++++++++++++++ .../ParameterToNativeExpression.cs | 2 + .../Converter/Long.cs | 14 ++++++ .../Converter/UnsignedLong.cs | 14 ++++++ .../ReturnTypeToManagedExpression.cs | 2 + src/Libs/GObject-2.0/Public/Object.Signals.cs | 5 ++- 23 files changed, 319 insertions(+), 4 deletions(-) create mode 100644 src/Generation/Generator/Renderer/Internal/Parameter/Converter/Long.cs create mode 100644 src/Generation/Generator/Renderer/Internal/Parameter/Converter/UnsignedLong.cs create mode 100644 src/Generation/Generator/Renderer/Internal/ParameterToManagedExpression/Converter/Long.cs create mode 100644 src/Generation/Generator/Renderer/Internal/ParameterToManagedExpression/Converter/UnsignedLong.cs create mode 100644 src/Generation/Generator/Renderer/Internal/ReturnType/Converter/Long.cs create mode 100644 src/Generation/Generator/Renderer/Internal/ReturnType/Converter/UnsignedLong.cs create mode 100644 src/Generation/Generator/Renderer/Internal/ReturnTypeToNativeExpression/Converter/Long.cs create mode 100644 src/Generation/Generator/Renderer/Internal/ReturnTypeToNativeExpression/Converter/UnsignedLong.cs create mode 100644 src/Generation/Generator/Renderer/Public/ParameterToNativeExpression/Converter/Long.cs create mode 100644 src/Generation/Generator/Renderer/Public/ParameterToNativeExpression/Converter/UnsignedLong.cs create mode 100644 src/Generation/Generator/Renderer/Public/ReturnTypeToManagedExpression/Converter/Long.cs create mode 100644 src/Generation/Generator/Renderer/Public/ReturnTypeToManagedExpression/Converter/UnsignedLong.cs 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);