diff options
Diffstat (limited to 'Ryujinx.Memory/Range')
| -rw-r--r-- | Ryujinx.Memory/Range/MultiRange.cs | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/Ryujinx.Memory/Range/MultiRange.cs b/Ryujinx.Memory/Range/MultiRange.cs index b40daa8a..3d505c7c 100644 --- a/Ryujinx.Memory/Range/MultiRange.cs +++ b/Ryujinx.Memory/Range/MultiRange.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace Ryujinx.Memory.Range { @@ -76,6 +77,53 @@ namespace Ryujinx.Memory.Range } /// <summary> + /// Gets a slice of the multi-range. + /// </summary> + /// <param name="offset">Offset of the slice into the multi-range in bytes</param> + /// <param name="size">Size of the slice in bytes</param> + /// <returns>A new multi-range representing the given slice of this one</returns> + public MultiRange GetSlice(ulong offset, ulong size) + { + if (HasSingleRange) + { + if (_singleRange.Size - offset < size) + { + throw new ArgumentOutOfRangeException(nameof(size)); + } + + return new MultiRange(_singleRange.Address + offset, size); + } + else + { + var ranges = new List<MemoryRange>(); + + foreach (MemoryRange range in _ranges) + { + if ((long)offset <= 0) + { + ranges.Add(new MemoryRange(range.Address, Math.Min(size, range.Size))); + size -= range.Size; + } + else if (offset < range.Size) + { + ulong sliceSize = Math.Min(size, range.Size - offset); + ranges.Add(new MemoryRange(range.Address + offset, sliceSize)); + size -= sliceSize; + } + + if ((long)size <= 0) + { + break; + } + + offset -= range.Size; + } + + return new MultiRange(ranges.ToArray()); + } + } + + /// <summary> /// Gets the physical region at the specified index. /// </summary> /// <param name="index">Index of the physical region</param> |
