/ src / Ryujinx.Memory / Range / MemoryRange.cs
MemoryRange.cs
 1  namespace Ryujinx.Memory.Range
 2  {
 3      /// <summary>
 4      /// Range of memory composed of an address and size.
 5      /// </summary>
 6      public readonly record struct MemoryRange
 7      {
 8          /// <summary>
 9          /// Special address value used to indicate than an address is invalid.
10          /// </summary>
11          internal const ulong InvalidAddress = ulong.MaxValue;
12  
13          /// <summary>
14          /// An empty memory range, with a null address and zero size.
15          /// </summary>
16          public static MemoryRange Empty => new(0UL, 0);
17  
18          /// <summary>
19          /// Start address of the range.
20          /// </summary>
21          public ulong Address { get; }
22  
23          /// <summary>
24          /// Size of the range in bytes.
25          /// </summary>
26          public ulong Size { get; }
27  
28          /// <summary>
29          /// Address where the range ends (exclusive).
30          /// </summary>
31          public ulong EndAddress => Address + Size;
32  
33          /// <summary>
34          /// Creates a new memory range with the specified address and size.
35          /// </summary>
36          /// <param name="address">Start address</param>
37          /// <param name="size">Size in bytes</param>
38          public MemoryRange(ulong address, ulong size)
39          {
40              Address = address;
41              Size = size;
42          }
43  
44          /// <summary>
45          /// Checks if the range overlaps with another.
46          /// </summary>
47          /// <param name="other">The other range to check for overlap</param>
48          /// <returns>True if the ranges overlap, false otherwise</returns>
49          public bool OverlapsWith(MemoryRange other)
50          {
51              ulong thisAddress = Address;
52              ulong thisEndAddress = EndAddress;
53              ulong otherAddress = other.Address;
54              ulong otherEndAddress = other.EndAddress;
55  
56              // If any of the ranges if invalid (address + size overflows),
57              // then they are never considered to overlap.
58              if (thisEndAddress < thisAddress || otherEndAddress < otherAddress)
59              {
60                  return false;
61              }
62  
63              return thisAddress < otherEndAddress && otherAddress < thisEndAddress;
64          }
65  
66          /// <summary>
67          /// Checks if a given sub-range of memory is invalid.
68          /// Those are used to represent unmapped memory regions (holes in the region mapping).
69          /// </summary>
70          /// <param name="subRange">Memory range to check</param>
71          /// <returns>True if the memory range is considered invalid, false otherwise</returns>
72          internal static bool IsInvalid(ref MemoryRange subRange)
73          {
74              return subRange.Address == InvalidAddress;
75          }
76  
77          /// <summary>
78          /// Returns a string summary of the memory range.
79          /// </summary>
80          /// <returns>A string summary of the memory range</returns>
81          public override string ToString()
82          {
83              if (Address == InvalidAddress)
84              {
85                  return $"[Unmapped 0x{Size:X}]";
86              }
87  
88              return $"[0x{Address:X}, 0x{EndAddress:X})";
89          }
90      }
91  }