using CPF.Mac.Foundation; using CPF.Mac.ObjCRuntime; using System; using System.Collections.Generic; using System.Runtime.InteropServices; namespace CPF.Mac.CoreFoundation { public class CFException : Exception { public int Code { get; private set; } public NSString Domain { get; private set; } public string FailureReason { get; private set; } public string RecoverySuggestion { get; private set; } public CFException(string description, NSString domain, int code, string failureReason, string recoverySuggestion) : base(description) { Code = code; Domain = domain; FailureReason = failureReason; RecoverySuggestion = recoverySuggestion; } public static CFException FromCFError(IntPtr cfErrorHandle) { return FromCFError(cfErrorHandle, release: true); } public static CFException FromCFError(IntPtr cfErrorHandle, bool release) { if (cfErrorHandle == IntPtr.Zero) { throw new ArgumentException("cfErrorHandle must not be null.", "cfErrorHandle"); } CFException ex = new CFException(ToString(CFErrorCopyDescription(cfErrorHandle)), (NSString)Runtime.GetNSObject(CFErrorGetDomain(cfErrorHandle)), CFErrorGetCode(cfErrorHandle), ToString(CFErrorCopyFailureReason(cfErrorHandle)), ToString(CFErrorCopyRecoverySuggestion(cfErrorHandle))); IntPtr intPtr = CFErrorCopyUserInfo(cfErrorHandle); if (intPtr != IntPtr.Zero) { using (NSDictionary nSDictionary = new NSDictionary(intPtr)) { foreach (KeyValuePair item in nSDictionary) { ex.Data.Add(item.Key, item.Value); } } } if (release) { CFObject.CFRelease(cfErrorHandle); } return ex; } private static string ToString(IntPtr cfStringRef) { return ToString(cfStringRef, release: true); } private static string ToString(IntPtr cfStringRef, bool release) { string result = CFString.FetchString(cfStringRef); if (release && cfStringRef != IntPtr.Zero) { CFObject.CFRelease(cfStringRef); } return result; } [DllImport("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")] private static extern IntPtr CFErrorCopyDescription(IntPtr err); [DllImport("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")] private static extern IntPtr CFErrorCopyFailureReason(IntPtr err); [DllImport("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")] private static extern IntPtr CFErrorCopyRecoverySuggestion(IntPtr err); [DllImport("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")] private static extern IntPtr CFErrorCopyUserInfo(IntPtr err); [DllImport("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")] private static extern int CFErrorGetCode(IntPtr err); [DllImport("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")] private static extern IntPtr CFErrorGetDomain(IntPtr err); } }