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.
This commit is contained in:
@@ -13,6 +13,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using OpenRA.FileSystem;
|
using OpenRA.FileSystem;
|
||||||
|
using OpenRA.Primitives;
|
||||||
using FS = OpenRA.FileSystem.FileSystem;
|
using FS = OpenRA.FileSystem.FileSystem;
|
||||||
|
|
||||||
namespace OpenRA.Mods.Cnc.FileSystem
|
namespace OpenRA.Mods.Cnc.FileSystem
|
||||||
@@ -62,36 +63,28 @@ namespace OpenRA.Mods.Cnc.FileSystem
|
|||||||
|
|
||||||
class Entry
|
class Entry
|
||||||
{
|
{
|
||||||
readonly Stream s;
|
public readonly uint Offset;
|
||||||
readonly uint offset;
|
public readonly uint Size;
|
||||||
readonly uint size;
|
|
||||||
public readonly string Path;
|
public readonly string Path;
|
||||||
|
|
||||||
public Entry(Stream s)
|
public Entry(Stream s)
|
||||||
{
|
{
|
||||||
this.s = s;
|
Offset = s.ReadUInt32();
|
||||||
|
Size = s.ReadUInt32();
|
||||||
offset = s.ReadUInt32();
|
|
||||||
size = s.ReadUInt32();
|
|
||||||
if (BitConverter.IsLittleEndian)
|
if (BitConverter.IsLittleEndian)
|
||||||
{
|
{
|
||||||
offset = int2.Swap(offset);
|
Offset = int2.Swap(Offset);
|
||||||
size = int2.Swap(size);
|
Size = int2.Swap(Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
Path = s.ReadASCIIZ();
|
Path = s.ReadASCIIZ();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Stream GetData()
|
|
||||||
{
|
|
||||||
s.Position = offset;
|
|
||||||
return new MemoryStream(s.ReadBytes((int)size));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Stream GetStream(string filename)
|
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)
|
public bool Contains(string filename)
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using OpenRA.FileSystem;
|
using OpenRA.FileSystem;
|
||||||
|
using OpenRA.Primitives;
|
||||||
using FS = OpenRA.FileSystem.FileSystem;
|
using FS = OpenRA.FileSystem.FileSystem;
|
||||||
|
|
||||||
namespace OpenRA.Mods.Cnc.FileSystem
|
namespace OpenRA.Mods.Cnc.FileSystem
|
||||||
@@ -69,9 +70,7 @@ namespace OpenRA.Mods.Cnc.FileSystem
|
|||||||
if (!index.TryGetValue(filename, out entry))
|
if (!index.TryGetValue(filename, out entry))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
stream.Seek(entry.Offset, SeekOrigin.Begin);
|
return SegmentStream.CreateWithoutOwningStream(stream, entry.Offset, (int)entry.Length);
|
||||||
var data = stream.ReadBytes((int)entry.Length);
|
|
||||||
return new MemoryStream(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Contains(string filename)
|
public bool Contains(string filename)
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using OpenRA.FileSystem;
|
using OpenRA.FileSystem;
|
||||||
|
using OpenRA.Primitives;
|
||||||
|
|
||||||
namespace OpenRA.Mods.D2k.PackageLoaders
|
namespace OpenRA.Mods.D2k.PackageLoaders
|
||||||
{
|
{
|
||||||
@@ -67,8 +68,7 @@ namespace OpenRA.Mods.D2k.PackageLoaders
|
|||||||
if (!index.TryGetValue(filename, out e))
|
if (!index.TryGetValue(filename, out e))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
s.Seek(e.Offset, SeekOrigin.Begin);
|
return SegmentStream.CreateWithoutOwningStream(s, e.Offset, (int)e.Length);
|
||||||
return new MemoryStream(s.ReadBytes((int)e.Length));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IReadOnlyPackage OpenPackage(string filename, FileSystem.FileSystem context)
|
public IReadOnlyPackage OpenPackage(string filename, FileSystem.FileSystem context)
|
||||||
|
|||||||
Reference in New Issue
Block a user