From b98123d9f884755b32e891f59785dfd279961326 Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Tue, 10 Apr 2018 20:14:41 +0100 Subject: [PATCH] Use SegmentStream.CreateWithoutOwningStream to avoid reading data into memory. To avoid creating copied data in memory (e.g. via MemoryStream), this method can be used to reference offsets on files on disk, reducing memory requirements. --- OpenRA.Mods.Cnc/FileSystem/BigFile.cs | 25 +++++++------------ OpenRA.Mods.Cnc/FileSystem/Pak.cs | 5 ++-- .../PackageLoaders/D2kSoundResources.cs | 4 +-- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/OpenRA.Mods.Cnc/FileSystem/BigFile.cs b/OpenRA.Mods.Cnc/FileSystem/BigFile.cs index a369b4662e..1c8b955a93 100644 --- a/OpenRA.Mods.Cnc/FileSystem/BigFile.cs +++ b/OpenRA.Mods.Cnc/FileSystem/BigFile.cs @@ -13,6 +13,7 @@ using System; using System.Collections.Generic; using System.IO; using OpenRA.FileSystem; +using OpenRA.Primitives; using FS = OpenRA.FileSystem.FileSystem; namespace OpenRA.Mods.Cnc.FileSystem @@ -62,36 +63,28 @@ namespace OpenRA.Mods.Cnc.FileSystem class Entry { - readonly Stream s; - readonly uint offset; - readonly uint size; + public readonly uint Offset; + public readonly uint Size; public readonly string Path; public Entry(Stream s) { - this.s = s; - - offset = s.ReadUInt32(); - size = s.ReadUInt32(); + Offset = s.ReadUInt32(); + Size = s.ReadUInt32(); if (BitConverter.IsLittleEndian) { - offset = int2.Swap(offset); - size = int2.Swap(size); + Offset = int2.Swap(Offset); + Size = int2.Swap(Size); } Path = s.ReadASCIIZ(); } - - public Stream GetData() - { - s.Position = offset; - return new MemoryStream(s.ReadBytes((int)size)); - } } public Stream GetStream(string filename) { - return index[filename].GetData(); + var entry = index[filename]; + return SegmentStream.CreateWithoutOwningStream(s, entry.Offset, (int)entry.Size); } public bool Contains(string filename) diff --git a/OpenRA.Mods.Cnc/FileSystem/Pak.cs b/OpenRA.Mods.Cnc/FileSystem/Pak.cs index 6708968a1c..2091aa5c03 100644 --- a/OpenRA.Mods.Cnc/FileSystem/Pak.cs +++ b/OpenRA.Mods.Cnc/FileSystem/Pak.cs @@ -13,6 +13,7 @@ using System; using System.Collections.Generic; using System.IO; using OpenRA.FileSystem; +using OpenRA.Primitives; using FS = OpenRA.FileSystem.FileSystem; namespace OpenRA.Mods.Cnc.FileSystem @@ -69,9 +70,7 @@ namespace OpenRA.Mods.Cnc.FileSystem if (!index.TryGetValue(filename, out entry)) return null; - stream.Seek(entry.Offset, SeekOrigin.Begin); - var data = stream.ReadBytes((int)entry.Length); - return new MemoryStream(data); + return SegmentStream.CreateWithoutOwningStream(stream, entry.Offset, (int)entry.Length); } public bool Contains(string filename) diff --git a/OpenRA.Mods.D2k/PackageLoaders/D2kSoundResources.cs b/OpenRA.Mods.D2k/PackageLoaders/D2kSoundResources.cs index 514292b39b..927ba3f590 100644 --- a/OpenRA.Mods.D2k/PackageLoaders/D2kSoundResources.cs +++ b/OpenRA.Mods.D2k/PackageLoaders/D2kSoundResources.cs @@ -13,6 +13,7 @@ using System; using System.Collections.Generic; using System.IO; using OpenRA.FileSystem; +using OpenRA.Primitives; namespace OpenRA.Mods.D2k.PackageLoaders { @@ -67,8 +68,7 @@ namespace OpenRA.Mods.D2k.PackageLoaders if (!index.TryGetValue(filename, out e)) return null; - s.Seek(e.Offset, SeekOrigin.Begin); - return new MemoryStream(s.ReadBytes((int)e.Length)); + return SegmentStream.CreateWithoutOwningStream(s, e.Offset, (int)e.Length); } public IReadOnlyPackage OpenPackage(string filename, FileSystem.FileSystem context)