Skip to content

Commit

Permalink
[Network] Make P/Invokes in NWFramer[Message] have blittable signatures.
Browse files Browse the repository at this point in the history
Contributes towards xamarin#15684.
  • Loading branch information
rolfbjarne committed May 27, 2024
1 parent 85ff5f7 commit 124c8db
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 27 deletions.
29 changes: 12 additions & 17 deletions src/Network/NWFramer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,9 @@ public class NWFramer : NativeObject {
internal NWFramer (NativeHandle handle, bool owns) : base (handle, owns) { }

[DllImport (Constants.NetworkLibrary)]
[return: MarshalAs (UnmanagedType.I1)]
static extern bool nw_framer_write_output_no_copy (OS_nw_framer framer, nuint output_length);
static extern byte nw_framer_write_output_no_copy (OS_nw_framer framer, nuint output_length);

public bool WriteOutputNoCopy (nuint outputLength) => nw_framer_write_output_no_copy (GetCheckedHandle (), outputLength);
public bool WriteOutputNoCopy (nuint outputLength) => nw_framer_write_output_no_copy (GetCheckedHandle (), outputLength) != 0;

[DllImport (Constants.NetworkLibrary)]
static extern void nw_framer_write_output_data (OS_nw_framer framer, OS_dispatch_data output_data);
Expand Down Expand Up @@ -288,14 +287,13 @@ public NWFramerMessage CreateMessage ()
=> new NWFramerMessage (nw_framer_message_create (GetCheckedHandle ()), owns: true);

[DllImport (Constants.NetworkLibrary)]
[return: MarshalAs (UnmanagedType.I1)]
static extern bool nw_framer_prepend_application_protocol (OS_nw_framer framer, OS_nw_protocol_options protocol_options);
static extern byte nw_framer_prepend_application_protocol (OS_nw_framer framer, OS_nw_protocol_options protocol_options);

public bool PrependApplicationProtocol (NWProtocolOptions options)
{
if (options is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (options));
return nw_framer_prepend_application_protocol (GetCheckedHandle (), options.Handle);
return nw_framer_prepend_application_protocol (GetCheckedHandle (), options.Handle) != 0;
}

[DllImport (Constants.NetworkLibrary)]
Expand All @@ -319,14 +317,13 @@ public bool PrependApplicationProtocol (NWProtocolOptions options)
public void MarkFailedWithError (int errorCode) => nw_framer_mark_failed_with_error (GetCheckedHandle (), errorCode);

[DllImport (Constants.NetworkLibrary)]
[return: MarshalAs (UnmanagedType.I1)]
static extern bool nw_framer_deliver_input_no_copy (OS_nw_framer framer, nuint input_length, OS_nw_protocol_metadata message, [MarshalAs (UnmanagedType.I1)] bool is_complete);
static extern byte nw_framer_deliver_input_no_copy (OS_nw_framer framer, nuint input_length, OS_nw_protocol_metadata message, byte is_complete);

public bool DeliverInputNoCopy (nuint length, NWFramerMessage message, bool isComplete)
{
if (message is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (message));
return nw_framer_deliver_input_no_copy (GetCheckedHandle (), length, message.Handle, isComplete);
return nw_framer_deliver_input_no_copy (GetCheckedHandle (), length, message.Handle, isComplete.AsByte ()) != 0;
}

[DllImport (Constants.NetworkLibrary)]
Expand Down Expand Up @@ -372,8 +369,7 @@ public void ScheduleAsync (Action handler)
}

[DllImport (Constants.NetworkLibrary)]
[return: MarshalAs (UnmanagedType.I1)]
static extern unsafe bool nw_framer_parse_output (OS_nw_framer framer, nuint minimum_incomplete_length, nuint maximum_length, byte* temp_buffer, BlockLiteral* parse);
static extern unsafe byte nw_framer_parse_output (OS_nw_framer framer, nuint minimum_incomplete_length, nuint maximum_length, byte* temp_buffer, BlockLiteral* parse);

#if !NET
delegate void nw_framer_parse_output_t (IntPtr block, IntPtr buffer, nuint buffer_length, byte is_complete);
Expand Down Expand Up @@ -408,13 +404,12 @@ public bool ParseOutput (nuint minimumIncompleteLength, nuint maximumLength, Mem
block.SetupBlockUnsafe (static_ParseOutputHandler, handler);
#endif
using (var mh = tempBuffer.Pin ())
return nw_framer_parse_output (GetCheckedHandle (), minimumIncompleteLength, maximumLength, (byte*) mh.Pointer, &block);
return nw_framer_parse_output (GetCheckedHandle (), minimumIncompleteLength, maximumLength, (byte*) mh.Pointer, &block) != 0;
}
}

[DllImport (Constants.NetworkLibrary)]
[return: MarshalAs (UnmanagedType.I1)]
static extern unsafe bool nw_framer_parse_input (OS_nw_framer framer, nuint minimum_incomplete_length, nuint maximum_length, byte* temp_buffer, BlockLiteral* parse);
static extern unsafe byte nw_framer_parse_input (OS_nw_framer framer, nuint minimum_incomplete_length, nuint maximum_length, byte* temp_buffer, BlockLiteral* parse);

#if !NET
delegate nuint nw_framer_parse_input_t (IntPtr block, IntPtr buffer, nuint buffer_length, byte is_complete);
Expand Down Expand Up @@ -450,20 +445,20 @@ public bool ParseInput (nuint minimumIncompleteLength, nuint maximumLength, Memo
block.SetupBlockUnsafe (static_ParseInputHandler, handler);
#endif
using (var mh = tempBuffer.Pin ())
return nw_framer_parse_input (GetCheckedHandle (), minimumIncompleteLength, maximumLength, (byte*) mh.Pointer, &block);
return nw_framer_parse_input (GetCheckedHandle (), minimumIncompleteLength, maximumLength, (byte*) mh.Pointer, &block) != 0;
}
}

[DllImport (Constants.NetworkLibrary)]
unsafe static extern void nw_framer_deliver_input (OS_nw_framer framer, byte* input_buffer, nuint input_length, OS_nw_protocol_metadata message, [MarshalAs (UnmanagedType.I1)] bool is_complete);
unsafe static extern void nw_framer_deliver_input (OS_nw_framer framer, byte* input_buffer, nuint input_length, OS_nw_protocol_metadata message, byte is_complete);

public void DeliverInput (ReadOnlySpan<byte> buffer, NWFramerMessage message, bool isComplete)
{
if (message is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (message));
unsafe {
fixed (byte* mh = buffer)
nw_framer_deliver_input (GetCheckedHandle (), mh, (nuint) buffer.Length, message.Handle, isComplete);
nw_framer_deliver_input (GetCheckedHandle (), mh, (nuint) buffer.Length, message.Handle, isComplete.AsByte ());
}
}

Expand Down
5 changes: 2 additions & 3 deletions src/Network/NWFramerMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,7 @@ public void SetData (string key, byte [] value)
}

[DllImport (Constants.NetworkLibrary)]
[return: MarshalAs (UnmanagedType.I1)]
unsafe static extern bool nw_framer_message_access_value (OS_nw_protocol_metadata message, IntPtr key, BlockLiteral* access_value);
unsafe static extern byte nw_framer_message_access_value (OS_nw_protocol_metadata message, IntPtr key, BlockLiteral* access_value);
#if !NET
delegate byte nw_framer_message_access_value_t (IntPtr block, IntPtr data);
static nw_framer_message_access_value_t static_AccessValueHandler = TrampolineAccessValueHandler;
Expand Down Expand Up @@ -147,7 +146,7 @@ public bool GetData (string key, int dataLength, out ReadOnlySpan<byte> outData)
#endif
// the callback is inlined!!!
using var keyPtr = new TransientString (key);
var found = nw_framer_message_access_value (GetCheckedHandle (), keyPtr, &block);
var found = nw_framer_message_access_value (GetCheckedHandle (), keyPtr, &block) != 0;
if (found) {
unsafe {
outData = new ReadOnlySpan<byte> ((void*) outPointer, dataLength);
Expand Down
7 changes: 0 additions & 7 deletions tests/cecil-tests/BlittablePInvokes.KnownFailures.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,6 @@ public partial class BlittablePInvokes {
"System.Boolean Network.NWContentContext::nw_content_context_get_is_final(System.IntPtr)",
"System.Boolean Network.NWEstablishmentReport::nw_establishment_report_get_proxy_configured(System.IntPtr)",
"System.Boolean Network.NWEstablishmentReport::nw_establishment_report_get_used_proxy(System.IntPtr)",
"System.Boolean Network.NWFramer::nw_framer_deliver_input_no_copy(System.IntPtr,System.UIntPtr,System.IntPtr,System.Boolean)",
"System.Boolean Network.NWFramer::nw_framer_parse_input(System.IntPtr,System.UIntPtr,System.UIntPtr,System.Byte*,ObjCRuntime.BlockLiteral*)",
"System.Boolean Network.NWFramer::nw_framer_parse_output(System.IntPtr,System.UIntPtr,System.UIntPtr,System.Byte*,ObjCRuntime.BlockLiteral*)",
"System.Boolean Network.NWFramer::nw_framer_prepend_application_protocol(System.IntPtr,System.IntPtr)",
"System.Boolean Network.NWFramer::nw_framer_write_output_no_copy(System.IntPtr,System.UIntPtr)",
"System.Boolean Network.NWFramerMessage::nw_framer_message_access_value(System.IntPtr,System.IntPtr,ObjCRuntime.BlockLiteral*)",
"System.Boolean Network.NWMulticastGroup::nw_group_descriptor_add_endpoint(System.IntPtr,System.IntPtr)",
"System.Boolean Network.NWMulticastGroup::nw_multicast_group_descriptor_get_disable_unicast_traffic(System.IntPtr)",
"System.Boolean Network.NWParameters::nw_parameters_get_fast_open_enabled(System.IntPtr)",
Expand Down Expand Up @@ -74,7 +68,6 @@ public partial class BlittablePInvokes {
"System.Void Network.NWConnection::nw_connection_send(System.IntPtr,System.IntPtr,System.IntPtr,System.Boolean,ObjCRuntime.BlockLiteral*)",
"System.Void Network.NWConnectionGroup::nw_connection_group_set_receive_handler(System.IntPtr,System.UInt32,System.Boolean,ObjCRuntime.BlockLiteral*)",
"System.Void Network.NWContentContext::nw_content_context_set_is_final(System.IntPtr,System.Boolean)",
"System.Void Network.NWFramer::nw_framer_deliver_input(System.IntPtr,System.Byte*,System.UIntPtr,System.IntPtr,System.Boolean)",
"System.Void Network.NWMulticastGroup::nw_multicast_group_descriptor_set_disable_unicast_traffic(System.IntPtr,System.Boolean)",
"System.Void Network.NWParameters::nw_parameters_set_fast_open_enabled(System.IntPtr,System.Boolean)",
"System.Void Network.NWParameters::nw_parameters_set_include_peer_to_peer(System.IntPtr,System.Boolean)",
Expand Down

0 comments on commit 124c8db

Please sign in to comment.