2025-07-30 07:30:00 +07:00
|
|
|
using System.IO.MemoryMappedFiles;
|
|
|
|
|
using System.Runtime.CompilerServices;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using StitchATon2.Infra.Buffers;
|
|
|
|
|
|
|
|
|
|
namespace StitchATon2.Infra;
|
|
|
|
|
|
|
|
|
|
public static class Utils
|
|
|
|
|
{
|
|
|
|
|
private static unsafe uint AlignedSizeOf<T>() where T : unmanaged
|
|
|
|
|
{
|
|
|
|
|
uint size = (uint)sizeof(T);
|
|
|
|
|
return size is 1 or 2 ? size : (uint)((size + 3) & (~3));
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-31 06:19:32 +07:00
|
|
|
internal static void DangerousReadSpan<T>(this MemoryMappedViewAccessor view, long position, Span<T> span, int offset, int count)
|
2025-07-30 07:30:00 +07:00
|
|
|
where T : unmanaged
|
|
|
|
|
{
|
|
|
|
|
uint sizeOfT = AlignedSizeOf<T>();
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-31 06:19:32 +07:00
|
|
|
var byteOffset = (ulong)(view.PointerOffset + position);
|
|
|
|
|
view.SafeMemoryMappedViewHandle.ReadSpan(byteOffset, span.Slice(offset, n));
|
2025-07-30 07:30:00 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static ArrayOwner<T> Clone<T>(this ArrayOwner<T> arrayOwner, int length) where T : unmanaged
|
|
|
|
|
{
|
|
|
|
|
var newArrayOwner = MemoryAllocator.AllocateArray<T>(length);
|
|
|
|
|
Array.Copy(arrayOwner.Array, 0, newArrayOwner.Array, 0, length);
|
|
|
|
|
return newArrayOwner;
|
|
|
|
|
}
|
|
|
|
|
}
|