MemoryStreamManager.cs
1 using Microsoft.IO; 2 using System; 3 4 namespace Ryujinx.Common.Memory 5 { 6 public static class MemoryStreamManager 7 { 8 private static readonly RecyclableMemoryStreamManager _shared = new(); 9 10 /// <summary> 11 /// We don't expose the <c>RecyclableMemoryStreamManager</c> directly because version 2.x 12 /// returns them as <c>MemoryStream</c>. This Shared class is here to a) offer only the GetStream() versions we use 13 /// and b) return them as <c>RecyclableMemoryStream</c> so we don't have to cast. 14 /// </summary> 15 public static class Shared 16 { 17 /// <summary> 18 /// Retrieve a new <c>MemoryStream</c> object with no tag and a default initial capacity. 19 /// </summary> 20 /// <returns>A <c>RecyclableMemoryStream</c></returns> 21 public static RecyclableMemoryStream GetStream() 22 => new(_shared); 23 24 /// <summary> 25 /// Retrieve a new <c>MemoryStream</c> object with the contents copied from the provided 26 /// buffer. The provided buffer is not wrapped or used after construction. 27 /// </summary> 28 /// <remarks>The new stream's position is set to the beginning of the stream when returned.</remarks> 29 /// <param name="buffer">The byte buffer to copy data from</param> 30 /// <returns>A <c>RecyclableMemoryStream</c></returns> 31 public static RecyclableMemoryStream GetStream(byte[] buffer) 32 => GetStream(Guid.NewGuid(), null, buffer, 0, buffer.Length); 33 34 /// <summary> 35 /// Retrieve a new <c>MemoryStream</c> object with the given tag and with contents copied from the provided 36 /// buffer. The provided buffer is not wrapped or used after construction. 37 /// </summary> 38 /// <remarks>The new stream's position is set to the beginning of the stream when returned.</remarks> 39 /// <param name="buffer">The byte buffer to copy data from</param> 40 /// <returns>A <c>RecyclableMemoryStream</c></returns> 41 public static RecyclableMemoryStream GetStream(ReadOnlySpan<byte> buffer) 42 => GetStream(Guid.NewGuid(), null, buffer); 43 44 /// <summary> 45 /// Retrieve a new <c>RecyclableMemoryStream</c> object with the given tag and with contents copied from the provided 46 /// buffer. The provided buffer is not wrapped or used after construction. 47 /// </summary> 48 /// <remarks>The new stream's position is set to the beginning of the stream when returned.</remarks> 49 /// <param name="id">A unique identifier which can be used to trace usages of the stream</param> 50 /// <param name="tag">A tag which can be used to track the source of the stream</param> 51 /// <param name="buffer">The byte buffer to copy data from</param> 52 /// <returns>A <c>RecyclableMemoryStream</c></returns> 53 public static RecyclableMemoryStream GetStream(Guid id, string tag, ReadOnlySpan<byte> buffer) 54 { 55 RecyclableMemoryStream stream = null; 56 try 57 { 58 stream = new RecyclableMemoryStream(_shared, id, tag, buffer.Length); 59 stream.Write(buffer); 60 stream.Position = 0; 61 return stream; 62 } 63 catch 64 { 65 stream?.Dispose(); 66 throw; 67 } 68 } 69 70 /// <summary> 71 /// Retrieve a new <c>RecyclableMemoryStream</c> object with the given tag and with contents copied from the provided 72 /// buffer. The provided buffer is not wrapped or used after construction. 73 /// </summary> 74 /// <remarks>The new stream's position is set to the beginning of the stream when returned</remarks> 75 /// <param name="id">A unique identifier which can be used to trace usages of the stream</param> 76 /// <param name="tag">A tag which can be used to track the source of the stream</param> 77 /// <param name="buffer">The byte buffer to copy data from</param> 78 /// <param name="offset">The offset from the start of the buffer to copy from</param> 79 /// <param name="count">The number of bytes to copy from the buffer</param> 80 /// <returns>A <c>RecyclableMemoryStream</c></returns> 81 public static RecyclableMemoryStream GetStream(Guid id, string tag, byte[] buffer, int offset, int count) 82 { 83 RecyclableMemoryStream stream = null; 84 try 85 { 86 stream = new RecyclableMemoryStream(_shared, id, tag, count); 87 stream.Write(buffer, offset, count); 88 stream.Position = 0; 89 return stream; 90 } 91 catch 92 { 93 stream?.Dispose(); 94 throw; 95 } 96 } 97 } 98 } 99 }