using System.IO.MemoryMappedFiles; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using StitchATon2.Infra.Buffers; namespace StitchATon2.Infra; public static class Utils { [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_buffer")] private static extern ref SafeBuffer GetSafeBuffer(this UnmanagedMemoryAccessor view); [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_offset")] private static extern ref long GetOffset(this UnmanagedMemoryAccessor view); private static unsafe uint AlignedSizeOf() where T : unmanaged { uint size = (uint)sizeof(T); return size is 1 or 2 ? size : (uint)((size + 3) & (~3)); } public static void DangerousReadSpan(this UnmanagedMemoryAccessor view, long position, Span span, int offset, int count) where T : unmanaged { uint sizeOfT = AlignedSizeOf(); int n = count; long spaceLeft = view.Capacity - position; if (spaceLeft < 0) { n = 0; } else { ulong spaceNeeded = (ulong)(sizeOfT * count); if ((ulong)spaceLeft < spaceNeeded) { n = (int)(spaceLeft / sizeOfT); } } var byteOffset = (ulong)(view.GetOffset() + position); view.GetSafeBuffer().ReadSpan(byteOffset, span.Slice(offset, n)); } public static ArrayOwner Clone(this ArrayOwner arrayOwner, int length) where T : unmanaged { var newArrayOwner = MemoryAllocator.AllocateArray(length); Array.Copy(arrayOwner.Array, 0, newArrayOwner.Array, 0, length); return newArrayOwner; } public static void CopyTo(this ArrayOwner arrayOwner, ArrayOwner target, int length) where T : unmanaged { Array.Copy(arrayOwner.Array, 0, target.Array, 0, length); } }