using System; using System.IO; using System.Runtime.InteropServices; using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; namespace UnityEngine.XR.ARKit { static class NSKeyedUnarchiver { public static T Unarchive(NSData data) where T : struct, INSObject { var unarchivedObject = Unarchive(data, out var error); try { if (error != null) throw new InvalidDataException($"Unable to deserialize {typeof(T).FullName}: {error.localizedDescription}"); return unarchivedObject; } finally { error.Dispose(); } } public static T Unarchive(NSData data, out NSError error) where T : struct, INSObject { var t = default(T); var ptr = UnarchivedObjectOfClass(t.staticClass, data, out error); t.SetUnderlyingNativePtr(ptr); return t; } public static unsafe T Unarchive(void* bytes, int byteCount) where T : struct, INSObject { using var data = NSData.CreateWithBytesNoCopy(bytes, byteCount); return Unarchive(data); } public static T Unarchive(NativeSlice bytes) where T : struct, INSObject { unsafe { return Unarchive(bytes.GetUnsafeReadOnlyPtr(), bytes.Length); } } public static T Unarchive(byte[] bytes) where T : struct, INSObject { if (bytes == null) { return default; } unsafe { fixed (void* ptr = bytes) { return Unarchive(ptr, bytes.Length); } } } #if UNITY_EDITOR || !UNITY_XR_ARKIT_LOADER_ENABLED static IntPtr UnarchivedObjectOfClass(Class cls, NSData data, out NSError error) { error = default; return default; } #else [DllImport("__Internal", EntryPoint = "NSKeyedUnarchiver_unarchivedObjectOfClass_fromData_error_")] static extern IntPtr UnarchivedObjectOfClass(Class cls, NSData data, out NSError error); #endif } }