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 { 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 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"); } [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); } } } }