42 lines
1.9 KiB
C#
42 lines
1.9 KiB
C#
using System.Buffers.Binary;
|
|
|
|
sealed class PacketMemoryFixture
|
|
{
|
|
public Dictionary<nint,byte[]> Blocks { get; }=[];
|
|
public List<(nint Address,int Count)> Reads { get; }=[];
|
|
public bool ShortReads { get; set; }
|
|
public bool Read(nint address,int count,out byte[] bytes)
|
|
{
|
|
Reads.Add((address,count));
|
|
foreach(var (start,block) in Blocks)
|
|
{
|
|
var offset=(long)address-(long)start;
|
|
if(offset<0 || offset>block.Length || count>block.Length-offset) continue;
|
|
bytes=block.AsSpan((int)offset,ShortReads ? Math.Max(0,count-1) : count).ToArray();
|
|
return true;
|
|
}
|
|
bytes=[]; return false;
|
|
}
|
|
public static PacketMemoryFixture Up(byte[] payload,ulong? length=null)
|
|
{
|
|
var memory=new PacketMemoryFixture();
|
|
var header=new byte[16]; BinaryPrimitives.WriteUInt16LittleEndian(header,838);
|
|
BinaryPrimitives.WriteUInt64LittleEndian(header.AsSpan(8),length ?? (ulong)payload.Length+16);
|
|
memory.Blocks[0x1000]=header; memory.Blocks[0x1020]=payload.ToArray();
|
|
return memory;
|
|
}
|
|
public static PacketMemoryFixture Down(byte[] payload,ulong? length=null,uint target=0x12345678)
|
|
{
|
|
var memory=new PacketMemoryFixture();
|
|
var reference=new byte[8]; BinaryPrimitives.WriteUInt64LittleEndian(reference,0x2000);
|
|
memory.Blocks[0x1010]=reference;
|
|
var descriptor=new byte[32]; BinaryPrimitives.WriteUInt32LittleEndian(descriptor,target);
|
|
BinaryPrimitives.WriteUInt64LittleEndian(descriptor.AsSpan(16),length ?? (ulong)payload.Length+16);
|
|
BinaryPrimitives.WriteUInt64LittleEndian(descriptor.AsSpan(24),0x3000);
|
|
memory.Blocks[0x2020]=descriptor;
|
|
var ipc=new byte[16+payload.Length]; BinaryPrimitives.WriteUInt16LittleEndian(ipc.AsSpan(2),354);
|
|
payload.CopyTo(ipc,16); memory.Blocks[0x3000]=ipc;
|
|
return memory;
|
|
}
|
|
}
|