From e65c73785e591db68b7baffacb1c109247dae8c6 Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Fri, 9 Sep 2016 18:53:11 +0100 Subject: [PATCH] Allow MixFile to support all stream types again, not just FileStream. --- OpenRA.Game/FileSystem/MixFile.cs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/OpenRA.Game/FileSystem/MixFile.cs b/OpenRA.Game/FileSystem/MixFile.cs index 7a36fb7e15..8a8f7b0d6e 100644 --- a/OpenRA.Game/FileSystem/MixFile.cs +++ b/OpenRA.Game/FileSystem/MixFile.cs @@ -191,9 +191,22 @@ namespace OpenRA.FileSystem public Stream GetContent(PackageEntry entry) { Stream parentStream; - var offset = dataStart + entry.Offset + SegmentStream.GetOverallNestedOffset(s, out parentStream); - var path = ((FileStream)parentStream).Name; - return new SegmentStream(File.OpenRead(path), offset, entry.Length); + var baseOffset = dataStart + entry.Offset; + var nestedOffset = baseOffset + SegmentStream.GetOverallNestedOffset(s, out parentStream); + + // Special case FileStream - instead of creating an in-memory copy, + // just reference the portion of the on-disk file that we need to save memory. + // We use GetType instead of 'is' here since we can't handle any derived classes of FileStream. + if (parentStream.GetType() == typeof(FileStream)) + { + var path = ((FileStream)parentStream).Name; + return new SegmentStream(File.OpenRead(path), nestedOffset, entry.Length); + } + + // For all other streams, create a copy in memory. + // This uses more memory but is the only way in general to ensure the returned streams won't clash. + s.Seek(baseOffset, SeekOrigin.Begin); + return new MemoryStream(s.ReadBytes((int)entry.Length)); } public Stream GetStream(string filename)