/// <summary> /// Writes data into an existing (single) segment. /// </summary> /// <param name="address">The address to write to.</param> /// <param name="bytes">The bytes to write.</param> internal void SetData(ModuleAddress address, byte[] bytes) { var segment = GetSegment(address); segment.SetData(address, bytes); DataChanged?.Invoke(this, new ModuleDataChangedEventArgs(segment)); }
public DataSegment(ModuleAddress start, byte[] data) { if (data.Length > 0xff) { throw new ArgumentOutOfRangeException("Data segments cannot (currently) be more than 255 bytes long"); } (Start, Data, End) = (start, data, start + data.Length); }
public byte[] GetData(ModuleAddress address, int size) { // Normal "we don't really mean it" sizing. if (size >= 0x100) { size -= 0x80; } var segment = GetSegment(address); byte[] ret = new byte[size]; for (int i = 0; i < size; i++) { // This handles overflow from 0x7f to 0x100 appropriately. ret[i] = segment[address + i]; } return(ret); }
public void Populate(ModuleAddress address, byte[] data) { if (data.Length >= 0x100) { throw new ArgumentException("Data size must be less than 0x100"); } var segment = new DataSegment(address, data); lock (sync) { int index = segments.BinarySearch(segment, DataSegment.AddressComparer); if (index >= 0) { throw new ArgumentException($"Segment already exists for address {address}"); } segments.Insert(~index, segment); } DataChanged?.Invoke(this, new ModuleDataChangedEventArgs(segment)); }
public DataSegment?GetSegmentOrNull(ModuleAddress address) { lock (sync) { // Binary search on start addresses, expecting not to find an exact match necessarily. // TODO: This shouldn't be necessary, surely int lowInc = 0; int highExc = segments.Count; while (lowInc < highExc) { int candidate = (lowInc + highExc) / 2; ModuleAddress candidateAddress = segments[candidate].Start; var comparison = candidateAddress.CompareTo(address); // Exact match! Great, can exit immediately. if (comparison == 0) { return(segments[candidate]); } else if (comparison < 0) { lowInc = candidate + 1; } else { highExc = candidate; } } // No exact match, but it's possible (likely!) that we found a match in "lowInc-1", with // a start address greater than the target, but which contains the target. if (lowInc > 0) { var segment = segments[lowInc - 1]; if (segment.Contains(address)) { return(segment); } } return(null); } }
public byte this[ModuleAddress address] { get => Data[GetOffset(address)];
public bool Contains(ModuleAddress other) => other.CompareTo(Start) >= 0 && other.CompareTo(End) < 0;
public byte GetAddressValue(ModuleAddress address) => GetSegment(address)[address];
public DataSegment GetSegment(ModuleAddress address) => GetSegmentOrNull(address) ?? throw new ArgumentException($"No data found for {address}");
public bool HasData(ModuleAddress address) => GetSegmentOrNull(address) != null;