diff --git a/MEOS.NET.Tests/ValueClassTests.cs b/MEOS.NET.Tests/ValueClassTests.cs index ea62cb5..84c2c2d 100644 --- a/MEOS.NET.Tests/ValueClassTests.cs +++ b/MEOS.NET.Tests/ValueClassTests.cs @@ -55,8 +55,9 @@ public void ATemporalGeoIsRestrictedByAGeometry() // The trip leaves the square at (2,2), halfway along, so what the // restriction answers ends there rather than at the trip's own end. Assert.IsNotNull(inside); - StringAssert.Contains(inside!.ToString(), "2024-12-07"); - Assert.IsFalse(inside.ToString().Contains("2024-12-08")); + string text = inside!.ToString() ?? string.Empty; + StringAssert.Contains(text, "2024-12-07"); + Assert.IsFalse(text.Contains("2024-12-08")); } } } diff --git a/MEOS.NET.Tests/ValueStructTests.cs b/MEOS.NET.Tests/ValueStructTests.cs new file mode 100644 index 0000000..75241bd --- /dev/null +++ b/MEOS.NET.Tests/ValueStructTests.cs @@ -0,0 +1,77 @@ +using MEOS.NET.Structures; +using MEOS.NET.Types; + +namespace MEOS.NET.Tests +{ + /// + /// A MEOS struct whose layout is all scalars and that no class stands for is + /// carried as a value: the method takes and answers the value itself rather + /// than an address into MEOS. + /// + [TestClass] + public class ValueStructTests : MeosTest + { + [TestMethod] + public void ASpanAnswersItsDurationAsAnInterval() + { + TsTzSpan span = (TsTzSpan)TsTzSpan.In("[2024-12-06, 2024-12-08]")!; + + Interval? duration = span.Duration(); + + Assert.IsNotNull(duration); + Assert.AreEqual(2, duration!.Value.day); + Assert.AreEqual(0, duration!.Value.month); + Assert.AreEqual("2 days", duration.ToString()); + } + + [TestMethod] + public void AnIntervalReadsAndWritesTheTextMeosDoes() + { + Interval? day = Interval.In("1 day"); + + Assert.IsNotNull(day); + Assert.AreEqual(1, day!.Value.day); + Assert.AreEqual(0, day!.Value.time); + Assert.AreEqual("1 day", day.ToString()); + Assert.ThrowsException( + () => Interval.In("not an interval")); + } + + [TestMethod] + public void ASpanIsShiftedByAnIntervalItIsGivenAsAValue() + { + TsTzSpan span = (TsTzSpan)TsTzSpan.In("[2024-12-06, 2024-12-08]")!; + + Span? shifted = span.ShiftScale(Interval.In("1 day")!.Value, + Interval.In("4 days")!.Value); + + Assert.IsNotNull(shifted); + Assert.AreEqual("[2024-12-07 00:00:00+00, 2024-12-11 00:00:00+00]", + shifted!.ToString()); + } + + [TestMethod] + public void AFrechetPathComesBackAsTheMatchesThemselves() + { + Temporal trip = TFloat.In("[1@2024-12-06, 3@2024-12-08]")!; + Temporal other = TFloat.In("[2@2024-12-06, 4@2024-12-08]")!; + + Match[] path = trip.FrechetPath(other); + + // A match pairs an instant of one value with an instant of the + // other, and MEOS walks the distance matrix back from the last pair + // to the first, so the path arrives in that order. + Assert.IsTrue(path.Length > 0); + foreach (Match match in path) + { + Assert.IsTrue(match.i >= 0 && match.i < 2, $"i={match.i}"); + Assert.IsTrue(match.j >= 0 && match.j < 2, $"j={match.j}"); + } + + Assert.AreEqual(1, path[0].i); + Assert.AreEqual(1, path[0].j); + Assert.AreEqual(0, path[path.Length - 1].i); + Assert.AreEqual(0, path[path.Length - 1].j); + } + } +} diff --git a/MEOS.NET/Functions/Meos.Native.g.cs b/MEOS.NET/Functions/Meos.Native.g.cs index 96a15d9..fea9327 100644 --- a/MEOS.NET/Functions/Meos.Native.g.cs +++ b/MEOS.NET/Functions/Meos.Native.g.cs @@ -10455,6 +10455,12 @@ private static partial class Native [LibraryImport(DllPath, EntryPoint = "pcpatch_npoints", StringMarshalling = StringMarshalling.Utf8)] internal static partial uint PcpatchNpoints(IntPtr pa); + [LibraryImport(DllPath, EntryPoint = "pcpatch_point_n", StringMarshalling = StringMarshalling.Utf8)] + internal static partial IntPtr PcpatchPointN(IntPtr pa, int n); + + [LibraryImport(DllPath, EntryPoint = "pcpatch_points", StringMarshalling = StringMarshalling.Utf8)] + internal static partial IntPtr PcpatchPoints(IntPtr pa, IntPtr count); + [LibraryImport(DllPath, EntryPoint = "pcpatch_hash", StringMarshalling = StringMarshalling.Utf8)] internal static partial uint PcpatchHash(IntPtr pa); diff --git a/MEOS.NET/Functions/Meos.meos_pointcloud.g.cs b/MEOS.NET/Functions/Meos.meos_pointcloud.g.cs index f2ff594..62e953b 100644 --- a/MEOS.NET/Functions/Meos.meos_pointcloud.g.cs +++ b/MEOS.NET/Functions/Meos.meos_pointcloud.g.cs @@ -132,6 +132,24 @@ public static uint PcpatchGetPcid(IntPtr pa) public static uint PcpatchNpoints(IntPtr pa) => SafeExecution(() => Native.PcpatchNpoints(pa)); + public static IntPtr PcpatchPointN(IntPtr pa, int n) + => SafeExecution(() => Native.PcpatchPointN(pa, n)); + + public static IntPtr[] PcpatchPoints(IntPtr pa) + { + IntPtr _cnt = Marshal.AllocHGlobal(sizeof(int)); + try + { + IntPtr _p = SafeExecution(() => Native.PcpatchPoints(pa, _cnt)); + int _n = Marshal.ReadInt32(_cnt); + IntPtr[] _out = new IntPtr[_n]; + for (int _i = 0; _i < _n; _i++) + { _out[_i] = Marshal.ReadIntPtr(_p, _i * IntPtr.Size); } + return _out; + } + finally { Marshal.FreeHGlobal(_cnt); } + } + public static uint PcpatchHash(IntPtr pa) => SafeExecution(() => Native.PcpatchHash(pa)); diff --git a/MEOS.NET/Structures/MeosStructs.g.cs b/MEOS.NET/Structures/MeosStructs.g.cs index 8728d90..c53d454 100644 --- a/MEOS.NET/Structures/MeosStructs.g.cs +++ b/MEOS.NET/Structures/MeosStructs.g.cs @@ -3,8 +3,106 @@ using System.CodeDom.Compiler; using System.Runtime.InteropServices; +using MEOS.NET.Functions; + namespace MEOS.NET.Structures { + /// The MEOS AFFINE struct, as MEOS returns it. + [GeneratedCode("MEOS.NET.Codegen", "0.1.0")] + [StructLayout(LayoutKind.Sequential)] + public struct AFFINE + { + public double afac; + public double bfac; + public double cfac; + public double dfac; + public double efac; + public double ffac; + public double gfac; + public double hfac; + public double ifac; + public double xoff; + public double yoff; + public double zoff; + } + + /// The MEOS BOX3D struct, as MEOS returns it. + [GeneratedCode("MEOS.NET.Codegen", "0.1.0")] + [StructLayout(LayoutKind.Sequential)] + public struct BOX3D + { + public double xmin; + public double ymin; + public double zmin; + public double xmax; + public double ymax; + public double zmax; + public int srid; + + /// The BOX3D MEOS reads from this text. + public static BOX3D? In(string str) + { + IntPtr ptr = Meos.Box3dIn(str); + return ptr == IntPtr.Zero ? null : Marshal.PtrToStructure(ptr); + } + + /// The text MEOS writes this value as. + public override string ToString() + { + IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(this, ptr, false); + return Meos.Box3dOut(ptr, 15); + } + finally + { + Marshal.FreeHGlobal(ptr); + } + } + } + + /// The MEOS Interval struct, as MEOS returns it. + [GeneratedCode("MEOS.NET.Codegen", "0.1.0")] + [StructLayout(LayoutKind.Sequential)] + public struct Interval + { + public long time; + public int day; + public int month; + + /// The Interval MEOS reads from this text. + public static Interval? In(string str) + { + IntPtr ptr = Meos.IntervalIn(str, -1); + return ptr == IntPtr.Zero ? null : Marshal.PtrToStructure(ptr); + } + + /// The text MEOS writes this value as. + public override string ToString() + { + IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(this, ptr, false); + return Meos.IntervalOut(ptr); + } + finally + { + Marshal.FreeHGlobal(ptr); + } + } + } + + /// The MEOS Match struct, as MEOS returns it. + [GeneratedCode("MEOS.NET.Codegen", "0.1.0")] + [StructLayout(LayoutKind.Sequential)] + public struct Match + { + public int i; + public int j; + } + /// The MEOS MvtGeom struct, as MEOS returns it. [GeneratedCode("MEOS.NET.Codegen", "0.1.0")] [StructLayout(LayoutKind.Sequential)] @@ -36,4 +134,35 @@ public struct SpaceTimeSplit public int count; } + /// The MEOS TimeTzADT struct, as MEOS returns it. + [GeneratedCode("MEOS.NET.Codegen", "0.1.0")] + [StructLayout(LayoutKind.Sequential)] + public struct TimeTzADT + { + public long time; + public int zone; + + /// The TimeTzADT MEOS reads from this text. + public static TimeTzADT? In(string str) + { + IntPtr ptr = Meos.PgTimetzIn(str, -1); + return ptr == IntPtr.Zero ? null : Marshal.PtrToStructure(ptr); + } + + /// The text MEOS writes this value as. + public override string ToString() + { + IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(this, ptr, false); + return Meos.PgTimetzOut(ptr); + } + finally + { + Marshal.FreeHGlobal(ptr); + } + } + } + } diff --git a/MEOS.NET/Types/BigIntSet.g.cs b/MEOS.NET/Types/BigIntSet.g.cs index f797ccb..babb57f 100644 --- a/MEOS.NET/Types/BigIntSet.g.cs +++ b/MEOS.NET/Types/BigIntSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/BigIntSpan.g.cs b/MEOS.NET/Types/BigIntSpan.g.cs index bc3c38e..4fef9ec 100644 --- a/MEOS.NET/Types/BigIntSpan.g.cs +++ b/MEOS.NET/Types/BigIntSpan.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/BigIntSpanSet.g.cs b/MEOS.NET/Types/BigIntSpanSet.g.cs index 73c6e84..ac4bd5f 100644 --- a/MEOS.NET/Types/BigIntSpanSet.g.cs +++ b/MEOS.NET/Types/BigIntSpanSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/Box.g.cs b/MEOS.NET/Types/Box.g.cs index 4147bb6..f6ca6cc 100644 --- a/MEOS.NET/Types/Box.g.cs +++ b/MEOS.NET/Types/Box.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/Cbuffer.g.cs b/MEOS.NET/Types/Cbuffer.g.cs index c0e1ff3..22713e7 100644 --- a/MEOS.NET/Types/Cbuffer.g.cs +++ b/MEOS.NET/Types/Cbuffer.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/CbufferSet.g.cs b/MEOS.NET/Types/CbufferSet.g.cs index d24c9ee..49d3121 100644 --- a/MEOS.NET/Types/CbufferSet.g.cs +++ b/MEOS.NET/Types/CbufferSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/Collection.g.cs b/MEOS.NET/Types/Collection.g.cs index 7ffd7cc..7ffae20 100644 --- a/MEOS.NET/Types/Collection.g.cs +++ b/MEOS.NET/Types/Collection.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/DateSet.g.cs b/MEOS.NET/Types/DateSet.g.cs index 978f4d0..779b5cf 100644 --- a/MEOS.NET/Types/DateSet.g.cs +++ b/MEOS.NET/Types/DateSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/DateSpan.g.cs b/MEOS.NET/Types/DateSpan.g.cs index 76d299f..cbde652 100644 --- a/MEOS.NET/Types/DateSpan.g.cs +++ b/MEOS.NET/Types/DateSpan.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { @@ -17,6 +18,23 @@ internal DateSpan(IntPtr ptr) : base(ptr) { } public override string ToString() => this.Out(); + public Span?[] Bins(Interval duration, DateOnly torigin) + { + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapSpanArray(Meos.DatespanBins(this.Ptr, _duration, MEOSConvert.ToDateADT(torigin))); + } + finally + { + Marshal.FreeHGlobal(_duration); + } + } + + public Interval? Duration() + => MEOSConvert.ToStruct(Meos.DatespanDuration(this.Ptr)); + public DateOnly Lower() => MEOSConvert.ToDateOnly(Meos.DatespanLower(this.Ptr)); diff --git a/MEOS.NET/Types/DateSpanSet.g.cs b/MEOS.NET/Types/DateSpanSet.g.cs index 378f520..8477509 100644 --- a/MEOS.NET/Types/DateSpanSet.g.cs +++ b/MEOS.NET/Types/DateSpanSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { @@ -17,6 +18,20 @@ internal DateSpanSet(IntPtr ptr) : base(ptr) { } public override string ToString() => this.Out(); + public Span?[] Bins(Interval duration, DateOnly torigin) + { + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapSpanArray(Meos.DatespansetBins(this.Ptr, _duration, MEOSConvert.ToDateADT(torigin))); + } + finally + { + Marshal.FreeHGlobal(_duration); + } + } + public DateOnly? DateN(int n) { IntPtr _result = Marshal.AllocHGlobal(4); @@ -38,6 +53,9 @@ public override string ToString() public Set? Dates() => MEOSFactory.WrapSet(Meos.DatespansetDates(this.Ptr)); + public Interval? Duration(bool boundspan) + => MEOSConvert.ToStruct(Meos.DatespansetDuration(this.Ptr, boundspan)); + public DateOnly EndDate() => MEOSConvert.ToDateOnly(Meos.DatespansetEndDate(this.Ptr)); diff --git a/MEOS.NET/Types/FloatSet.g.cs b/MEOS.NET/Types/FloatSet.g.cs index 33edc9b..89889d1 100644 --- a/MEOS.NET/Types/FloatSet.g.cs +++ b/MEOS.NET/Types/FloatSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/FloatSpan.g.cs b/MEOS.NET/Types/FloatSpan.g.cs index bba4ef0..0c33641 100644 --- a/MEOS.NET/Types/FloatSpan.g.cs +++ b/MEOS.NET/Types/FloatSpan.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/FloatSpanSet.g.cs b/MEOS.NET/Types/FloatSpanSet.g.cs index ea65d63..e483a7c 100644 --- a/MEOS.NET/Types/FloatSpanSet.g.cs +++ b/MEOS.NET/Types/FloatSpanSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/Geo.g.cs b/MEOS.NET/Types/Geo.g.cs index 6e2f856..bd7f6c4 100644 --- a/MEOS.NET/Types/Geo.g.cs +++ b/MEOS.NET/Types/Geo.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/GeogSet.g.cs b/MEOS.NET/Types/GeogSet.g.cs index 107f2ca..c101eaf 100644 --- a/MEOS.NET/Types/GeogSet.g.cs +++ b/MEOS.NET/Types/GeogSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/Geography.g.cs b/MEOS.NET/Types/Geography.g.cs index 6a6c7a6..98f816d 100644 --- a/MEOS.NET/Types/Geography.g.cs +++ b/MEOS.NET/Types/Geography.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/GeomSet.g.cs b/MEOS.NET/Types/GeomSet.g.cs index 8c02b00..ea57dc5 100644 --- a/MEOS.NET/Types/GeomSet.g.cs +++ b/MEOS.NET/Types/GeomSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/Geometry.g.cs b/MEOS.NET/Types/Geometry.g.cs index 36b71c4..41b26c9 100644 --- a/MEOS.NET/Types/Geometry.g.cs +++ b/MEOS.NET/Types/Geometry.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/IntSet.g.cs b/MEOS.NET/Types/IntSet.g.cs index 9d4248e..2f71aea 100644 --- a/MEOS.NET/Types/IntSet.g.cs +++ b/MEOS.NET/Types/IntSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/IntSpan.g.cs b/MEOS.NET/Types/IntSpan.g.cs index 13d26cf..1c511c8 100644 --- a/MEOS.NET/Types/IntSpan.g.cs +++ b/MEOS.NET/Types/IntSpan.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/IntSpanSet.g.cs b/MEOS.NET/Types/IntSpanSet.g.cs index df3fbb2..faaac17 100644 --- a/MEOS.NET/Types/IntSpanSet.g.cs +++ b/MEOS.NET/Types/IntSpanSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/Jsonb.g.cs b/MEOS.NET/Types/Jsonb.g.cs index 3d9bd89..ca29bf1 100644 --- a/MEOS.NET/Types/Jsonb.g.cs +++ b/MEOS.NET/Types/Jsonb.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/MEOSConvert.g.cs b/MEOS.NET/Types/MEOSConvert.g.cs index 724e782..ec372f1 100644 --- a/MEOS.NET/Types/MEOSConvert.g.cs +++ b/MEOS.NET/Types/MEOSConvert.g.cs @@ -1,6 +1,7 @@ #nullable enable using System.Globalization; +using System.Runtime.InteropServices; using MEOS.NET.Functions; @@ -31,5 +32,23 @@ internal static DateOnly ToDateOnly(int date) internal static int ToDateADT(DateOnly day) => Meos.DateIn( day.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)); + + /// The struct MEOS answers through a pointer, as a value. The + /// memory behind the pointer stays MEOS's, as it does for every other + /// value the layer reads back. + internal static T? ToStruct(IntPtr ptr) where T : struct + => ptr == IntPtr.Zero ? null : Marshal.PtrToStructure(ptr); + + /// Each struct of an array MEOS answers, as a value. + internal static T[] ToStructArray(IntPtr[] ptrs) where T : struct + { + T[] values = new T[ptrs.Length]; + for (int i = 0; i < ptrs.Length; i++) + { + values[i] = Marshal.PtrToStructure(ptrs[i]); + } + + return values; + } } } diff --git a/MEOS.NET/Types/Npoint.g.cs b/MEOS.NET/Types/Npoint.g.cs index 0368ed7..a6a3919 100644 --- a/MEOS.NET/Types/Npoint.g.cs +++ b/MEOS.NET/Types/Npoint.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/NpointSet.g.cs b/MEOS.NET/Types/NpointSet.g.cs index 2933f81..f37ede9 100644 --- a/MEOS.NET/Types/NpointSet.g.cs +++ b/MEOS.NET/Types/NpointSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/Nsegment.g.cs b/MEOS.NET/Types/Nsegment.g.cs index 3b18892..50e6274 100644 --- a/MEOS.NET/Types/Nsegment.g.cs +++ b/MEOS.NET/Types/Nsegment.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/Pcpatch.g.cs b/MEOS.NET/Types/Pcpatch.g.cs index 4033f29..9b11a35 100644 --- a/MEOS.NET/Types/Pcpatch.g.cs +++ b/MEOS.NET/Types/Pcpatch.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { @@ -37,6 +38,12 @@ public string HexOut(int maxdd) public uint Npoints() => Meos.PcpatchNpoints(this.Ptr); + public Pcpoint? PointN(int n) + => MEOSFactory.WrapPcpoint(Meos.PcpatchPointN(this.Ptr, n)); + + public Pcpoint?[] Points() + => MEOSFactory.WrapPcpointArray(Meos.PcpatchPoints(this.Ptr)); + public Geo? ToGeom() => MEOSFactory.WrapGeo(Meos.PcpatchToGeom(this.Ptr)); diff --git a/MEOS.NET/Types/Pcpoint.g.cs b/MEOS.NET/Types/Pcpoint.g.cs index 30763eb..f006758 100644 --- a/MEOS.NET/Types/Pcpoint.g.cs +++ b/MEOS.NET/Types/Pcpoint.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/Pose.g.cs b/MEOS.NET/Types/Pose.g.cs index 9fa42f7..49beaa8 100644 --- a/MEOS.NET/Types/Pose.g.cs +++ b/MEOS.NET/Types/Pose.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/PoseChain.g.cs b/MEOS.NET/Types/PoseChain.g.cs index 52ad731..3a4c08a 100644 --- a/MEOS.NET/Types/PoseChain.g.cs +++ b/MEOS.NET/Types/PoseChain.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/PoseSet.g.cs b/MEOS.NET/Types/PoseSet.g.cs index 061d72e..b906a0f 100644 --- a/MEOS.NET/Types/PoseSet.g.cs +++ b/MEOS.NET/Types/PoseSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/Raquet.g.cs b/MEOS.NET/Types/Raquet.g.cs index e3c3408..2acc778 100644 --- a/MEOS.NET/Types/Raquet.g.cs +++ b/MEOS.NET/Types/Raquet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/STBox.g.cs b/MEOS.NET/Types/STBox.g.cs index eedbd49..54be205 100644 --- a/MEOS.NET/Types/STBox.g.cs +++ b/MEOS.NET/Types/STBox.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { @@ -32,6 +33,20 @@ public bool Eq(STBox box2) public STBox? ExpandSpace(double d) => MEOSFactory.WrapSTBox(Meos.StboxExpandSpace(this.Ptr, d)); + public STBox? ExpandTime(Interval interv) + { + IntPtr _interv = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(interv, _interv, false); + return MEOSFactory.WrapSTBox(Meos.StboxExpandTime(this.Ptr, _interv)); + } + finally + { + Marshal.FreeHGlobal(_interv); + } + } + public bool Ge(STBox box2) => Meos.StboxGe(this.Ptr, box2.Ptr); @@ -86,12 +101,57 @@ public int SRID() public STBox? SetSRID(int srid) => MEOSFactory.WrapSTBox(Meos.StboxSetSrid(this.Ptr, srid)); + public STBox? ShiftScaleTime(Interval shift, Interval duration) + { + IntPtr _shift = Marshal.AllocHGlobal(Marshal.SizeOf()); + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(shift, _shift, false); + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapSTBox(Meos.StboxShiftScaleTime(this.Ptr, _shift, _duration)); + } + finally + { + Marshal.FreeHGlobal(_shift); + Marshal.FreeHGlobal(_duration); + } + } + public STBox?[] SpaceTiles(double xsize, double ysize, double zsize, Geo sorigin, bool border_inc) => MEOSFactory.WrapSTBoxArray(Meos.StboxSpaceTiles(this.Ptr, xsize, ysize, zsize, sorigin.Ptr, border_inc)); + public STBox?[] SpaceTimeTiles(double xsize, double ysize, double zsize, Interval duration, Geo sorigin, DateTime torigin, bool border_inc) + { + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapSTBoxArray(Meos.StboxSpaceTimeTiles(this.Ptr, xsize, ysize, zsize, _duration, sorigin.Ptr, MEOSConvert.ToTimestampTz(torigin), border_inc)); + } + finally + { + Marshal.FreeHGlobal(_duration); + } + } + public double SpatialDistance(STBox box2) => Meos.StboxSpatialDistance(this.Ptr, box2.Ptr); + public STBox?[] TimeTiles(Interval duration, DateTime torigin, bool border_inc) + { + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapSTBoxArray(Meos.StboxTimeTiles(this.Ptr, _duration, MEOSConvert.ToTimestampTz(torigin), border_inc)); + } + finally + { + Marshal.FreeHGlobal(_duration); + } + } + public DateTime? Tmax() { IntPtr _result = Marshal.AllocHGlobal(8); @@ -164,6 +224,9 @@ public double SpatialDistance(STBox box2) } } + public BOX3D? ToBox3d() + => MEOSConvert.ToStruct(Meos.StboxToBox3d(this.Ptr)); + public Geo? ToGeo() => MEOSFactory.WrapGeo(Meos.StboxToGeo(this.Ptr)); @@ -293,6 +356,34 @@ public double Volume() public static STBox? GetSpaceTile(Geo point, double xsize, double ysize, double zsize, Geo sorigin) => MEOSFactory.WrapSTBox(Meos.StboxGetSpaceTile(point.Ptr, xsize, ysize, zsize, sorigin.Ptr)); + public static STBox? GetSpaceTimeTile(Geo point, DateTime t, double xsize, double ysize, double zsize, Interval duration, Geo sorigin, DateTime torigin) + { + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapSTBox(Meos.StboxGetSpaceTimeTile(point.Ptr, MEOSConvert.ToTimestampTz(t), xsize, ysize, zsize, _duration, sorigin.Ptr, MEOSConvert.ToTimestampTz(torigin))); + } + finally + { + Marshal.FreeHGlobal(_duration); + } + } + + public static STBox? GetTimeTile(DateTime t, Interval duration, DateTime torigin) + { + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapSTBox(Meos.StboxGetTimeTile(MEOSConvert.ToTimestampTz(t), _duration, MEOSConvert.ToTimestampTz(torigin))); + } + finally + { + Marshal.FreeHGlobal(_duration); + } + } + public static STBox? In(string str) => MEOSFactory.WrapSTBox(Meos.StboxIn(str)); diff --git a/MEOS.NET/Types/Set.g.cs b/MEOS.NET/Types/Set.g.cs index c8b16ae..d027a4a 100644 --- a/MEOS.NET/Types/Set.g.cs +++ b/MEOS.NET/Types/Set.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/Span.g.cs b/MEOS.NET/Types/Span.g.cs index 1199e83..b953178 100644 --- a/MEOS.NET/Types/Span.g.cs +++ b/MEOS.NET/Types/Span.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/SpanSet.g.cs b/MEOS.NET/Types/SpanSet.g.cs index b5ed634..31d1e34 100644 --- a/MEOS.NET/Types/SpanSet.g.cs +++ b/MEOS.NET/Types/SpanSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TAlpha.g.cs b/MEOS.NET/Types/TAlpha.g.cs index a75e539..33170fd 100644 --- a/MEOS.NET/Types/TAlpha.g.cs +++ b/MEOS.NET/Types/TAlpha.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TBigint.g.cs b/MEOS.NET/Types/TBigint.g.cs index 70e71d7..5105d83 100644 --- a/MEOS.NET/Types/TBigint.g.cs +++ b/MEOS.NET/Types/TBigint.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TBigintInst.g.cs b/MEOS.NET/Types/TBigintInst.g.cs index 402640c..adfcfd5 100644 --- a/MEOS.NET/Types/TBigintInst.g.cs +++ b/MEOS.NET/Types/TBigintInst.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TBigintSeq.g.cs b/MEOS.NET/Types/TBigintSeq.g.cs index 0c8c5bc..077217d 100644 --- a/MEOS.NET/Types/TBigintSeq.g.cs +++ b/MEOS.NET/Types/TBigintSeq.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TBigintSeqSet.g.cs b/MEOS.NET/Types/TBigintSeqSet.g.cs index d5f271f..7e18993 100644 --- a/MEOS.NET/Types/TBigintSeqSet.g.cs +++ b/MEOS.NET/Types/TBigintSeqSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TBool.g.cs b/MEOS.NET/Types/TBool.g.cs index 9777500..c75c7db 100644 --- a/MEOS.NET/Types/TBool.g.cs +++ b/MEOS.NET/Types/TBool.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TBoolInst.g.cs b/MEOS.NET/Types/TBoolInst.g.cs index 3f7d07c..594dc61 100644 --- a/MEOS.NET/Types/TBoolInst.g.cs +++ b/MEOS.NET/Types/TBoolInst.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TBoolSeq.g.cs b/MEOS.NET/Types/TBoolSeq.g.cs index c3d0456..6701ab6 100644 --- a/MEOS.NET/Types/TBoolSeq.g.cs +++ b/MEOS.NET/Types/TBoolSeq.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TBoolSeqSet.g.cs b/MEOS.NET/Types/TBoolSeqSet.g.cs index 22dabc6..2089352 100644 --- a/MEOS.NET/Types/TBoolSeqSet.g.cs +++ b/MEOS.NET/Types/TBoolSeqSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TBox.g.cs b/MEOS.NET/Types/TBox.g.cs index d8dd6ce..bccb117 100644 --- a/MEOS.NET/Types/TBox.g.cs +++ b/MEOS.NET/Types/TBox.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { @@ -26,6 +27,20 @@ public int Cmp(TBox box2) public bool Eq(TBox box2) => Meos.TboxEq(this.Ptr, box2.Ptr); + public TBox? ExpandTime(Interval interv) + { + IntPtr _interv = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(interv, _interv, false); + return MEOSFactory.WrapTBox(Meos.TboxExpandTime(this.Ptr, _interv)); + } + finally + { + Marshal.FreeHGlobal(_interv); + } + } + public bool Ge(TBox box2) => Meos.TboxGe(this.Ptr, box2.Ptr); @@ -59,6 +74,23 @@ public string Out(int maxdd) public TBox? Round(int maxdd) => MEOSFactory.WrapTBox(Meos.TboxRound(this.Ptr, maxdd)); + public TBox? ShiftScaleTime(Interval shift, Interval duration) + { + IntPtr _shift = Marshal.AllocHGlobal(Marshal.SizeOf()); + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(shift, _shift, false); + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapTBox(Meos.TboxShiftScaleTime(this.Ptr, _shift, _duration)); + } + finally + { + Marshal.FreeHGlobal(_shift); + Marshal.FreeHGlobal(_duration); + } + } + public DateTime? Tmax() { IntPtr _result = Marshal.AllocHGlobal(8); diff --git a/MEOS.NET/Types/TCbuffer.g.cs b/MEOS.NET/Types/TCbuffer.g.cs index 327167a..915db03 100644 --- a/MEOS.NET/Types/TCbuffer.g.cs +++ b/MEOS.NET/Types/TCbuffer.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TCbufferInst.g.cs b/MEOS.NET/Types/TCbufferInst.g.cs index 37a1fb9..fd19b5a 100644 --- a/MEOS.NET/Types/TCbufferInst.g.cs +++ b/MEOS.NET/Types/TCbufferInst.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TCbufferSeq.g.cs b/MEOS.NET/Types/TCbufferSeq.g.cs index d07332b..2d54fad 100644 --- a/MEOS.NET/Types/TCbufferSeq.g.cs +++ b/MEOS.NET/Types/TCbufferSeq.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TCbufferSeqSet.g.cs b/MEOS.NET/Types/TCbufferSeqSet.g.cs index 53a947e..f1709ca 100644 --- a/MEOS.NET/Types/TCbufferSeqSet.g.cs +++ b/MEOS.NET/Types/TCbufferSeqSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TFloat.g.cs b/MEOS.NET/Types/TFloat.g.cs index 14f7e92..4b579cc 100644 --- a/MEOS.NET/Types/TFloat.g.cs +++ b/MEOS.NET/Types/TFloat.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { @@ -77,6 +78,20 @@ public double StartValue() public Temporal? Tan() => MEOSFactory.WrapTemporal(Meos.TfloatTan(this.Ptr)); + public TBox?[] TimeBoxes(Interval duration, DateTime torigin) + { + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapTBoxArray(Meos.TfloatTimeBoxes(this.Ptr, _duration, MEOSConvert.ToTimestampTz(torigin))); + } + finally + { + Marshal.FreeHGlobal(_duration); + } + } + public Temporal? ToTbigint() => MEOSFactory.WrapTemporal(Meos.TfloatToTbigint(this.Ptr)); @@ -125,6 +140,20 @@ public double StartValue() } } + public TBox?[] ValueTimeBoxes(double vsize, Interval duration, double vorigin, DateTime torigin) + { + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapTBoxArray(Meos.TfloatValueTimeBoxes(this.Ptr, vsize, _duration, vorigin, MEOSConvert.ToTimestampTz(torigin))); + } + finally + { + Marshal.FreeHGlobal(_duration); + } + } + public double[] Values() => Meos.TfloatValues(this.Ptr); diff --git a/MEOS.NET/Types/TFloatInst.g.cs b/MEOS.NET/Types/TFloatInst.g.cs index 77ae2b9..f283af9 100644 --- a/MEOS.NET/Types/TFloatInst.g.cs +++ b/MEOS.NET/Types/TFloatInst.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TFloatSeq.g.cs b/MEOS.NET/Types/TFloatSeq.g.cs index cbc06cb..7993e7e 100644 --- a/MEOS.NET/Types/TFloatSeq.g.cs +++ b/MEOS.NET/Types/TFloatSeq.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TFloatSeqSet.g.cs b/MEOS.NET/Types/TFloatSeqSet.g.cs index 7abe65f..3ec02b3 100644 --- a/MEOS.NET/Types/TFloatSeqSet.g.cs +++ b/MEOS.NET/Types/TFloatSeqSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TGeo.g.cs b/MEOS.NET/Types/TGeo.g.cs index 52ec178..249eda8 100644 --- a/MEOS.NET/Types/TGeo.g.cs +++ b/MEOS.NET/Types/TGeo.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { @@ -13,6 +14,20 @@ public class TGeo : TSpatial { internal TGeo(IntPtr ptr) : base(ptr) { } + public Temporal? Affine(AFFINE a) + { + IntPtr _a = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(a, _a, false); + return MEOSFactory.WrapTemporal(Meos.TgeoAffine(this.Ptr, _a)); + } + finally + { + Marshal.FreeHGlobal(_a); + } + } + public Temporal? AtGeom(Geo gs) => MEOSFactory.WrapTemporal(Meos.TgeoAtGeom(this.Ptr, gs.Ptr)); @@ -46,6 +61,20 @@ internal TGeo(IntPtr ptr) : base(ptr) { } public STBox?[] SpaceBoxes(double xsize, double ysize, double zsize, Geo sorigin, bool bitmatrix, bool border_inc) => MEOSFactory.WrapSTBoxArray(Meos.TgeoSpaceBoxes(this.Ptr, xsize, ysize, zsize, sorigin.Ptr, bitmatrix, border_inc)); + public STBox?[] SpaceTimeBoxes(double xsize, double ysize, double zsize, Interval duration, Geo sorigin, DateTime torigin, bool bitmatrix, bool border_inc) + { + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapSTBoxArray(Meos.TgeoSpaceTimeBoxes(this.Ptr, xsize, ysize, zsize, _duration, sorigin.Ptr, MEOSConvert.ToTimestampTz(torigin), bitmatrix, border_inc)); + } + finally + { + Marshal.FreeHGlobal(_duration); + } + } + public STBox?[] SplitEachNStboxes(int elem_count) => MEOSFactory.WrapSTBoxArray(Meos.TgeoSplitEachNStboxes(this.Ptr, elem_count)); diff --git a/MEOS.NET/Types/TGeogPoint.g.cs b/MEOS.NET/Types/TGeogPoint.g.cs index 1cc5bdd..9a54800 100644 --- a/MEOS.NET/Types/TGeogPoint.g.cs +++ b/MEOS.NET/Types/TGeogPoint.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TGeogPointInst.g.cs b/MEOS.NET/Types/TGeogPointInst.g.cs index bcf02c9..fe23d18 100644 --- a/MEOS.NET/Types/TGeogPointInst.g.cs +++ b/MEOS.NET/Types/TGeogPointInst.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TGeogPointSeq.g.cs b/MEOS.NET/Types/TGeogPointSeq.g.cs index 099af6c..452bdb0 100644 --- a/MEOS.NET/Types/TGeogPointSeq.g.cs +++ b/MEOS.NET/Types/TGeogPointSeq.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TGeogPointSeqSet.g.cs b/MEOS.NET/Types/TGeogPointSeqSet.g.cs index f31d686..7dbb1c9 100644 --- a/MEOS.NET/Types/TGeogPointSeqSet.g.cs +++ b/MEOS.NET/Types/TGeogPointSeqSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TGeography.g.cs b/MEOS.NET/Types/TGeography.g.cs index 3555fbf..fa10d47 100644 --- a/MEOS.NET/Types/TGeography.g.cs +++ b/MEOS.NET/Types/TGeography.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TGeographyInst.g.cs b/MEOS.NET/Types/TGeographyInst.g.cs index 98ea92c..0b1bec5 100644 --- a/MEOS.NET/Types/TGeographyInst.g.cs +++ b/MEOS.NET/Types/TGeographyInst.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TGeographySeq.g.cs b/MEOS.NET/Types/TGeographySeq.g.cs index df793a5..34d8b59 100644 --- a/MEOS.NET/Types/TGeographySeq.g.cs +++ b/MEOS.NET/Types/TGeographySeq.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TGeographySeqSet.g.cs b/MEOS.NET/Types/TGeographySeqSet.g.cs index 7676ed3..3dd5235 100644 --- a/MEOS.NET/Types/TGeographySeqSet.g.cs +++ b/MEOS.NET/Types/TGeographySeqSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TGeomPoint.g.cs b/MEOS.NET/Types/TGeomPoint.g.cs index 3dd793e..28136ed 100644 --- a/MEOS.NET/Types/TGeomPoint.g.cs +++ b/MEOS.NET/Types/TGeomPoint.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TGeomPointInst.g.cs b/MEOS.NET/Types/TGeomPointInst.g.cs index 110488d..19547e2 100644 --- a/MEOS.NET/Types/TGeomPointInst.g.cs +++ b/MEOS.NET/Types/TGeomPointInst.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TGeomPointSeq.g.cs b/MEOS.NET/Types/TGeomPointSeq.g.cs index 8b1fd8a..f8628cc 100644 --- a/MEOS.NET/Types/TGeomPointSeq.g.cs +++ b/MEOS.NET/Types/TGeomPointSeq.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TGeomPointSeqSet.g.cs b/MEOS.NET/Types/TGeomPointSeqSet.g.cs index 7ba7d77..861288a 100644 --- a/MEOS.NET/Types/TGeomPointSeqSet.g.cs +++ b/MEOS.NET/Types/TGeomPointSeqSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TGeometry.g.cs b/MEOS.NET/Types/TGeometry.g.cs index 52e799d..cdc5289 100644 --- a/MEOS.NET/Types/TGeometry.g.cs +++ b/MEOS.NET/Types/TGeometry.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TGeometryInst.g.cs b/MEOS.NET/Types/TGeometryInst.g.cs index 35dc952..bc4519d 100644 --- a/MEOS.NET/Types/TGeometryInst.g.cs +++ b/MEOS.NET/Types/TGeometryInst.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TGeometrySeq.g.cs b/MEOS.NET/Types/TGeometrySeq.g.cs index 20247ee..f084a36 100644 --- a/MEOS.NET/Types/TGeometrySeq.g.cs +++ b/MEOS.NET/Types/TGeometrySeq.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TGeometrySeqSet.g.cs b/MEOS.NET/Types/TGeometrySeqSet.g.cs index d0e6245..b61008a 100644 --- a/MEOS.NET/Types/TGeometrySeqSet.g.cs +++ b/MEOS.NET/Types/TGeometrySeqSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TInstant.g.cs b/MEOS.NET/Types/TInstant.g.cs index 1d49aff..460b686 100644 --- a/MEOS.NET/Types/TInstant.g.cs +++ b/MEOS.NET/Types/TInstant.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TInt.g.cs b/MEOS.NET/Types/TInt.g.cs index 3c2cc5a..b4b43a5 100644 --- a/MEOS.NET/Types/TInt.g.cs +++ b/MEOS.NET/Types/TInt.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { @@ -47,6 +48,20 @@ public string Out() public int StartValue() => Meos.TintStartValue(this.Ptr); + public TBox?[] TimeBoxes(Interval duration, DateTime torigin) + { + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapTBoxArray(Meos.TintTimeBoxes(this.Ptr, _duration, MEOSConvert.ToTimestampTz(torigin))); + } + finally + { + Marshal.FreeHGlobal(_duration); + } + } + public Temporal? ToTbigint() => MEOSFactory.WrapTemporal(Meos.TintToTbigint(this.Ptr)); @@ -95,6 +110,20 @@ public int StartValue() } } + public TBox?[] ValueTimeBoxes(int vsize, Interval duration, int vorigin, DateTime torigin) + { + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapTBoxArray(Meos.TintValueTimeBoxes(this.Ptr, vsize, _duration, vorigin, MEOSConvert.ToTimestampTz(torigin))); + } + finally + { + Marshal.FreeHGlobal(_duration); + } + } + public int[] Values() => Meos.TintValues(this.Ptr); diff --git a/MEOS.NET/Types/TIntInst.g.cs b/MEOS.NET/Types/TIntInst.g.cs index 273085d..dad84bb 100644 --- a/MEOS.NET/Types/TIntInst.g.cs +++ b/MEOS.NET/Types/TIntInst.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TIntSeq.g.cs b/MEOS.NET/Types/TIntSeq.g.cs index c6bb2d2..5ee5dad 100644 --- a/MEOS.NET/Types/TIntSeq.g.cs +++ b/MEOS.NET/Types/TIntSeq.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TIntSeqSet.g.cs b/MEOS.NET/Types/TIntSeqSet.g.cs index 11731a0..3c18a07 100644 --- a/MEOS.NET/Types/TIntSeqSet.g.cs +++ b/MEOS.NET/Types/TIntSeqSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TJsonb.g.cs b/MEOS.NET/Types/TJsonb.g.cs index bb9d81a..bbe0c65 100644 --- a/MEOS.NET/Types/TJsonb.g.cs +++ b/MEOS.NET/Types/TJsonb.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TJsonbInst.g.cs b/MEOS.NET/Types/TJsonbInst.g.cs index b37d61a..2425807 100644 --- a/MEOS.NET/Types/TJsonbInst.g.cs +++ b/MEOS.NET/Types/TJsonbInst.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TJsonbSeq.g.cs b/MEOS.NET/Types/TJsonbSeq.g.cs index efed139..1ece8ac 100644 --- a/MEOS.NET/Types/TJsonbSeq.g.cs +++ b/MEOS.NET/Types/TJsonbSeq.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TJsonbSeqSet.g.cs b/MEOS.NET/Types/TJsonbSeqSet.g.cs index 308c9d5..0aad38d 100644 --- a/MEOS.NET/Types/TJsonbSeqSet.g.cs +++ b/MEOS.NET/Types/TJsonbSeqSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TNpoint.g.cs b/MEOS.NET/Types/TNpoint.g.cs index 42f82cc..205736c 100644 --- a/MEOS.NET/Types/TNpoint.g.cs +++ b/MEOS.NET/Types/TNpoint.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TNpointInst.g.cs b/MEOS.NET/Types/TNpointInst.g.cs index 9b0e705..062ae21 100644 --- a/MEOS.NET/Types/TNpointInst.g.cs +++ b/MEOS.NET/Types/TNpointInst.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TNpointSeq.g.cs b/MEOS.NET/Types/TNpointSeq.g.cs index e1872a9..f8cd631 100644 --- a/MEOS.NET/Types/TNpointSeq.g.cs +++ b/MEOS.NET/Types/TNpointSeq.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TNpointSeqSet.g.cs b/MEOS.NET/Types/TNpointSeqSet.g.cs index cda15e6..884b847 100644 --- a/MEOS.NET/Types/TNpointSeqSet.g.cs +++ b/MEOS.NET/Types/TNpointSeqSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TNumber.g.cs b/MEOS.NET/Types/TNumber.g.cs index 9e1534a..7041a37 100644 --- a/MEOS.NET/Types/TNumber.g.cs +++ b/MEOS.NET/Types/TNumber.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TPCBox.g.cs b/MEOS.NET/Types/TPCBox.g.cs index 031260d..8c314e7 100644 --- a/MEOS.NET/Types/TPCBox.g.cs +++ b/MEOS.NET/Types/TPCBox.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TPoint.g.cs b/MEOS.NET/Types/TPoint.g.cs index e95b38a..ae808f8 100644 --- a/MEOS.NET/Types/TPoint.g.cs +++ b/MEOS.NET/Types/TPoint.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TPose.g.cs b/MEOS.NET/Types/TPose.g.cs index 6509852..841eb7c 100644 --- a/MEOS.NET/Types/TPose.g.cs +++ b/MEOS.NET/Types/TPose.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TPoseInst.g.cs b/MEOS.NET/Types/TPoseInst.g.cs index 6795730..5c7d4dc 100644 --- a/MEOS.NET/Types/TPoseInst.g.cs +++ b/MEOS.NET/Types/TPoseInst.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TPoseSeq.g.cs b/MEOS.NET/Types/TPoseSeq.g.cs index 8495e0d..23b7e27 100644 --- a/MEOS.NET/Types/TPoseSeq.g.cs +++ b/MEOS.NET/Types/TPoseSeq.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TPoseSeqSet.g.cs b/MEOS.NET/Types/TPoseSeqSet.g.cs index 9573bb6..fe87784 100644 --- a/MEOS.NET/Types/TPoseSeqSet.g.cs +++ b/MEOS.NET/Types/TPoseSeqSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TRGeometry.g.cs b/MEOS.NET/Types/TRGeometry.g.cs index 5e7eef1..174c739 100644 --- a/MEOS.NET/Types/TRGeometry.g.cs +++ b/MEOS.NET/Types/TRGeometry.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { @@ -23,6 +24,20 @@ public override string ToString() public Temporal? AngularSpeed() => MEOSFactory.WrapTemporal(Meos.TrgeometryAngularSpeed(this.Ptr)); + public new Temporal? AppendTinstant(Temporal inst, InterpType interp, double maxdist, Interval maxt, bool expand) + { + IntPtr _maxt = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(maxt, _maxt, false); + return MEOSFactory.WrapTemporal(Meos.TrgeometryAppendTinstant(this.Ptr, inst.Ptr, (int) interp, maxdist, _maxt, expand)); + } + finally + { + Marshal.FreeHGlobal(_maxt); + } + } + public new Temporal? AppendTsequence(Temporal seq, bool expand) => MEOSFactory.WrapTemporal(Meos.TrgeometryAppendTsequence(this.Ptr, seq.Ptr, expand)); @@ -98,6 +113,9 @@ public override string ToString() public new double DyntimewarpDistance(Temporal temp2) => Meos.TrgeometryDyntimewarpDistance(this.Ptr, temp2.Ptr); + public new Match[] DyntimewarpPath(Temporal temp2) + => MEOSConvert.ToStructArray(Meos.TrgeometryDyntimewarpPath(this.Ptr, temp2.Ptr)); + public new Temporal? EndInstant() => MEOSFactory.WrapTemporal(Meos.TrgeometryEndInstant(this.Ptr)); @@ -110,6 +128,9 @@ public override string ToString() public new double FrechetDistance(Temporal temp2) => Meos.TrgeometryFrechetDistance(this.Ptr, temp2.Ptr); + public new Match[] FrechetPath(Temporal temp2) + => MEOSConvert.ToStructArray(Meos.TrgeometryFrechetPath(this.Ptr, temp2.Ptr)); + public Geo? Geom() => MEOSFactory.WrapGeo(Meos.TrgeometryGeom(this.Ptr)); @@ -185,6 +206,20 @@ public string Out() public STBox?[] SpaceBoxes(double xsize, double ysize, double zsize, Geo sorigin, bool bitmatrix, bool border_inc) => MEOSFactory.WrapSTBoxArray(Meos.TrgeometrySpaceBoxes(this.Ptr, xsize, ysize, zsize, sorigin.Ptr, bitmatrix, border_inc)); + public STBox?[] SpaceTimeBoxes(double xsize, double ysize, double zsize, Interval duration, Geo sorigin, DateTime torigin, bool bitmatrix, bool border_inc) + { + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapSTBoxArray(Meos.TrgeometrySpaceTimeBoxes(this.Ptr, xsize, ysize, zsize, _duration, sorigin.Ptr, MEOSConvert.ToTimestampTz(torigin), bitmatrix, border_inc)); + } + finally + { + Marshal.FreeHGlobal(_duration); + } + } + public Temporal? Speed() => MEOSFactory.WrapTemporal(Meos.TrgeometrySpeed(this.Ptr)); diff --git a/MEOS.NET/Types/TRGeometryInst.g.cs b/MEOS.NET/Types/TRGeometryInst.g.cs index 3c5f48b..f9ed8e3 100644 --- a/MEOS.NET/Types/TRGeometryInst.g.cs +++ b/MEOS.NET/Types/TRGeometryInst.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TRGeometrySeq.g.cs b/MEOS.NET/Types/TRGeometrySeq.g.cs index 28e0967..91a1ebc 100644 --- a/MEOS.NET/Types/TRGeometrySeq.g.cs +++ b/MEOS.NET/Types/TRGeometrySeq.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TRGeometrySeqSet.g.cs b/MEOS.NET/Types/TRGeometrySeqSet.g.cs index af028a5..c67c358 100644 --- a/MEOS.NET/Types/TRGeometrySeqSet.g.cs +++ b/MEOS.NET/Types/TRGeometrySeqSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TSequence.g.cs b/MEOS.NET/Types/TSequence.g.cs index 3793c15..e1a404b 100644 --- a/MEOS.NET/Types/TSequence.g.cs +++ b/MEOS.NET/Types/TSequence.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TSequenceSet.g.cs b/MEOS.NET/Types/TSequenceSet.g.cs index 876cbb4..36ad5a4 100644 --- a/MEOS.NET/Types/TSequenceSet.g.cs +++ b/MEOS.NET/Types/TSequenceSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TSpatial.g.cs b/MEOS.NET/Types/TSpatial.g.cs index 91dd7d2..f2d548a 100644 --- a/MEOS.NET/Types/TSpatial.g.cs +++ b/MEOS.NET/Types/TSpatial.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TText.g.cs b/MEOS.NET/Types/TText.g.cs index d5d9e42..7d94d1c 100644 --- a/MEOS.NET/Types/TText.g.cs +++ b/MEOS.NET/Types/TText.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TTextInst.g.cs b/MEOS.NET/Types/TTextInst.g.cs index 4b7ad1d..5df748d 100644 --- a/MEOS.NET/Types/TTextInst.g.cs +++ b/MEOS.NET/Types/TTextInst.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TTextSeq.g.cs b/MEOS.NET/Types/TTextSeq.g.cs index 858166f..8bac643 100644 --- a/MEOS.NET/Types/TTextSeq.g.cs +++ b/MEOS.NET/Types/TTextSeq.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TTextSeqSet.g.cs b/MEOS.NET/Types/TTextSeqSet.g.cs index ba42d3c..764b884 100644 --- a/MEOS.NET/Types/TTextSeqSet.g.cs +++ b/MEOS.NET/Types/TTextSeqSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/Temporal.g.cs b/MEOS.NET/Types/Temporal.g.cs index 351abe4..957d13d 100644 --- a/MEOS.NET/Types/Temporal.g.cs +++ b/MEOS.NET/Types/Temporal.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { @@ -16,6 +17,20 @@ internal Temporal(IntPtr ptr) : base(ptr) { } public Temporal? AfterTimestamptz(DateTime t, bool strict) => MEOSFactory.WrapTemporal(Meos.TemporalAfterTimestamptz(this.Ptr, MEOSConvert.ToTimestampTz(t), strict)); + public Temporal? AppendTinstant(Temporal inst, InterpType interp, double maxdist, Interval maxt, bool expand) + { + IntPtr _maxt = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(maxt, _maxt, false); + return MEOSFactory.WrapTemporal(Meos.TemporalAppendTinstant(this.Ptr, inst.Ptr, (int) interp, maxdist, _maxt, expand)); + } + finally + { + Marshal.FreeHGlobal(_maxt); + } + } + public Temporal? AppendTsequence(Temporal seq, bool expand) => MEOSFactory.WrapTemporal(Meos.TemporalAppendTsequence(this.Ptr, seq.Ptr, expand)); @@ -82,9 +97,15 @@ public int Cmp(Temporal temp2) public Temporal? Derivative() => MEOSFactory.WrapTemporal(Meos.TemporalDerivative(this.Ptr)); + public Interval? Duration(bool boundspan) + => MEOSConvert.ToStruct(Meos.TemporalDuration(this.Ptr, boundspan)); + public double DyntimewarpDistance(Temporal temp2) => Meos.TemporalDyntimewarpDistance(this.Ptr, temp2.Ptr); + public Match[] DyntimewarpPath(Temporal temp2) + => MEOSConvert.ToStructArray(Meos.TemporalDyntimewarpPath(this.Ptr, temp2.Ptr)); + public Temporal? EndInstant() => MEOSFactory.WrapTemporal(Meos.TemporalEndInstant(this.Ptr)); @@ -103,6 +124,9 @@ public bool Eq(Temporal temp2) public double FrechetDistance(Temporal temp2) => Meos.TemporalFrechetDistance(this.Ptr, temp2.Ptr); + public Match[] FrechetPath(Temporal temp2) + => MEOSConvert.ToStructArray(Meos.TemporalFrechetPath(this.Ptr, temp2.Ptr)); + public bool Ge(Temporal temp2) => Meos.TemporalGe(this.Ptr, temp2.Ptr); @@ -187,6 +211,34 @@ public int NumTimestamps() public Temporal? Round(int maxdd) => MEOSFactory.WrapTemporal(Meos.TemporalRound(this.Ptr, maxdd)); + public Temporal? ScaleTime(Interval duration) + { + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapTemporal(Meos.TemporalScaleTime(this.Ptr, _duration)); + } + finally + { + Marshal.FreeHGlobal(_duration); + } + } + + public Temporal? SegmDuration(Interval duration, bool atleast, bool strict) + { + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapTemporal(Meos.TemporalSegmDuration(this.Ptr, _duration, atleast, strict)); + } + finally + { + Marshal.FreeHGlobal(_duration); + } + } + public Temporal?[] Segments() => MEOSFactory.WrapTemporalArray(Meos.TemporalSegments(this.Ptr)); @@ -199,6 +251,37 @@ public int NumTimestamps() public Temporal? SetInterp(InterpType interp) => MEOSFactory.WrapTemporal(Meos.TemporalSetInterp(this.Ptr, (int) interp)); + public Temporal? ShiftScaleTime(Interval shift, Interval duration) + { + IntPtr _shift = Marshal.AllocHGlobal(Marshal.SizeOf()); + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(shift, _shift, false); + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapTemporal(Meos.TemporalShiftScaleTime(this.Ptr, _shift, _duration)); + } + finally + { + Marshal.FreeHGlobal(_shift); + Marshal.FreeHGlobal(_duration); + } + } + + public Temporal? ShiftTime(Interval shift) + { + IntPtr _shift = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(shift, _shift, false); + return MEOSFactory.WrapTemporal(Meos.TemporalShiftTime(this.Ptr, _shift)); + } + finally + { + Marshal.FreeHGlobal(_shift); + } + } + public Temporal? SimplifyDp(double dist, bool synchronized) => MEOSFactory.WrapTemporal(Meos.TemporalSimplifyDp(this.Ptr, dist, synchronized)); @@ -208,6 +291,20 @@ public int NumTimestamps() public Temporal? SimplifyMinDist(double dist) => MEOSFactory.WrapTemporal(Meos.TemporalSimplifyMinDist(this.Ptr, dist)); + public Temporal? SimplifyMinTdelta(Interval mint) + { + IntPtr _mint = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(mint, _mint, false); + return MEOSFactory.WrapTemporal(Meos.TemporalSimplifyMinTdelta(this.Ptr, _mint)); + } + finally + { + Marshal.FreeHGlobal(_mint); + } + } + public Span?[] Spans() => MEOSFactory.WrapSpanArray(Meos.TemporalSpans(this.Ptr)); @@ -226,12 +323,40 @@ public int NumTimestamps() public DateTime StartTimestamptz() => MEOSConvert.ToDateTime(Meos.TemporalStartTimestamptz(this.Ptr)); + public Temporal? Stops(double maxdist, Interval minduration) + { + IntPtr _minduration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(minduration, _minduration, false); + return MEOSFactory.WrapTemporal(Meos.TemporalStops(this.Ptr, maxdist, _minduration)); + } + finally + { + Marshal.FreeHGlobal(_minduration); + } + } + public string? Subtype() => Meos.TemporalSubtype(this.Ptr); public SpanSet? Time() => MEOSFactory.WrapSpanSet(Meos.TemporalTime(this.Ptr)); + public Span?[] TimeBins(Interval duration, DateTime origin) + { + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapSpanArray(Meos.TemporalTimeBins(this.Ptr, _duration, MEOSConvert.ToTimestampTz(origin))); + } + finally + { + Marshal.FreeHGlobal(_duration); + } + } + public long[] Timestamps() => Meos.TemporalTimestamps(this.Ptr); @@ -256,6 +381,34 @@ public long[] Timestamps() public Span? ToTstzspan() => MEOSFactory.WrapSpan(Meos.TemporalToTstzspan(this.Ptr)); + public Temporal? Tprecision(Interval duration, DateTime origin) + { + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapTemporal(Meos.TemporalTprecision(this.Ptr, _duration, MEOSConvert.ToTimestampTz(origin))); + } + finally + { + Marshal.FreeHGlobal(_duration); + } + } + + public Temporal? Tsample(Interval duration, DateTime origin, InterpType interp) + { + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapTemporal(Meos.TemporalTsample(this.Ptr, _duration, MEOSConvert.ToTimestampTz(origin), (int) interp)); + } + finally + { + Marshal.FreeHGlobal(_duration); + } + } + public Temporal? Update(Temporal temp2, bool connect) => MEOSFactory.WrapTemporal(Meos.TemporalUpdate(this.Ptr, temp2.Ptr, connect)); diff --git a/MEOS.NET/Types/Text.g.cs b/MEOS.NET/Types/Text.g.cs index f579199..fca12d3 100644 --- a/MEOS.NET/Types/Text.g.cs +++ b/MEOS.NET/Types/Text.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TextSet.g.cs b/MEOS.NET/Types/TextSet.g.cs index b47fe42..06e9ff7 100644 --- a/MEOS.NET/Types/TextSet.g.cs +++ b/MEOS.NET/Types/TextSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/MEOS.NET/Types/TsTzSet.g.cs b/MEOS.NET/Types/TsTzSet.g.cs index a10036b..313c633 100644 --- a/MEOS.NET/Types/TsTzSet.g.cs +++ b/MEOS.NET/Types/TsTzSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { @@ -23,6 +24,23 @@ public DateTime EndValue() public string Out() => Meos.TstzsetOut(this.Ptr); + public Set? ShiftScale(Interval shift, Interval duration) + { + IntPtr _shift = Marshal.AllocHGlobal(Marshal.SizeOf()); + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(shift, _shift, false); + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapSet(Meos.TstzsetShiftScale(this.Ptr, _shift, _duration)); + } + finally + { + Marshal.FreeHGlobal(_shift); + Marshal.FreeHGlobal(_duration); + } + } + public DateTime StartValue() => MEOSConvert.ToDateTime(Meos.TstzsetStartValue(this.Ptr)); @@ -32,6 +50,20 @@ public DateTime StartValue() public STBox? ToStbox() => MEOSFactory.WrapSTBox(Meos.TstzsetToStbox(this.Ptr)); + public Set? Tprecision(Interval duration, DateTime torigin) + { + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapSet(Meos.TstzsetTprecision(this.Ptr, _duration, MEOSConvert.ToTimestampTz(torigin))); + } + finally + { + Marshal.FreeHGlobal(_duration); + } + } + public DateTime? ValueN(int n) { IntPtr _result = Marshal.AllocHGlobal(8); diff --git a/MEOS.NET/Types/TsTzSpan.g.cs b/MEOS.NET/Types/TsTzSpan.g.cs index 834c3ec..a8529ca 100644 --- a/MEOS.NET/Types/TsTzSpan.g.cs +++ b/MEOS.NET/Types/TsTzSpan.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { @@ -17,18 +18,80 @@ internal TsTzSpan(IntPtr ptr) : base(ptr) { } public override string ToString() => this.Out(); + public Span?[] Bins(Interval duration, DateTime origin) + { + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapSpanArray(Meos.TstzspanBins(this.Ptr, _duration, MEOSConvert.ToTimestampTz(origin))); + } + finally + { + Marshal.FreeHGlobal(_duration); + } + } + + public Interval? Duration() + => MEOSConvert.ToStruct(Meos.TstzspanDuration(this.Ptr)); + + public Span? Expand(Interval interv) + { + IntPtr _interv = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(interv, _interv, false); + return MEOSFactory.WrapSpan(Meos.TstzspanExpand(this.Ptr, _interv)); + } + finally + { + Marshal.FreeHGlobal(_interv); + } + } + public DateTime Lower() => MEOSConvert.ToDateTime(Meos.TstzspanLower(this.Ptr)); public string Out() => Meos.TstzspanOut(this.Ptr); + public Span? ShiftScale(Interval shift, Interval duration) + { + IntPtr _shift = Marshal.AllocHGlobal(Marshal.SizeOf()); + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(shift, _shift, false); + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapSpan(Meos.TstzspanShiftScale(this.Ptr, _shift, _duration)); + } + finally + { + Marshal.FreeHGlobal(_shift); + Marshal.FreeHGlobal(_duration); + } + } + public Span? ToDatespan() => MEOSFactory.WrapSpan(Meos.TstzspanToDatespan(this.Ptr)); public STBox? ToStbox() => MEOSFactory.WrapSTBox(Meos.TstzspanToStbox(this.Ptr)); + public Span? Tprecision(Interval duration, DateTime torigin) + { + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapSpan(Meos.TstzspanTprecision(this.Ptr, _duration, MEOSConvert.ToTimestampTz(torigin))); + } + finally + { + Marshal.FreeHGlobal(_duration); + } + } + public DateTime Upper() => MEOSConvert.ToDateTime(Meos.TstzspanUpper(this.Ptr)); diff --git a/MEOS.NET/Types/TsTzSpanSet.g.cs b/MEOS.NET/Types/TsTzSpanSet.g.cs index bfa2938..c3652b8 100644 --- a/MEOS.NET/Types/TsTzSpanSet.g.cs +++ b/MEOS.NET/Types/TsTzSpanSet.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { @@ -17,6 +18,23 @@ internal TsTzSpanSet(IntPtr ptr) : base(ptr) { } public override string ToString() => this.Out(); + public Span?[] Bins(Interval duration, DateTime torigin) + { + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapSpanArray(Meos.TstzspansetBins(this.Ptr, _duration, MEOSConvert.ToTimestampTz(torigin))); + } + finally + { + Marshal.FreeHGlobal(_duration); + } + } + + public Interval? Duration(bool boundspan) + => MEOSConvert.ToStruct(Meos.TstzspansetDuration(this.Ptr, boundspan)); + public DateTime EndTimestamptz() => MEOSConvert.ToDateTime(Meos.TstzspansetEndTimestamptz(this.Ptr)); @@ -29,6 +47,23 @@ public int NumTimestamps() public string Out() => Meos.TstzspansetOut(this.Ptr); + public SpanSet? ShiftScale(Interval shift, Interval duration) + { + IntPtr _shift = Marshal.AllocHGlobal(Marshal.SizeOf()); + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(shift, _shift, false); + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapSpanSet(Meos.TstzspansetShiftScale(this.Ptr, _shift, _duration)); + } + finally + { + Marshal.FreeHGlobal(_shift); + Marshal.FreeHGlobal(_duration); + } + } + public DateTime StartTimestamptz() => MEOSConvert.ToDateTime(Meos.TstzspansetStartTimestamptz(this.Ptr)); @@ -59,6 +94,20 @@ public DateTime StartTimestamptz() public STBox? ToStbox() => MEOSFactory.WrapSTBox(Meos.TstzspansetToStbox(this.Ptr)); + public SpanSet? Tprecision(Interval duration, DateTime torigin) + { + IntPtr _duration = Marshal.AllocHGlobal(Marshal.SizeOf()); + try + { + Marshal.StructureToPtr(duration, _duration, false); + return MEOSFactory.WrapSpanSet(Meos.TstzspansetTprecision(this.Ptr, _duration, MEOSConvert.ToTimestampTz(torigin))); + } + finally + { + Marshal.FreeHGlobal(_duration); + } + } + public DateTime Upper() => MEOSConvert.ToDateTime(Meos.TstzspansetUpper(this.Ptr)); diff --git a/MEOS.NET/Types/Value.g.cs b/MEOS.NET/Types/Value.g.cs index 6b98fec..f19fd22 100644 --- a/MEOS.NET/Types/Value.g.cs +++ b/MEOS.NET/Types/Value.g.cs @@ -4,6 +4,7 @@ using MEOS.NET.Enums; using MEOS.NET.Functions; +using MEOS.NET.Structures; namespace MEOS.NET.Types { diff --git a/tools/codegen.py b/tools/codegen.py index e114ecc..39222bb 100755 --- a/tools/codegen.py +++ b/tools/codegen.py @@ -47,6 +47,7 @@ # MEOS / Postgres / vendored typedefs that libclang doesn't always reduce. "DateADT": "int", "TimeADT": "long", + "TimeOffset": "long", "TimestampTz": "long", "Timestamp": "long", "Datum": "long", @@ -78,6 +79,12 @@ # added enum from arriving as an opaque pointer the way a hand-list leaves it. ENUM_TYPES: set[str] = set() +# The catalog's text I/O per C type, filled in by ``configure``: which function +# reads a value and which writes it, and what the arguments beside the value +# itself default to. +TYPE_ENCODINGS: dict[str, dict] = {} + + # The catalog's structs by name, filled in by ``configure``. An array of struct # values is walked at the struct's own stride, which the field layout the catalog # records is what gives. @@ -90,12 +97,33 @@ def configure(idl: dict) -> None: ENUM_TYPES.update(e["name"] for e in idl.get("enums", []) if e.get("name")) STRUCTS.clear() STRUCTS.update({s["name"]: s for s in idl.get("structs", []) if s.get("fields")}) + TYPE_ENCODINGS.clear() + TYPE_ENCODINGS.update(idl.get("typeEncodings", {})) BY_VALUE_STRUCTS.clear() + classed = {c["cType"] for c in + idl.get("objectModel", {}).get("classes", {}).values() + if c.get("cType")} for f in idl.get("functions", []): + if f.get("vendored"): + continue for spot in [f["returnType"]] + list(f.get("params", [])): canonical = spot["canonical"].replace("const ", "").strip() if "*" not in canonical and canonical in STRUCTS: BY_VALUE_STRUCTS.add(canonical) + continue + # A struct MEOS hands over through a pointer is a VALUE too when + # its fields are all scalars and no class stands for it: nothing + # about it is opaque, so the binding carries the value rather than + # the address. A struct a class stands for is that class's, and + # giving it a second C# form would be two spellings of one type. + if (canonical.endswith("*") and canonical.count("*") == 1 + and canonical[:-1].strip() in STRUCTS): + base = canonical[:-1].strip() + if base in classed: + continue + fields = STRUCTS[base]["fields"] + if all(fl["cType"] in _SCALAR_BYTES for fl in fields): + BY_VALUE_STRUCTS.add(base) # Size and alignment in bytes of the scalar C types a struct field can have, on @@ -107,13 +135,15 @@ def configure(idl: dict) -> None: "float": 4, "Oid": 4, "DateADT": 4, "long": 8, "int64": 8, "int64_t": 8, "uint64": 8, "uint64_t": 8, "double": 8, "float8": 8, "Datum": 8, "Timestamp": 8, "TimestampTz": 8, - "TimeADT": 8, "size_t": 8, "uintptr_t": 8, + "TimeADT": 8, "TimeOffset": 8, "size_t": 8, "uintptr_t": 8, } -# The catalog structs a function returns or takes BY VALUE, filled in by -# ``configure``. Those are the only ones the binding gives a C# type: every -# other MEOS struct crosses the boundary as a pointer and stays opaque. +# The catalog structs the binding gives a C# VALUE type, filled in by +# ``configure``: the ones a function hands over by value, and the ones it hands +# over through a pointer while stating their whole layout in scalars and giving +# them no class. Every other MEOS struct crosses the boundary as a pointer and +# stays opaque. BY_VALUE_STRUCTS: set[str] = set() @@ -130,17 +160,21 @@ def csharp_field_type(c_type: str) -> str: def gen_structs() -> str: - """The C# form of each struct a function hands back by value. + """The C# form of each struct the binding carries as a value. A struct return is not a pointer: the ABI passes it in registers or through a hidden pointer the caller supplies, so declaring it as an IntPtr reads an - address where there is none.""" + address where there is none. A struct MEOS reads through a pointer is a + value too when its layout is all scalars, and it is written and read as the + text MEOS publishes for it wherever the catalog names that pair.""" lines = [ "#nullable enable", "", "using System.CodeDom.Compiler;", "using System.Runtime.InteropServices;", "", + f"using {NAMESPACE};", + "", f"namespace {STRUCT_NAMESPACE}", "{", ] @@ -156,11 +190,78 @@ def gen_structs() -> str: for field in struct["fields"]: lines.append(f" public {csharp_field_type(field['cType'])} " f"{csharp_param_name(field['name'])};") + lines += _struct_text_io(name, struct) lines += [" }", ""] lines += ["}", ""] return "\n".join(lines) +def _io_args(params: list, primary: str, aux: list | None) -> str | None: + """The call arguments of a text reader or writer, or None when one is + unanswerable. + + The first argument is the value itself — the text to read, or the address of + the value to write — and the catalog names the rest with the default each + takes, which is where a `maxdd` gets its digits.""" + defaults = {a["name"]: a.get("default") for a in (aux or [])} + args = [primary] + for _cs_type, pname in params[1:]: + if pname == "typmod": + args.append("-1") + continue + if pname in defaults and defaults[pname] is not None: + args.append(str(defaults[pname])) + continue + return None + return ", ".join(args) + + +def _struct_text_io(name: str, struct: dict) -> list[str]: + """`In` and `ToString` for a value struct MEOS publishes text I/O for. + + The catalog names the pair, so the value is read and written through MEOS's + own parser and printer rather than a format the binding would have to keep + in step with. The reader hands back a pointer MEOS owns, which is read as a + value the same way every other struct return is.""" + io = struct.get("serialization") or {} + reader, writer = io.get("in"), io.get("out") + if not reader or not writer: + return [] + read_fn, write_fn = SIGNATURES.get(reader), SIGNATURES.get(writer) + if not read_fn or not write_fn: + return [] + encoding = TYPE_ENCODINGS.get(name, {}) + read_args = _io_args(read_fn[1], "str", encoding.get("in_aux")) + write_args = _io_args(write_fn[1], "ptr", encoding.get("out_aux")) + if read_args is None or write_args is None: + return [] + return [ + "", + f" /// The {name} MEOS reads from this text.", + f" public static {name}? In(string str)", + f" {{", + f" IntPtr ptr = {CLASS}.{public_name(reader)}({read_args});", + f" return ptr == IntPtr.Zero" + f" ? null : Marshal.PtrToStructure<{name}>(ptr);", + f" }}", + "", + " /// The text MEOS writes this value as.", + " public override string ToString()", + f" {{", + f" IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf<{name}>());", + " try", + f" {{", + " Marshal.StructureToPtr(this, ptr, false);", + f" return {CLASS}.{public_name(writer)}({write_args});", + f" }}", + " finally", + f" {{", + " Marshal.FreeHGlobal(ptr);", + f" }}", + f" }}", + ] + + def _type_layout(c_type: str) -> tuple[int, int]: """``(size, alignment)`` in bytes of a struct field's type: a scalar, a pointer, a fixed-size array, or a nested catalog struct.""" @@ -692,18 +793,20 @@ def main(idl_path: str, dll_path: str = DLL_PATH) -> None: if clashing: raise SystemExit(f"codegen: C names sharing one C# name: {clashing}") + (out_dir / "Meos.Native.g.cs").write_text(gen_external_functions(funcs)) + grouped = by_header(funcs) + for header, group in sorted(grouped.items()): + stem = header.removesuffix(".h") + (out_dir / f"Meos.{stem}.g.cs").write_text(gen_exposed_functions(group, header)) + + # The structs come last: a value struct reads and writes itself through the + # wrappers above, so the signature registry has to hold them first. struct_dir = repo_root / "MEOS.NET" / "Structures" if struct_dir.exists(): for stale in struct_dir.glob("*.g.cs"): stale.unlink() struct_dir.mkdir(parents=True, exist_ok=True) (struct_dir / "MeosStructs.g.cs").write_text(gen_structs()) - - (out_dir / "Meos.Native.g.cs").write_text(gen_external_functions(funcs)) - grouped = by_header(funcs) - for header, group in sorted(grouped.items()): - stem = header.removesuffix(".h") - (out_dir / f"Meos.{stem}.g.cs").write_text(gen_exposed_functions(group, header)) vendored = len(idl["functions"]) - len(funcs) print(f"Wrote {len(funcs)} functions across {len(grouped)} headers " f"to MEOS.NET/Functions/, {len(BY_VALUE_STRUCTS)} by-value structs, " diff --git a/tools/objectgen.py b/tools/objectgen.py index 5b18e0e..af1d331 100644 --- a/tools/objectgen.py +++ b/tools/objectgen.py @@ -262,7 +262,8 @@ class Method: def __init__(self, name: str, ret: str, params: list[tuple[str, str]], body: str, static: bool, arrays: list[tuple[str, str]] | None = None, - out_param: tuple[str, int, str] | None = None): + out_param: tuple[str, int, str] | None = None, + structs: list[tuple[str, str]] | None = None): self.name = name self.ret = ret self.params = params @@ -272,6 +273,8 @@ def __init__(self, name: str, ret: str, params: list[tuple[str, str]], self.arrays = arrays or [] # (parameter name, bytes, reader expression) for a value out-parameter. self.out_param = out_param + # (parameter name, struct type) for each struct argument passed by value. + self.structs = structs or [] class Generator: @@ -312,8 +315,24 @@ def map_return(self, f: dict, wrapper_ret: str) -> tuple[str, str] | None: return (f"{elem}?[]", f"MEOSFactory.Wrap{elem}Array($)") if wrapper_ret in ("long[]", "int[]", "double[]", "byte[]"): return (wrapper_ret, "$") + struct = self.value_struct(c) + if struct and wrapper_ret == "IntPtr": + return (f"{struct}?", f"MEOSConvert.ToStruct<{struct}>($)") + if struct and wrapper_ret == "IntPtr[]": + return (f"{struct}[]", f"MEOSConvert.ToStructArray<{struct}>($)") return None + def value_struct(self, c_type: str) -> str | None: + """The struct a single pointer to a scalar-only struct carries. + + MEOS hands such a value over through a pointer, but nothing about it is + opaque: the catalog states its whole layout and no class stands for it, + so the layer carries the value rather than the address.""" + base = clean(c_type) + base = base[:-1].strip() if base.endswith("*") else base + base = base[:-1].strip() if base.endswith("*") else base + return base if base in codegen.BY_VALUE_STRUCTS else None + def map_param(self, c_type: str, cs_type: str, name: str) -> tuple[str, str] | None: """``(csharp_type, argument expression)`` for one parameter, or None.""" c = clean(c_type) @@ -330,6 +349,9 @@ def map_param(self, c_type: str, cs_type: str, name: str) -> tuple[str, str] | N cls = self.m.class_for_ctype(c) if cls and cs_type == "IntPtr": return (cls, f"{name}.Ptr") + struct = self.value_struct(c) + if struct and cs_type == "IntPtr": + return (struct, f"_{name}") return None # -- emission --------------------------------------------------------- @@ -421,6 +443,7 @@ def method_for(self, cls: str, entry: dict) -> Method | None: sig: list[tuple[str, str]] = [] arrays: list[tuple[str, str]] = [] + structs: 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}") @@ -447,14 +470,21 @@ def method_for(self, cls: str, entry: dict) -> Method | None: return None sig.append((mapped[0], pname)) args.append(mapped[1]) + if mapped[1] == f"_{pname}" and self.value_struct(c_by_name.get(pname, "")): + structs.append((pname, mapped[0])) call = f"Meos.{codegen.public_name(fname)}({', '.join(args)})" out = None if result_out is not None: name, (_, size, reader) = result_out out = (name, size, reader.format(f"_{name}")) + if structs and (arrays or out): + self.deferred[cls].append( + f"{oo}: a struct argument beside a counted array or an " + "out-parameter needs one body doing both") + return None return Method(pascal(oo), ret_type, sig, ret_expr.replace("$", call), static, - arrays, out) + arrays, out, structs) def inherited_names(self, cls: str) -> set[tuple]: names: set[tuple] = set() @@ -486,6 +516,7 @@ def emit_class(self, cls: str) -> str: "", "using MEOS.NET.Enums;", "using MEOS.NET.Functions;", + "using MEOS.NET.Structures;", "", f"namespace {NAMESPACE}", "{", @@ -506,6 +537,8 @@ def emit_class(self, cls: str) -> str: lines.extend(self.out_param_body(m)) elif m.arrays: lines.extend(self.array_body(m)) + elif m.structs: + lines.extend(self.struct_body(m)) else: lines.append(f" => {m.body};") lines.append("") @@ -538,6 +571,32 @@ def out_param_body(self, method: Method) -> list[str]: " }", ] + def struct_body(self, method: Method) -> list[str]: + """The body of a method taking a struct MEOS reads through a pointer. + + The caller hands over a value, so the call gets the address of a copy + that lives exactly as long as it does. MEOS reads what it needs before + returning — the values it keeps it copies — so nothing outlives the + frame.""" + lines = [" {"] + for name, struct in method.structs: + lines.append( + f" IntPtr _{name} = " + f"Marshal.AllocHGlobal(Marshal.SizeOf<{struct}>());") + lines.append(" try") + lines.append(" {") + for name, _ in method.structs: + lines.append( + f" Marshal.StructureToPtr({ident(name)}, _{name}, false);") + lines.append(f" return {method.body};") + lines.append(" }") + lines.append(" finally") + lines.append(" {") + for name, _ in method.structs: + lines.append(f" Marshal.FreeHGlobal(_{name});") + lines += [" }", " }"] + return lines + def array_body(self, method: Method) -> list[str]: """The body of a method taking a counted array. @@ -637,6 +696,7 @@ def convert_file(self) -> str: return f'''#nullable enable using System.Globalization; +using System.Runtime.InteropServices; using MEOS.NET.Functions; @@ -667,6 +727,24 @@ def convert_file(self) -> str: internal static int ToDateADT(DateOnly day) => Meos.DateIn( day.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)); + + /// The struct MEOS answers through a pointer, as a value. The + /// memory behind the pointer stays MEOS's, as it does for every other + /// value the layer reads back. + internal static T? ToStruct(IntPtr ptr) where T : struct + => ptr == IntPtr.Zero ? null : Marshal.PtrToStructure(ptr); + + /// Each struct of an array MEOS answers, as a value. + internal static T[] ToStructArray(IntPtr[] ptrs) where T : struct + {{ + T[] values = new T[ptrs.Length]; + for (int i = 0; i < ptrs.Length; i++) + {{ + values[i] = Marshal.PtrToStructure(ptrs[i]); + }} + + return values; + }} }} }} '''