public partial class {{ name }}
{
IntPtr _data;
ulong _len;
}
{{ _types_docs_owned }}
[NativeMarshalling(typeof(MarshallerMeta))]
public partial class {{ name }} : IDisposable
{
public int Count => (int) _len;
public unsafe {{ element_type }} this[int i]
{
{{ _fns_decorators_all | indent(prefix=" ") }}
get
{
if (i >= (int) _len) throw new IndexOutOfRangeException();
if (_data == IntPtr.Zero) { throw new NullReferenceException(); }
var size = sizeof({{ unmanaged_element_type }});
var ptr = IntPtr.Add(_data, i * size);
var unmanaged = Marshal.PtrToStructure<{{ unmanaged_element_type }}>(ptr);
return unmanaged.{{ element_to_managed }}();
}
}
{{ _fns_decorators_all | indent }}
{{ name }}() { }
{{ _fns_decorators_all | indent }}
public static unsafe {{ name }} From({{ element_type }}[] managed)
{
var rval = new {{ name }}();
var size = sizeof({{ unmanaged_element_type }});
rval._data = Marshal.AllocHGlobal(size * managed.Length);
rval._len = (ulong) managed.Length;
for (var i = 0; i < managed.Length; ++i)
{
var unmanaged = managed[i].AsUnmanaged();
var dst = IntPtr.Add(rval._data, i * size);
Marshal.StructureToPtr(unmanaged, dst, false);
}
return rval;
}
{{ _fns_decorators_all | indent }}
public void Dispose()
{
if (_data == IntPtr.Zero) return;
Marshal.FreeHGlobal(_data);
_data = IntPtr.Zero;
}
{{ _fns_decorators_all | indent }}
{{ _fns_decorators_internal | indent }}
internal Unmanaged ToUnmanaged()
{
var unmanaged = new Unmanaged();
unmanaged._data = _data;
unmanaged._len = _len;
return unmanaged;
}
{{ _fns_decorators_all | indent }}
{{ _fns_decorators_internal | indent }}
internal Unmanaged AsUnmanaged() => ToUnmanaged();
[CustomMarshaller(typeof({{ name }}), MarshalMode.Default, typeof(Marshaller))]
private struct MarshallerMeta { }
[StructLayout(LayoutKind.Sequential)]
internal struct Unmanaged
{
public IntPtr _data;
public ulong _len;
{{ _fns_decorators_all | indent(prefix=" ") }}
{{ _fns_decorators_internal | indent(prefix=" ") }}
internal {{ name }} ToManaged()
{
var _managed = new {{ name }}();
_managed._data = _data;
_managed._len = _len;
return _managed;
}
}
}
{%- include "rust/pattern/slice/common_marshaller.cs" %}
public static class {{ name }}Extensions
{
public static {{ name }} {{ method }}(this {{ element_type }}[] s) { return {{ name }}.From(s); }
}