a bunch of minor changes combined:
- From instead of Into - unsafe_data_ref for other payloads - CByteSlice for returning memory spans - send Packet instead of Into<Packet> - expose packet layer to C/C#
This commit is contained in:
parent
5803b71f3a
commit
1dad113ca1
33 changed files with 462 additions and 733 deletions
|
@ -8,6 +8,8 @@ fn main() {
|
|||
.input_extern_file("../servicepoint2/src/connection.rs")
|
||||
.input_extern_file("../servicepoint2/src/pixel_grid.rs")
|
||||
.input_extern_file("../servicepoint2/src/lib.rs")
|
||||
.input_extern_file("../servicepoint2/src/c_slice.rs")
|
||||
.input_extern_file("../servicepoint2/src/packet.rs")
|
||||
.csharp_dll_name("servicepoint2")
|
||||
.csharp_namespace("ServicePoint2.BindGen")
|
||||
.csharp_use_nint_types(true)
|
||||
|
|
|
@ -50,6 +50,10 @@ namespace ServicePoint2.BindGen
|
|||
[DllImport(__DllName, EntryPoint = "sp2_bit_vec_len", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern nuint sp2_bit_vec_len(BitVec* @this);
|
||||
|
||||
/// <summary>Gets an unsafe reference to the data of the `BitVec` instance. ## Safety The caller has to make sure to never access the returned memory after the `BitVec` instance has been consumed or manually deallocated. Reading and writing concurrently to either the original instance or the returned data will result in undefined behavior.</summary>
|
||||
[DllImport(__DllName, EntryPoint = "sp2_bit_vec_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern CByteSlice sp2_bit_vec_unsafe_data_ref(BitVec* @this);
|
||||
|
||||
/// <summary>Creates a new `ByteGrid` instance. The returned instance has to be freed with `byte_grid_dealloc`.</summary>
|
||||
[DllImport(__DllName, EntryPoint = "sp2_byte_grid_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern ByteGrid* sp2_byte_grid_new(nuint width, nuint height);
|
||||
|
@ -86,9 +90,13 @@ namespace ServicePoint2.BindGen
|
|||
[DllImport(__DllName, EntryPoint = "sp2_byte_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern nuint sp2_byte_grid_height(ByteGrid* @this);
|
||||
|
||||
/// <summary>Tries to load a `Command` from the passed array with the specified length. returns: NULL in case of an error, pointer to the allocated command otherwise</summary>
|
||||
[DllImport(__DllName, EntryPoint = "sp2_command_try_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern Command* sp2_command_try_load(byte* data, nuint length);
|
||||
/// <summary>Gets an unsafe reference to the data of the `ByteGrid` instance. ## Safety The caller has to make sure to never access the returned memory after the `ByteGrid` instance has been consumed or manually deallocated. Reading and writing concurrently to either the original instance or the returned data will result in undefined behavior.</summary>
|
||||
[DllImport(__DllName, EntryPoint = "sp2_byte_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern CByteSlice sp2_byte_grid_unsafe_data_ref(ByteGrid* @this);
|
||||
|
||||
/// <summary>Tries to turn a `Packet` into a `Command`. The packet is gets deallocated in the process. Returns: pointer to command or NULL</summary>
|
||||
[DllImport(__DllName, EntryPoint = "sp2_command_try_from_packet", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern Command* sp2_command_try_from_packet(Packet* packet);
|
||||
|
||||
/// <summary>Clones a `Command` instance</summary>
|
||||
[DllImport(__DllName, EntryPoint = "sp2_command_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
|
@ -149,7 +157,7 @@ namespace ServicePoint2.BindGen
|
|||
/// <summary>Sends the command instance. The instance is consumed / destroyed and cannot be used after this call.</summary>
|
||||
[DllImport(__DllName, EntryPoint = "sp2_connection_send", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
public static extern bool sp2_connection_send(Connection* connection, Command* command_ptr);
|
||||
public static extern bool sp2_connection_send(Connection* connection, Packet* command_ptr);
|
||||
|
||||
/// <summary>Closes and deallocates a connection instance</summary>
|
||||
[DllImport(__DllName, EntryPoint = "sp2_connection_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
|
@ -192,9 +200,21 @@ namespace ServicePoint2.BindGen
|
|||
[DllImport(__DllName, EntryPoint = "sp2_pixel_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern nuint sp2_pixel_grid_height(PixelGrid* @this);
|
||||
|
||||
/// <summary>Gets a reference to the data of the `PixelGrid` instance.</summary>
|
||||
[DllImport(__DllName, EntryPoint = "sp2_pixel_grid_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern byte* sp2_pixel_grid_data_ref(PixelGrid* @this);
|
||||
/// <summary>Gets an unsafe reference to the data of the `PixelGrid` instance. ## Safety The caller has to make sure to never access the returned memory after the `PixelGrid` instance has been consumed or manually deallocated. Reading and writing concurrently to either the original instance or the returned data will result in undefined behavior.</summary>
|
||||
[DllImport(__DllName, EntryPoint = "sp2_pixel_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern CByteSlice sp2_pixel_grid_unsafe_data_ref(PixelGrid* @this);
|
||||
|
||||
/// <summary>Turns a `Command` into a `Packet`. The command gets deallocated in the process.</summary>
|
||||
[DllImport(__DllName, EntryPoint = "sp2_packet_from_command", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern Packet* sp2_packet_from_command(Command* command);
|
||||
|
||||
/// <summary>Tries to load a `Packet` from the passed array with the specified length. returns: NULL in case of an error, pointer to the allocated packet otherwise</summary>
|
||||
[DllImport(__DllName, EntryPoint = "sp2_packet_try_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern Packet* sp2_packet_try_load(byte* data, nuint length);
|
||||
|
||||
/// <summary>Deallocates a `Packet`. Note: do not call this if the instance has been consumed in another way, e.g. by sending it.</summary>
|
||||
[DllImport(__DllName, EntryPoint = "sp2_packet_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern void sp2_packet_dealloc(Packet* @this);
|
||||
|
||||
|
||||
}
|
||||
|
@ -219,6 +239,18 @@ namespace ServicePoint2.BindGen
|
|||
{
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe partial struct CByteSlice
|
||||
{
|
||||
public byte* start;
|
||||
public nuint length;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe partial struct Packet
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public enum Command
|
||||
{
|
||||
|
|
|
@ -68,11 +68,23 @@ public sealed class BitVec : Sp2NativeInstance<BindGen.BitVec>
|
|||
}
|
||||
}
|
||||
|
||||
public Span<byte> Data
|
||||
{
|
||||
get
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
var slice = NativeMethods.sp2_bit_vec_unsafe_data_ref(Instance);
|
||||
return new Span<byte>(slice.start, (int)slice.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe BitVec(BindGen.BitVec* instance) : base(instance)
|
||||
{
|
||||
}
|
||||
|
||||
protected override unsafe void Dealloc()
|
||||
private protected override unsafe void Dealloc()
|
||||
{
|
||||
NativeMethods.sp2_bit_vec_dealloc(Instance);
|
||||
}
|
||||
|
|
|
@ -111,11 +111,23 @@ public sealed class ByteGrid : Sp2NativeInstance<BindGen.ByteGrid>
|
|||
}
|
||||
}
|
||||
|
||||
public Span<byte> Data
|
||||
{
|
||||
get
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
var slice = NativeMethods.sp2_byte_grid_unsafe_data_ref(Instance);
|
||||
return new Span<byte>(slice.start, (int)slice.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe ByteGrid(BindGen.ByteGrid* instance) : base(instance)
|
||||
{
|
||||
}
|
||||
|
||||
protected override unsafe void Dealloc()
|
||||
private protected override unsafe void Dealloc()
|
||||
{
|
||||
NativeMethods.sp2_byte_grid_dealloc(Instance);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,22 @@ namespace ServicePoint2;
|
|||
|
||||
public sealed class Command : Sp2NativeInstance<BindGen.Command>
|
||||
{
|
||||
public static bool TryFromPacket(Packet packet, [MaybeNullWhen(false)] out Command command)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
var result = NativeMethods.sp2_command_try_from_packet(packet.Into());
|
||||
if (result == null)
|
||||
{
|
||||
command = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
command = new Command(result);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public Command Clone()
|
||||
{
|
||||
unsafe
|
||||
|
@ -13,21 +29,6 @@ public sealed class Command : Sp2NativeInstance<BindGen.Command>
|
|||
}
|
||||
}
|
||||
|
||||
public static bool TryLoad(Span<byte> bytes, [MaybeNullWhen(false)] out Command command)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* bytesPtr = bytes)
|
||||
{
|
||||
var instance = NativeMethods.sp2_command_try_load(bytesPtr, (nuint)bytes.Length);
|
||||
command = instance == null
|
||||
? null
|
||||
: new Command(instance);
|
||||
return command != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Command Clear()
|
||||
{
|
||||
unsafe
|
||||
|
@ -124,7 +125,7 @@ public sealed class Command : Sp2NativeInstance<BindGen.Command>
|
|||
{
|
||||
}
|
||||
|
||||
protected override unsafe void Dealloc()
|
||||
private protected override unsafe void Dealloc()
|
||||
{
|
||||
NativeMethods.sp2_command_dealloc(Instance);
|
||||
}
|
||||
|
|
|
@ -16,15 +16,15 @@ public sealed class Connection : Sp2NativeInstance<BindGen.Connection>
|
|||
}
|
||||
}
|
||||
|
||||
public bool Send(Command command)
|
||||
public bool Send(Packet packet)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
return NativeMethods.sp2_connection_send(Instance, command.Into());
|
||||
return NativeMethods.sp2_connection_send(Instance, packet.Into());
|
||||
}
|
||||
}
|
||||
|
||||
protected override unsafe void Dealloc()
|
||||
private protected override unsafe void Dealloc()
|
||||
{
|
||||
NativeMethods.sp2_connection_dealloc(Instance);
|
||||
}
|
||||
|
|
39
servicepoint2-binding-cs/src/Packet.cs
Normal file
39
servicepoint2-binding-cs/src/Packet.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using ServicePoint2.BindGen;
|
||||
|
||||
namespace ServicePoint2;
|
||||
|
||||
public sealed class Packet : Sp2NativeInstance<BindGen.Packet>
|
||||
{
|
||||
public static Packet FromCommand(Command command)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
return new Packet(NativeMethods.sp2_packet_from_command(command.Into()));
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TryFromBytes(Span<byte> bytes, [MaybeNullWhen(false)] out Packet packet)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* bytesPtr = bytes)
|
||||
{
|
||||
var instance = NativeMethods.sp2_packet_try_load(bytesPtr, (nuint)bytes.Length);
|
||||
packet = instance == null
|
||||
? null
|
||||
: new Packet(instance);
|
||||
return packet != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe Packet(BindGen.Packet* instance) : base(instance)
|
||||
{
|
||||
}
|
||||
|
||||
private protected override unsafe void Dealloc()
|
||||
{
|
||||
NativeMethods.sp2_packet_dealloc(Instance);
|
||||
}
|
||||
}
|
|
@ -86,8 +86,8 @@ public sealed class PixelGrid : Sp2NativeInstance<BindGen.PixelGrid>
|
|||
{
|
||||
unsafe
|
||||
{
|
||||
var ptr = NativeMethods.sp2_pixel_grid_data_ref(Instance);
|
||||
return new Span<byte>(ptr, Width * Height / 8);
|
||||
var slice = NativeMethods.sp2_pixel_grid_unsafe_data_ref(Instance);
|
||||
return new Span<byte>(slice.start, (int)slice.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ public sealed class PixelGrid : Sp2NativeInstance<BindGen.PixelGrid>
|
|||
{
|
||||
}
|
||||
|
||||
protected override unsafe void Dealloc()
|
||||
private protected override unsafe void Dealloc()
|
||||
{
|
||||
NativeMethods.sp2_pixel_grid_dealloc(Instance);
|
||||
}
|
||||
|
|
16
servicepoint2-binding-cs/src/ServicePoint2Extensions.cs
Normal file
16
servicepoint2-binding-cs/src/ServicePoint2Extensions.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace ServicePoint2;
|
||||
|
||||
public static class ServicePoint2Extensions
|
||||
{
|
||||
public static Packet IntoPacket(this Command command)
|
||||
{
|
||||
return Packet.FromCommand(command);
|
||||
}
|
||||
|
||||
public static bool TryIntoCommand(this Packet packet, [MaybeNullWhen(false)] out Command command)
|
||||
{
|
||||
return Command.TryFromPacket(packet, out command);
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@ public abstract class Sp2NativeInstance<T>
|
|||
_instance = instance;
|
||||
}
|
||||
|
||||
protected abstract void Dealloc();
|
||||
private protected abstract void Dealloc();
|
||||
|
||||
internal unsafe T* Into()
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue