112 lines
4.9 KiB
C#
112 lines
4.9 KiB
C#
using System.Runtime.InteropServices;
|
|
|
|
namespace NucleicProtocol.Interop;
|
|
|
|
public enum ProtocolResult
|
|
{
|
|
Ok = 0,
|
|
InvalidArgument = -1,
|
|
InvalidState = -2,
|
|
DecodeError = -3,
|
|
Unsupported = -4,
|
|
}
|
|
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
public delegate void NativeProtocolCallback(nint context, nint utf8Json);
|
|
|
|
/// Injectable native surface: production delegates to the Swift DLL; tests use an in-memory
|
|
/// implementation and exercise callback lifetime without loading a platform binary.
|
|
public interface INativeProtocol
|
|
{
|
|
nint ClientCreate(string configurationJson);
|
|
void ClientSetCallbacks(
|
|
nint handle, NativeProtocolCallback? eventCallback,
|
|
NativeProtocolCallback? stateCallback, nint context);
|
|
int ClientConnectLocal(nint handle, string rendezvousJson);
|
|
int ClientConnectRemote(nint handle, string endpointJson);
|
|
int ClientPair(nint handle, string pairingCode);
|
|
int ClientSendIntent(nint handle, string clientMessageJson);
|
|
void ClientClose(nint handle);
|
|
nint ProjectionCreate();
|
|
nint ProjectionApply(nint projection, string hostMessageJson);
|
|
void ProjectionFree(nint projection);
|
|
string CopyAndFreeString(nint value);
|
|
}
|
|
|
|
internal sealed class PInvokeNativeProtocol : INativeProtocol
|
|
{
|
|
public static PInvokeNativeProtocol Instance { get; } = new();
|
|
private PInvokeNativeProtocol() { }
|
|
|
|
public nint ClientCreate(string json) => NativeMethods.np_client_create(json);
|
|
public void ClientSetCallbacks(
|
|
nint handle, NativeProtocolCallback? eventCallback,
|
|
NativeProtocolCallback? stateCallback, nint context) =>
|
|
NativeMethods.np_client_set_callbacks(handle, eventCallback, stateCallback, context);
|
|
public int ClientConnectLocal(nint handle, string json) =>
|
|
NativeMethods.np_client_connect_local(handle, json);
|
|
public int ClientConnectRemote(nint handle, string json) =>
|
|
NativeMethods.np_client_connect_remote(handle, json);
|
|
public int ClientPair(nint handle, string code) => NativeMethods.np_client_pair(handle, code);
|
|
public int ClientSendIntent(nint handle, string json) =>
|
|
NativeMethods.np_client_send_intent(handle, json);
|
|
public void ClientClose(nint handle) => NativeMethods.np_client_close(handle);
|
|
public nint ProjectionCreate() => NativeMethods.np_projection_create();
|
|
public nint ProjectionApply(nint projection, string json) =>
|
|
NativeMethods.np_projection_apply(projection, json);
|
|
public void ProjectionFree(nint projection) => NativeMethods.np_projection_free(projection);
|
|
|
|
public string CopyAndFreeString(nint value)
|
|
{
|
|
if (value == 0) throw new InvalidOperationException("native protocol returned NULL");
|
|
try { return Marshal.PtrToStringUTF8(value) ?? string.Empty; }
|
|
finally { NativeMethods.np_free(value); }
|
|
}
|
|
|
|
private static class NativeMethods
|
|
{
|
|
private const string Dll = "NucleicProtocolC";
|
|
|
|
[DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
|
|
internal static extern nint np_client_create(
|
|
[MarshalAs(UnmanagedType.LPUTF8Str)] string configurationJson);
|
|
|
|
[DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
|
|
internal static extern void np_client_set_callbacks(
|
|
nint handle, NativeProtocolCallback? eventCallback,
|
|
NativeProtocolCallback? stateCallback, nint context);
|
|
|
|
[DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
|
|
internal static extern int np_client_connect_local(
|
|
nint handle, [MarshalAs(UnmanagedType.LPUTF8Str)] string rendezvousJson);
|
|
|
|
[DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
|
|
internal static extern int np_client_connect_remote(
|
|
nint handle, [MarshalAs(UnmanagedType.LPUTF8Str)] string endpointJson);
|
|
|
|
[DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
|
|
internal static extern int np_client_pair(
|
|
nint handle, [MarshalAs(UnmanagedType.LPUTF8Str)] string pairingCode);
|
|
|
|
[DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
|
|
internal static extern int np_client_send_intent(
|
|
nint handle, [MarshalAs(UnmanagedType.LPUTF8Str)] string clientMessageJson);
|
|
|
|
[DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
|
|
internal static extern void np_client_close(nint handle);
|
|
|
|
[DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
|
|
internal static extern nint np_projection_create();
|
|
|
|
[DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
|
|
internal static extern nint np_projection_apply(
|
|
nint projection, [MarshalAs(UnmanagedType.LPUTF8Str)] string hostMessageJson);
|
|
|
|
[DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
|
|
internal static extern void np_projection_free(nint projection);
|
|
|
|
[DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
|
|
internal static extern void np_free(nint value);
|
|
}
|
|
}
|