[CF[Read|Write|HTTP]Stream] Subclass NativeObject + numerous other code updates (#13127)
* Subclass NativeObject to reuse object lifetime code. * Enable nullability and fix code accordingly. * Use 'is' and 'is not' instead of '==' and '!=' for object identity. * Use the null-safe NativeObjectExtensions.GetHandle extension method to get the handle instead of checking for null (avoids some code duplication). * Use 'nameof (parameter)' instead of string constants. * Call 'GetCheckedHandle ()' (which will throw an ObjectDisposedException if Handle == IntPtr.Zero) instead of manually checking for IntPtr.Zero and throwing ObjectDisposedException. * Use Array.Empty<T> instead of creating an empty array manually. * Remove the (IntPtr) constructor for XAMCORE_4_0. * Add an internal (IntPtr, bool) constructor.
This commit is contained in:
Родитель
cf8008cbc0
Коммит
a28fc44056
|
@ -7,6 +7,8 @@
|
|||
// Copyright 2012-2015 Xamarin Inc. (http://www.xamarin.com)
|
||||
//
|
||||
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using Foundation;
|
||||
using CoreFoundation;
|
||||
|
@ -28,12 +30,12 @@ namespace CoreServices {
|
|||
#endif
|
||||
public partial class CFHTTPStream : CFReadStream {
|
||||
|
||||
internal CFHTTPStream (IntPtr handle)
|
||||
: base (handle)
|
||||
internal CFHTTPStream (IntPtr handle, bool owns)
|
||||
: base (handle, owns)
|
||||
{
|
||||
}
|
||||
|
||||
public Uri FinalURL {
|
||||
public Uri? FinalURL {
|
||||
get {
|
||||
var handle = GetProperty (_FinalURL);
|
||||
if (handle == IntPtr.Zero)
|
||||
|
@ -44,12 +46,12 @@ namespace CoreServices {
|
|||
throw new InvalidCastException ();
|
||||
}
|
||||
|
||||
using (var url = new CFUrl (handle))
|
||||
using (var url = new CFUrl (handle, false))
|
||||
return new Uri (url.ToString ());
|
||||
}
|
||||
}
|
||||
|
||||
public CFHTTPMessage GetFinalRequest ()
|
||||
public CFHTTPMessage? GetFinalRequest ()
|
||||
{
|
||||
var handle = GetProperty (_FinalRequest);
|
||||
if (handle == IntPtr.Zero)
|
||||
|
@ -63,7 +65,7 @@ namespace CoreServices {
|
|||
return new CFHTTPMessage (handle, true);
|
||||
}
|
||||
|
||||
public CFHTTPMessage GetResponseHeader ()
|
||||
public CFHTTPMessage? GetResponseHeader ()
|
||||
{
|
||||
var handle = GetProperty (_ResponseHeader);
|
||||
if (handle == IntPtr.Zero)
|
||||
|
@ -132,8 +134,8 @@ namespace CoreServices {
|
|||
#if !WATCHOS
|
||||
public void SetProxy (CFProxySettings proxySettings)
|
||||
{
|
||||
if (proxySettings == null)
|
||||
throw new ArgumentNullException ("proxySettings");
|
||||
if (proxySettings is null)
|
||||
throw new ArgumentNullException (nameof (proxySettings));
|
||||
|
||||
SetProperty (_Proxy, proxySettings.Dictionary);
|
||||
}
|
||||
|
|
|
@ -27,11 +27,9 @@
|
|||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Runtime.InteropServices;
|
||||
using CoreFoundation;
|
||||
using Foundation;
|
||||
|
@ -43,15 +41,22 @@ namespace CoreFoundation {
|
|||
|
||||
// CFStream.h
|
||||
public class CFReadStream : CFStream {
|
||||
#if !XAMCORE_4_0
|
||||
public CFReadStream (IntPtr handle)
|
||||
: base (handle)
|
||||
: base (handle, true)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
internal CFReadStream (IntPtr handle, bool owns)
|
||||
: base (handle, owns)
|
||||
{
|
||||
}
|
||||
|
||||
[DllImport (Constants.CoreFoundationLibrary)]
|
||||
extern static /* CFErrorRef */ IntPtr CFReadStreamCopyError (/* CFReadStreamRef */ IntPtr stream);
|
||||
|
||||
public override CFException GetError ()
|
||||
public override CFException? GetError ()
|
||||
{
|
||||
var error = CFReadStreamCopyError (Handle);
|
||||
if (error == IntPtr.Zero)
|
||||
|
@ -96,36 +101,36 @@ namespace CoreFoundation {
|
|||
[DllImport (Constants.CoreFoundationLibrary)]
|
||||
extern static void CFReadStreamScheduleWithRunLoop (/* CFReadStreamRef */ IntPtr stream, /* CFRunLoopRef */ IntPtr runLoop, /* CFStringRef */ IntPtr runLoopMode);
|
||||
|
||||
protected override void ScheduleWithRunLoop (CFRunLoop loop, NSString mode)
|
||||
protected override void ScheduleWithRunLoop (CFRunLoop loop, NSString? mode)
|
||||
{
|
||||
if (loop == null)
|
||||
throw new ArgumentNullException ("loop");
|
||||
if (mode == null)
|
||||
throw new ArgumentNullException ("mode");
|
||||
if (loop is null)
|
||||
throw new ArgumentNullException (nameof (loop));
|
||||
if (mode is null)
|
||||
throw new ArgumentNullException (nameof (mode));
|
||||
CFReadStreamScheduleWithRunLoop (Handle, loop.Handle, mode.Handle);
|
||||
}
|
||||
|
||||
[DllImport (Constants.CoreFoundationLibrary)]
|
||||
extern static void CFReadStreamUnscheduleFromRunLoop (/* CFReadStreamRef */ IntPtr stream, /* CFRunLoopRef */ IntPtr runLoop, /* CFStringRef */ IntPtr runLoopMode);
|
||||
|
||||
protected override void UnscheduleFromRunLoop (CFRunLoop loop, NSString mode)
|
||||
protected override void UnscheduleFromRunLoop (CFRunLoop loop, NSString? mode)
|
||||
{
|
||||
if (loop == null)
|
||||
throw new ArgumentNullException ("loop");
|
||||
if (mode == null)
|
||||
throw new ArgumentNullException ("mode");
|
||||
if (loop is null)
|
||||
throw new ArgumentNullException (nameof (loop));
|
||||
if (mode is null)
|
||||
throw new ArgumentNullException (nameof (mode));
|
||||
CFReadStreamUnscheduleFromRunLoop (Handle, loop.Handle, mode.Handle);
|
||||
}
|
||||
|
||||
[DllImport (Constants.CoreFoundationLibrary)]
|
||||
[return: MarshalAs (UnmanagedType.I1)]
|
||||
static extern bool CFReadStreamSetClient (/* CFReadStreamRef */ IntPtr stream, /* CFOptionFlags */ nint streamEvents,
|
||||
/* CFReadStreamClientCallBack */ CFStreamCallback clientCB, /* CFStreamClientContext* */ IntPtr clientContext);
|
||||
/* CFReadStreamClientCallBack */ CFStreamCallback? clientCB, /* CFStreamClientContext* */ IntPtr clientContext);
|
||||
|
||||
protected override bool DoSetClient (CFStreamCallback callback, CFIndex eventTypes,
|
||||
protected override bool DoSetClient (CFStreamCallback? callback, CFIndex eventTypes,
|
||||
IntPtr context)
|
||||
{
|
||||
return CFReadStreamSetClient (Handle, eventTypes, callback, context);
|
||||
return CFReadStreamSetClient (Handle, (nint) eventTypes, callback, context);
|
||||
}
|
||||
|
||||
[DllImport (Constants.CoreFoundationLibrary)]
|
||||
|
@ -133,16 +138,16 @@ namespace CoreFoundation {
|
|||
|
||||
public nint Read (byte[] buffer)
|
||||
{
|
||||
if (buffer == null)
|
||||
throw new ArgumentNullException ("buffer");
|
||||
if (buffer is null)
|
||||
throw new ArgumentNullException (nameof (buffer));
|
||||
return Read (buffer, 0, buffer.Length);
|
||||
}
|
||||
|
||||
public unsafe nint Read (byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (buffer == null)
|
||||
throw new ArgumentNullException ("buffer");
|
||||
CheckHandle ();
|
||||
if (buffer is null)
|
||||
throw new ArgumentNullException (nameof (buffer));
|
||||
GetCheckedHandle ();
|
||||
if (offset < 0)
|
||||
throw new ArgumentException ();
|
||||
if (count < 1)
|
||||
|
@ -158,8 +163,8 @@ namespace CoreFoundation {
|
|||
|
||||
protected override IntPtr DoGetProperty (NSString name)
|
||||
{
|
||||
if (name == null)
|
||||
throw new ArgumentNullException ("name");
|
||||
if (name is null)
|
||||
throw new ArgumentNullException (nameof (name));
|
||||
return CFReadStreamCopyProperty (Handle, name.Handle);
|
||||
}
|
||||
|
||||
|
@ -167,11 +172,11 @@ namespace CoreFoundation {
|
|||
[return: MarshalAs (UnmanagedType.I1)]
|
||||
extern static /* Boolean */ bool CFReadStreamSetProperty (/* CFReadStreamRef */ IntPtr stream, /* CFStreamRef */ IntPtr propertyName, /* CFTypeRef */ IntPtr propertyValue);
|
||||
|
||||
protected override bool DoSetProperty (NSString name, INativeObject value)
|
||||
protected override bool DoSetProperty (NSString name, INativeObject? value)
|
||||
{
|
||||
if (name == null)
|
||||
throw new ArgumentNullException ("name");
|
||||
return CFReadStreamSetProperty (Handle, name.Handle, value == null ? IntPtr.Zero : value.Handle);
|
||||
if (name is null)
|
||||
throw new ArgumentNullException (nameof (name));
|
||||
return CFReadStreamSetProperty (Handle, name.Handle, value.GetHandle ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
@ -84,14 +86,13 @@ namespace CoreFoundation {
|
|||
CFReadStreamRef_InvokeRelease (release, Info);
|
||||
}
|
||||
|
||||
public override string ToString ()
|
||||
public override string? ToString ()
|
||||
{
|
||||
if (copyDescription != IntPtr.Zero) {
|
||||
var ptr = CFReadStreamRef_InvokeCopyDescription (copyDescription, Info);
|
||||
if (ptr != IntPtr.Zero) {
|
||||
// Copy* -> so we must not retain again
|
||||
using (var s = new CFString (ptr, true))
|
||||
return s.ToString ();
|
||||
return CFString.FromHandle (ptr, true);
|
||||
}
|
||||
}
|
||||
return base.ToString ();
|
||||
|
@ -151,11 +152,10 @@ namespace CoreFoundation {
|
|||
Error
|
||||
}
|
||||
|
||||
public abstract class CFStream : CFType, INativeObject, IDisposable {
|
||||
IntPtr handle;
|
||||
public abstract class CFStream : CFType {
|
||||
GCHandle gch;
|
||||
CFRunLoop loop;
|
||||
NSString loopMode;
|
||||
CFRunLoop? loop;
|
||||
NSString? loopMode;
|
||||
bool open, closed;
|
||||
|
||||
#region Stream Constructors
|
||||
|
@ -209,13 +209,13 @@ namespace CoreFoundation {
|
|||
public static void CreatePairWithSocket (CFSocket socket, out CFReadStream readStream,
|
||||
out CFWriteStream writeStream)
|
||||
{
|
||||
if (socket == null)
|
||||
throw new ArgumentNullException ("socket");
|
||||
if (socket is null)
|
||||
throw new ArgumentNullException (nameof (socket));
|
||||
|
||||
IntPtr read, write;
|
||||
CFStreamCreatePairWithSocket (IntPtr.Zero, socket.GetNative (), out read, out write);
|
||||
readStream = new CFReadStream (read);
|
||||
writeStream = new CFWriteStream (write);
|
||||
readStream = new CFReadStream (read, true);
|
||||
writeStream = new CFWriteStream (write, true);
|
||||
}
|
||||
|
||||
#if !NET
|
||||
|
@ -274,8 +274,8 @@ namespace CoreFoundation {
|
|||
var sig = new CFSocketSignature (family, type, proto, address);
|
||||
IntPtr read, write;
|
||||
CFStreamCreatePairWithPeerSocketSignature (IntPtr.Zero, ref sig, out read, out write);
|
||||
readStream = new CFReadStream (read);
|
||||
writeStream = new CFWriteStream (write);
|
||||
readStream = new CFReadStream (read, true);
|
||||
writeStream = new CFWriteStream (write, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -331,15 +331,15 @@ namespace CoreFoundation {
|
|||
#endif
|
||||
#endif
|
||||
public static void CreatePairWithSocketToHost (IPEndPoint endpoint,
|
||||
out CFReadStream readStream,
|
||||
out CFWriteStream writeStream)
|
||||
out CFReadStream? readStream,
|
||||
out CFWriteStream? writeStream)
|
||||
{
|
||||
using (var host = CFHost.Create (endpoint)) {
|
||||
IntPtr read, write;
|
||||
CFStreamCreatePairWithSocketToCFHost (IntPtr.Zero, host.Handle, endpoint.Port, out read, out write);
|
||||
// API can return null streams
|
||||
readStream = read == IntPtr.Zero ? null : new CFReadStream (read);
|
||||
writeStream = write == IntPtr.Zero ? null : new CFWriteStream (write);
|
||||
readStream = read == IntPtr.Zero ? null : new CFReadStream (read, true);
|
||||
writeStream = write == IntPtr.Zero ? null : new CFWriteStream (write, true);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -392,16 +392,16 @@ namespace CoreFoundation {
|
|||
#endif
|
||||
#endif
|
||||
public static void CreatePairWithSocketToHost (string host, int port,
|
||||
out CFReadStream readStream,
|
||||
out CFWriteStream writeStream)
|
||||
out CFReadStream? readStream,
|
||||
out CFWriteStream? writeStream)
|
||||
{
|
||||
using (var str = new CFString (host)) {
|
||||
IntPtr read, write;
|
||||
CFStreamCreatePairWithSocketToHost (
|
||||
IntPtr.Zero, str.Handle, port, out read, out write);
|
||||
// API not annotated (yet?) but it's safe to bet it match CFStreamCreatePairWithSocketToCFHost
|
||||
readStream = read == IntPtr.Zero ? null : new CFReadStream (read);
|
||||
writeStream = write == IntPtr.Zero ? null : new CFWriteStream (write);
|
||||
readStream = read == IntPtr.Zero ? null : new CFReadStream (read, true);
|
||||
writeStream = write == IntPtr.Zero ? null : new CFWriteStream (write, true);
|
||||
}
|
||||
}
|
||||
#if !WATCH
|
||||
|
@ -431,11 +431,11 @@ namespace CoreFoundation {
|
|||
#endif
|
||||
public static CFHTTPStream CreateForHTTPRequest (CFHTTPMessage request)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException ("request");
|
||||
if (request is null)
|
||||
throw new ArgumentNullException (nameof (request));
|
||||
|
||||
var handle = CFReadStreamCreateForHTTPRequest (IntPtr.Zero, request.Handle);
|
||||
return new CFHTTPStream (handle);
|
||||
return new CFHTTPStream (handle, true);
|
||||
}
|
||||
|
||||
// CFHTTPStream.h in CFNetwork.framework (not CoreFoundation)
|
||||
|
@ -465,24 +465,24 @@ namespace CoreFoundation {
|
|||
#endif
|
||||
public static CFHTTPStream CreateForStreamedHTTPRequest (CFHTTPMessage request, CFReadStream body)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException ("request");
|
||||
if (body == null)
|
||||
throw new ArgumentNullException ("body");
|
||||
if (request is null)
|
||||
throw new ArgumentNullException (nameof (request));
|
||||
if (body is null)
|
||||
throw new ArgumentNullException (nameof (body));
|
||||
|
||||
var handle = CFReadStreamCreateForStreamedHTTPRequest (IntPtr.Zero, request.Handle, body.Handle);
|
||||
return new CFHTTPStream (handle);
|
||||
return new CFHTTPStream (handle, true);
|
||||
}
|
||||
|
||||
public static CFHTTPStream CreateForStreamedHTTPRequest (CFHTTPMessage request, NSInputStream body)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException ("request");
|
||||
if (body == null)
|
||||
throw new ArgumentNullException ("body");
|
||||
if (request is null)
|
||||
throw new ArgumentNullException (nameof (request));
|
||||
if (body is null)
|
||||
throw new ArgumentNullException (nameof (body));
|
||||
|
||||
var handle = CFReadStreamCreateForStreamedHTTPRequest (IntPtr.Zero, request.Handle, body.Handle);
|
||||
return new CFHTTPStream (handle);
|
||||
return new CFHTTPStream (handle, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -495,15 +495,15 @@ namespace CoreFoundation {
|
|||
{
|
||||
IntPtr read, write;
|
||||
CFStreamCreateBoundPair (IntPtr.Zero, out read, out write, bufferSize);
|
||||
readStream = new CFReadStream (read);
|
||||
writeStream = new CFWriteStream (write);
|
||||
readStream = new CFReadStream (read, true);
|
||||
writeStream = new CFWriteStream (write, true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Stream API
|
||||
|
||||
public abstract CFException GetError ();
|
||||
public abstract CFException? GetError ();
|
||||
|
||||
protected void CheckError ()
|
||||
{
|
||||
|
@ -516,7 +516,7 @@ namespace CoreFoundation {
|
|||
{
|
||||
if (open || closed)
|
||||
throw new InvalidOperationException ();
|
||||
CheckHandle ();
|
||||
GetCheckedHandle ();
|
||||
if (!DoOpen ()) {
|
||||
CheckError ();
|
||||
throw new InvalidOperationException ();
|
||||
|
@ -530,8 +530,8 @@ namespace CoreFoundation {
|
|||
{
|
||||
if (!open)
|
||||
return;
|
||||
CheckHandle ();
|
||||
if (loop != null) {
|
||||
GetCheckedHandle ();
|
||||
if (loop is not null) {
|
||||
DoSetClient (null, (CFIndex) 0, IntPtr.Zero);
|
||||
UnscheduleFromRunLoop (loop, loopMode);
|
||||
loop = null;
|
||||
|
@ -549,7 +549,7 @@ namespace CoreFoundation {
|
|||
|
||||
public CFStreamStatus GetStatus ()
|
||||
{
|
||||
CheckHandle ();
|
||||
GetCheckedHandle ();
|
||||
return DoGetStatus ();
|
||||
}
|
||||
|
||||
|
@ -557,17 +557,17 @@ namespace CoreFoundation {
|
|||
|
||||
internal IntPtr GetProperty (NSString name)
|
||||
{
|
||||
CheckHandle ();
|
||||
GetCheckedHandle ();
|
||||
return DoGetProperty (name);
|
||||
}
|
||||
|
||||
protected abstract IntPtr DoGetProperty (NSString name);
|
||||
|
||||
protected abstract bool DoSetProperty (NSString name, INativeObject value);
|
||||
protected abstract bool DoSetProperty (NSString name, INativeObject? value);
|
||||
|
||||
internal void SetProperty (NSString name, INativeObject value)
|
||||
internal void SetProperty (NSString name, INativeObject? value)
|
||||
{
|
||||
CheckHandle ();
|
||||
GetCheckedHandle ();
|
||||
if (DoSetProperty (name, value))
|
||||
return;
|
||||
throw new InvalidOperationException (string.Format (
|
||||
|
@ -596,11 +596,11 @@ namespace CoreFoundation {
|
|||
}
|
||||
}
|
||||
|
||||
public event EventHandler<StreamEventArgs> OpenCompletedEvent;
|
||||
public event EventHandler<StreamEventArgs> HasBytesAvailableEvent;
|
||||
public event EventHandler<StreamEventArgs> CanAcceptBytesEvent;
|
||||
public event EventHandler<StreamEventArgs> ErrorEvent;
|
||||
public event EventHandler<StreamEventArgs> ClosedEvent;
|
||||
public event EventHandler<StreamEventArgs>? OpenCompletedEvent;
|
||||
public event EventHandler<StreamEventArgs>? HasBytesAvailableEvent;
|
||||
public event EventHandler<StreamEventArgs>? CanAcceptBytesEvent;
|
||||
public event EventHandler<StreamEventArgs>? ErrorEvent;
|
||||
public event EventHandler<StreamEventArgs>? ClosedEvent;
|
||||
|
||||
protected virtual void OnOpenCompleted (StreamEventArgs args)
|
||||
{
|
||||
|
@ -639,9 +639,9 @@ namespace CoreFoundation {
|
|||
|
||||
#endregion
|
||||
|
||||
protected abstract void ScheduleWithRunLoop (CFRunLoop loop, NSString mode);
|
||||
protected abstract void ScheduleWithRunLoop (CFRunLoop loop, NSString? mode);
|
||||
|
||||
protected abstract void UnscheduleFromRunLoop (CFRunLoop loop, NSString mode);
|
||||
protected abstract void UnscheduleFromRunLoop (CFRunLoop loop, NSString? mode);
|
||||
|
||||
protected delegate void CFStreamCallback (IntPtr s, nint type, IntPtr info);
|
||||
|
||||
|
@ -649,7 +649,7 @@ namespace CoreFoundation {
|
|||
static void OnCallback (IntPtr s, nint type, IntPtr info)
|
||||
{
|
||||
var stream = GCHandle.FromIntPtr (info).Target as CFStream;
|
||||
stream.OnCallback ((CFStreamEventType) (long) type);
|
||||
stream?.OnCallback ((CFStreamEventType) (long) type);
|
||||
}
|
||||
|
||||
static CFStreamCallback OnCallbackDelegate = OnCallback;
|
||||
|
@ -678,9 +678,9 @@ namespace CoreFoundation {
|
|||
|
||||
public void EnableEvents (CFRunLoop runLoop, NSString runLoopMode)
|
||||
{
|
||||
if (open || closed || (loop != null))
|
||||
if (open || closed || (loop is not null))
|
||||
throw new InvalidOperationException ();
|
||||
CheckHandle ();
|
||||
GetCheckedHandle ();
|
||||
|
||||
loop = runLoop;
|
||||
loopMode = runLoopMode;
|
||||
|
@ -699,7 +699,7 @@ namespace CoreFoundation {
|
|||
var ptr = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (CFStreamClientContext)));
|
||||
try {
|
||||
Marshal.StructureToPtr (ctx, ptr, false);
|
||||
if (!DoSetClient (OnCallbackDelegate, (nint) (long) args, ptr))
|
||||
if (!DoSetClient (OnCallbackDelegate, (CFIndex) (long) args, ptr))
|
||||
throw new InvalidOperationException ("Stream does not support async events.");
|
||||
} finally {
|
||||
Marshal.FreeHGlobal (ptr);
|
||||
|
@ -708,46 +708,30 @@ namespace CoreFoundation {
|
|||
ScheduleWithRunLoop (runLoop, runLoopMode);
|
||||
}
|
||||
|
||||
protected abstract bool DoSetClient (CFStreamCallback callback, CFIndex eventTypes,
|
||||
protected abstract bool DoSetClient (CFStreamCallback? callback, CFIndex eventTypes,
|
||||
IntPtr context);
|
||||
|
||||
protected CFStream (IntPtr handle)
|
||||
{
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
#if !XAMCORE_4_0
|
||||
[Obsolete ("Call 'GetCheckedHandle ()' instead.")]
|
||||
protected void CheckHandle ()
|
||||
{
|
||||
if (handle == IntPtr.Zero)
|
||||
throw new ObjectDisposedException (GetType ().Name);
|
||||
GetCheckedHandle ();
|
||||
}
|
||||
#endif
|
||||
|
||||
protected CFStream (IntPtr handle, bool owns)
|
||||
: base (handle, owns)
|
||||
{
|
||||
}
|
||||
|
||||
~CFStream ()
|
||||
{
|
||||
Dispose (false);
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
Dispose (true);
|
||||
GC.SuppressFinalize (this);
|
||||
}
|
||||
|
||||
public IntPtr Handle {
|
||||
get { return handle; }
|
||||
}
|
||||
|
||||
protected virtual void Dispose (bool disposing)
|
||||
protected override void Dispose (bool disposing)
|
||||
{
|
||||
if (disposing) {
|
||||
Close ();
|
||||
if (gch.IsAllocated)
|
||||
gch.Free ();
|
||||
}
|
||||
if (handle != IntPtr.Zero) {
|
||||
CFObject.CFRelease (handle);
|
||||
handle = IntPtr.Zero;
|
||||
}
|
||||
base.Dispose (disposing);
|
||||
}
|
||||
|
||||
#if !NET
|
||||
|
@ -779,10 +763,10 @@ namespace CoreFoundation {
|
|||
#endif
|
||||
public DispatchQueue ReadDispatchQueue {
|
||||
get {
|
||||
return new DispatchQueue (CFReadStreamCopyDispatchQueue (handle));
|
||||
return new DispatchQueue (CFReadStreamCopyDispatchQueue (Handle));
|
||||
}
|
||||
set {
|
||||
CFReadStreamSetDispatchQueue (handle, value == null ? IntPtr.Zero : value.Handle);
|
||||
CFReadStreamSetDispatchQueue (Handle, value.GetHandle ());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -791,10 +775,10 @@ namespace CoreFoundation {
|
|||
#endif
|
||||
public DispatchQueue WriteDispatchQueue {
|
||||
get {
|
||||
return new DispatchQueue (CFWriteStreamCopyDispatchQueue (handle));
|
||||
return new DispatchQueue (CFWriteStreamCopyDispatchQueue (Handle));
|
||||
}
|
||||
set {
|
||||
CFWriteStreamSetDispatchQueue (handle, value == null ? IntPtr.Zero : value.Handle);
|
||||
CFWriteStreamSetDispatchQueue (Handle, value.GetHandle ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using CoreFoundation;
|
||||
|
@ -38,15 +40,15 @@ using CFIndex = System.nint;
|
|||
namespace CoreFoundation {
|
||||
|
||||
public class CFWriteStream : CFStream {
|
||||
internal CFWriteStream (IntPtr handle)
|
||||
: base (handle)
|
||||
internal CFWriteStream (IntPtr handle, bool owns)
|
||||
: base (handle, owns)
|
||||
{
|
||||
}
|
||||
|
||||
[DllImport (Constants.CoreFoundationLibrary)]
|
||||
extern static /* CFErrorRef */ IntPtr CFWriteStreamCopyError (/* CFWriteStreamRef */ IntPtr stream);
|
||||
|
||||
public override CFException GetError ()
|
||||
public override CFException? GetError ()
|
||||
{
|
||||
var error = CFWriteStreamCopyError (Handle);
|
||||
if (error == IntPtr.Zero)
|
||||
|
@ -93,16 +95,16 @@ namespace CoreFoundation {
|
|||
|
||||
public int Write (byte[] buffer)
|
||||
{
|
||||
if (buffer == null)
|
||||
throw new ArgumentNullException ("buffer");
|
||||
if (buffer is null)
|
||||
throw new ArgumentNullException (nameof (buffer));
|
||||
return Write (buffer, 0, buffer.Length);
|
||||
}
|
||||
|
||||
public unsafe int Write (byte[] buffer, nint offset, nint count)
|
||||
{
|
||||
if (buffer == null)
|
||||
throw new ArgumentNullException ("buffer");
|
||||
CheckHandle ();
|
||||
if (buffer is null)
|
||||
throw new ArgumentNullException (nameof (buffer));
|
||||
GetCheckedHandle ();
|
||||
if (offset < 0)
|
||||
throw new ArgumentException ();
|
||||
if (count < 1)
|
||||
|
@ -116,35 +118,35 @@ namespace CoreFoundation {
|
|||
[DllImport (Constants.CoreFoundationLibrary)]
|
||||
[return: MarshalAs (UnmanagedType.I1)]
|
||||
static extern /* Boolean */ bool CFWriteStreamSetClient (/* CFWriteStreamRef */ IntPtr stream, /* CFOptionFlags */ nint streamEvents,
|
||||
/* CFWriteStreamClientCallBack */ CFStreamCallback clientCB, /* CFStreamClientContext* */ IntPtr clientContext);
|
||||
/* CFWriteStreamClientCallBack */ CFStreamCallback? clientCB, /* CFStreamClientContext* */ IntPtr clientContext);
|
||||
|
||||
protected override bool DoSetClient (CFStreamCallback callback, CFIndex eventTypes,
|
||||
protected override bool DoSetClient (CFStreamCallback? callback, CFIndex eventTypes,
|
||||
IntPtr context)
|
||||
{
|
||||
return CFWriteStreamSetClient (Handle, eventTypes, callback, context);
|
||||
return CFWriteStreamSetClient (Handle, (nint) eventTypes, callback, context);
|
||||
}
|
||||
|
||||
[DllImport (Constants.CoreFoundationLibrary)]
|
||||
extern static void CFWriteStreamScheduleWithRunLoop (/* CFWriteStreamRef */ IntPtr stream, /* CFRunLoopRef */ IntPtr runLoop, /* CFStringRef */ IntPtr runLoopMode);
|
||||
|
||||
protected override void ScheduleWithRunLoop (CFRunLoop loop, NSString mode)
|
||||
protected override void ScheduleWithRunLoop (CFRunLoop loop, NSString? mode)
|
||||
{
|
||||
if (loop == null)
|
||||
throw new ArgumentNullException ("loop");
|
||||
if (mode == null)
|
||||
throw new ArgumentNullException ("mode");
|
||||
if (loop is null)
|
||||
throw new ArgumentNullException (nameof (loop));
|
||||
if (mode is null)
|
||||
throw new ArgumentNullException (nameof (mode));
|
||||
CFWriteStreamScheduleWithRunLoop (Handle, loop.Handle, mode.Handle);
|
||||
}
|
||||
|
||||
[DllImport (Constants.CoreFoundationLibrary)]
|
||||
extern static void CFWriteStreamUnscheduleFromRunLoop (/* CFWriteStreamRef */ IntPtr stream, /* CFRunLoopRef */ IntPtr runLoop, /* CFStringRef */ IntPtr runLoopMode);
|
||||
|
||||
protected override void UnscheduleFromRunLoop (CFRunLoop loop, NSString mode)
|
||||
protected override void UnscheduleFromRunLoop (CFRunLoop loop, NSString? mode)
|
||||
{
|
||||
if (loop == null)
|
||||
throw new ArgumentNullException ("loop");
|
||||
if (mode == null)
|
||||
throw new ArgumentNullException ("mode");
|
||||
if (loop is null)
|
||||
throw new ArgumentNullException (nameof (loop));
|
||||
if (mode is null)
|
||||
throw new ArgumentNullException (nameof (mode));
|
||||
CFWriteStreamUnscheduleFromRunLoop (Handle, loop.Handle, mode.Handle);
|
||||
}
|
||||
|
||||
|
@ -153,8 +155,8 @@ namespace CoreFoundation {
|
|||
|
||||
protected override IntPtr DoGetProperty (NSString name)
|
||||
{
|
||||
if (name == null)
|
||||
throw new ArgumentNullException ("name");
|
||||
if (name is null)
|
||||
throw new ArgumentNullException (nameof (name));
|
||||
return CFWriteStreamSetProperty (Handle, name.Handle);
|
||||
}
|
||||
|
||||
|
@ -162,11 +164,11 @@ namespace CoreFoundation {
|
|||
[return: MarshalAs (UnmanagedType.I1)]
|
||||
extern static /* Boolean */ bool CFWriteStreamSetProperty (/* CFWriteStreamRef */ IntPtr stream, /* CFStringRef */ IntPtr propertyName, /* CFTypeRef */ IntPtr value);
|
||||
|
||||
protected override bool DoSetProperty (NSString name, INativeObject value)
|
||||
protected override bool DoSetProperty (NSString name, INativeObject? value)
|
||||
{
|
||||
if (name == null)
|
||||
throw new ArgumentNullException ("name");
|
||||
return CFWriteStreamSetProperty (Handle, name.Handle, value == null ? IntPtr.Zero : value.Handle);
|
||||
if (name is null)
|
||||
throw new ArgumentNullException (nameof (name));
|
||||
return CFWriteStreamSetProperty (Handle, name.Handle, value.GetHandle ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче