/ src / Ryujinx.Memory / BytesReadOnlySequenceSegment.cs
BytesReadOnlySequenceSegment.cs
 1  using System;
 2  using System.Buffers;
 3  using System.Runtime.InteropServices;
 4  
 5  namespace Ryujinx.Memory
 6  {
 7      /// <summary>
 8      /// A concrete implementation of <seealso cref="ReadOnlySequence{Byte}"/>,
 9      /// with methods to help build a full sequence.
10      /// </summary>
11      public sealed class BytesReadOnlySequenceSegment : ReadOnlySequenceSegment<byte>
12      {
13          public BytesReadOnlySequenceSegment(Memory<byte> memory) => Memory = memory;
14  
15          public BytesReadOnlySequenceSegment Append(Memory<byte> memory)
16          {
17              var nextSegment = new BytesReadOnlySequenceSegment(memory)
18              {
19                  RunningIndex = RunningIndex + Memory.Length
20              };
21  
22              Next = nextSegment;
23  
24              return nextSegment;
25          }
26  
27          /// <summary>
28          /// Attempts to determine if the current <seealso cref="Memory{Byte}"/> and <paramref name="other"/> are contiguous.
29          /// Only works if both were created by a <seealso cref="NativeMemoryManager{Byte}"/>.
30          /// </summary>
31          /// <param name="other">The segment to check if continuous with the current one</param>
32          /// <param name="contiguousStart">The starting address of the contiguous segment</param>
33          /// <param name="contiguousSize">The size of the contiguous segment</param>
34          /// <returns>True if the segments are contiguous, otherwise false</returns>
35          public unsafe bool IsContiguousWith(Memory<byte> other, out nuint contiguousStart, out int contiguousSize)
36          {
37              if (MemoryMarshal.TryGetMemoryManager<byte, NativeMemoryManager<byte>>(Memory, out var thisMemoryManager) &&
38                  MemoryMarshal.TryGetMemoryManager<byte, NativeMemoryManager<byte>>(other, out var otherMemoryManager) &&
39                  thisMemoryManager.Pointer + thisMemoryManager.Length == otherMemoryManager.Pointer)
40              {
41                  contiguousStart = (nuint)thisMemoryManager.Pointer;
42                  contiguousSize = thisMemoryManager.Length + otherMemoryManager.Length;
43                  return true;
44              }
45              else
46              {
47                  contiguousStart = 0;
48                  contiguousSize = 0;
49                  return false;
50              }
51          }
52  
53          /// <summary>
54          /// Replaces the current <seealso cref="Memory{Byte}"/> value with the one provided.
55          /// </summary>
56          /// <param name="memory">The new segment to hold in this <seealso cref="BytesReadOnlySequenceSegment"/></param>
57          public void Replace(Memory<byte> memory)
58              => Memory = memory;
59      }
60  }