/
NWListener.cs
229 lines (186 loc) · 7.37 KB
/
NWListener.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
//
// NWListener.cs: Bindings the Netowrk nw_listener_t API
//
// Authors:
// Miguel de Icaza (miguel@microsoft.com)
//
// Copyrigh 2018 Microsoft Inc
//
using System;
using System.Runtime.InteropServices;
using ObjCRuntime;
using Foundation;
using CoreFoundation;
namespace Network {
public enum NWListenerState {
Invalid = 0,
Waiting = 1,
Ready = 2,
Failed = 3,
Cancelled = 4,
}
[TV (12,0), Mac (10,14, onlyOn64: true), iOS (12,0)]
public class NWListener : NativeObject {
public NWListener (IntPtr handle, bool owns) : base (handle, owns)
{
}
[DllImport (Constants.NetworkLibrary)]
extern static IntPtr nw_listener_create_with_port (string port, IntPtr nwparameters);
public static NWListener Create (string port, NWParameters parameters)
{
IntPtr handle;
if (parameters == null)
throw new ArgumentNullException (nameof (parameters));
if (port == null)
throw new ArgumentNullException (nameof (port));
handle = nw_listener_create_with_port (port, parameters.Handle);
if (handle == IntPtr.Zero)
return null;
return new NWListener (handle, owns: true);
}
[DllImport (Constants.NetworkLibrary)]
extern static IntPtr nw_listener_create (IntPtr nwparameters);
public static NWListener Create (NWParameters parameters)
{
IntPtr handle;
if (parameters == null)
throw new ArgumentNullException (nameof (parameters));
handle = nw_listener_create (parameters.Handle);
if (handle == IntPtr.Zero)
return null;
return new NWListener (handle, owns: true);
}
[DllImport (Constants.NetworkLibrary)]
extern static IntPtr nw_listener_create_with_connection (IntPtr nwconnection, IntPtr nwparameters);
public static NWListener Create (NWConnection connection, NWParameters parameters)
{
if (parameters == null)
throw new ArgumentNullException (nameof (parameters));
if (connection == null)
throw new ArgumentNullException (nameof (connection));
var handle = nw_listener_create_with_connection (connection.Handle, parameters.Handle);
if (handle == IntPtr.Zero)
return null;
return new NWListener (handle, owns: true);
}
[DllImport (Constants.NetworkLibrary)]
extern static void nw_listener_set_queue (IntPtr listener, IntPtr queue);
public void SetQueue (DispatchQueue queue)
{
if (queue == null)
throw new ArgumentNullException (nameof (queue));
nw_listener_set_queue (GetCheckedHandle (), queue.handle);
}
[DllImport (Constants.NetworkLibrary)]
extern static ushort nw_listener_get_port (IntPtr listener);
public ushort Port => nw_listener_get_port (GetCheckedHandle ());
[DllImport (Constants.NetworkLibrary)]
extern static void nw_listener_start (IntPtr handle);
public void Start () => nw_listener_start (GetCheckedHandle ());
[DllImport (Constants.NetworkLibrary)]
extern static void nw_listener_cancel (IntPtr handle);
public void Cancel () => nw_listener_cancel (GetCheckedHandle ());
delegate void nw_listener_state_changed_handler_t (IntPtr block, NWListenerState state, IntPtr nwerror);
static nw_listener_state_changed_handler_t static_ListenerStateChanged = TrampolineListenerStateChanged;
[MonoPInvokeCallback (typeof (nw_listener_state_changed_handler_t))]
static void TrampolineListenerStateChanged (IntPtr block, NWListenerState state, IntPtr nwerror)
{
var del = BlockLiteral.GetTarget<Action<NWListenerState,NWError>> (block);
if (del != null){
NWError err = nwerror == IntPtr.Zero ? null : new NWError (nwerror, owns: false);
del (state, err);
err?.Dispose ();
}
}
[DllImport (Constants.NetworkLibrary)]
static extern unsafe void nw_listener_set_state_changed_handler (IntPtr handle, void *callback);
[BindingImpl (BindingImplOptions.Optimizable)]
public void SetStateChangedHandler (Action<NWListenerState,NWError> callback)
{
unsafe {
if (callback == null){
nw_listener_set_state_changed_handler (GetCheckedHandle (), null);
return;
}
BlockLiteral block_handler = new BlockLiteral ();
BlockLiteral *block_ptr_handler = &block_handler;
block_handler.SetupBlockUnsafe (static_ListenerStateChanged, callback);
try {
nw_listener_set_state_changed_handler (GetCheckedHandle (), (void*) block_ptr_handler);
} finally {
block_handler.CleanupBlock ();
}
}
}
delegate void nw_listener_new_connection_handler_t (IntPtr block, IntPtr connection);
static nw_listener_new_connection_handler_t static_NewConnection = TrampolineNewConnection;
[MonoPInvokeCallback (typeof (nw_listener_new_connection_handler_t))]
static void TrampolineNewConnection (IntPtr block, IntPtr connection)
{
var del = BlockLiteral.GetTarget<Action<NWConnection>> (block);
if (del != null){
var nwconnection = new NWConnection (connection, owns: false);
del (nwconnection);
}
}
[DllImport (Constants.NetworkLibrary)]
static extern unsafe void nw_listener_set_new_connection_handler (IntPtr handle, void *callback);
[BindingImpl (BindingImplOptions.Optimizable)]
public void SetNewConnectionHandler (Action<NWConnection> callback)
{
unsafe {
if (callback == null){
nw_listener_set_new_connection_handler (GetCheckedHandle (), null);
return;
}
BlockLiteral block_handler = new BlockLiteral ();
BlockLiteral *block_ptr_handler = &block_handler;
block_handler.SetupBlockUnsafe (static_NewConnection, callback);
try {
nw_listener_set_new_connection_handler (GetCheckedHandle (), (void*) block_ptr_handler);
} finally {
block_handler.CleanupBlock ();
}
}
}
delegate void nw_listener_advertised_endpoint_changed_handler_t (IntPtr block, IntPtr endpoint, byte added);
static nw_listener_advertised_endpoint_changed_handler_t static_AdvertisedEndpointChangedHandler = TrampolineAdvertisedEndpointChangedHandler;
public delegate void AdvertisedEndpointChanged (NWEndpoint endpoint, bool added);
[MonoPInvokeCallback (typeof (nw_listener_advertised_endpoint_changed_handler_t))]
static void TrampolineAdvertisedEndpointChangedHandler (IntPtr block, IntPtr endpoint, byte added)
{
var del = BlockLiteral.GetTarget<AdvertisedEndpointChanged> (block);
if (del != null) {
var nwendpoint = new NWEndpoint (endpoint, owns: false);
del (nwendpoint, added != 0 ? true : false);
nwendpoint.Dispose ();
}
}
[DllImport (Constants.NetworkLibrary)]
static extern unsafe void nw_listener_set_advertised_endpoint_changed_handler (IntPtr handle, void *callback);
[BindingImpl (BindingImplOptions.Optimizable)]
public void SetAdvertisedEndpointChangedHandler (AdvertisedEndpointChanged callback)
{
unsafe {
if (callback == null){
nw_listener_set_advertised_endpoint_changed_handler (GetCheckedHandle (), null);
return;
}
BlockLiteral block_handler = new BlockLiteral ();
BlockLiteral *block_ptr_handler = &block_handler;
block_handler.SetupBlockUnsafe (static_AdvertisedEndpointChangedHandler, callback);
try {
nw_listener_set_advertised_endpoint_changed_handler (GetCheckedHandle (), (void*) block_ptr_handler);
} finally {
block_handler.CleanupBlock ();
}
}
}
[DllImport (Constants.NetworkLibrary)]
extern static void nw_listener_set_advertise_descriptor (IntPtr handle, IntPtr advertiseDescriptor);
public void SetAdvertiseDescriptor (NWAdvertiseDescriptor descriptor)
{
nw_listener_set_advertise_descriptor (GetCheckedHandle (), descriptor.GetHandle ());
}
}
}