diff --git a/MEOS.NET.Tests/CountedArrayTests.cs b/MEOS.NET.Tests/CountedArrayTests.cs
new file mode 100644
index 0000000..bc9eeac
--- /dev/null
+++ b/MEOS.NET.Tests/CountedArrayTests.cs
@@ -0,0 +1,54 @@
+using MEOS.NET.Enums;
+using MEOS.NET.Types;
+
+namespace MEOS.NET.Tests
+{
+ ///
+ /// MEOS reads an array of its own values through a pointer to the first
+ /// element and a count, so a method taking one takes a C# array and answers
+ /// its length to MEOS.
+ ///
+ [TestClass]
+ public class CountedArrayTests : MeosTest
+ {
+ [TestMethod]
+ public void ASequenceIsMadeOfItsInstants()
+ {
+ Temporal[] instants =
+ [
+ TFloat.In("25.0@2024-12-06")!,
+ TFloat.In("27.0@2024-12-07")!,
+ TFloat.In("30.0@2024-12-09")!,
+ ];
+
+ Temporal sequence = TSequence.Make(instants, true, true, InterpType.Linear, true)!;
+
+ Assert.AreEqual(3, sequence.NumInstants());
+ Assert.AreEqual(
+ "[25@2024-12-06 00:00:00+00, 27@2024-12-07 00:00:00+00, 30@2024-12-09 00:00:00+00]",
+ sequence.ToString());
+ }
+
+ [TestMethod]
+ public void MergingAnArrayOfTemporalValuesJoinsThem()
+ {
+ Temporal[] parts =
+ [
+ TFloat.In("[25.0@2024-12-06, 27.0@2024-12-07]")!,
+ TFloat.In("[30.0@2024-12-09, 32.0@2024-12-10]")!,
+ ];
+
+ Temporal merged = Temporal.MergeArray(parts)!;
+
+ Assert.AreEqual(4, merged.NumInstants());
+ Assert.AreEqual(2, merged.NumSequences());
+ }
+
+ [TestMethod]
+ public void AnEmptyArrayIsARequestMeosRefuses()
+ {
+ Assert.ThrowsException(
+ () => TSequence.Make([], true, true, InterpType.Linear, true));
+ }
+ }
+}
diff --git a/MEOS.NET.Tests/OutParameterTests.cs b/MEOS.NET.Tests/OutParameterTests.cs
new file mode 100644
index 0000000..c80285d
--- /dev/null
+++ b/MEOS.NET.Tests/OutParameterTests.cs
@@ -0,0 +1,53 @@
+using MEOS.NET.Types;
+
+namespace MEOS.NET.Tests
+{
+ ///
+ /// MEOS answers some values through an out-parameter and returns whether the
+ /// value exists at all, so those methods answer the value or null.
+ ///
+ [TestClass]
+ public class OutParameterTests : MeosTest
+ {
+ [TestMethod]
+ public void ABoxAnswersTheBoundsItHas()
+ {
+ TBox box = TBox.In("TBOXFLOAT XT([1.0, 3.0],[2024-12-06, 2024-12-08])")!;
+
+ Assert.AreEqual(1.0, box.Xmin());
+ Assert.AreEqual(3.0, box.Xmax());
+ Assert.AreEqual(true, box.TminInc());
+ }
+
+ [TestMethod]
+ public void ABoxAnswersNullForABoundItDoesNotHave()
+ {
+ TBox box = TBox.In("TBOX T([2024-12-06, 2024-12-08])")!;
+
+ Assert.IsNull(box.Xmin());
+ Assert.IsNull(box.Xmax());
+ Assert.IsNotNull(box.TminInc());
+ }
+
+ [TestMethod]
+ public void ASetAnswersTheValueAtAnIndex()
+ {
+ Set set = FloatSet.In("{1.5, 2.5, 3.5}")!;
+
+ Assert.AreEqual(1.5, ((FloatSet)set).ValueN(1));
+ Assert.AreEqual(3.5, ((FloatSet)set).ValueN(3));
+ Assert.IsNull(((FloatSet)set).ValueN(4));
+ }
+
+ [TestMethod]
+ public void ATemporalFloatAnswersItsValueAtAMoment()
+ {
+ TFloat temp = (TFloat)TFloat.In("[25.0@2024-12-06, 27.0@2024-12-08]")!;
+
+ Assert.AreEqual(25.0,
+ temp.ValueAtTimestamptz(new DateTime(2024, 12, 6, 0, 0, 0, DateTimeKind.Utc), true));
+ Assert.IsNull(
+ temp.ValueAtTimestamptz(new DateTime(2024, 12, 9, 0, 0, 0, DateTimeKind.Utc), true));
+ }
+ }
+}
diff --git a/MEOS.NET/Types/BigIntSet.g.cs b/MEOS.NET/Types/BigIntSet.g.cs
index c2cbf30..f797ccb 100644
--- a/MEOS.NET/Types/BigIntSet.g.cs
+++ b/MEOS.NET/Types/BigIntSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
@@ -27,6 +29,24 @@ public string Out()
public long StartValue()
=> Meos.BigintsetStartValue(this.Ptr);
+ public long? ValueN(int n)
+ {
+ IntPtr _result = Marshal.AllocHGlobal(8);
+ try
+ {
+ if (!Meos.BigintsetValueN(this.Ptr, n, _result))
+ {
+ return null;
+ }
+
+ return Marshal.ReadInt64(_result);
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
public long[] Values()
=> Meos.BigintsetValues(this.Ptr);
diff --git a/MEOS.NET/Types/BigIntSpan.g.cs b/MEOS.NET/Types/BigIntSpan.g.cs
index 16bf168..bc3c38e 100644
--- a/MEOS.NET/Types/BigIntSpan.g.cs
+++ b/MEOS.NET/Types/BigIntSpan.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/BigIntSpanSet.g.cs b/MEOS.NET/Types/BigIntSpanSet.g.cs
index 50aa718..73c6e84 100644
--- a/MEOS.NET/Types/BigIntSpanSet.g.cs
+++ b/MEOS.NET/Types/BigIntSpanSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/Box.g.cs b/MEOS.NET/Types/Box.g.cs
index cd06e96..4147bb6 100644
--- a/MEOS.NET/Types/Box.g.cs
+++ b/MEOS.NET/Types/Box.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/CbufferSet.g.cs b/MEOS.NET/Types/CbufferSet.g.cs
index 52cf06f..755bbbe 100644
--- a/MEOS.NET/Types/CbufferSet.g.cs
+++ b/MEOS.NET/Types/CbufferSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/Collection.g.cs b/MEOS.NET/Types/Collection.g.cs
index 6b65e5b..7ffd7cc 100644
--- a/MEOS.NET/Types/Collection.g.cs
+++ b/MEOS.NET/Types/Collection.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/DateSet.g.cs b/MEOS.NET/Types/DateSet.g.cs
index 81b5c43..978f4d0 100644
--- a/MEOS.NET/Types/DateSet.g.cs
+++ b/MEOS.NET/Types/DateSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
@@ -30,6 +32,24 @@ public DateOnly StartValue()
public Set? ToTstzset()
=> MEOSFactory.WrapSet(Meos.DatesetToTstzset(this.Ptr));
+ public DateOnly? ValueN(int n)
+ {
+ IntPtr _result = Marshal.AllocHGlobal(4);
+ try
+ {
+ if (!Meos.DatesetValueN(this.Ptr, n, _result))
+ {
+ return null;
+ }
+
+ return MEOSConvert.ToDateOnly(Marshal.ReadInt32(_result));
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
public int[] Values()
=> Meos.DatesetValues(this.Ptr);
diff --git a/MEOS.NET/Types/DateSpan.g.cs b/MEOS.NET/Types/DateSpan.g.cs
index cc95052..76d299f 100644
--- a/MEOS.NET/Types/DateSpan.g.cs
+++ b/MEOS.NET/Types/DateSpan.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/DateSpanSet.g.cs b/MEOS.NET/Types/DateSpanSet.g.cs
index 7b671a2..378f520 100644
--- a/MEOS.NET/Types/DateSpanSet.g.cs
+++ b/MEOS.NET/Types/DateSpanSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
@@ -15,6 +17,24 @@ internal DateSpanSet(IntPtr ptr) : base(ptr) { }
public override string ToString()
=> this.Out();
+ public DateOnly? DateN(int n)
+ {
+ IntPtr _result = Marshal.AllocHGlobal(4);
+ try
+ {
+ if (!Meos.DatespansetDateN(this.Ptr, n, _result))
+ {
+ return null;
+ }
+
+ return MEOSConvert.ToDateOnly(Marshal.ReadInt32(_result));
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
public Set? Dates()
=> MEOSFactory.WrapSet(Meos.DatespansetDates(this.Ptr));
diff --git a/MEOS.NET/Types/FloatSet.g.cs b/MEOS.NET/Types/FloatSet.g.cs
index be1b2fa..33edc9b 100644
--- a/MEOS.NET/Types/FloatSet.g.cs
+++ b/MEOS.NET/Types/FloatSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
@@ -42,6 +44,24 @@ public double StartValue()
public Set? ToIntset()
=> MEOSFactory.WrapSet(Meos.FloatsetToIntset(this.Ptr));
+ public double? ValueN(int n)
+ {
+ IntPtr _result = Marshal.AllocHGlobal(8);
+ try
+ {
+ if (!Meos.FloatsetValueN(this.Ptr, n, _result))
+ {
+ return null;
+ }
+
+ return Marshal.PtrToStructure(_result);
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
public double[] Values()
=> Meos.FloatsetValues(this.Ptr);
diff --git a/MEOS.NET/Types/FloatSpan.g.cs b/MEOS.NET/Types/FloatSpan.g.cs
index 75fcf5a..bba4ef0 100644
--- a/MEOS.NET/Types/FloatSpan.g.cs
+++ b/MEOS.NET/Types/FloatSpan.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/FloatSpanSet.g.cs b/MEOS.NET/Types/FloatSpanSet.g.cs
index 528ef1f..ea65d63 100644
--- a/MEOS.NET/Types/FloatSpanSet.g.cs
+++ b/MEOS.NET/Types/FloatSpanSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/GeogSet.g.cs b/MEOS.NET/Types/GeogSet.g.cs
index e37f3fe..107f2ca 100644
--- a/MEOS.NET/Types/GeogSet.g.cs
+++ b/MEOS.NET/Types/GeogSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/GeomSet.g.cs b/MEOS.NET/Types/GeomSet.g.cs
index 6f92b60..f091385 100644
--- a/MEOS.NET/Types/GeomSet.g.cs
+++ b/MEOS.NET/Types/GeomSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/IntSet.g.cs b/MEOS.NET/Types/IntSet.g.cs
index 296ffd7..9d4248e 100644
--- a/MEOS.NET/Types/IntSet.g.cs
+++ b/MEOS.NET/Types/IntSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
@@ -30,6 +32,24 @@ public int StartValue()
public Set? ToFloatset()
=> MEOSFactory.WrapSet(Meos.IntsetToFloatset(this.Ptr));
+ public int? ValueN(int n)
+ {
+ IntPtr _result = Marshal.AllocHGlobal(4);
+ try
+ {
+ if (!Meos.IntsetValueN(this.Ptr, n, _result))
+ {
+ return null;
+ }
+
+ return Marshal.ReadInt32(_result);
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
public int[] Values()
=> Meos.IntsetValues(this.Ptr);
diff --git a/MEOS.NET/Types/IntSpan.g.cs b/MEOS.NET/Types/IntSpan.g.cs
index d5682c2..13d26cf 100644
--- a/MEOS.NET/Types/IntSpan.g.cs
+++ b/MEOS.NET/Types/IntSpan.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/IntSpanSet.g.cs b/MEOS.NET/Types/IntSpanSet.g.cs
index 25421a4..df3fbb2 100644
--- a/MEOS.NET/Types/IntSpanSet.g.cs
+++ b/MEOS.NET/Types/IntSpanSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/NpointSet.g.cs b/MEOS.NET/Types/NpointSet.g.cs
index cc40491..74516e7 100644
--- a/MEOS.NET/Types/NpointSet.g.cs
+++ b/MEOS.NET/Types/NpointSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/PoseSet.g.cs b/MEOS.NET/Types/PoseSet.g.cs
index c11b9fc..43edda2 100644
--- a/MEOS.NET/Types/PoseSet.g.cs
+++ b/MEOS.NET/Types/PoseSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/STBox.g.cs b/MEOS.NET/Types/STBox.g.cs
index 1364163..115bdc3 100644
--- a/MEOS.NET/Types/STBox.g.cs
+++ b/MEOS.NET/Types/STBox.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
@@ -87,6 +89,78 @@ public int SRID()
public double SpatialDistance(STBox box2)
=> Meos.StboxSpatialDistance(this.Ptr, box2.Ptr);
+ public DateTime? Tmax()
+ {
+ IntPtr _result = Marshal.AllocHGlobal(8);
+ try
+ {
+ if (!Meos.StboxTmax(this.Ptr, _result))
+ {
+ return null;
+ }
+
+ return MEOSConvert.ToDateTime(Marshal.ReadInt64(_result));
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
+ public bool? TmaxInc()
+ {
+ IntPtr _result = Marshal.AllocHGlobal(1);
+ try
+ {
+ if (!Meos.StboxTmaxInc(this.Ptr, _result))
+ {
+ return null;
+ }
+
+ return Marshal.ReadByte(_result) != 0;
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
+ public DateTime? Tmin()
+ {
+ IntPtr _result = Marshal.AllocHGlobal(8);
+ try
+ {
+ if (!Meos.StboxTmin(this.Ptr, _result))
+ {
+ return null;
+ }
+
+ return MEOSConvert.ToDateTime(Marshal.ReadInt64(_result));
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
+ public bool? TminInc()
+ {
+ IntPtr _result = Marshal.AllocHGlobal(1);
+ try
+ {
+ if (!Meos.StboxTminInc(this.Ptr, _result))
+ {
+ return null;
+ }
+
+ return Marshal.ReadByte(_result) != 0;
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
public Span? ToTstzspan()
=> MEOSFactory.WrapSpan(Meos.StboxToTstzspan(this.Ptr));
@@ -99,6 +173,114 @@ public double SpatialDistance(STBox box2)
public double Volume()
=> Meos.StboxVolume(this.Ptr);
+ public double? Xmax()
+ {
+ IntPtr _result = Marshal.AllocHGlobal(8);
+ try
+ {
+ if (!Meos.StboxXmax(this.Ptr, _result))
+ {
+ return null;
+ }
+
+ return Marshal.PtrToStructure(_result);
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
+ public double? Xmin()
+ {
+ IntPtr _result = Marshal.AllocHGlobal(8);
+ try
+ {
+ if (!Meos.StboxXmin(this.Ptr, _result))
+ {
+ return null;
+ }
+
+ return Marshal.PtrToStructure(_result);
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
+ public double? Ymax()
+ {
+ IntPtr _result = Marshal.AllocHGlobal(8);
+ try
+ {
+ if (!Meos.StboxYmax(this.Ptr, _result))
+ {
+ return null;
+ }
+
+ return Marshal.PtrToStructure(_result);
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
+ public double? Ymin()
+ {
+ IntPtr _result = Marshal.AllocHGlobal(8);
+ try
+ {
+ if (!Meos.StboxYmin(this.Ptr, _result))
+ {
+ return null;
+ }
+
+ return Marshal.PtrToStructure(_result);
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
+ public double? Zmax()
+ {
+ IntPtr _result = Marshal.AllocHGlobal(8);
+ try
+ {
+ if (!Meos.StboxZmax(this.Ptr, _result))
+ {
+ return null;
+ }
+
+ return Marshal.PtrToStructure(_result);
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
+ public double? Zmin()
+ {
+ IntPtr _result = Marshal.AllocHGlobal(8);
+ try
+ {
+ if (!Meos.StboxZmin(this.Ptr, _result))
+ {
+ return null;
+ }
+
+ return Marshal.PtrToStructure(_result);
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
public static STBox? FromHEXWKB(string hexwkb)
=> MEOSFactory.WrapSTBox(Meos.StboxFromHexwkb(hexwkb));
diff --git a/MEOS.NET/Types/Set.g.cs b/MEOS.NET/Types/Set.g.cs
index 4591a62..c8b16ae 100644
--- a/MEOS.NET/Types/Set.g.cs
+++ b/MEOS.NET/Types/Set.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/Span.g.cs b/MEOS.NET/Types/Span.g.cs
index 4d1d016..1199e83 100644
--- a/MEOS.NET/Types/Span.g.cs
+++ b/MEOS.NET/Types/Span.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/SpanSet.g.cs b/MEOS.NET/Types/SpanSet.g.cs
index 0223c92..b5ed634 100644
--- a/MEOS.NET/Types/SpanSet.g.cs
+++ b/MEOS.NET/Types/SpanSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TAlpha.g.cs b/MEOS.NET/Types/TAlpha.g.cs
index c87c5e8..a75e539 100644
--- a/MEOS.NET/Types/TAlpha.g.cs
+++ b/MEOS.NET/Types/TAlpha.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TBigint.g.cs b/MEOS.NET/Types/TBigint.g.cs
index a042297..70e71d7 100644
--- a/MEOS.NET/Types/TBigint.g.cs
+++ b/MEOS.NET/Types/TBigint.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
@@ -54,6 +56,42 @@ public long StartValue()
public Temporal? ToTs2cell()
=> MEOSFactory.WrapTemporal(Meos.TbigintToTs2cell(this.Ptr));
+ public long? ValueAtTimestamptz(DateTime t, bool strict)
+ {
+ IntPtr _value = Marshal.AllocHGlobal(8);
+ try
+ {
+ if (!Meos.TbigintValueAtTimestamptz(this.Ptr, MEOSConvert.ToTimestampTz(t), strict, _value))
+ {
+ return null;
+ }
+
+ return Marshal.ReadInt64(_value);
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_value);
+ }
+ }
+
+ public long? ValueN(long n)
+ {
+ IntPtr _result = Marshal.AllocHGlobal(8);
+ try
+ {
+ if (!Meos.TbigintValueN(this.Ptr, n, _result))
+ {
+ return null;
+ }
+
+ return Marshal.ReadInt64(_result);
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
public static Temporal? FromBaseTemp(long i, Temporal temp)
=> MEOSFactory.WrapTemporal(Meos.TbigintFromBaseTemp(i, temp.Ptr));
diff --git a/MEOS.NET/Types/TBigintInst.g.cs b/MEOS.NET/Types/TBigintInst.g.cs
index 53f7416..402640c 100644
--- a/MEOS.NET/Types/TBigintInst.g.cs
+++ b/MEOS.NET/Types/TBigintInst.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TBigintSeq.g.cs b/MEOS.NET/Types/TBigintSeq.g.cs
index eb92b2b..0c8c5bc 100644
--- a/MEOS.NET/Types/TBigintSeq.g.cs
+++ b/MEOS.NET/Types/TBigintSeq.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TBigintSeqSet.g.cs b/MEOS.NET/Types/TBigintSeqSet.g.cs
index 1c0a8a8..d5f271f 100644
--- a/MEOS.NET/Types/TBigintSeqSet.g.cs
+++ b/MEOS.NET/Types/TBigintSeqSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TBool.g.cs b/MEOS.NET/Types/TBool.g.cs
index 64d2b27..9777500 100644
--- a/MEOS.NET/Types/TBool.g.cs
+++ b/MEOS.NET/Types/TBool.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
@@ -33,6 +35,42 @@ public bool StartValue()
public Temporal? ToTint()
=> MEOSFactory.WrapTemporal(Meos.TboolToTint(this.Ptr));
+ public bool? ValueAtTimestamptz(DateTime t, bool strict)
+ {
+ IntPtr _value = Marshal.AllocHGlobal(1);
+ try
+ {
+ if (!Meos.TboolValueAtTimestamptz(this.Ptr, MEOSConvert.ToTimestampTz(t), strict, _value))
+ {
+ return null;
+ }
+
+ return Marshal.ReadByte(_value) != 0;
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_value);
+ }
+ }
+
+ public bool? ValueN(int n)
+ {
+ IntPtr _result = Marshal.AllocHGlobal(1);
+ try
+ {
+ if (!Meos.TboolValueN(this.Ptr, n, _result))
+ {
+ return null;
+ }
+
+ return Marshal.ReadByte(_result) != 0;
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
public SpanSet? WhenTrue()
=> MEOSFactory.WrapSpanSet(Meos.TboolWhenTrue(this.Ptr));
diff --git a/MEOS.NET/Types/TBoolInst.g.cs b/MEOS.NET/Types/TBoolInst.g.cs
index 3a14e5a..3f7d07c 100644
--- a/MEOS.NET/Types/TBoolInst.g.cs
+++ b/MEOS.NET/Types/TBoolInst.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TBoolSeq.g.cs b/MEOS.NET/Types/TBoolSeq.g.cs
index dcc7129..c3d0456 100644
--- a/MEOS.NET/Types/TBoolSeq.g.cs
+++ b/MEOS.NET/Types/TBoolSeq.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TBoolSeqSet.g.cs b/MEOS.NET/Types/TBoolSeqSet.g.cs
index 73c8520..22dabc6 100644
--- a/MEOS.NET/Types/TBoolSeqSet.g.cs
+++ b/MEOS.NET/Types/TBoolSeqSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TBox.g.cs b/MEOS.NET/Types/TBox.g.cs
index d7e3c17..d8dd6ce 100644
--- a/MEOS.NET/Types/TBox.g.cs
+++ b/MEOS.NET/Types/TBox.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
@@ -57,6 +59,78 @@ public string Out(int maxdd)
public TBox? Round(int maxdd)
=> MEOSFactory.WrapTBox(Meos.TboxRound(this.Ptr, maxdd));
+ public DateTime? Tmax()
+ {
+ IntPtr _result = Marshal.AllocHGlobal(8);
+ try
+ {
+ if (!Meos.TboxTmax(this.Ptr, _result))
+ {
+ return null;
+ }
+
+ return MEOSConvert.ToDateTime(Marshal.ReadInt64(_result));
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
+ public bool? TmaxInc()
+ {
+ IntPtr _result = Marshal.AllocHGlobal(1);
+ try
+ {
+ if (!Meos.TboxTmaxInc(this.Ptr, _result))
+ {
+ return null;
+ }
+
+ return Marshal.ReadByte(_result) != 0;
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
+ public DateTime? Tmin()
+ {
+ IntPtr _result = Marshal.AllocHGlobal(8);
+ try
+ {
+ if (!Meos.TboxTmin(this.Ptr, _result))
+ {
+ return null;
+ }
+
+ return MEOSConvert.ToDateTime(Marshal.ReadInt64(_result));
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
+ public bool? TminInc()
+ {
+ IntPtr _result = Marshal.AllocHGlobal(1);
+ try
+ {
+ if (!Meos.TboxTminInc(this.Ptr, _result))
+ {
+ return null;
+ }
+
+ return Marshal.ReadByte(_result) != 0;
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
public Span? ToBigintspan()
=> MEOSFactory.WrapSpan(Meos.TboxToBigintspan(this.Ptr));
@@ -69,6 +143,78 @@ public string Out(int maxdd)
public Span? ToTstzspan()
=> MEOSFactory.WrapSpan(Meos.TboxToTstzspan(this.Ptr));
+ public double? Xmax()
+ {
+ IntPtr _result = Marshal.AllocHGlobal(8);
+ try
+ {
+ if (!Meos.TboxXmax(this.Ptr, _result))
+ {
+ return null;
+ }
+
+ return Marshal.PtrToStructure(_result);
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
+ public bool? XmaxInc()
+ {
+ IntPtr _result = Marshal.AllocHGlobal(1);
+ try
+ {
+ if (!Meos.TboxXmaxInc(this.Ptr, _result))
+ {
+ return null;
+ }
+
+ return Marshal.ReadByte(_result) != 0;
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
+ public double? Xmin()
+ {
+ IntPtr _result = Marshal.AllocHGlobal(8);
+ try
+ {
+ if (!Meos.TboxXmin(this.Ptr, _result))
+ {
+ return null;
+ }
+
+ return Marshal.PtrToStructure(_result);
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
+ public bool? XminInc()
+ {
+ IntPtr _result = Marshal.AllocHGlobal(1);
+ try
+ {
+ if (!Meos.TboxXminInc(this.Ptr, _result))
+ {
+ return null;
+ }
+
+ return Marshal.ReadByte(_result) != 0;
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
public static TBox? FromHEXWKB(string hexwkb)
=> MEOSFactory.WrapTBox(Meos.TboxFromHexwkb(hexwkb));
diff --git a/MEOS.NET/Types/TCbuffer.g.cs b/MEOS.NET/Types/TCbuffer.g.cs
index c5d3404..15fa255 100644
--- a/MEOS.NET/Types/TCbuffer.g.cs
+++ b/MEOS.NET/Types/TCbuffer.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TCbufferInst.g.cs b/MEOS.NET/Types/TCbufferInst.g.cs
index cfb28fb..f3e4ed3 100644
--- a/MEOS.NET/Types/TCbufferInst.g.cs
+++ b/MEOS.NET/Types/TCbufferInst.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TCbufferSeq.g.cs b/MEOS.NET/Types/TCbufferSeq.g.cs
index a914339..1f7edf1 100644
--- a/MEOS.NET/Types/TCbufferSeq.g.cs
+++ b/MEOS.NET/Types/TCbufferSeq.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TCbufferSeqSet.g.cs b/MEOS.NET/Types/TCbufferSeqSet.g.cs
index e2d07be..bafdc5b 100644
--- a/MEOS.NET/Types/TCbufferSeqSet.g.cs
+++ b/MEOS.NET/Types/TCbufferSeqSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TFloat.g.cs b/MEOS.NET/Types/TFloat.g.cs
index cf10297..14f7e92 100644
--- a/MEOS.NET/Types/TFloat.g.cs
+++ b/MEOS.NET/Types/TFloat.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
@@ -81,12 +83,48 @@ public double StartValue()
public Temporal? ToTint()
=> MEOSFactory.WrapTemporal(Meos.TfloatToTint(this.Ptr));
+ public double? ValueAtTimestamptz(DateTime t, bool strict)
+ {
+ IntPtr _value = Marshal.AllocHGlobal(8);
+ try
+ {
+ if (!Meos.TfloatValueAtTimestamptz(this.Ptr, MEOSConvert.ToTimestampTz(t), strict, _value))
+ {
+ return null;
+ }
+
+ return Marshal.PtrToStructure(_value);
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_value);
+ }
+ }
+
public Span?[] ValueBins(double vsize, double vorigin)
=> MEOSFactory.WrapSpanArray(Meos.TfloatValueBins(this.Ptr, vsize, vorigin));
public TBox?[] ValueBoxes(double vsize, double vorigin)
=> MEOSFactory.WrapTBoxArray(Meos.TfloatValueBoxes(this.Ptr, vsize, vorigin));
+ public double? ValueN(int n)
+ {
+ IntPtr _result = Marshal.AllocHGlobal(8);
+ try
+ {
+ if (!Meos.TfloatValueN(this.Ptr, n, _result))
+ {
+ return null;
+ }
+
+ return Marshal.PtrToStructure(_result);
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
public double[] Values()
=> Meos.TfloatValues(this.Ptr);
diff --git a/MEOS.NET/Types/TFloatInst.g.cs b/MEOS.NET/Types/TFloatInst.g.cs
index 45e38fd..77ae2b9 100644
--- a/MEOS.NET/Types/TFloatInst.g.cs
+++ b/MEOS.NET/Types/TFloatInst.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TFloatSeq.g.cs b/MEOS.NET/Types/TFloatSeq.g.cs
index f0860ca..cbc06cb 100644
--- a/MEOS.NET/Types/TFloatSeq.g.cs
+++ b/MEOS.NET/Types/TFloatSeq.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TFloatSeqSet.g.cs b/MEOS.NET/Types/TFloatSeqSet.g.cs
index e8b94c9..7abe65f 100644
--- a/MEOS.NET/Types/TFloatSeqSet.g.cs
+++ b/MEOS.NET/Types/TFloatSeqSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TGeo.g.cs b/MEOS.NET/Types/TGeo.g.cs
index be2ce7a..b13a2d6 100644
--- a/MEOS.NET/Types/TGeo.g.cs
+++ b/MEOS.NET/Types/TGeo.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TGeogPoint.g.cs b/MEOS.NET/Types/TGeogPoint.g.cs
index 7000248..1cc5bdd 100644
--- a/MEOS.NET/Types/TGeogPoint.g.cs
+++ b/MEOS.NET/Types/TGeogPoint.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TGeogPointInst.g.cs b/MEOS.NET/Types/TGeogPointInst.g.cs
index e1e6325..bcf02c9 100644
--- a/MEOS.NET/Types/TGeogPointInst.g.cs
+++ b/MEOS.NET/Types/TGeogPointInst.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TGeogPointSeq.g.cs b/MEOS.NET/Types/TGeogPointSeq.g.cs
index eb4f4a7..099af6c 100644
--- a/MEOS.NET/Types/TGeogPointSeq.g.cs
+++ b/MEOS.NET/Types/TGeogPointSeq.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TGeogPointSeqSet.g.cs b/MEOS.NET/Types/TGeogPointSeqSet.g.cs
index 090e73e..f31d686 100644
--- a/MEOS.NET/Types/TGeogPointSeqSet.g.cs
+++ b/MEOS.NET/Types/TGeogPointSeqSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TGeography.g.cs b/MEOS.NET/Types/TGeography.g.cs
index 73a6594..3555fbf 100644
--- a/MEOS.NET/Types/TGeography.g.cs
+++ b/MEOS.NET/Types/TGeography.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TGeographyInst.g.cs b/MEOS.NET/Types/TGeographyInst.g.cs
index 23b2feb..98ea92c 100644
--- a/MEOS.NET/Types/TGeographyInst.g.cs
+++ b/MEOS.NET/Types/TGeographyInst.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TGeographySeq.g.cs b/MEOS.NET/Types/TGeographySeq.g.cs
index a132e8c..df793a5 100644
--- a/MEOS.NET/Types/TGeographySeq.g.cs
+++ b/MEOS.NET/Types/TGeographySeq.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TGeographySeqSet.g.cs b/MEOS.NET/Types/TGeographySeqSet.g.cs
index c5f1e78..7676ed3 100644
--- a/MEOS.NET/Types/TGeographySeqSet.g.cs
+++ b/MEOS.NET/Types/TGeographySeqSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TGeomPoint.g.cs b/MEOS.NET/Types/TGeomPoint.g.cs
index 1ad0ebf..3dd793e 100644
--- a/MEOS.NET/Types/TGeomPoint.g.cs
+++ b/MEOS.NET/Types/TGeomPoint.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TGeomPointInst.g.cs b/MEOS.NET/Types/TGeomPointInst.g.cs
index 8a87535..110488d 100644
--- a/MEOS.NET/Types/TGeomPointInst.g.cs
+++ b/MEOS.NET/Types/TGeomPointInst.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TGeomPointSeq.g.cs b/MEOS.NET/Types/TGeomPointSeq.g.cs
index 08ad3b4..8b1fd8a 100644
--- a/MEOS.NET/Types/TGeomPointSeq.g.cs
+++ b/MEOS.NET/Types/TGeomPointSeq.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TGeomPointSeqSet.g.cs b/MEOS.NET/Types/TGeomPointSeqSet.g.cs
index 963b109..7ba7d77 100644
--- a/MEOS.NET/Types/TGeomPointSeqSet.g.cs
+++ b/MEOS.NET/Types/TGeomPointSeqSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TGeometry.g.cs b/MEOS.NET/Types/TGeometry.g.cs
index f76d612..52e799d 100644
--- a/MEOS.NET/Types/TGeometry.g.cs
+++ b/MEOS.NET/Types/TGeometry.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TGeometryInst.g.cs b/MEOS.NET/Types/TGeometryInst.g.cs
index cfddf5e..35dc952 100644
--- a/MEOS.NET/Types/TGeometryInst.g.cs
+++ b/MEOS.NET/Types/TGeometryInst.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TGeometrySeq.g.cs b/MEOS.NET/Types/TGeometrySeq.g.cs
index d56fe31..20247ee 100644
--- a/MEOS.NET/Types/TGeometrySeq.g.cs
+++ b/MEOS.NET/Types/TGeometrySeq.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TGeometrySeqSet.g.cs b/MEOS.NET/Types/TGeometrySeqSet.g.cs
index 561585e..d0e6245 100644
--- a/MEOS.NET/Types/TGeometrySeqSet.g.cs
+++ b/MEOS.NET/Types/TGeometrySeqSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TInstant.g.cs b/MEOS.NET/Types/TInstant.g.cs
index 0fb49ef..1d49aff 100644
--- a/MEOS.NET/Types/TInstant.g.cs
+++ b/MEOS.NET/Types/TInstant.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TInt.g.cs b/MEOS.NET/Types/TInt.g.cs
index a78e0ed..3c2cc5a 100644
--- a/MEOS.NET/Types/TInt.g.cs
+++ b/MEOS.NET/Types/TInt.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
@@ -51,12 +53,48 @@ public int StartValue()
public Temporal? ToTfloat()
=> MEOSFactory.WrapTemporal(Meos.TintToTfloat(this.Ptr));
+ public int? ValueAtTimestamptz(DateTime t, bool strict)
+ {
+ IntPtr _value = Marshal.AllocHGlobal(4);
+ try
+ {
+ if (!Meos.TintValueAtTimestamptz(this.Ptr, MEOSConvert.ToTimestampTz(t), strict, _value))
+ {
+ return null;
+ }
+
+ return Marshal.ReadInt32(_value);
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_value);
+ }
+ }
+
public Span?[] ValueBins(int vsize, int vorigin)
=> MEOSFactory.WrapSpanArray(Meos.TintValueBins(this.Ptr, vsize, vorigin));
public TBox?[] ValueBoxes(int vsize, int vorigin)
=> MEOSFactory.WrapTBoxArray(Meos.TintValueBoxes(this.Ptr, vsize, vorigin));
+ public int? ValueN(int n)
+ {
+ IntPtr _result = Marshal.AllocHGlobal(4);
+ try
+ {
+ if (!Meos.TintValueN(this.Ptr, n, _result))
+ {
+ return null;
+ }
+
+ return Marshal.ReadInt32(_result);
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
public int[] Values()
=> Meos.TintValues(this.Ptr);
diff --git a/MEOS.NET/Types/TIntInst.g.cs b/MEOS.NET/Types/TIntInst.g.cs
index d734142..273085d 100644
--- a/MEOS.NET/Types/TIntInst.g.cs
+++ b/MEOS.NET/Types/TIntInst.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TIntSeq.g.cs b/MEOS.NET/Types/TIntSeq.g.cs
index 1ab09dd..c6bb2d2 100644
--- a/MEOS.NET/Types/TIntSeq.g.cs
+++ b/MEOS.NET/Types/TIntSeq.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TIntSeqSet.g.cs b/MEOS.NET/Types/TIntSeqSet.g.cs
index 35dfc94..11731a0 100644
--- a/MEOS.NET/Types/TIntSeqSet.g.cs
+++ b/MEOS.NET/Types/TIntSeqSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TJsonb.g.cs b/MEOS.NET/Types/TJsonb.g.cs
index d5cde93..239c88c 100644
--- a/MEOS.NET/Types/TJsonb.g.cs
+++ b/MEOS.NET/Types/TJsonb.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TJsonbInst.g.cs b/MEOS.NET/Types/TJsonbInst.g.cs
index 05487af..89399af 100644
--- a/MEOS.NET/Types/TJsonbInst.g.cs
+++ b/MEOS.NET/Types/TJsonbInst.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TJsonbSeq.g.cs b/MEOS.NET/Types/TJsonbSeq.g.cs
index 1358209..1e9271b 100644
--- a/MEOS.NET/Types/TJsonbSeq.g.cs
+++ b/MEOS.NET/Types/TJsonbSeq.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TJsonbSeqSet.g.cs b/MEOS.NET/Types/TJsonbSeqSet.g.cs
index fdbf680..0589ea4 100644
--- a/MEOS.NET/Types/TJsonbSeqSet.g.cs
+++ b/MEOS.NET/Types/TJsonbSeqSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TNpoint.g.cs b/MEOS.NET/Types/TNpoint.g.cs
index 5581560..c2ed0db 100644
--- a/MEOS.NET/Types/TNpoint.g.cs
+++ b/MEOS.NET/Types/TNpoint.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TNpointInst.g.cs b/MEOS.NET/Types/TNpointInst.g.cs
index 31ed367..b167a0b 100644
--- a/MEOS.NET/Types/TNpointInst.g.cs
+++ b/MEOS.NET/Types/TNpointInst.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TNpointSeq.g.cs b/MEOS.NET/Types/TNpointSeq.g.cs
index e945b60..3b560b0 100644
--- a/MEOS.NET/Types/TNpointSeq.g.cs
+++ b/MEOS.NET/Types/TNpointSeq.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TNpointSeqSet.g.cs b/MEOS.NET/Types/TNpointSeqSet.g.cs
index 3715e3c..3722161 100644
--- a/MEOS.NET/Types/TNpointSeqSet.g.cs
+++ b/MEOS.NET/Types/TNpointSeqSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TNumber.g.cs b/MEOS.NET/Types/TNumber.g.cs
index 29f83b1..9e1534a 100644
--- a/MEOS.NET/Types/TNumber.g.cs
+++ b/MEOS.NET/Types/TNumber.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TPoint.g.cs b/MEOS.NET/Types/TPoint.g.cs
index b9a6118..035955c 100644
--- a/MEOS.NET/Types/TPoint.g.cs
+++ b/MEOS.NET/Types/TPoint.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
@@ -23,6 +25,24 @@ internal TPoint(IntPtr ptr) : base(ptr) { }
public Temporal? CumulativeLength()
=> MEOSFactory.WrapTemporal(Meos.TpointCumulativeLength(this.Ptr));
+ public double? Direction()
+ {
+ IntPtr _result = Marshal.AllocHGlobal(8);
+ try
+ {
+ if (!Meos.TpointDirection(this.Ptr, _result))
+ {
+ return null;
+ }
+
+ return Marshal.PtrToStructure(_result);
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
public Temporal? GetX()
=> MEOSFactory.WrapTemporal(Meos.TpointGetX(this.Ptr));
diff --git a/MEOS.NET/Types/TPose.g.cs b/MEOS.NET/Types/TPose.g.cs
index 076af2e..ae53a5e 100644
--- a/MEOS.NET/Types/TPose.g.cs
+++ b/MEOS.NET/Types/TPose.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TPoseInst.g.cs b/MEOS.NET/Types/TPoseInst.g.cs
index 8d5e5e3..3c7213e 100644
--- a/MEOS.NET/Types/TPoseInst.g.cs
+++ b/MEOS.NET/Types/TPoseInst.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TPoseSeq.g.cs b/MEOS.NET/Types/TPoseSeq.g.cs
index 88aa0bf..1f70f9a 100644
--- a/MEOS.NET/Types/TPoseSeq.g.cs
+++ b/MEOS.NET/Types/TPoseSeq.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TPoseSeqSet.g.cs b/MEOS.NET/Types/TPoseSeqSet.g.cs
index 79e348e..cb5b373 100644
--- a/MEOS.NET/Types/TPoseSeqSet.g.cs
+++ b/MEOS.NET/Types/TPoseSeqSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TRGeometry.g.cs b/MEOS.NET/Types/TRGeometry.g.cs
index 0eaa6f5..f4c44fa 100644
--- a/MEOS.NET/Types/TRGeometry.g.cs
+++ b/MEOS.NET/Types/TRGeometry.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
@@ -192,5 +194,24 @@ public string Out()
public static Temporal? In(string str)
=> MEOSFactory.WrapTemporal(Meos.TrgeometryIn(str));
+ public new static Temporal? MergeArray(Temporal[] temparr)
+ {
+ IntPtr[] _temparrValues = new IntPtr[temparr.Length];
+ for (int i = 0; i < temparr.Length; i++)
+ {
+ _temparrValues[i] = temparr[i].Ptr;
+ }
+
+ GCHandle _temparr = GCHandle.Alloc(_temparrValues, GCHandleType.Pinned);
+ try
+ {
+ return MEOSFactory.WrapTemporal(Meos.TrgeometryMergeArray(_temparr.AddrOfPinnedObject(), temparr.Length));
+ }
+ finally
+ {
+ _temparr.Free();
+ }
+ }
+
}
}
diff --git a/MEOS.NET/Types/TRGeometryInst.g.cs b/MEOS.NET/Types/TRGeometryInst.g.cs
index 9432f2f..d317814 100644
--- a/MEOS.NET/Types/TRGeometryInst.g.cs
+++ b/MEOS.NET/Types/TRGeometryInst.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TRGeometrySeq.g.cs b/MEOS.NET/Types/TRGeometrySeq.g.cs
index 6868e48..864dea3 100644
--- a/MEOS.NET/Types/TRGeometrySeq.g.cs
+++ b/MEOS.NET/Types/TRGeometrySeq.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TRGeometrySeqSet.g.cs b/MEOS.NET/Types/TRGeometrySeqSet.g.cs
index 6401afb..7474e78 100644
--- a/MEOS.NET/Types/TRGeometrySeqSet.g.cs
+++ b/MEOS.NET/Types/TRGeometrySeqSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TSequence.g.cs b/MEOS.NET/Types/TSequence.g.cs
index 7f774f4..3793c15 100644
--- a/MEOS.NET/Types/TSequence.g.cs
+++ b/MEOS.NET/Types/TSequence.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
@@ -11,5 +13,24 @@ public class TSequence : Temporal
{
internal TSequence(IntPtr ptr) : base(ptr) { }
+ public static Temporal? Make(Temporal[] instants, bool lower_inc, bool upper_inc, InterpType interp, bool normalize)
+ {
+ IntPtr[] _instantsValues = new IntPtr[instants.Length];
+ for (int i = 0; i < instants.Length; i++)
+ {
+ _instantsValues[i] = instants[i].Ptr;
+ }
+
+ GCHandle _instants = GCHandle.Alloc(_instantsValues, GCHandleType.Pinned);
+ try
+ {
+ return MEOSFactory.WrapTemporal(Meos.TsequenceMake(_instants.AddrOfPinnedObject(), instants.Length, lower_inc, upper_inc, (int) interp, normalize));
+ }
+ finally
+ {
+ _instants.Free();
+ }
+ }
+
}
}
diff --git a/MEOS.NET/Types/TSequenceSet.g.cs b/MEOS.NET/Types/TSequenceSet.g.cs
index df0c491..876cbb4 100644
--- a/MEOS.NET/Types/TSequenceSet.g.cs
+++ b/MEOS.NET/Types/TSequenceSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
@@ -11,5 +13,24 @@ public class TSequenceSet : Temporal
{
internal TSequenceSet(IntPtr ptr) : base(ptr) { }
+ public static Temporal? Make(Temporal[] sequences, bool normalize)
+ {
+ IntPtr[] _sequencesValues = new IntPtr[sequences.Length];
+ for (int i = 0; i < sequences.Length; i++)
+ {
+ _sequencesValues[i] = sequences[i].Ptr;
+ }
+
+ GCHandle _sequences = GCHandle.Alloc(_sequencesValues, GCHandleType.Pinned);
+ try
+ {
+ return MEOSFactory.WrapTemporal(Meos.TsequencesetMake(_sequences.AddrOfPinnedObject(), sequences.Length, normalize));
+ }
+ finally
+ {
+ _sequences.Free();
+ }
+ }
+
}
}
diff --git a/MEOS.NET/Types/TSpatial.g.cs b/MEOS.NET/Types/TSpatial.g.cs
index 5a543c1..91dd7d2 100644
--- a/MEOS.NET/Types/TSpatial.g.cs
+++ b/MEOS.NET/Types/TSpatial.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TText.g.cs b/MEOS.NET/Types/TText.g.cs
index e7cffb2..54f98f9 100644
--- a/MEOS.NET/Types/TText.g.cs
+++ b/MEOS.NET/Types/TText.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TTextInst.g.cs b/MEOS.NET/Types/TTextInst.g.cs
index 5f819bb..058b79c 100644
--- a/MEOS.NET/Types/TTextInst.g.cs
+++ b/MEOS.NET/Types/TTextInst.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TTextSeq.g.cs b/MEOS.NET/Types/TTextSeq.g.cs
index 3fbb9d2..3dd14da 100644
--- a/MEOS.NET/Types/TTextSeq.g.cs
+++ b/MEOS.NET/Types/TTextSeq.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TTextSeqSet.g.cs b/MEOS.NET/Types/TTextSeqSet.g.cs
index 87e1064..546f736 100644
--- a/MEOS.NET/Types/TTextSeqSet.g.cs
+++ b/MEOS.NET/Types/TTextSeqSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/Temporal.g.cs b/MEOS.NET/Types/Temporal.g.cs
index 0c6e8da..351abe4 100644
--- a/MEOS.NET/Types/Temporal.g.cs
+++ b/MEOS.NET/Types/Temporal.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
@@ -233,6 +235,24 @@ public DateTime StartTimestamptz()
public long[] Timestamps()
=> Meos.TemporalTimestamps(this.Ptr);
+ public DateTime? TimestamptzN(int n)
+ {
+ IntPtr _result = Marshal.AllocHGlobal(8);
+ try
+ {
+ if (!Meos.TemporalTimestamptzN(this.Ptr, n, _result))
+ {
+ return null;
+ }
+
+ return MEOSConvert.ToDateTime(Marshal.ReadInt64(_result));
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
public Span? ToTstzspan()
=> MEOSFactory.WrapSpan(Meos.TemporalToTstzspan(this.Ptr));
@@ -245,5 +265,24 @@ public bool UpperInc()
public static Temporal? FromHEXWKB(string hexwkb)
=> MEOSFactory.WrapTemporal(Meos.TemporalFromHexwkb(hexwkb));
+ public static Temporal? MergeArray(Temporal[] temparr)
+ {
+ IntPtr[] _temparrValues = new IntPtr[temparr.Length];
+ for (int i = 0; i < temparr.Length; i++)
+ {
+ _temparrValues[i] = temparr[i].Ptr;
+ }
+
+ GCHandle _temparr = GCHandle.Alloc(_temparrValues, GCHandleType.Pinned);
+ try
+ {
+ return MEOSFactory.WrapTemporal(Meos.TemporalMergeArray(_temparr.AddrOfPinnedObject(), temparr.Length));
+ }
+ finally
+ {
+ _temparr.Free();
+ }
+ }
+
}
}
diff --git a/MEOS.NET/Types/TextSet.g.cs b/MEOS.NET/Types/TextSet.g.cs
index 5343968..e4c6a32 100644
--- a/MEOS.NET/Types/TextSet.g.cs
+++ b/MEOS.NET/Types/TextSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TsTzSet.g.cs b/MEOS.NET/Types/TsTzSet.g.cs
index e884934..a10036b 100644
--- a/MEOS.NET/Types/TsTzSet.g.cs
+++ b/MEOS.NET/Types/TsTzSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
@@ -30,6 +32,24 @@ public DateTime StartValue()
public STBox? ToStbox()
=> MEOSFactory.WrapSTBox(Meos.TstzsetToStbox(this.Ptr));
+ public DateTime? ValueN(int n)
+ {
+ IntPtr _result = Marshal.AllocHGlobal(8);
+ try
+ {
+ if (!Meos.TstzsetValueN(this.Ptr, n, _result))
+ {
+ return null;
+ }
+
+ return MEOSConvert.ToDateTime(Marshal.ReadInt64(_result));
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
public long[] Values()
=> Meos.TstzsetValues(this.Ptr);
diff --git a/MEOS.NET/Types/TsTzSpan.g.cs b/MEOS.NET/Types/TsTzSpan.g.cs
index 81d675a..834c3ec 100644
--- a/MEOS.NET/Types/TsTzSpan.g.cs
+++ b/MEOS.NET/Types/TsTzSpan.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
diff --git a/MEOS.NET/Types/TsTzSpanSet.g.cs b/MEOS.NET/Types/TsTzSpanSet.g.cs
index aa690a6..bfa2938 100644
--- a/MEOS.NET/Types/TsTzSpanSet.g.cs
+++ b/MEOS.NET/Types/TsTzSpanSet.g.cs
@@ -1,5 +1,7 @@
#nullable enable
+using System.Runtime.InteropServices;
+
using MEOS.NET.Enums;
using MEOS.NET.Functions;
@@ -33,6 +35,24 @@ public DateTime StartTimestamptz()
public Set? Timestamps()
=> MEOSFactory.WrapSet(Meos.TstzspansetTimestamps(this.Ptr));
+ public DateTime? TimestamptzN(int n)
+ {
+ IntPtr _result = Marshal.AllocHGlobal(8);
+ try
+ {
+ if (!Meos.TstzspansetTimestamptzN(this.Ptr, n, _result))
+ {
+ return null;
+ }
+
+ return MEOSConvert.ToDateTime(Marshal.ReadInt64(_result));
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(_result);
+ }
+ }
+
public SpanSet? ToDatespanset()
=> MEOSFactory.WrapSpanSet(Meos.TstzspansetToDatespanset(this.Ptr));
diff --git a/tools/objectgen.py b/tools/objectgen.py
index 9f4ef40..889a7ed 100644
--- a/tools/objectgen.py
+++ b/tools/objectgen.py
@@ -61,6 +61,19 @@
# The template axis: a concrete class is the product ``.
SUBTYPE_SUFFIX = {"TInstant": "Inst", "TSequence": "Seq", "TSequenceSet": "SeqSet"}
+# What a value out-parameter of each pointee type reads back as: the C# type, the
+# bytes to allocate for it, and how to read the value MEOS wrote there.
+OUT_PARAM_READERS = {
+ "double *": ("double", 8, "Marshal.PtrToStructure({0})"),
+ "float8 *": ("double", 8, "Marshal.PtrToStructure({0})"),
+ "bool *": ("bool", 1, "Marshal.ReadByte({0}) != 0"),
+ "int *": ("int", 4, "Marshal.ReadInt32({0})"),
+ "int32_t *": ("int", 4, "Marshal.ReadInt32({0})"),
+ "int64_t *": ("long", 8, "Marshal.ReadInt64({0})"),
+ "TimestampTz *": ("DateTime", 8, "MEOSConvert.ToDateTime(Marshal.ReadInt64({0}))"),
+ "DateADT *": ("DateOnly", 4, "MEOSConvert.ToDateOnly(Marshal.ReadInt32({0}))"),
+}
+
# C types the object layer passes and returns as C# scalars, keyed by the cleaned
# C spelling. Everything else is either a wrapped class pointer or deferred.
PASSTHROUGH_C = {
@@ -233,12 +246,17 @@ class Method:
"""One emitted method: its C# signature and the wrapper call behind it."""
def __init__(self, name: str, ret: str, params: list[tuple[str, str]],
- body: str, static: bool):
+ body: str, static: bool, arrays: list[tuple[str, str]] | None = None,
+ out_param: tuple[str, int, str] | None = None):
self.name = name
self.ret = ret
self.params = params
self.body = body
self.static = static
+ # (parameter name, element class) for each counted array the method takes.
+ self.arrays = arrays or []
+ # (parameter name, bytes, reader expression) for a value out-parameter.
+ self.out_param = out_param
class Generator:
@@ -321,16 +339,22 @@ def method_for(self, cls: str, entry: dict) -> Method | None:
# `T *values, int count` is MEOS's counted-array convention: the pointer is
# the first element of an array, not one value, so wrapping it as one
# object would hand the callee a single element and a length that lies.
- raw = [p["name"] for p in f.get("params", [])]
+ recv_ctype = self.m.ctype.get(cls)
+ declared = f.get("params", [])
+ receiver_first = (bool(declared)
+ and clean(declared[0]["cType"]) == f"{recv_ctype} *")
+ # `T *values, int count` is MEOS's counted-array convention. The length is
+ # named `count`; a parameter named `n` is the INDEX of the `*_n`
+ # accessors, whose pointer is the receiver and no array at all.
counted = set()
- for i, p in enumerate(f.get("params", [])):
- nxt = f["params"][i + 1] if i + 1 < len(f["params"]) else None
- if (clean(p["cType"]).endswith("*") and nxt
- and nxt["name"] in ("count", "n")
+ for i, p in enumerate(declared):
+ nxt = declared[i + 1] if i + 1 < len(declared) else None
+ if (i == 0 and receiver_first) or not clean(p["cType"]).endswith("*"):
+ continue
+ if (nxt and nxt["name"] == "count"
and clean(nxt["cType"]) in ("int", "int32", "int32_t")):
counted.add(codegen.csharp_param_name(p["name"]))
- recv_ctype = self.m.ctype.get(cls)
params = list(wrapper_params)
static = True
args: list[str] = []
@@ -339,6 +363,23 @@ def method_for(self, cls: str, entry: dict) -> Method | None:
args.append("this.Ptr")
params = params[1:]
+ # A `bool` return with one value out-parameter is MEOS saying whether the
+ # value exists: the method answers the value, or nothing.
+ out_params = (f.get("shape") or {}).get("outParams") or []
+ result_out = None
+ if clean(f["returnType"]["c"]) == "bool" and len(out_params) == 1:
+ pointee = clean(next(
+ (p["cType"] for p in f.get("params", [])
+ if p["name"] == out_params[0]), ""))
+ reader = OUT_PARAM_READERS.get(pointee)
+ if reader:
+ result_out = (codegen.csharp_param_name(out_params[0]), reader)
+ else:
+ self.deferred[cls].append(
+ f"{oo}: the value out-parameter {out_params[0]} is a "
+ f"{pointee}, which has no reader")
+ return None
+
ret = self.map_return(f, wrapper_ret)
if ret is None:
self.deferred[cls].append(
@@ -349,12 +390,40 @@ def method_for(self, cls: str, entry: dict) -> Method | None:
self.deferred[cls].append(f"{oo}: neither a receiver nor a value to return")
return None
+ # A counted array is one parameter to the caller and two to MEOS: the
+ # array and its length, which the array itself answers.
+ declared = f.get("params", [])
+ count_of = {}
+ for i, p in enumerate(declared):
+ if (codegen.csharp_param_name(p["name"]) in counted
+ and i + 1 < len(declared)):
+ count_of[codegen.csharp_param_name(declared[i + 1]["name"])] = \
+ codegen.csharp_param_name(p["name"])
+
+ if result_out is not None:
+ ret_type = f"{result_out[1][0]}?"
+ ret_expr = "$"
+
sig: list[tuple[str, str]] = []
+ arrays: list[tuple[str, str]] = []
for cs_type, pname in params:
+ if result_out is not None and pname == result_out[0]:
+ args.append(f"_{pname}")
+ continue
+ if pname in count_of:
+ args.append(f"{count_of[pname]}.Length")
+ continue
if pname in counted:
- self.deferred[cls].append(
- f"{oo}: argument {pname} is a counted array")
- return None
+ element = self.m.class_for_ctype(clean(c_by_name[pname])[:-1])
+ if element is None:
+ self.deferred[cls].append(
+ f"{oo}: argument {pname} is an array of "
+ f"{clean(c_by_name[pname])[:-1]}, which has no class")
+ return None
+ sig.append((f"{element}[]", pname))
+ arrays.append((pname, element))
+ args.append(f"_{pname}.AddrOfPinnedObject()")
+ continue
mapped = self.map_param(c_by_name.get(pname, ""), cs_type, pname)
if mapped is None:
self.deferred[cls].append(
@@ -365,7 +434,12 @@ def method_for(self, cls: str, entry: dict) -> Method | None:
args.append(mapped[1])
call = f"Meos.{codegen.public_name(fname)}({', '.join(args)})"
- return Method(pascal(oo), ret_type, sig, ret_expr.replace("$", call), static)
+ out = None
+ if result_out is not None:
+ name, (_, size, reader) = result_out
+ out = (name, size, reader.format(f"_{name}"))
+ return Method(pascal(oo), ret_type, sig, ret_expr.replace("$", call), static,
+ arrays, out)
def inherited_names(self, cls: str) -> set[tuple]:
names: set[tuple] = set()
@@ -393,6 +467,8 @@ def emit_class(self, cls: str) -> str:
lines = [
"#nullable enable",
"",
+ "using System.Runtime.InteropServices;",
+ "",
"using MEOS.NET.Enums;",
"using MEOS.NET.Functions;",
"",
@@ -411,11 +487,71 @@ def emit_class(self, cls: str) -> str:
new = "new " if (m.name, tuple(t for t, _ in m.params)) in inherited else ""
kind = "static " if m.static else ""
lines.append(f" public {new}{kind}{m.ret} {m.name}({args})")
- lines.append(f" => {m.body};")
+ if m.out_param:
+ lines.extend(self.out_param_body(m))
+ elif m.arrays:
+ lines.extend(self.array_body(m))
+ else:
+ lines.append(f" => {m.body};")
lines.append("")
lines += [" }", "}", ""]
return "\n".join(lines)
+ def out_param_body(self, method: Method) -> list[str]:
+ """The body of a method whose value MEOS writes through an out-parameter.
+
+ MEOS answers `false` when the value does not exist and leaves the
+ out-parameter untouched, so the method answers null there and the value
+ otherwise."""
+ name, size, reader = method.out_param
+ return [
+ " {",
+ f" IntPtr _{name} = Marshal.AllocHGlobal({size});",
+ " try",
+ " {",
+ f" if (!{method.body})",
+ " {",
+ " return null;",
+ " }",
+ "",
+ f" return {reader};",
+ " }",
+ " finally",
+ " {",
+ f" Marshal.FreeHGlobal(_{name});",
+ " }",
+ " }",
+ ]
+
+ def array_body(self, method: Method) -> list[str]:
+ """The body of a method taking a counted array.
+
+ MEOS reads an array of its own values through a pointer to the first
+ element, so the wrappers' pointers are gathered into one array and pinned
+ for the call. MEOS copies what it keeps, so the pin lasts exactly as long
+ as the call does."""
+ lines = [" {"]
+ for name, element in method.arrays:
+ lines += [
+ f" IntPtr[] _{name}Values = new IntPtr[{ident(name)}.Length];",
+ f" for (int i = 0; i < {ident(name)}.Length; i++)",
+ " {",
+ f" _{name}Values[i] = {ident(name)}[i].Ptr;",
+ " }",
+ "",
+ f" GCHandle _{name} = GCHandle.Alloc(_{name}Values, GCHandleType.Pinned);",
+ ]
+ lines.append(" try")
+ lines.append(" {")
+ lines.append(f" return {method.body};")
+ lines.append(" }")
+ lines.append(" finally")
+ lines.append(" {")
+ for name, _ in method.arrays:
+ lines.append(f" _{name}.Free();")
+ lines += [" }", " }"]
+ return lines
+
def to_string(self, cls: str, methods: list) -> list[str]:
"""`ToString` over the class's own text output, where MEOS publishes one.