using CPF.Mac.ObjCRuntime; using System; using System.ComponentModel; namespace CPF.Mac.Foundation { [Register("NSKeyedUnarchiver", true)] public class NSKeyedUnarchiver : NSCoder { [Register] private sealed class _NSKeyedUnarchiverDelegate : NSKeyedUnarchiverDelegate { internal NSDecoderCallback decodedObject; internal EventHandler finished; internal NSDecoderHandler cannotDecodeClass; internal EventHandler finishing; internal EventHandler replacingObject; [Preserve(Conditional = true)] public override NSObject DecodedObject(NSKeyedUnarchiver unarchiver, NSObject obj) { return decodedObject?.Invoke(unarchiver, obj); } [Preserve(Conditional = true)] public override void Finished(NSKeyedUnarchiver unarchiver) { finished?.Invoke(unarchiver, EventArgs.Empty); } [Preserve(Conditional = true)] public override Class CannotDecodeClass(NSKeyedUnarchiver unarchiver, string klass, string[] classes) { return cannotDecodeClass?.Invoke(unarchiver, klass, classes); } [Preserve(Conditional = true)] public override void Finishing(NSKeyedUnarchiver unarchiver) { finishing?.Invoke(unarchiver, EventArgs.Empty); } [Preserve(Conditional = true)] public override void ReplacingObject(NSKeyedUnarchiver unarchiver, NSObject oldObject, NSObject newObject) { EventHandler eventHandler = replacingObject; if (eventHandler != null) { NSArchiveReplaceEventArgs e = new NSArchiveReplaceEventArgs(oldObject, newObject); eventHandler(unarchiver, e); } } } private static readonly IntPtr selDelegateHandle = Selector.GetHandle("delegate"); private static readonly IntPtr selSetDelegate_Handle = Selector.GetHandle("setDelegate:"); private static readonly IntPtr selInitForReadingWithData_Handle = Selector.GetHandle("initForReadingWithData:"); private static readonly IntPtr selUnarchiveObjectWithData_Handle = Selector.GetHandle("unarchiveObjectWithData:"); private static readonly IntPtr selUnarchiveObjectWithFile_Handle = Selector.GetHandle("unarchiveObjectWithFile:"); private static readonly IntPtr selFinishDecodingHandle = Selector.GetHandle("finishDecoding"); private static readonly IntPtr selSetClassForClassName_Handle = Selector.GetHandle("setClass:forClassName:"); private static readonly IntPtr selClassForClassName_Handle = Selector.GetHandle("classForClassName:"); private static readonly IntPtr class_ptr = Class.GetHandle("NSKeyedUnarchiver"); private object __mt_WeakDelegate_var; public override IntPtr ClassHandle => class_ptr; public NSKeyedUnarchiverDelegate Delegate { get { return WeakDelegate as NSKeyedUnarchiverDelegate; } set { WeakDelegate = value; } } public virtual NSObject WeakDelegate { [Export("delegate", ArgumentSemantic.Assign)] get { return (NSObject)(__mt_WeakDelegate_var = ((!IsDirectBinding) ? Runtime.GetNSObject(Messaging.IntPtr_objc_msgSendSuper(base.SuperHandle, selDelegateHandle)) : Runtime.GetNSObject(Messaging.IntPtr_objc_msgSend(base.Handle, selDelegateHandle)))); } [Export("setDelegate:", ArgumentSemantic.Assign)] set { if (IsDirectBinding) { Messaging.void_objc_msgSend_IntPtr(base.Handle, selSetDelegate_Handle, value?.Handle ?? IntPtr.Zero); } else { Messaging.void_objc_msgSendSuper_IntPtr(base.SuperHandle, selSetDelegate_Handle, value?.Handle ?? IntPtr.Zero); } __mt_WeakDelegate_var = value; } } public NSDecoderCallback DecodedObject { get { return EnsureNSKeyedUnarchiverDelegate().decodedObject; } set { EnsureNSKeyedUnarchiverDelegate().decodedObject = value; } } public NSDecoderHandler CannotDecodeClass { get { return EnsureNSKeyedUnarchiverDelegate().cannotDecodeClass; } set { EnsureNSKeyedUnarchiverDelegate().cannotDecodeClass = value; } } public event EventHandler Finished { add { _NSKeyedUnarchiverDelegate nSKeyedUnarchiverDelegate = EnsureNSKeyedUnarchiverDelegate(); nSKeyedUnarchiverDelegate.finished = (EventHandler)System.Delegate.Combine(nSKeyedUnarchiverDelegate.finished, value); } remove { _NSKeyedUnarchiverDelegate nSKeyedUnarchiverDelegate = EnsureNSKeyedUnarchiverDelegate(); nSKeyedUnarchiverDelegate.finished = (EventHandler)System.Delegate.Remove(nSKeyedUnarchiverDelegate.finished, value); } } public event EventHandler Finishing { add { _NSKeyedUnarchiverDelegate nSKeyedUnarchiverDelegate = EnsureNSKeyedUnarchiverDelegate(); nSKeyedUnarchiverDelegate.finishing = (EventHandler)System.Delegate.Combine(nSKeyedUnarchiverDelegate.finishing, value); } remove { _NSKeyedUnarchiverDelegate nSKeyedUnarchiverDelegate = EnsureNSKeyedUnarchiverDelegate(); nSKeyedUnarchiverDelegate.finishing = (EventHandler)System.Delegate.Remove(nSKeyedUnarchiverDelegate.finishing, value); } } public event EventHandler ReplacingObject { add { _NSKeyedUnarchiverDelegate nSKeyedUnarchiverDelegate = EnsureNSKeyedUnarchiverDelegate(); nSKeyedUnarchiverDelegate.replacingObject = (EventHandler)System.Delegate.Combine(nSKeyedUnarchiverDelegate.replacingObject, value); } remove { _NSKeyedUnarchiverDelegate nSKeyedUnarchiverDelegate = EnsureNSKeyedUnarchiverDelegate(); nSKeyedUnarchiverDelegate.replacingObject = (EventHandler)System.Delegate.Remove(nSKeyedUnarchiverDelegate.replacingObject, value); } } public static void GlobalSetClass(Class kls, string codedName) { if (codedName == null) { throw new ArgumentNullException("codedName"); } if (kls == null) { throw new ArgumentNullException("kls"); } using (NSString nSString = new NSString(codedName)) { Messaging.void_objc_msgSend_IntPtr_IntPtr(class_ptr, selSetClassForClassName_Handle, kls.Handle, nSString.Handle); } } public static Class GlobalGetClass(string codedName) { if (codedName == null) { throw new ArgumentNullException("codedName"); } using (NSString nSString = new NSString(codedName)) { return new Class(Messaging.IntPtr_objc_msgSend_IntPtr(class_ptr, selClassForClassName_Handle, nSString.Handle)); } } [EditorBrowsable(EditorBrowsableState.Advanced)] [Export("initWithCoder:")] public NSKeyedUnarchiver(NSCoder coder) : base(NSObjectFlag.Empty) { if (IsDirectBinding) { base.Handle = Messaging.IntPtr_objc_msgSend_IntPtr(base.Handle, Selector.InitWithCoder, coder.Handle); } else { base.Handle = Messaging.IntPtr_objc_msgSendSuper_IntPtr(base.SuperHandle, Selector.InitWithCoder, coder.Handle); } } [EditorBrowsable(EditorBrowsableState.Advanced)] public NSKeyedUnarchiver(NSObjectFlag t) : base(t) { } [EditorBrowsable(EditorBrowsableState.Advanced)] public NSKeyedUnarchiver(IntPtr handle) : base(handle) { } [Export("initForReadingWithData:")] public NSKeyedUnarchiver(NSData data) : base(NSObjectFlag.Empty) { if (data == null) { throw new ArgumentNullException("data"); } if (IsDirectBinding) { base.Handle = Messaging.IntPtr_objc_msgSend_IntPtr(base.Handle, selInitForReadingWithData_Handle, data.Handle); } else { base.Handle = Messaging.IntPtr_objc_msgSendSuper_IntPtr(base.SuperHandle, selInitForReadingWithData_Handle, data.Handle); } } [Export("unarchiveObjectWithData:")] public static NSObject UnarchiveObject(NSData data) { if (data == null) { throw new ArgumentNullException("data"); } return Runtime.GetNSObject(Messaging.IntPtr_objc_msgSend_IntPtr(class_ptr, selUnarchiveObjectWithData_Handle, data.Handle)); } [Export("unarchiveObjectWithFile:")] public static NSObject UnarchiveFile(string file) { if (file == null) { throw new ArgumentNullException("file"); } IntPtr intPtr = NSString.CreateNative(file); NSObject nSObject = Runtime.GetNSObject(Messaging.IntPtr_objc_msgSend_IntPtr(class_ptr, selUnarchiveObjectWithFile_Handle, intPtr)); NSString.ReleaseNative(intPtr); return nSObject; } [Export("finishDecoding")] public virtual void FinishDecoding() { if (IsDirectBinding) { Messaging.void_objc_msgSend(base.Handle, selFinishDecodingHandle); } else { Messaging.void_objc_msgSendSuper(base.SuperHandle, selFinishDecodingHandle); } } [Export("setClass:forClassName:")] public virtual void SetClass(Class kls, string codedName) { if (kls == null) { throw new ArgumentNullException("kls"); } if (codedName == null) { throw new ArgumentNullException("codedName"); } IntPtr intPtr = NSString.CreateNative(codedName); if (IsDirectBinding) { Messaging.void_objc_msgSend_IntPtr_IntPtr(base.Handle, selSetClassForClassName_Handle, kls.Handle, intPtr); } else { Messaging.void_objc_msgSendSuper_IntPtr_IntPtr(base.SuperHandle, selSetClassForClassName_Handle, kls.Handle, intPtr); } NSString.ReleaseNative(intPtr); } [Export("classForClassName:")] public virtual Class GetClass(string codedName) { if (codedName == null) { throw new ArgumentNullException("codedName"); } IntPtr intPtr = NSString.CreateNative(codedName); Class result = (!IsDirectBinding) ? new Class(Messaging.IntPtr_objc_msgSendSuper_IntPtr(base.SuperHandle, selClassForClassName_Handle, intPtr)) : new Class(Messaging.IntPtr_objc_msgSend_IntPtr(base.Handle, selClassForClassName_Handle, intPtr)); NSString.ReleaseNative(intPtr); return result; } private _NSKeyedUnarchiverDelegate EnsureNSKeyedUnarchiverDelegate() { NSObject nSObject = WeakDelegate; if (nSObject == null || !(nSObject is _NSKeyedUnarchiverDelegate)) { nSObject = (WeakDelegate = new _NSKeyedUnarchiverDelegate()); } return (_NSKeyedUnarchiverDelegate)nSObject; } protected override void Dispose(bool disposing) { base.Dispose(disposing); if (base.Handle == IntPtr.Zero) { __mt_WeakDelegate_var = null; } } } }