CPF/CPF.Mac/Mac/Foundation/NSArray.cs
2023-11-21 23:05:03 +08:00

422 lines
12 KiB
C#

using CPF.Mac.ObjCRuntime;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace CPF.Mac.Foundation
{
[Register("NSArray", true)]
public class NSArray : NSObject
{
private static readonly IntPtr selCountHandle = Selector.GetHandle("count");
private static readonly IntPtr selObjectAtIndex_Handle = Selector.GetHandle("objectAtIndex:");
private static readonly IntPtr selArrayWithObjectsCount_Handle = Selector.GetHandle("arrayWithObjects:count:");
private static readonly IntPtr selValueForKey_Handle = Selector.GetHandle("valueForKey:");
private static readonly IntPtr selSetValueForKey_Handle = Selector.GetHandle("setValue:forKey:");
private static readonly IntPtr selWriteToFileAtomically_Handle = Selector.GetHandle("writeToFile:atomically:");
private static readonly IntPtr selArrayWithContentsOfFile_Handle = Selector.GetHandle("arrayWithContentsOfFile:");
private static readonly IntPtr selSortedArrayUsingComparator_Handle = Selector.GetHandle("sortedArrayUsingComparator:");
private static readonly IntPtr selFilteredArrayUsingPredicate_Handle = Selector.GetHandle("filteredArrayUsingPredicate:");
private static readonly IntPtr class_ptr = Class.GetHandle("NSArray");
public override IntPtr ClassHandle => class_ptr;
public virtual ulong Count
{
[Export("count")]
get
{
if (IsDirectBinding)
{
return Messaging.UInt64_objc_msgSend(base.Handle, selCountHandle);
}
return Messaging.UInt64_objc_msgSendSuper(base.SuperHandle, selCountHandle);
}
}
internal NSArray(bool empty)
{
base.Handle = IntPtr.Zero;
}
public static NSArray FromNSObjects(params NSObject[] items)
{
return FromNSObjects((IList<NSObject>)items);
}
public static NSArray FromNSObjects(int count, params NSObject[] items)
{
if (items.Length < count)
{
throw new ArgumentException("count is larger than the number of items", "count");
}
return FromNSObjects(items, count);
}
public static NSArray FromObjects(params object[] items)
{
if (items == null)
{
return new NSArray(empty: true);
}
return FromObjects(items.Length, items);
}
public static NSArray FromObjects(int count, params object[] items)
{
if (items == null)
{
return new NSArray(empty: true);
}
if (count > items.Length)
{
throw new ArgumentException("count is larger than the number of items", "count");
}
NSObject[] array = new NSObject[count];
for (int i = 0; i < count; i++)
{
NSObject nSObject = NSObject.FromObject(items[i]);
if (nSObject == null)
{
throw new ArgumentException($"Do not know how to marshal object of type '{items[i].GetType()}' to an NSObject");
}
array[i] = nSObject;
}
return FromNSObjects(array);
}
public static NSArray FromObjects(IntPtr array, int count)
{
return FromObjects(array, (ulong)count);
}
internal static NSArray FromNSObjects(IList<NSObject> items)
{
if (items == null)
{
return new NSArray(empty: true);
}
IntPtr intPtr = Marshal.AllocHGlobal(items.Count * IntPtr.Size);
for (int i = 0; i < items.Count; i++)
{
Marshal.WriteIntPtr(intPtr, i * IntPtr.Size, items[i].Handle);
}
NSArray result = FromObjects(intPtr, items.Count);
Marshal.FreeHGlobal(intPtr);
return result;
}
internal static NSArray FromNSObjects(IList<NSObject> items, int count)
{
if (items == null)
{
return new NSArray(empty: true);
}
IntPtr intPtr = Marshal.AllocHGlobal(items.Count * IntPtr.Size);
for (int i = 0; i < count; i++)
{
Marshal.WriteIntPtr(intPtr, i * IntPtr.Size, items[i].Handle);
}
NSArray result = FromObjects(intPtr, count);
Marshal.FreeHGlobal(intPtr);
return result;
}
public static NSArray FromStrings(params string[] items)
{
if (items == null)
{
throw new ArgumentNullException("items");
}
IntPtr intPtr = Marshal.AllocHGlobal(items.Length * IntPtr.Size);
try
{
NSString[] array = new NSString[items.Length];
for (int i = 0; i < items.Length; i++)
{
if (items[i] == null)
{
throw new ArgumentNullException($"items[{i}]");
}
array[i] = new NSString(items[i]);
IntPtr handle = array[i].Handle;
Marshal.WriteIntPtr(intPtr, i * IntPtr.Size, handle);
}
NSArray result = FromObjects(intPtr, items.Length);
NSString[] array2 = array;
for (int j = 0; j < array2.Length; j++)
{
array2[j].Dispose();
}
return result;
}
finally
{
Marshal.FreeHGlobal(intPtr);
}
}
public static NSArray FromIntPtrs(IntPtr[] vals)
{
if (vals == null)
{
throw new ArgumentNullException("vals");
}
int num = vals.Length;
IntPtr intPtr = Marshal.AllocHGlobal(num * IntPtr.Size);
for (int i = 0; i < num; i++)
{
Marshal.WriteIntPtr(intPtr, i * IntPtr.Size, vals[i]);
}
NSArray result = FromObjects(intPtr, vals.Length);
Marshal.FreeHGlobal(intPtr);
return result;
}
public static string[] StringArrayFromHandle(IntPtr handle)
{
if (handle == IntPtr.Zero)
{
return null;
}
uint num = Messaging.UInt32_objc_msgSend(handle, selCountHandle);
string[] array = new string[num];
for (uint num2 = 0u; num2 < num; num2++)
{
IntPtr usrhandle = Messaging.IntPtr_objc_msgSend_UInt32(handle, selObjectAtIndex_Handle, num2);
array[num2] = NSString.FromHandle(usrhandle);
}
return array;
}
public static T[] ArrayFromHandle<T>(IntPtr handle) where T : NSObject
{
if (handle == IntPtr.Zero)
{
return null;
}
uint num = Messaging.UInt32_objc_msgSend(handle, selCountHandle);
T[] array = new T[num];
for (uint num2 = 0u; num2 < num; num2++)
{
IntPtr intPtr = Messaging.IntPtr_objc_msgSend_UInt32(handle, selObjectAtIndex_Handle, num2);
array[num2] = (T)Runtime.GetNSObject(intPtr);
array[num2].Handle = intPtr;
}
return array;
}
public static T[] FromArray<T>(NSArray weakArray) where T : NSObject
{
if (weakArray == null || weakArray.Handle == IntPtr.Zero)
{
return null;
}
try
{
ulong count = weakArray.Count;
T[] array = new T[count];
for (ulong num = 0uL; num < count; num++)
{
array[num] = (T)Runtime.GetNSObject(weakArray.ValueAt(num));
}
return array;
}
catch
{
return null;
}
}
public static T[] ArrayFromHandleFunc<T>(IntPtr handle, Func<IntPtr, T> createObject)
{
if (handle == IntPtr.Zero)
{
return null;
}
uint num = Messaging.UInt32_objc_msgSend(handle, selCountHandle);
T[] array = new T[num];
for (uint num2 = 0u; num2 < num; num2++)
{
IntPtr arg = Messaging.IntPtr_objc_msgSend_UInt32(handle, selObjectAtIndex_Handle, num2);
array[num2] = createObject(arg);
}
return array;
}
public static T[] ArrayFromHandle<T>(IntPtr handle, Converter<IntPtr, T> creator)
{
if (handle == IntPtr.Zero)
{
return null;
}
uint num = Messaging.UInt32_objc_msgSend(handle, selCountHandle);
T[] array = new T[num];
for (uint num2 = 0u; num2 < num; num2++)
{
IntPtr input = Messaging.IntPtr_objc_msgSend_UInt32(handle, selObjectAtIndex_Handle, num2);
array[num2] = creator(input);
}
return array;
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
[Export("init")]
public NSArray()
: base(NSObjectFlag.Empty)
{
if (IsDirectBinding)
{
base.Handle = Messaging.IntPtr_objc_msgSend(base.Handle, Selector.Init);
}
else
{
base.Handle = Messaging.IntPtr_objc_msgSendSuper(base.SuperHandle, Selector.Init);
}
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
[Export("initWithCoder:")]
public NSArray(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 NSArray(NSObjectFlag t)
: base(t)
{
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
public NSArray(IntPtr handle)
: base(handle)
{
}
[Export("objectAtIndex:")]
public virtual IntPtr ValueAt(ulong idx)
{
if (IsDirectBinding)
{
return Messaging.IntPtr_objc_msgSend_UInt64(base.Handle, selObjectAtIndex_Handle, idx);
}
return Messaging.IntPtr_objc_msgSendSuper_UInt64(base.SuperHandle, selObjectAtIndex_Handle, idx);
}
[Export("arrayWithObjects:count:")]
internal static NSArray FromObjects(IntPtr array, ulong count)
{
return (NSArray)Runtime.GetNSObject(Messaging.IntPtr_objc_msgSend_IntPtr_UInt64(class_ptr, selArrayWithObjectsCount_Handle, array, count));
}
[Export("valueForKey:")]
public new virtual NSObject ValueForKey(NSString key)
{
if (key == null)
{
throw new ArgumentNullException("key");
}
if (IsDirectBinding)
{
return Runtime.GetNSObject(Messaging.IntPtr_objc_msgSend_IntPtr(base.Handle, selValueForKey_Handle, key.Handle));
}
return Runtime.GetNSObject(Messaging.IntPtr_objc_msgSendSuper_IntPtr(base.SuperHandle, selValueForKey_Handle, key.Handle));
}
[Export("setValue:forKey:")]
public new virtual void SetValueForKey(NSObject value, NSString key)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
if (key == null)
{
throw new ArgumentNullException("key");
}
if (IsDirectBinding)
{
Messaging.void_objc_msgSend_IntPtr_IntPtr(base.Handle, selSetValueForKey_Handle, value.Handle, key.Handle);
}
else
{
Messaging.void_objc_msgSendSuper_IntPtr_IntPtr(base.SuperHandle, selSetValueForKey_Handle, value.Handle, key.Handle);
}
}
[Export("writeToFile:atomically:")]
public virtual bool WriteToFile(string path, bool useAuxiliaryFile)
{
if (path == null)
{
throw new ArgumentNullException("path");
}
IntPtr intPtr = NSString.CreateNative(path);
bool result = (!IsDirectBinding) ? Messaging.bool_objc_msgSendSuper_IntPtr_bool(base.SuperHandle, selWriteToFileAtomically_Handle, intPtr, useAuxiliaryFile) : Messaging.bool_objc_msgSend_IntPtr_bool(base.Handle, selWriteToFileAtomically_Handle, intPtr, useAuxiliaryFile);
NSString.ReleaseNative(intPtr);
return result;
}
[Export("arrayWithContentsOfFile:")]
public static NSArray FromFile(string path)
{
if (path == null)
{
throw new ArgumentNullException("path");
}
IntPtr intPtr = NSString.CreateNative(path);
NSArray result = (NSArray)Runtime.GetNSObject(Messaging.IntPtr_objc_msgSend_IntPtr(class_ptr, selArrayWithContentsOfFile_Handle, intPtr));
NSString.ReleaseNative(intPtr);
return result;
}
[Export("sortedArrayUsingComparator:")]
public unsafe virtual NSArray Sort(NSComparator cmptr)
{
if (cmptr == null)
{
throw new ArgumentNullException("cmptr");
}
BlockLiteral blockLiteral = default(BlockLiteral);
BlockLiteral* ptr = &blockLiteral;
blockLiteral.SetupBlock(Trampolines.SDNSComparator.Handler, cmptr);
NSArray result = (!IsDirectBinding) ? ((NSArray)Runtime.GetNSObject(Messaging.IntPtr_objc_msgSendSuper_IntPtr(base.SuperHandle, selSortedArrayUsingComparator_Handle, (IntPtr)(void*)ptr))) : ((NSArray)Runtime.GetNSObject(Messaging.IntPtr_objc_msgSend_IntPtr(base.Handle, selSortedArrayUsingComparator_Handle, (IntPtr)(void*)ptr)));
ptr->CleanupBlock();
return result;
}
[Export("filteredArrayUsingPredicate:")]
public virtual NSArray Filter(NSPredicate predicate)
{
if (predicate == null)
{
throw new ArgumentNullException("predicate");
}
if (IsDirectBinding)
{
return (NSArray)Runtime.GetNSObject(Messaging.IntPtr_objc_msgSend_IntPtr(base.Handle, selFilteredArrayUsingPredicate_Handle, predicate.Handle));
}
return (NSArray)Runtime.GetNSObject(Messaging.IntPtr_objc_msgSendSuper_IntPtr(base.SuperHandle, selFilteredArrayUsingPredicate_Handle, predicate.Handle));
}
}
}