diff --git a/MEOS.NET.Tests/CallerAllocatedArrayTests.cs b/MEOS.NET.Tests/CallerAllocatedArrayTests.cs
new file mode 100644
index 0000000..f1ea7a5
--- /dev/null
+++ b/MEOS.NET.Tests/CallerAllocatedArrayTests.cs
@@ -0,0 +1,39 @@
+using System.Runtime.InteropServices;
+
+using MEOS.NET.Functions;
+using MEOS.NET.Types;
+
+namespace MEOS.NET.Tests
+{
+ ///
+ /// The `each` family fills an array the CALLER allocates, so the wrapper
+ /// takes that array rather than making one: MEOS writes one pointer per
+ /// member of the object, and storage for fewer of them is written past.
+ ///
+ [TestClass]
+ public class CallerAllocatedArrayTests : MeosTest
+ {
+ [TestMethod]
+ public void EachFillsTheArrayTheCallerGivesIt()
+ {
+ Jsonb jb = Jsonb.In("{\"a\": 1, \"b\": \"two\"}")!;
+ IntPtr values = Marshal.AllocHGlobal(IntPtr.Size * 8);
+ try
+ {
+ IntPtr[] keys = Meos.JsonbEach(jb.Ptr, values);
+
+ Assert.AreEqual(2, keys.Length);
+ Assert.AreEqual("a", Meos.TextOut(keys[0]));
+ Assert.AreEqual("b", Meos.TextOut(keys[1]));
+ Assert.AreEqual("1",
+ Meos.JsonbOut(Marshal.ReadIntPtr(values, 0)));
+ Assert.AreEqual("\"two\"",
+ Meos.JsonbOut(Marshal.ReadIntPtr(values, IntPtr.Size)));
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(values);
+ }
+ }
+ }
+}
diff --git a/MEOS.NET/Functions/Meos.meos_json.g.cs b/MEOS.NET/Functions/Meos.meos_json.g.cs
index 27542e7..81fd440 100644
--- a/MEOS.NET/Functions/Meos.meos_json.g.cs
+++ b/MEOS.NET/Functions/Meos.meos_json.g.cs
@@ -105,52 +105,34 @@ public static IntPtr[] JsonArrayElementsText(IntPtr js)
public static int JsonArrayLength(IntPtr js)
=> SafeExecution(() => Native.JsonArrayLength(js));
- public static (IntPtr[], IntPtr[]) JsonEach(IntPtr js)
+ public static IntPtr[] JsonEach(IntPtr js, IntPtr values)
{
- IntPtr _out_values = Marshal.AllocHGlobal(IntPtr.Size);
- IntPtr _count_count = Marshal.AllocHGlobal(sizeof(int));
+ IntPtr _cnt = Marshal.AllocHGlobal(sizeof(int));
try
{
- IntPtr _resultPtr = SafeExecution(() => Native.JsonEach(js, _out_values, _count_count));
- int _n = Marshal.ReadInt32(_count_count);
- IntPtr[] _resultArr = new IntPtr[_n];
- for (int _i = 0; _i < _n; _i++)
- { _resultArr[_i] = Marshal.ReadIntPtr(_resultPtr, _i * IntPtr.Size); }
- IntPtr __out_values_arr = Marshal.ReadIntPtr(_out_values);
- IntPtr[] __out_values_out = new IntPtr[_n];
+ IntPtr _p = SafeExecution(() => Native.JsonEach(js, values, _cnt));
+ int _n = Marshal.ReadInt32(_cnt);
+ IntPtr[] _out = new IntPtr[_n];
for (int _i = 0; _i < _n; _i++)
- { __out_values_out[_i] = Marshal.ReadIntPtr(__out_values_arr, _i * IntPtr.Size); }
- return (_resultArr, __out_values_out);
- }
- finally
- {
- Marshal.FreeHGlobal(_out_values);
- Marshal.FreeHGlobal(_count_count);
+ { _out[_i] = Marshal.ReadIntPtr(_p, _i * IntPtr.Size); }
+ return _out;
}
+ finally { Marshal.FreeHGlobal(_cnt); }
}
- public static (IntPtr[], IntPtr[]) JsonEachText(IntPtr js)
+ public static IntPtr[] JsonEachText(IntPtr js, IntPtr values)
{
- IntPtr _out_values = Marshal.AllocHGlobal(IntPtr.Size);
- IntPtr _count_count = Marshal.AllocHGlobal(sizeof(int));
+ IntPtr _cnt = Marshal.AllocHGlobal(sizeof(int));
try
{
- IntPtr _resultPtr = SafeExecution(() => Native.JsonEachText(js, _out_values, _count_count));
- int _n = Marshal.ReadInt32(_count_count);
- IntPtr[] _resultArr = new IntPtr[_n];
- for (int _i = 0; _i < _n; _i++)
- { _resultArr[_i] = Marshal.ReadIntPtr(_resultPtr, _i * IntPtr.Size); }
- IntPtr __out_values_arr = Marshal.ReadIntPtr(_out_values);
- IntPtr[] __out_values_out = new IntPtr[_n];
+ IntPtr _p = SafeExecution(() => Native.JsonEachText(js, values, _cnt));
+ int _n = Marshal.ReadInt32(_cnt);
+ IntPtr[] _out = new IntPtr[_n];
for (int _i = 0; _i < _n; _i++)
- { __out_values_out[_i] = Marshal.ReadIntPtr(__out_values_arr, _i * IntPtr.Size); }
- return (_resultArr, __out_values_out);
- }
- finally
- {
- Marshal.FreeHGlobal(_out_values);
- Marshal.FreeHGlobal(_count_count);
+ { _out[_i] = Marshal.ReadIntPtr(_p, _i * IntPtr.Size); }
+ return _out;
}
+ finally { Marshal.FreeHGlobal(_cnt); }
}
public static IntPtr JsonExtractPath(IntPtr js, IntPtr path_elems, int path_len)
@@ -228,52 +210,34 @@ public static bool JsonbContained(IntPtr jb1, IntPtr jb2)
public static bool JsonbContains(IntPtr jb1, IntPtr jb2)
=> SafeExecution(() => Native.JsonbContains(jb1, jb2));
- public static (IntPtr[], IntPtr[]) JsonbEach(IntPtr jb)
+ public static IntPtr[] JsonbEach(IntPtr jb, IntPtr values)
{
- IntPtr _out_values = Marshal.AllocHGlobal(IntPtr.Size);
- IntPtr _count_count = Marshal.AllocHGlobal(sizeof(int));
+ IntPtr _cnt = Marshal.AllocHGlobal(sizeof(int));
try
{
- IntPtr _resultPtr = SafeExecution(() => Native.JsonbEach(jb, _out_values, _count_count));
- int _n = Marshal.ReadInt32(_count_count);
- IntPtr[] _resultArr = new IntPtr[_n];
- for (int _i = 0; _i < _n; _i++)
- { _resultArr[_i] = Marshal.ReadIntPtr(_resultPtr, _i * IntPtr.Size); }
- IntPtr __out_values_arr = Marshal.ReadIntPtr(_out_values);
- IntPtr[] __out_values_out = new IntPtr[_n];
+ IntPtr _p = SafeExecution(() => Native.JsonbEach(jb, values, _cnt));
+ int _n = Marshal.ReadInt32(_cnt);
+ IntPtr[] _out = new IntPtr[_n];
for (int _i = 0; _i < _n; _i++)
- { __out_values_out[_i] = Marshal.ReadIntPtr(__out_values_arr, _i * IntPtr.Size); }
- return (_resultArr, __out_values_out);
- }
- finally
- {
- Marshal.FreeHGlobal(_out_values);
- Marshal.FreeHGlobal(_count_count);
+ { _out[_i] = Marshal.ReadIntPtr(_p, _i * IntPtr.Size); }
+ return _out;
}
+ finally { Marshal.FreeHGlobal(_cnt); }
}
- public static (IntPtr[], IntPtr[]) JsonbEachText(IntPtr jb)
+ public static IntPtr[] JsonbEachText(IntPtr jb, IntPtr values)
{
- IntPtr _out_values = Marshal.AllocHGlobal(IntPtr.Size);
- IntPtr _count_count = Marshal.AllocHGlobal(sizeof(int));
+ IntPtr _cnt = Marshal.AllocHGlobal(sizeof(int));
try
{
- IntPtr _resultPtr = SafeExecution(() => Native.JsonbEachText(jb, _out_values, _count_count));
- int _n = Marshal.ReadInt32(_count_count);
- IntPtr[] _resultArr = new IntPtr[_n];
- for (int _i = 0; _i < _n; _i++)
- { _resultArr[_i] = Marshal.ReadIntPtr(_resultPtr, _i * IntPtr.Size); }
- IntPtr __out_values_arr = Marshal.ReadIntPtr(_out_values);
- IntPtr[] __out_values_out = new IntPtr[_n];
+ IntPtr _p = SafeExecution(() => Native.JsonbEachText(jb, values, _cnt));
+ int _n = Marshal.ReadInt32(_cnt);
+ IntPtr[] _out = new IntPtr[_n];
for (int _i = 0; _i < _n; _i++)
- { __out_values_out[_i] = Marshal.ReadIntPtr(__out_values_arr, _i * IntPtr.Size); }
- return (_resultArr, __out_values_out);
- }
- finally
- {
- Marshal.FreeHGlobal(_out_values);
- Marshal.FreeHGlobal(_count_count);
+ { _out[_i] = Marshal.ReadIntPtr(_p, _i * IntPtr.Size); }
+ return _out;
}
+ finally { Marshal.FreeHGlobal(_cnt); }
}
public static bool JsonbExists(IntPtr jb, IntPtr key)
diff --git a/MEOS.NET/Functions/Meos.pgtypes.g.cs b/MEOS.NET/Functions/Meos.pgtypes.g.cs
index 5dd3553..5992523 100644
--- a/MEOS.NET/Functions/Meos.pgtypes.g.cs
+++ b/MEOS.NET/Functions/Meos.pgtypes.g.cs
@@ -534,52 +534,34 @@ public static IntPtr[] PgJsonArrayElementsText(IntPtr js)
public static int PgJsonArrayLength(IntPtr js)
=> SafeExecution(() => Native.PgJsonArrayLength(js));
- public static (IntPtr[], IntPtr[]) PgJsonEach(IntPtr js)
+ public static IntPtr[] PgJsonEach(IntPtr js, IntPtr values)
{
- IntPtr _out_values = Marshal.AllocHGlobal(IntPtr.Size);
- IntPtr _count_count = Marshal.AllocHGlobal(sizeof(int));
+ IntPtr _cnt = Marshal.AllocHGlobal(sizeof(int));
try
{
- IntPtr _resultPtr = SafeExecution(() => Native.PgJsonEach(js, _out_values, _count_count));
- int _n = Marshal.ReadInt32(_count_count);
- IntPtr[] _resultArr = new IntPtr[_n];
- for (int _i = 0; _i < _n; _i++)
- { _resultArr[_i] = Marshal.ReadIntPtr(_resultPtr, _i * IntPtr.Size); }
- IntPtr __out_values_arr = Marshal.ReadIntPtr(_out_values);
- IntPtr[] __out_values_out = new IntPtr[_n];
+ IntPtr _p = SafeExecution(() => Native.PgJsonEach(js, values, _cnt));
+ int _n = Marshal.ReadInt32(_cnt);
+ IntPtr[] _out = new IntPtr[_n];
for (int _i = 0; _i < _n; _i++)
- { __out_values_out[_i] = Marshal.ReadIntPtr(__out_values_arr, _i * IntPtr.Size); }
- return (_resultArr, __out_values_out);
- }
- finally
- {
- Marshal.FreeHGlobal(_out_values);
- Marshal.FreeHGlobal(_count_count);
+ { _out[_i] = Marshal.ReadIntPtr(_p, _i * IntPtr.Size); }
+ return _out;
}
+ finally { Marshal.FreeHGlobal(_cnt); }
}
- public static (IntPtr[], IntPtr[]) PgJsonEachText(IntPtr js)
+ public static IntPtr[] PgJsonEachText(IntPtr js, IntPtr values)
{
- IntPtr _out_values = Marshal.AllocHGlobal(IntPtr.Size);
- IntPtr _count_count = Marshal.AllocHGlobal(sizeof(int));
+ IntPtr _cnt = Marshal.AllocHGlobal(sizeof(int));
try
{
- IntPtr _resultPtr = SafeExecution(() => Native.PgJsonEachText(js, _out_values, _count_count));
- int _n = Marshal.ReadInt32(_count_count);
- IntPtr[] _resultArr = new IntPtr[_n];
- for (int _i = 0; _i < _n; _i++)
- { _resultArr[_i] = Marshal.ReadIntPtr(_resultPtr, _i * IntPtr.Size); }
- IntPtr __out_values_arr = Marshal.ReadIntPtr(_out_values);
- IntPtr[] __out_values_out = new IntPtr[_n];
+ IntPtr _p = SafeExecution(() => Native.PgJsonEachText(js, values, _cnt));
+ int _n = Marshal.ReadInt32(_cnt);
+ IntPtr[] _out = new IntPtr[_n];
for (int _i = 0; _i < _n; _i++)
- { __out_values_out[_i] = Marshal.ReadIntPtr(__out_values_arr, _i * IntPtr.Size); }
- return (_resultArr, __out_values_out);
- }
- finally
- {
- Marshal.FreeHGlobal(_out_values);
- Marshal.FreeHGlobal(_count_count);
+ { _out[_i] = Marshal.ReadIntPtr(_p, _i * IntPtr.Size); }
+ return _out;
}
+ finally { Marshal.FreeHGlobal(_cnt); }
}
public static IntPtr[] PgJsonObjectKeys(IntPtr js)
@@ -642,52 +624,34 @@ public static bool PgJsonbContained(IntPtr jb1, IntPtr jb2)
public static bool PgJsonbContains(IntPtr jb1, IntPtr jb2)
=> SafeExecution(() => Native.PgJsonbContains(jb1, jb2));
- public static (IntPtr[], IntPtr[]) PgJsonbEach(IntPtr jb)
+ public static IntPtr[] PgJsonbEach(IntPtr jb, IntPtr values)
{
- IntPtr _out_values = Marshal.AllocHGlobal(IntPtr.Size);
- IntPtr _count_count = Marshal.AllocHGlobal(sizeof(int));
+ IntPtr _cnt = Marshal.AllocHGlobal(sizeof(int));
try
{
- IntPtr _resultPtr = SafeExecution(() => Native.PgJsonbEach(jb, _out_values, _count_count));
- int _n = Marshal.ReadInt32(_count_count);
- IntPtr[] _resultArr = new IntPtr[_n];
- for (int _i = 0; _i < _n; _i++)
- { _resultArr[_i] = Marshal.ReadIntPtr(_resultPtr, _i * IntPtr.Size); }
- IntPtr __out_values_arr = Marshal.ReadIntPtr(_out_values);
- IntPtr[] __out_values_out = new IntPtr[_n];
+ IntPtr _p = SafeExecution(() => Native.PgJsonbEach(jb, values, _cnt));
+ int _n = Marshal.ReadInt32(_cnt);
+ IntPtr[] _out = new IntPtr[_n];
for (int _i = 0; _i < _n; _i++)
- { __out_values_out[_i] = Marshal.ReadIntPtr(__out_values_arr, _i * IntPtr.Size); }
- return (_resultArr, __out_values_out);
- }
- finally
- {
- Marshal.FreeHGlobal(_out_values);
- Marshal.FreeHGlobal(_count_count);
+ { _out[_i] = Marshal.ReadIntPtr(_p, _i * IntPtr.Size); }
+ return _out;
}
+ finally { Marshal.FreeHGlobal(_cnt); }
}
- public static (IntPtr[], IntPtr[]) PgJsonbEachText(IntPtr jb)
+ public static IntPtr[] PgJsonbEachText(IntPtr jb, IntPtr values)
{
- IntPtr _out_values = Marshal.AllocHGlobal(IntPtr.Size);
- IntPtr _count_count = Marshal.AllocHGlobal(sizeof(int));
+ IntPtr _cnt = Marshal.AllocHGlobal(sizeof(int));
try
{
- IntPtr _resultPtr = SafeExecution(() => Native.PgJsonbEachText(jb, _out_values, _count_count));
- int _n = Marshal.ReadInt32(_count_count);
- IntPtr[] _resultArr = new IntPtr[_n];
- for (int _i = 0; _i < _n; _i++)
- { _resultArr[_i] = Marshal.ReadIntPtr(_resultPtr, _i * IntPtr.Size); }
- IntPtr __out_values_arr = Marshal.ReadIntPtr(_out_values);
- IntPtr[] __out_values_out = new IntPtr[_n];
+ IntPtr _p = SafeExecution(() => Native.PgJsonbEachText(jb, values, _cnt));
+ int _n = Marshal.ReadInt32(_cnt);
+ IntPtr[] _out = new IntPtr[_n];
for (int _i = 0; _i < _n; _i++)
- { __out_values_out[_i] = Marshal.ReadIntPtr(__out_values_arr, _i * IntPtr.Size); }
- return (_resultArr, __out_values_out);
- }
- finally
- {
- Marshal.FreeHGlobal(_out_values);
- Marshal.FreeHGlobal(_count_count);
+ { _out[_i] = Marshal.ReadIntPtr(_p, _i * IntPtr.Size); }
+ return _out;
}
+ finally { Marshal.FreeHGlobal(_cnt); }
}
public static bool PgJsonbEq(IntPtr jb1, IntPtr jb2)
diff --git a/MEOS.NET/Types/Jsonb.g.cs b/MEOS.NET/Types/Jsonb.g.cs
index d08e44c..210a745 100644
--- a/MEOS.NET/Types/Jsonb.g.cs
+++ b/MEOS.NET/Types/Jsonb.g.cs
@@ -86,20 +86,6 @@ public bool Contained(Jsonb jb2)
}
}
- public (Text?[], Jsonb?[]) Each()
- {
- var _answered = Meos.JsonbEach(this.Ptr);
-
- return (MEOSFactory.WrapTextArray(_answered.Item1), MEOSFactory.WrapJsonbArray(_answered.Item2));
- }
-
- public (Text?[], Text?[]) EachText()
- {
- var _answered = Meos.JsonbEachText(this.Ptr);
-
- return (MEOSFactory.WrapTextArray(_answered.Item1), MEOSFactory.WrapTextArray(_answered.Item2));
- }
-
public bool Exists(Text key)
=> Meos.JsonbExists(this.Ptr, key.Ptr);