Example #1
0
        /// <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));
        }
Example #2
0
 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);
 }
Example #3
0
        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);
        }
Example #4
0
        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));
        }
Example #5
0
 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);
     }
 }
Example #6
0
 public byte this[ModuleAddress address]
 {
     get => Data[GetOffset(address)];
Example #7
0
 public bool Contains(ModuleAddress other) =>
 other.CompareTo(Start) >= 0 && other.CompareTo(End) < 0;
Example #8
0
 public byte GetAddressValue(ModuleAddress address) => GetSegment(address)[address];
Example #9
0
 public DataSegment GetSegment(ModuleAddress address) =>
 GetSegmentOrNull(address) ?? throw new ArgumentException($"No data found for {address}");
Example #10
0
 public bool HasData(ModuleAddress address) => GetSegmentOrNull(address) != null;