BytesReadOnlySequenceSegment.cs 2.6 KB

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