Answer the value MEOS writes through an out-parameter - #26
Merged
estebanzimanyi merged 2 commits intoSep 2, 2026
Merged
Conversation
MEOS reads an array of its own values through a pointer to the first element and a count — `tsequence_make`, `tsequenceset_make`, `temporal_merge_array` and the trgeometry twin of each. The object layer takes that as one C# array: the wrappers' pointers are gathered into an `IntPtr[]` and pinned across the call. The pin lasts exactly that long because the array is the caller's throughout — `tsequence_make_free` is the twin that takes ownership, and it does so by calling `tsequence_make` and then `pfree_array` on the array it passed, which is sound only if `tsequence_make` neither frees nor retains it. Eight constructors reach the object layer that way, 611 methods against 607. The length parameter never appears in the C# signature, so it cannot disagree with the array. That also settles which parameter is an array at all: the length is named `count`, while a parameter named `n` is the index of the `*_n` accessors, whose pointer is the receiver and no array — reading `n` as a length turns `trgeometry_instant_n(temp, n)` into a call passing the receiver's own length. Three tests: a sequence made of three instants reads back as the text of all three, merging two sequences answers four instants across two sequences, and an empty array reaches MEOS as the invalid argument it is.
MEOS answers some values by writing them through an out-parameter and returning whether the value exists at all — `tbox_xmax(box, double *result)`, `floatset_value_n(set, n, double *result)`, `tfloat_value_at_timestamptz(temp, t, strict, double *result)`. The object layer answers that as a nullable: the buffer is allocated for the call, and a `false` return answers null while a `true` one answers what MEOS wrote. The out-parameter never appears in the C# signature, so a caller cannot pass a buffer of the wrong size or read one MEOS did not fill. The reader comes from the pointee: `double`, `bool`, `int`, `long`, and a `TimestampTz` or `DateADT` through the same conversion the rest of the layer uses. 35 accessors reach the object layer that way — `TBox.Xmin`, `TBox.TminInc`, `FloatSet.ValueN`, `TsTzSet.ValueN`, `TFloat.ValueAtTimestamptz` and their kin — 646 methods against 611. The 19 whose out-parameter is a `GSERIALIZED **`, `text **`, `Cbuffer **`, `Npoint **`, `Pose **` or `Jsonb **` name that pointee as their reason, since the model gives those values no class. Four tests read both answers: a float box answers its bounds and a box without an x dimension answers null for them while still answering its time bounds, a float set answers the value at an index and null past the end, and a temporal float answers its value at a moment inside its span and null outside.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
MEOS answers some values by writing them through an out-parameter and
returning whether the value exists at all —
tbox_xmax(box, double *result),floatset_value_n(set, n, double *result),tfloat_value_at_timestamptz(temp, t, strict, double *result). The objectlayer answers that as a nullable: the buffer is allocated for the call, and a
falsereturn answers null while atrueone answers what MEOS wrote.The out-parameter never appears in the C# signature, so a caller cannot pass a
buffer of the wrong size or read one MEOS did not fill. The reader comes from
the pointee:
double,bool,int,long, and aTimestampTzorDateADTthrough the same conversion the rest of the layer uses. 35 accessors reach the
object layer that way —
TBox.Xmin,TBox.TminInc,FloatSet.ValueN,TsTzSet.ValueN,TFloat.ValueAtTimestamptzand their kin — 646 methodsagainst 611. The 19 whose out-parameter is a
GSERIALIZED **,text **,Cbuffer **,Npoint **,Pose **orJsonb **name that pointee as theirreason, since the model gives those values no class.
Four tests read both answers: a float box answers its bounds and a box without
an x dimension answers null for them while still answering its time bounds, a
float set answers the value at an index and null past the end, and a temporal
float answers its value at a moment inside its span and null outside.