Skip to content

Commit

Permalink
Merge pull request #1065 from gircore/improve-long-handling
Browse files Browse the repository at this point in the history
  • Loading branch information
badcel authored May 29, 2024
2 parents 139ee1d + 31a2e20 commit 4803234
Show file tree
Hide file tree
Showing 12 changed files with 271 additions and 2 deletions.
25 changes: 25 additions & 0 deletions src/Generation/Generator/Renderer/Internal/Field/Converter/Long.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace Generator.Renderer.Internal.Field;

internal class Long : FieldConverter
{
public bool Supports(GirModel.Field field)
{
return field.AnyTypeOrCallback.TryPickT0(out var anyType, out _) && anyType.Is<GirModel.Long>();
}

public RenderableField Convert(GirModel.Field field)
{
return new RenderableField(
Name: Model.Field.GetName(field),
Attribute: null,
NullableTypeName: GetNullableTypeName(field)
);
}

private static string GetNullableTypeName(GirModel.Field field)
{
return field.IsPointer
? Model.Type.Pointer
: "CLong";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace Generator.Renderer.Internal.Field;

internal class UnsignedLong : FieldConverter
{
public bool Supports(GirModel.Field field)
{
return field.AnyTypeOrCallback.TryPickT0(out var anyType, out _) && anyType.Is<GirModel.UnsignedLong>();
}

public RenderableField Convert(GirModel.Field field)
{
return new RenderableField(
Name: Model.Field.GetName(field),
Attribute: null,
NullableTypeName: GetNullableTypeName(field)
);
}

private static string GetNullableTypeName(GirModel.Field field)
{
return field.IsPointer
? Model.Type.Pointer
: "CULong";
}
}
2 changes: 2 additions & 0 deletions src/Generation/Generator/Renderer/Internal/Field/Fields.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ internal static class Fields
new Field.Pointer(),
new Field.PointerAlias(),
new Field.PointerArray(),
new Field.Long(), //Must be before primitive value
new Field.UnsignedLong(), //Must be before primitive value
new Field.PrimitiveValueType(),
new Field.PrimitiveValueTypeAlias(),
new Field.PrimitiveValueTypeArray(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ private static string RenderFieldGetter(GirModel.Record record, GirModel.Field f
var typePrefix = field.AnyTypeOrCallback.IsT1 ? $"{Model.UntypedRecord.GetDataName(record)}." : string.Empty;
var dataName = Model.UntypedRecord.GetDataName(record);

return @$"public unsafe {typePrefix}{renderableField.NullableTypeName} Get{renderableField.Name}()
return @$"public {typePrefix}{renderableField.NullableTypeName} Get{renderableField.Name}()
{{
if (IsClosed || IsInvalid)
throw new InvalidOperationException(""Handle is closed or invalid"");
Expand All @@ -268,7 +268,7 @@ private static string RenderFieldSetter(GirModel.Record record, GirModel.Field f
{
var dataName = Model.UntypedRecord.GetDataName(record);

return @$"public unsafe void Set{renderableField.Name}({renderableField.NullableTypeName} value)
return @$"public void Set{renderableField.Name}({renderableField.NullableTypeName} value)
{{
if (IsClosed || IsInvalid)
throw new InvalidOperationException(""Handle is closed or invalid"");
Expand Down
36 changes: 36 additions & 0 deletions src/Generation/Generator/Renderer/Public/Field/Converter/Long.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
namespace Generator.Renderer.Public.Field;

internal class Long : FieldConverter
{
public bool Supports(GirModel.Field field)
{
return field.AnyTypeOrCallback.TryPickT0(out var anyType, out _) && anyType.Is<GirModel.Long>();
}

public RenderableField Convert(GirModel.Field field)
{
return new RenderableField(
Name: Model.Field.GetName(field),
NullableTypeName: GetNullableTypeName(field),
SetExpression: SetExpression,
GetExpression: GetExpression
);
}

private static string GetNullableTypeName(GirModel.Field field)
{
return field.IsPointer
? Model.Type.Pointer
: Model.Type.GetName(field.AnyTypeOrCallback.AsT0.AsT0);
}

private static string SetExpression(GirModel.Record record, GirModel.Field field)
{
return $"Handle.Set{Model.Field.GetName(field)}(new CLong((nint)value))";
}

private static string GetExpression(GirModel.Record record, GirModel.Field field)
{
return $"Handle.Get{Model.Field.GetName(field)}().Value";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
namespace Generator.Renderer.Public.Field;

internal class UnsignedLong : FieldConverter
{
public bool Supports(GirModel.Field field)
{
return field.AnyTypeOrCallback.TryPickT0(out var anyType, out _) && anyType.Is<GirModel.UnsignedLong>();
}

public RenderableField Convert(GirModel.Field field)
{
return new RenderableField(
Name: Model.Field.GetName(field),
NullableTypeName: GetNullableTypeName(field),
SetExpression: SetExpression,
GetExpression: GetExpression
);
}

private static string GetNullableTypeName(GirModel.Field field)
{
return field.IsPointer
? Model.Type.Pointer
: Model.Type.GetName(field.AnyTypeOrCallback.AsT0.AsT0);
}

private static string SetExpression(GirModel.Record record, GirModel.Field field)
{
return $"Handle.Set{Model.Field.GetName(field)}(new CULong((nuint)value))";
}

private static string GetExpression(GirModel.Record record, GirModel.Field field)
{
return $"Handle.Get{Model.Field.GetName(field)}().Value";
}
}
2 changes: 2 additions & 0 deletions src/Generation/Generator/Renderer/Public/Field/Fields.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ internal static class Fields
{
new Field.Bitfield(),
new Field.Enumeration(),
new Field.Long(), //Must be before PrimitiveValueType
new Field.UnsignedLong(), //Must be before PrimitiveValueType
new Field.PrimitiveValueType(),
new Field.String(),
};
Expand Down
17 changes: 17 additions & 0 deletions src/Native/GirTestLib/girtest-long-record-tester.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#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);
}
17 changes: 17 additions & 0 deletions src/Native/GirTestLib/girtest-long-record-tester.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include <glib-object.h>

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
1 change: 1 addition & 0 deletions src/Native/GirTestLib/girtest.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +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-opaque-typed-record-tester.h"
#include "girtest-opaque-untyped-record-tester.h"
#include "girtest-platform-string-array-null-terminated-tester.h"
Expand Down
2 changes: 2 additions & 0 deletions src/Native/GirTestLib/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ header_files = [
'girtest-enum-tester.h',
'girtest-error-tester.h',
'girtest-integer-array-tester.h',
'girtest-long-record-tester.h',
'girtest-opaque-typed-record-tester.h',
'girtest-opaque-untyped-record-tester.h',
'girtest-platform-string-array-null-terminated-tester.h',
Expand All @@ -39,6 +40,7 @@ source_files = [
'girtest-enum-tester.c',
'girtest-error-tester.c',
'girtest-integer-array-tester.c',
'girtest-long-record-tester.c',
'girtest-opaque-typed-record-tester.c',
'girtest-opaque-untyped-record-tester.c',
'girtest-platform-string-array-null-terminated-tester.c',
Expand Down
106 changes: 106 additions & 0 deletions src/Tests/Libs/GirTest-0.1.Tests/LongRecordTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
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<CULong>();
data.L.Should().BeOfType<CLong>();
}

[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<OverflowException>();
}

[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<OverflowException>();
}
}

0 comments on commit 4803234

Please sign in to comment.