Skip to content

Commit 60e46e5

Browse files
committed
Cache more properties using the field keyword
1 parent 0638998 commit 60e46e5

File tree

7 files changed

+98
-45
lines changed

7 files changed

+98
-45
lines changed

SabreTools.Serialization/Wrappers/AACSMediaKeyBlock.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,21 @@ public string? Version
2727
{
2828
get
2929
{
30+
// Use the cached value, if it exists
31+
if (field != null)
32+
return field;
33+
34+
// Find the type and version record, if possible
3035
var record = Array.Find(Records, r => r.RecordType == RecordType.TypeAndVersion);
3136
if (record is TypeAndVersionRecord tavr)
32-
return tavr.VersionNumber.ToString();
37+
{
38+
field = tavr.VersionNumber.ToString();
39+
return field;
40+
}
3341

34-
return null;
42+
return field;
3543
}
36-
}
44+
} = null;
3745

3846
#endregion
3947

SabreTools.Serialization/Wrappers/CFB.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public byte[] MiniStreamData
4141
return field;
4242

4343
// If there are no directory entries
44-
if (DirectoryEntries == null || DirectoryEntries.Length == 0)
44+
if (DirectoryEntries.Length == 0)
4545
return [];
4646

4747
// Get the mini stream offset from root object
@@ -56,12 +56,12 @@ public byte[] MiniStreamData
5656
/// <summary>
5757
/// Normal sector size in bytes
5858
/// </summary>
59-
public long SectorSize => (long)Math.Pow(2, Header?.SectorShift ?? 0);
59+
public long SectorSize => (long)Math.Pow(2, Header.SectorShift);
6060

6161
/// <summary>
6262
/// Mini sector size in bytes
6363
/// </summary>
64-
public long MiniSectorSize => (long)Math.Pow(2, Header?.MiniSectorShift ?? 0);
64+
public long MiniSectorSize => (long)Math.Pow(2, Header.MiniSectorShift);
6565

6666
#endregion
6767

SabreTools.Serialization/Wrappers/GCF.cs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public long[]? DataBlockOffsets
2424
{
2525
get
2626
{
27-
// Use the cached value if we have it
27+
// Use the cached value, if it exists
2828
if (field != null)
2929
return field;
3030

@@ -48,14 +48,10 @@ public FileInfo[]? Files
4848
{
4949
get
5050
{
51-
// Use the cached value if we have it
51+
// Use the cached value, if it exists
5252
if (field != null)
5353
return field;
5454

55-
// If we don't have a required property
56-
if (Model.DirectoryEntries == null || Model.DirectoryMapEntries == null)
57-
return null;
58-
5955
// Otherwise, scan and build the files
6056
var files = new List<FileInfo>();
6157
for (int i = 0; i < Model.DirectoryEntries.Length; i++)
@@ -82,15 +78,15 @@ public FileInfo[]? Files
8278
Encrypted = directoryEntry.DirectoryFlags.HasFlag(Data.Models.GCF.HL_GCF_FLAG.HL_GCF_FLAG_ENCRYPTED),
8379
#endif
8480
};
85-
var pathParts = new List<string> { Model.DirectoryNames![directoryEntry.NameOffset] ?? string.Empty };
81+
var pathParts = new List<string> { Model.DirectoryNames[directoryEntry.NameOffset] ?? string.Empty };
8682
var blockEntries = new List<Data.Models.GCF.BlockEntry>();
8783

8884
// Traverse the parent tree
8985
uint index = directoryEntry.ParentIndex;
9086
while (index != 0xFFFFFFFF)
9187
{
9288
var parentDirectoryEntry = Model.DirectoryEntries[index];
93-
pathParts.Add(Model.DirectoryNames![parentDirectoryEntry.NameOffset] ?? string.Empty);
89+
pathParts.Add(Model.DirectoryNames[parentDirectoryEntry.NameOffset] ?? string.Empty);
9490
index = parentDirectoryEntry.ParentIndex;
9591
}
9692

SabreTools.Serialization/Wrappers/GZip.cs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,16 @@ public byte[]? ContentCrc32
2727
if (!IsTorrentGZip)
2828
return null;
2929

30+
// Use the cached value, if it exists
31+
if (field != null)
32+
return field;
33+
3034
// CRC-32 is the second packed field
3135
int extraIndex = 0x10;
32-
return Header.ExtraFieldBytes.ReadBytes(ref extraIndex, 0x04);
36+
field = Header.ExtraFieldBytes.ReadBytes(ref extraIndex, 0x04);
37+
return field;
3338
}
34-
}
39+
} = null;
3540

3641
/// <summary>
3742
/// Content MD5 as stored in the extra field
@@ -45,11 +50,16 @@ public byte[]? ContentMd5
4550
if (!IsTorrentGZip)
4651
return null;
4752

53+
// Use the cached value, if it exists
54+
if (field != null)
55+
return field;
56+
4857
// MD5 is the first packed field
4958
int extraIndex = 0x00;
50-
return Header.ExtraFieldBytes.ReadBytes(ref extraIndex, 0x10);
59+
field = Header.ExtraFieldBytes.ReadBytes(ref extraIndex, 0x10);
60+
return field;
5161
}
52-
}
62+
} = null;
5363

5464
/// <summary>
5565
/// Content size as stored in the extra field
@@ -63,11 +73,16 @@ public ulong ContentSize
6373
if (!IsTorrentGZip)
6474
return 0;
6575

66-
// MD5 is the first packed field
67-
int extraIndex = 0x00;
68-
return Header.ExtraFieldBytes.ReadUInt64LittleEndian(ref extraIndex);
76+
// Use the cached value, if it exists
77+
if (field > 0)
78+
return field;
79+
80+
// Size is the third packed field
81+
int extraIndex = 0x14;
82+
field = Header.ExtraFieldBytes.ReadUInt64LittleEndian(ref extraIndex);
83+
return field;
6984
}
70-
}
85+
} = 0;
7186

7287
/// <summary>
7388
/// Offset to the compressed data
@@ -77,6 +92,7 @@ public long DataOffset
7792
{
7893
get
7994
{
95+
// Use the cached value, if it exists
8096
if (field > -1)
8197
return field;
8298

SabreTools.Serialization/Wrappers/LinearExecutable.cs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,49 @@ public partial class LinearExecutable : WrapperBase<Executable>
1717
#region Extension Properties
1818

1919
/// <inheritdoc cref="Executable.ObjectPageMap"/>
20-
public InformationBlock? InformationBlock => Model.InformationBlock;
20+
public InformationBlock InformationBlock => Model.InformationBlock;
2121

2222
/// <inheritdoc cref="Executable.ObjectPageMap"/>
23-
public ObjectPageMapEntry[]? ObjectPageMap => Model.ObjectPageMap;
23+
public ObjectPageMapEntry[] ObjectPageMap => Model.ObjectPageMap;
2424

2525
/// <inheritdoc cref="Executable.ResourceTable"/>
26-
public ResourceTableEntry[]? ResourceTable => Model.ResourceTable;
26+
public ResourceTableEntry[] ResourceTable => Model.ResourceTable;
2727

2828
/// <inheritdoc cref="Executable.Stub"/>
29-
public Data.Models.MSDOS.Executable? Stub => Model.Stub;
29+
public Data.Models.MSDOS.Executable Stub => Model.Stub;
30+
31+
/// <summary>
32+
/// Stub executable data, if it exists
33+
/// </summary>
34+
public byte[] StubExecutableData
35+
{
36+
get
37+
{
38+
lock (_stubExecutableDataLock)
39+
{
40+
// If we already have cached data, just use that immediately
41+
if (field != null)
42+
return field;
43+
44+
// Populate the raw stub executable data based on the source
45+
int endOfStubHeader = 0x40;
46+
int lengthOfStubExecutableData = (int)Stub.Header.NewExeHeaderAddr - endOfStubHeader;
47+
field = ReadRangeFromSource(endOfStubHeader, lengthOfStubExecutableData);
48+
49+
// Cache and return the stub executable data, even if null
50+
return field;
51+
}
52+
}
53+
} = null;
54+
55+
#endregion
56+
57+
#region Instance Variables
58+
59+
/// <summary>
60+
/// Lock object for <see cref="StubExecutableData"/>
61+
/// </summary>
62+
private readonly object _stubExecutableDataLock = new();
3063

3164
#endregion
3265

SabreTools.Serialization/Wrappers/PortableExecutable.cs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,19 @@ public Dictionary<int, object> DebugData
3434
lock (_debugDataLock)
3535
{
3636
// Use the cached data if possible
37-
if (_debugData.Count != 0)
38-
return _debugData;
37+
if (field.Count != 0)
38+
return field;
3939

4040
// If we have no resource table, just return
4141
if (DebugDirectoryTable == null || DebugDirectoryTable.Length == 0)
42-
return _debugData;
42+
return field;
4343

4444
// Otherwise, build and return the cached dictionary
45-
ParseDebugTable();
46-
return _debugData;
45+
field = ParseDebugTable();
46+
return field;
4747
}
4848
}
49-
}
49+
} = [];
5050

5151
/// <inheritdoc cref="Models.PortableExecutable.DebugData.Table.Table"/>
5252
public Data.Models.PortableExecutable.DebugData.Entry[]? DebugDirectoryTable
@@ -822,12 +822,7 @@ public string? AssemblyVersion
822822
#region Instance Variables
823823

824824
/// <summary>
825-
/// Cached debug data
826-
/// </summary>
827-
private readonly Dictionary<int, object> _debugData = [];
828-
829-
/// <summary>
830-
/// Lock object for <see cref="_debugData"/>
825+
/// Lock object for <see cref="DebugData"/>
831826
/// </summary>
832827
private readonly object _debugDataLock = new();
833828

@@ -1200,11 +1195,14 @@ public PortableExecutable(Executable model, Stream data, long offset, long lengt
12001195
/// <summary>
12011196
/// Parse the debug directory table information
12021197
/// </summary>
1203-
private void ParseDebugTable()
1198+
private Dictionary<int, object> ParseDebugTable()
12041199
{
12051200
// If there is no debug table
12061201
if (DebugDirectoryTable == null || DebugDirectoryTable.Length == 0)
1207-
return;
1202+
return [];
1203+
1204+
// Create a new debug table
1205+
Dictionary<int, object> debugData = [];
12081206

12091207
// Loop through all debug table entries
12101208
for (int i = 0; i < DebugDirectoryTable.Length; i++)
@@ -1223,7 +1221,7 @@ private void ParseDebugTable()
12231221
}
12241222
catch (EndOfStreamException)
12251223
{
1226-
return;
1224+
return debugData;
12271225
}
12281226

12291227
// If we have CodeView debug data, try to parse it
@@ -1242,7 +1240,7 @@ private void ParseDebugTable()
12421240
var nb10ProgramDatabase = entryData.ParseNB10ProgramDatabase(ref offset);
12431241
if (nb10ProgramDatabase != null)
12441242
{
1245-
_debugData[i] = nb10ProgramDatabase;
1243+
debugData[i] = nb10ProgramDatabase;
12461244
continue;
12471245
}
12481246
}
@@ -1253,16 +1251,18 @@ private void ParseDebugTable()
12531251
var rsdsProgramDatabase = entryData.ParseRSDSProgramDatabase(ref offset);
12541252
if (rsdsProgramDatabase != null)
12551253
{
1256-
_debugData[i] = rsdsProgramDatabase;
1254+
debugData[i] = rsdsProgramDatabase;
12571255
continue;
12581256
}
12591257
}
12601258
}
12611259
else
12621260
{
1263-
_debugData[i] = entryData;
1261+
debugData[i] = entryData;
12641262
}
12651263
}
1264+
1265+
return debugData;
12661266
}
12671267

12681268
#endregion

SabreTools.Serialization/Wrappers/VPK.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public string[]? ArchiveFilenames
2222
{
2323
get
2424
{
25-
// Use the cached value if we have it
25+
// Use the cached value, if it exists
2626
if (field != null)
2727
return field;
2828

0 commit comments

Comments
 (0)