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

307 lines
7.4 KiB
C#

using CPF.Mac.ObjCRuntime;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace CPF.Mac.Foundation
{
[Register("NSMutableData", true)]
public class NSMutableData : NSData, IEnumerable, IEnumerable<byte>
{
private static readonly IntPtr selMutableBytesHandle = Selector.GetHandle("mutableBytes");
private static readonly IntPtr selLengthHandle = Selector.GetHandle("length");
private static readonly IntPtr selSetLength_Handle = Selector.GetHandle("setLength:");
private static readonly IntPtr selDataWithCapacity_Handle = Selector.GetHandle("dataWithCapacity:");
private static readonly IntPtr selDataWithLength_Handle = Selector.GetHandle("dataWithLength:");
private static readonly IntPtr selDataHandle = Selector.GetHandle("data");
private static readonly IntPtr selInitWithCapacity_Handle = Selector.GetHandle("initWithCapacity:");
private static readonly IntPtr selAppendData_Handle = Selector.GetHandle("appendData:");
private static readonly IntPtr selAppendBytesLength_Handle = Selector.GetHandle("appendBytes:length:");
private static readonly IntPtr selSetData_Handle = Selector.GetHandle("setData:");
private static readonly IntPtr class_ptr = Class.GetHandle("NSMutableData");
public override byte this[int idx]
{
set
{
if (idx < 0 || idx >= int.MaxValue || idx > (int)Length)
{
throw new ArgumentException("idx");
}
Marshal.WriteByte(Bytes, idx, value);
}
}
public override IntPtr ClassHandle => class_ptr;
public virtual IntPtr MutableBytes
{
[Export("mutableBytes")]
get
{
if (IsDirectBinding)
{
return Messaging.IntPtr_objc_msgSend(base.Handle, selMutableBytesHandle);
}
return Messaging.IntPtr_objc_msgSendSuper(base.SuperHandle, selMutableBytesHandle);
}
}
public override ulong Length
{
[Export("length")]
get
{
if (IsDirectBinding)
{
return Messaging.UInt64_objc_msgSend(base.Handle, selLengthHandle);
}
return Messaging.UInt64_objc_msgSendSuper(base.SuperHandle, selLengthHandle);
}
[Export("setLength:")]
set
{
if (IsDirectBinding)
{
Messaging.void_objc_msgSend_UInt64(base.Handle, selSetLength_Handle, value);
}
else
{
Messaging.void_objc_msgSendSuper_UInt64(base.SuperHandle, selSetLength_Handle, value);
}
}
}
public unsafe void AppendBytes(byte[] bytes)
{
if (bytes == null)
{
throw new ArgumentNullException("bytes");
}
fixed (byte* value = &bytes[0])
{
AppendBytes((IntPtr)(void*)value, (uint)bytes.Length);
}
}
public unsafe void AppendBytes(byte[] bytes, int start, int len)
{
if (bytes == null)
{
throw new ArgumentNullException("bytes");
}
if (start < 0 || start > bytes.Length)
{
throw new ArgumentException("start");
}
if (start + len > bytes.Length)
{
throw new ArgumentException("len");
}
fixed (byte* value = &bytes[start])
{
AppendBytes((IntPtr)(void*)value, (uint)len);
}
}
IEnumerator IEnumerable.GetEnumerator()
{
IntPtr source = Bytes;
int top = (int)Length;
int i = 0;
while (true)
{
if (i < top)
{
if (!(source == Bytes) || top != (int)Length)
{
break;
}
yield return Marshal.ReadByte(source, i);
i++;
continue;
}
yield break;
}
throw new InvalidOperationException("The NSMutableData has changed");
}
IEnumerator<byte> IEnumerable<byte>.GetEnumerator()
{
IntPtr source = Bytes;
int top = (int)Length;
int i = 0;
while (true)
{
if (i < top)
{
if (!(source == Bytes) || top != (int)Length)
{
break;
}
yield return Marshal.ReadByte(source, i);
i++;
continue;
}
yield break;
}
throw new InvalidOperationException("The NSMutableData has changed");
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
[Export("init")]
public NSMutableData()
: 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 NSMutableData(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 NSMutableData(NSObjectFlag t)
: base(t)
{
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
public NSMutableData(IntPtr handle)
: base(handle)
{
}
[Export("dataWithCapacity:")]
public static NSMutableData FromCapacity(ulong capacity)
{
using (new NSAutoreleasePool())
{
return (NSMutableData)Runtime.GetNSObject(Messaging.IntPtr_objc_msgSend_UInt64(class_ptr, selDataWithCapacity_Handle, capacity));
}
}
[Export("dataWithLength:")]
public static NSMutableData FromLength(ulong length)
{
using (new NSAutoreleasePool())
{
return (NSMutableData)Runtime.GetNSObject(Messaging.IntPtr_objc_msgSend_UInt64(class_ptr, selDataWithLength_Handle, length));
}
}
[Export("data")]
public static NSMutableData Create()
{
using (new NSAutoreleasePool())
{
return (NSMutableData)Runtime.GetNSObject(Messaging.IntPtr_objc_msgSend(class_ptr, selDataHandle));
}
}
[Export("setLength:")]
public virtual void SetLength(ulong len)
{
if (IsDirectBinding)
{
Messaging.void_objc_msgSend_UInt64(base.Handle, selSetLength_Handle, len);
}
else
{
Messaging.void_objc_msgSendSuper_UInt64(base.SuperHandle, selSetLength_Handle, len);
}
}
[Export("initWithCapacity:")]
public NSMutableData(ulong len)
: base(NSObjectFlag.Empty)
{
if (IsDirectBinding)
{
base.Handle = Messaging.IntPtr_objc_msgSend_UInt64(base.Handle, selInitWithCapacity_Handle, len);
}
else
{
base.Handle = Messaging.IntPtr_objc_msgSendSuper_UInt64(base.SuperHandle, selInitWithCapacity_Handle, len);
}
}
[Export("appendData:")]
public virtual void AppendData(NSData other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (IsDirectBinding)
{
Messaging.void_objc_msgSend_IntPtr(base.Handle, selAppendData_Handle, other.Handle);
}
else
{
Messaging.void_objc_msgSendSuper_IntPtr(base.SuperHandle, selAppendData_Handle, other.Handle);
}
}
[Export("appendBytes:length:")]
public virtual void AppendBytes(IntPtr bytes, ulong len)
{
if (IsDirectBinding)
{
Messaging.void_objc_msgSend_IntPtr_UInt64(base.Handle, selAppendBytesLength_Handle, bytes, len);
}
else
{
Messaging.void_objc_msgSendSuper_IntPtr_UInt64(base.SuperHandle, selAppendBytesLength_Handle, bytes, len);
}
}
[Export("setData:")]
public virtual void SetData(NSData data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
if (IsDirectBinding)
{
Messaging.void_objc_msgSend_IntPtr(base.Handle, selSetData_Handle, data.Handle);
}
else
{
Messaging.void_objc_msgSendSuper_IntPtr(base.SuperHandle, selSetData_Handle, data.Handle);
}
}
}
}