add methods Ryyjinx.Common EmbeddedResources and SteamUtils
This commit is contained in:
parent
27c50de93d
commit
0c7327cd52
2 changed files with 81 additions and 3 deletions
|
@ -1,5 +1,6 @@
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
@ -23,6 +24,13 @@ namespace Ryujinx.Common
|
||||||
return Read(assembly, path);
|
return Read(assembly, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IMemoryOwner<byte> ReadRentedMemory(string filename)
|
||||||
|
{
|
||||||
|
var (assembly, path) = ResolveManifestPath(filename);
|
||||||
|
|
||||||
|
return ReadRentedMemory(assembly, path);
|
||||||
|
}
|
||||||
|
|
||||||
public static Task<byte[]> ReadAsync(string filename)
|
public static Task<byte[]> ReadAsync(string filename)
|
||||||
{
|
{
|
||||||
var (assembly, path) = ResolveManifestPath(filename);
|
var (assembly, path) = ResolveManifestPath(filename);
|
||||||
|
@ -41,6 +49,15 @@ namespace Ryujinx.Common
|
||||||
return StreamUtils.StreamToBytes(stream);
|
return StreamUtils.StreamToBytes(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IMemoryOwner<byte> ReadRentedMemory(Assembly assembly, string filename)
|
||||||
|
{
|
||||||
|
using var stream = GetStream(assembly, filename);
|
||||||
|
|
||||||
|
return stream is null
|
||||||
|
? null
|
||||||
|
: StreamUtils.StreamToRentedMemory(stream);
|
||||||
|
}
|
||||||
|
|
||||||
public async static Task<byte[]> ReadAsync(Assembly assembly, string filename)
|
public async static Task<byte[]> ReadAsync(Assembly assembly, string filename)
|
||||||
{
|
{
|
||||||
using var stream = GetStream(assembly, filename);
|
using var stream = GetStream(assembly, filename);
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
using Microsoft.IO;
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
|
using System.Buffers;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -9,12 +11,50 @@ namespace Ryujinx.Common.Utilities
|
||||||
{
|
{
|
||||||
public static byte[] StreamToBytes(Stream input)
|
public static byte[] StreamToBytes(Stream input)
|
||||||
{
|
{
|
||||||
using MemoryStream stream = MemoryStreamManager.Shared.GetStream();
|
using RecyclableMemoryStream output = StreamToRecyclableMemoryStream(input);
|
||||||
|
|
||||||
|
return output.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
input.CopyTo(stream);
|
public static IMemoryOwner<byte> StreamToRentedMemory(Stream input)
|
||||||
|
{
|
||||||
|
if (input is MemoryStream inputMemoryStream)
|
||||||
|
{
|
||||||
|
return MemoryStreamToRentedMemory(inputMemoryStream);
|
||||||
|
}
|
||||||
|
else if (input.CanSeek)
|
||||||
|
{
|
||||||
|
long bytesExpected = input.Length;
|
||||||
|
|
||||||
return stream.ToArray();
|
IMemoryOwner<byte> ownedMemory = ByteMemoryPool.Rent(bytesExpected);
|
||||||
|
|
||||||
|
var destSpan = ownedMemory.Memory.Span;
|
||||||
|
|
||||||
|
int totalBytesRead = 0;
|
||||||
|
|
||||||
|
while (totalBytesRead < bytesExpected)
|
||||||
|
{
|
||||||
|
int bytesRead = input.Read(destSpan[totalBytesRead..]);
|
||||||
|
|
||||||
|
if (bytesRead == 0)
|
||||||
|
{
|
||||||
|
ownedMemory.Dispose();
|
||||||
|
|
||||||
|
throw new IOException($"Tried reading {bytesExpected} but the stream closed after reading {totalBytesRead}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
totalBytesRead += bytesRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ownedMemory;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If input is (non-seekable) then copy twice: first into a RecyclableMemoryStream, then to a rented IMemoryOwner<byte>.
|
||||||
|
using RecyclableMemoryStream output = StreamToRecyclableMemoryStream(input);
|
||||||
|
|
||||||
|
return MemoryStreamToRentedMemory(output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<byte[]> StreamToBytesAsync(Stream input, CancellationToken cancellationToken = default)
|
public static async Task<byte[]> StreamToBytesAsync(Stream input, CancellationToken cancellationToken = default)
|
||||||
|
@ -25,5 +65,26 @@ namespace Ryujinx.Common.Utilities
|
||||||
|
|
||||||
return stream.ToArray();
|
return stream.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IMemoryOwner<byte> MemoryStreamToRentedMemory(MemoryStream input)
|
||||||
|
{
|
||||||
|
input.Position = 0;
|
||||||
|
|
||||||
|
IMemoryOwner<byte> ownedMemory = ByteMemoryPool.Rent(input.Length);
|
||||||
|
|
||||||
|
// Discard the return value because we assume reading a MemoryStream always succeeds completely.
|
||||||
|
_ = input.Read(ownedMemory.Memory.Span);
|
||||||
|
|
||||||
|
return ownedMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RecyclableMemoryStream StreamToRecyclableMemoryStream(Stream input)
|
||||||
|
{
|
||||||
|
RecyclableMemoryStream stream = MemoryStreamManager.Shared.GetStream();
|
||||||
|
|
||||||
|
input.CopyTo(stream);
|
||||||
|
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue