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 }