Skip to content

Commit

Permalink
Allow lazy loading of bunde entry data
Browse files Browse the repository at this point in the history
  • Loading branch information
ElektroKill committed Jun 17, 2023
1 parent 37fb18b commit d3d7223
Showing 1 changed file with 24 additions and 9 deletions.
33 changes: 24 additions & 9 deletions dnSpy/dnSpy.Contracts.DnSpy/Documents/Bundles/BundleEntry.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Threading;
using dnlib.IO;

namespace dnSpy.Contracts.Documents {
/// <summary>
/// Represents one entry in a <see cref="SingleFileBundle"/>
/// </summary>
public sealed class BundleEntry {
byte[]? data;
DataReader reader;

/// <summary>
/// Type of the entry <seealso cref="BundleFileType"/>
/// </summary>
Expand All @@ -31,12 +35,25 @@ public sealed class BundleEntry {
/// <summary>
/// The raw data of the entry.
/// </summary>
public byte[] Data { get; }
public byte[] Data {
get {
if (data is not null)
return data;
Interlocked.CompareExchange(ref data, reader.ReadRemainingBytes(), null);
return data;
}
}

BundleEntry(BundleFileType type, string relativePath, byte[] data) {
Type = type;
RelativePath = relativePath.Replace('/', '\\');
Data = data;
this.data = data;
}

BundleEntry(BundleFileType type, string relativePath, DataReader reader) {
Type = type;
RelativePath = relativePath.Replace('/', '\\');
this.reader = reader;
}

internal static IReadOnlyList<BundleEntry> ReadEntries(DataReader reader, int count, bool allowCompression) {
Expand All @@ -49,18 +66,16 @@ internal static IReadOnlyList<BundleEntry> ReadEntries(DataReader reader, int co
var type = (BundleFileType)reader.ReadByte();
string path = reader.ReadSerializedString();

res[i] = new BundleEntry(type, path, ReadEntryData(reader, offset, size, compSize));
if (compSize == 0)
res[i] = new BundleEntry(type, path, reader.Slice((uint)offset, (uint)size));
else
res[i] = new BundleEntry(type, path, ReadCompressedEntryData(reader, offset, size, compSize));
}

return res;
}

static byte[] ReadEntryData(DataReader reader, long offset, long size, long compSize) {
if (compSize == 0) {
reader.Position = (uint)offset;
return reader.ReadBytes((int)size);
}

static byte[] ReadCompressedEntryData(DataReader reader, long offset, long size, long compSize) {
using (var decompressedStream = new MemoryStream((int)size)) {
using (var compressedStream = reader.Slice((uint)offset, (uint)compSize).AsStream()) {
using (var deflateStream = new DeflateStream(compressedStream, CompressionMode.Decompress)) {
Expand Down

0 comments on commit d3d7223

Please sign in to comment.