private void Process(Request request) { lock (sync) { if (request.Blocks.Count != 0) { return; } requests.Remove(request); var data = new byte[request.Size]; // blocks start/end ulong start = Alignment.AlignDown(request.Address, BlockSize); ulong end = Alignment.AlignUp(request.Address + (ulong)request.Size, BlockSize); ulong requestStart = request.Address; ulong requestEnd = request.Address + request.Size; lock (sync) { for (ulong blockStart = start; blockStart < end; blockStart += BlockSize) { ulong blockEnd = blockStart + BlockSize; int blockOffset = 0; int dataOffset = 0; ulong overlapStart = Math.Max(requestStart, blockStart); ulong overlapEnd = Math.Min(requestEnd, blockEnd); int len = (int)(overlapEnd - overlapStart); if (requestStart > blockStart) { blockOffset = (int)(requestStart - blockStart); } if (blockStart > requestStart) { dataOffset = (int)(blockStart - requestStart); } var block = buffer[blockStart]; try { Array.Copy(block, blockOffset, data, dataOffset, len); } catch (Exception e) { Debug.WriteLine(e.ToString()); } } } request.OnMemoryRead(request.Address, data); } }
public void ReadMemory(ulong address, uint size, OnMemoryRead onMemoryRead) { var request = new Request(address, size, onMemoryRead); var start = Alignment.AlignDown(address, BlockSize); var end = Alignment.AlignUp(address + (ulong)size, BlockSize); var queries = new List <ulong>(); lock (sync) { requests.Add(request); for (var i = start; i < end; i += BlockSize) { if (!requested.Contains(i)) { requested.Add(i); //Connector.ReadMemory(i, BlockSize, OnMemoryRead); queries.Add(i); } if (!received.Contains(i)) { request.Blocks.Add(i); } } } foreach (var q in queries) { Connector.ReadMemory(q, BlockSize, OnMemoryRead); } Process(); }
public static IntPtr AlignDown(this IntPtr address, uint align) { return(new IntPtr((long)Alignment.AlignDown(address.ToInt64(), align))); }