Beispiel #1
0
        public void EnableEvents(CFRunLoop runLoop, NSString runLoopMode)
        {
            if (open || closed || (loop != null))
            {
                throw new InvalidOperationException();
            }
            CheckHandle();

            loop     = runLoop;
            loopMode = runLoopMode;

            var ctx = new CFStreamClientContext();

            ctx.Info = GCHandle.ToIntPtr(gch);

            var args = CFStreamEventType.OpenCompleted |
                       CFStreamEventType.CanAcceptBytes | CFStreamEventType.HasBytesAvailable |
                       CFStreamEventType.CanAcceptBytes | CFStreamEventType.ErrorOccurred |
                       CFStreamEventType.EndEncountered;

            var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CFStreamClientContext)));

            try {
                Marshal.StructureToPtr(ctx, ptr, false);
                if (!DoSetClient(OnCallback, (nint)(long)args, ptr))
                {
                    throw new InvalidOperationException("Stream does not support async events.");
                }
            } finally {
                Marshal.FreeHGlobal(ptr);
            }

            ScheduleWithRunLoop(runLoop, runLoopMode);
        }
Beispiel #2
0
        internal CFSocket(CFSocketNativeHandle sock)
        {
            var cbTypes = CFSocketCallBackType.DataCallBack | CFSocketCallBackType.WriteCallBack;

            gch = GCHandle.Alloc(this);
            var ctx = new CFStreamClientContext();

            ctx.Info = GCHandle.ToIntPtr(gch);

            var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CFStreamClientContext)));

            try {
                Marshal.StructureToPtr(ctx, ptr, false);
                handle = CFSocketCreateWithNative(
                    IntPtr.Zero, sock, (nuint)(ulong)cbTypes, OnCallback, ptr);
            } finally {
                Marshal.FreeHGlobal(ptr);
            }

            if (handle == IntPtr.Zero)
            {
                throw new CFSocketException(CFSocketError.Error);
            }

            var source = new CFRunLoopSource(CFSocketCreateRunLoopSource(IntPtr.Zero, handle, 0));
            var loop   = CFRunLoop.Current;

            loop.AddSource(source, CFRunLoop.ModeDefault);
        }
Beispiel #3
0
        CFSocket(int family, int type, int proto, CFRunLoop loop)
        {
            var cbTypes = CFSocketCallBackType.DataCallBack | CFSocketCallBackType.ConnectCallBack;

            gch = GCHandle.Alloc(this);
            var ctx = new CFStreamClientContext();

            ctx.Info = GCHandle.ToIntPtr(gch);

            var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CFStreamClientContext)));

            try {
                Marshal.StructureToPtr(ctx, ptr, false);
                handle = CFSocketCreate(
                    IntPtr.Zero, family, type, proto, (nuint)(ulong)cbTypes, OnCallback, ptr);
            } finally {
                Marshal.FreeHGlobal(ptr);
            }

            if (handle == IntPtr.Zero)
            {
                throw new CFSocketException(CFSocketError.Error);
            }
            gch = GCHandle.Alloc(this);

            var source = new CFRunLoopSource(CFSocketCreateRunLoopSource(IntPtr.Zero, handle, 0));

            loop.AddSource(source, CFRunLoop.ModeDefault);
        }
Beispiel #4
0
        CFSocket(int family, int type, int proto, CFRunLoop loop)
        {
            var cbTypes = CFSocketCallBackType.DataCallBack | CFSocketCallBackType.ConnectCallBack;

            gch = GCHandle.Alloc(this);
            try {
                var ctx = new CFStreamClientContext();
                ctx.Info = GCHandle.ToIntPtr(gch);

                var handle = CFSocketCreate(IntPtr.Zero, family, type, proto, (nuint)(ulong)cbTypes, OnCallback, ref ctx);
                InitializeHandle(handle);

                var source = new CFRunLoopSource(CFSocketCreateRunLoopSource(IntPtr.Zero, handle, 0), true);
                loop.AddSource(source, CFRunLoop.ModeDefault);
            } catch {
                gch.Free();
                throw;
            }
        }
Beispiel #5
0
        CFSocket(CFSocketNativeHandle sock)
        {
            var cbTypes = CFSocketCallBackType.DataCallBack | CFSocketCallBackType.WriteCallBack;

            gch = GCHandle.Alloc(this);
            try {
                var ctx = new CFStreamClientContext();
                ctx.Info = GCHandle.ToIntPtr(gch);

                var handle = CFSocketCreateWithNative(IntPtr.Zero, sock, (nuint)(ulong)cbTypes, OnCallback, ref ctx);
                InitializeHandle(handle);

                var source = new CFRunLoopSource(CFSocketCreateRunLoopSource(IntPtr.Zero, handle, 0), true);
                var loop   = CFRunLoop.Current;
                loop.AddSource(source, CFRunLoop.ModeDefault);
            } catch {
                gch.Free();
                throw;
            }
        }
        static CFProxy[] ExecutePacCFRunLoopSourceBlocking(CreatePACCFRunLoopSource factory, out NSError outError)
        {
            var runLoop = CFRunLoop.Current;

            outError = null;

            // build a struct that will have all the needed info for the callback
            var pacCbData = new PACProxyCallbackData();

            pacCbData.CFRunLoopPtr = runLoop.Handle;
            var pacDataPtr = Marshal.AllocHGlobal(Marshal.SizeOf(pacCbData));

            try {
                Marshal.StructureToPtr(pacCbData, pacDataPtr, false);

                var clientContext = new CFStreamClientContext();
                clientContext.Info = pacDataPtr;

                using (var loopSource = new CFRunLoopSource(factory(ExecutePacCallback, ref clientContext)))
                    using (var mode = new NSString("Xamarin.iOS.Proxy")) {
                        runLoop.AddSource(loopSource, mode);
                        runLoop.RunInMode(mode, double.MaxValue, false);
                        runLoop.RemoveSource(loopSource, mode);
                    }
                pacCbData = (PACProxyCallbackData)Marshal.PtrToStructure(pacDataPtr, typeof(PACProxyCallbackData));
                // get data from the struct
                outError = pacCbData.Error;
                return(pacCbData.ProxyList);
            } finally {
                if (pacCbData.ProxyListPtr != IntPtr.Zero)
                {
                    CFObject.CFRelease(pacCbData.ProxyListPtr);
                }
                if (pacCbData.ErrorPtr != IntPtr.Zero)
                {
                    NSObject.DangerousRelease(pacCbData.ErrorPtr);
                }
                Marshal.FreeHGlobal(pacDataPtr);
            }
        }
Beispiel #7
0
 extern static IntPtr CFSocketCreateWithNative(IntPtr allocator, CFSocketNativeHandle sock,
                                               nuint /*CFOptionFlags*/ callBackTypes,
                                               CFSocketCallBack callout, ref CFStreamClientContext ctx);
Beispiel #8
0
 extern static IntPtr CFSocketCreate(IntPtr allocator, int /*SInt32*/ family, int /*SInt32*/ type, int /*SInt32*/ proto,
                                     nuint /*CFOptionFlags*/ callBackTypes,
                                     CFSocketCallBack callout, ref CFStreamClientContext ctx);
 extern static /* CFRunLoopSourceRef __nonnull */ IntPtr CFNetworkExecuteProxyAutoConfigurationURL(
     /* CFURLRef __nonnull */ IntPtr proxyAutoConfigurationURL,
     /* CFURLRef __nonnull */ IntPtr targetURL,
     /* CFProxyAutoConfigurationResultCallback __nonnull */ CFProxyAutoConfigurationResultCallbackInternal cb,
     /* CFStreamClientContext * __nonnull */ ref CFStreamClientContext clientContext);
Beispiel #10
0
        static async Task <(CFProxy[] proxies, NSError error)> ExecutePacCFRunLoopSourceAsync(CreatePACCFRunLoopSource factory, CancellationToken cancellationToken)
        {
            CFProxy[] proxies  = null;
            NSError   outError = null;

            if (cancellationToken.IsCancellationRequested)
            {
                throw new OperationCanceledException("Operation was cancelled.");
            }

            await Task.Run(() => {
                // we need the runloop of THIS thread, so it is important to get it in the correct context
                var runLoop = CFRunLoop.Current;

                // build a struct that will have all the needed info for the callback
                var pacCbData          = new PACProxyCallbackData();
                pacCbData.CFRunLoopPtr = runLoop.Handle;
                var pacDataPtr         = Marshal.AllocHGlobal(Marshal.SizeOf(pacCbData));
                try {
                    Marshal.StructureToPtr(pacCbData, pacDataPtr, false);

                    var clientContext  = new CFStreamClientContext();
                    clientContext.Info = pacDataPtr;

                    using (var loopSource = new CFRunLoopSource(factory(ExecutePacCallback, ref clientContext)))
                        using (var mode = new NSString("Xamarin.iOS.Proxy")) {
                            if (cancellationToken.IsCancellationRequested)
                            {
                                throw new OperationCanceledException("Operation was cancelled.");
                            }

                            cancellationToken.Register(() => {
                                //if user cancels, we invalidte the source, stop the runloop and remove the source
                                loopSource.Invalidate();
                                runLoop.RemoveSource(loopSource, mode);
                                runLoop.Stop();
                            });
                            runLoop.AddSource(loopSource, mode);
                            // blocks until stop is called, will be done in the cb set previously
                            runLoop.RunInMode(mode, double.MaxValue, false);
                            // does not raise an error if source is not longer present, so no need to worry
                            runLoop.RemoveSource(loopSource, mode);
                        }

                    if (cancellationToken.IsCancellationRequested)
                    {
                        throw new OperationCanceledException("Operation was cancelled.");
                    }

                    pacCbData = (PACProxyCallbackData)Marshal.PtrToStructure(pacDataPtr, typeof(PACProxyCallbackData));
                    // get data from the struct
                    proxies  = pacCbData.ProxyList;
                    outError = pacCbData.Error;
                } finally {
                    // clean resources
                    if (pacCbData.ProxyListPtr != IntPtr.Zero)
                    {
                        CFObject.CFRelease(pacCbData.ProxyListPtr);
                    }
                    if (pacCbData.ErrorPtr != IntPtr.Zero)
                    {
                        NSObject.DangerousRelease(pacCbData.ErrorPtr);
                    }
                    Marshal.FreeHGlobal(pacDataPtr);
                }
            }, cancellationToken).ConfigureAwait(false);

            if (cancellationToken.IsCancellationRequested)
            {
                throw new OperationCanceledException("Operation was cancelled.");
            }
            return(proxies : proxies, error : outError);
        }
        public static CFRunLoopSource ExecuteProxyAutoConfigurationURL(NSUrl proxyAutoConfigurationURL, NSUrl targetURL, CFProxyAutoConfigurationResultCallback resultCallback, CFStreamClientContext clientContext)
        {
            if (proxyAutoConfigurationURL == null)
            {
                throw new ArgumentNullException("proxyAutoConfigurationURL");
            }

            if (targetURL == null)
            {
                throw new ArgumentNullException("targetURL");
            }

            if (resultCallback == null)
            {
                throw new ArgumentNullException("resultCallback");
            }

            if (clientContext == null)
            {
                throw new ArgumentNullException("clientContext");
            }

            IntPtr source = CFNetworkExecuteProxyAutoConfigurationURL(proxyAutoConfigurationURL.Handle, targetURL.Handle, resultCallback, clientContext);

            return((source == IntPtr.Zero) ? null : new CFRunLoopSource(source));
        }