diff --git a/osu.Android.props b/osu.Android.props
index c28085557e..116c7dbfcd 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -52,7 +52,7 @@
-
+
diff --git a/osu.Game/IO/Archives/ZipArchiveReader.cs b/osu.Game/IO/Archives/ZipArchiveReader.cs
index 80dfa104f3..ae2b85da51 100644
--- a/osu.Game/IO/Archives/ZipArchiveReader.cs
+++ b/osu.Game/IO/Archives/ZipArchiveReader.cs
@@ -1,11 +1,15 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using System.Buffers;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using Microsoft.Toolkit.HighPerformance;
+using osu.Framework.Extensions;
using osu.Framework.IO.Stores;
using SharpCompress.Archives.Zip;
+using SixLabors.ImageSharp.Memory;
namespace osu.Game.IO.Archives
{
@@ -27,15 +31,12 @@ namespace osu.Game.IO.Archives
if (entry == null)
throw new FileNotFoundException();
- // allow seeking
- MemoryStream copy = new MemoryStream();
+ var owner = MemoryAllocator.Default.Allocate((int)entry.Size);
using (Stream s = entry.OpenEntryStream())
- s.CopyTo(copy);
+ s.ReadToFill(owner.Memory.Span);
- copy.Position = 0;
-
- return copy;
+ return new MemoryOwnerMemoryStream(owner);
}
public override void Dispose()
@@ -45,5 +46,48 @@ namespace osu.Game.IO.Archives
}
public override IEnumerable Filenames => archive.Entries.Select(e => e.Key).ExcludeSystemFileNames();
+
+ private class MemoryOwnerMemoryStream : Stream
+ {
+ private readonly IMemoryOwner owner;
+ private readonly Stream stream;
+
+ public MemoryOwnerMemoryStream(IMemoryOwner owner)
+ {
+ this.owner = owner;
+
+ stream = owner.Memory.AsStream();
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ owner?.Dispose();
+ base.Dispose(disposing);
+ }
+
+ public override void Flush() => stream.Flush();
+
+ public override int Read(byte[] buffer, int offset, int count) => stream.Read(buffer, offset, count);
+
+ public override long Seek(long offset, SeekOrigin origin) => stream.Seek(offset, origin);
+
+ public override void SetLength(long value) => stream.SetLength(value);
+
+ public override void Write(byte[] buffer, int offset, int count) => stream.Write(buffer, offset, count);
+
+ public override bool CanRead => stream.CanRead;
+
+ public override bool CanSeek => stream.CanSeek;
+
+ public override bool CanWrite => stream.CanWrite;
+
+ public override long Length => stream.Length;
+
+ public override long Position
+ {
+ get => stream.Position;
+ set => stream.Position = value;
+ }
+ }
}
}
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 79cfd7c917..eb47d0468f 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -29,13 +29,14 @@
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/osu.iOS.props b/osu.iOS.props
index b1ba64beba..ccecad6f82 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -61,7 +61,7 @@
-
+
@@ -84,7 +84,7 @@
-
+