mirror of
https://github.com/SabreTools/SabreTools.Serialization.git
synced 2026-07-08 18:06:41 +00:00
Cache more properties using the field keyword
This commit is contained in:
@@ -27,13 +27,21 @@ namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
get
|
||||
{
|
||||
// Use the cached value, if it exists
|
||||
if (field != null)
|
||||
return field;
|
||||
|
||||
// Find the type and version record, if possible
|
||||
var record = Array.Find(Records, r => r.RecordType == RecordType.TypeAndVersion);
|
||||
if (record is TypeAndVersionRecord tavr)
|
||||
return tavr.VersionNumber.ToString();
|
||||
{
|
||||
field = tavr.VersionNumber.ToString();
|
||||
return field;
|
||||
}
|
||||
|
||||
return null;
|
||||
return field;
|
||||
}
|
||||
}
|
||||
} = null;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
return field;
|
||||
|
||||
// If there are no directory entries
|
||||
if (DirectoryEntries == null || DirectoryEntries.Length == 0)
|
||||
if (DirectoryEntries.Length == 0)
|
||||
return [];
|
||||
|
||||
// Get the mini stream offset from root object
|
||||
@@ -56,12 +56,12 @@ namespace SabreTools.Serialization.Wrappers
|
||||
/// <summary>
|
||||
/// Normal sector size in bytes
|
||||
/// </summary>
|
||||
public long SectorSize => (long)Math.Pow(2, Header?.SectorShift ?? 0);
|
||||
public long SectorSize => (long)Math.Pow(2, Header.SectorShift);
|
||||
|
||||
/// <summary>
|
||||
/// Mini sector size in bytes
|
||||
/// </summary>
|
||||
public long MiniSectorSize => (long)Math.Pow(2, Header?.MiniSectorShift ?? 0);
|
||||
public long MiniSectorSize => (long)Math.Pow(2, Header.MiniSectorShift);
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
get
|
||||
{
|
||||
// Use the cached value if we have it
|
||||
// Use the cached value, if it exists
|
||||
if (field != null)
|
||||
return field;
|
||||
|
||||
@@ -48,14 +48,10 @@ namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
get
|
||||
{
|
||||
// Use the cached value if we have it
|
||||
// Use the cached value, if it exists
|
||||
if (field != null)
|
||||
return field;
|
||||
|
||||
// If we don't have a required property
|
||||
if (Model.DirectoryEntries == null || Model.DirectoryMapEntries == null)
|
||||
return null;
|
||||
|
||||
// Otherwise, scan and build the files
|
||||
var files = new List<FileInfo>();
|
||||
for (int i = 0; i < Model.DirectoryEntries.Length; i++)
|
||||
@@ -82,7 +78,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
Encrypted = directoryEntry.DirectoryFlags.HasFlag(Data.Models.GCF.HL_GCF_FLAG.HL_GCF_FLAG_ENCRYPTED),
|
||||
#endif
|
||||
};
|
||||
var pathParts = new List<string> { Model.DirectoryNames![directoryEntry.NameOffset] ?? string.Empty };
|
||||
var pathParts = new List<string> { Model.DirectoryNames[directoryEntry.NameOffset] ?? string.Empty };
|
||||
var blockEntries = new List<Data.Models.GCF.BlockEntry>();
|
||||
|
||||
// Traverse the parent tree
|
||||
@@ -90,7 +86,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
while (index != 0xFFFFFFFF)
|
||||
{
|
||||
var parentDirectoryEntry = Model.DirectoryEntries[index];
|
||||
pathParts.Add(Model.DirectoryNames![parentDirectoryEntry.NameOffset] ?? string.Empty);
|
||||
pathParts.Add(Model.DirectoryNames[parentDirectoryEntry.NameOffset] ?? string.Empty);
|
||||
index = parentDirectoryEntry.ParentIndex;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,11 +27,16 @@ namespace SabreTools.Serialization.Wrappers
|
||||
if (!IsTorrentGZip)
|
||||
return null;
|
||||
|
||||
// Use the cached value, if it exists
|
||||
if (field != null)
|
||||
return field;
|
||||
|
||||
// CRC-32 is the second packed field
|
||||
int extraIndex = 0x10;
|
||||
return Header.ExtraFieldBytes.ReadBytes(ref extraIndex, 0x04);
|
||||
field = Header.ExtraFieldBytes.ReadBytes(ref extraIndex, 0x04);
|
||||
return field;
|
||||
}
|
||||
}
|
||||
} = null;
|
||||
|
||||
/// <summary>
|
||||
/// Content MD5 as stored in the extra field
|
||||
@@ -45,11 +50,16 @@ namespace SabreTools.Serialization.Wrappers
|
||||
if (!IsTorrentGZip)
|
||||
return null;
|
||||
|
||||
// Use the cached value, if it exists
|
||||
if (field != null)
|
||||
return field;
|
||||
|
||||
// MD5 is the first packed field
|
||||
int extraIndex = 0x00;
|
||||
return Header.ExtraFieldBytes.ReadBytes(ref extraIndex, 0x10);
|
||||
field = Header.ExtraFieldBytes.ReadBytes(ref extraIndex, 0x10);
|
||||
return field;
|
||||
}
|
||||
}
|
||||
} = null;
|
||||
|
||||
/// <summary>
|
||||
/// Content size as stored in the extra field
|
||||
@@ -63,11 +73,16 @@ namespace SabreTools.Serialization.Wrappers
|
||||
if (!IsTorrentGZip)
|
||||
return 0;
|
||||
|
||||
// MD5 is the first packed field
|
||||
int extraIndex = 0x00;
|
||||
return Header.ExtraFieldBytes.ReadUInt64LittleEndian(ref extraIndex);
|
||||
// Use the cached value, if it exists
|
||||
if (field > 0)
|
||||
return field;
|
||||
|
||||
// Size is the third packed field
|
||||
int extraIndex = 0x14;
|
||||
field = Header.ExtraFieldBytes.ReadUInt64LittleEndian(ref extraIndex);
|
||||
return field;
|
||||
}
|
||||
}
|
||||
} = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Offset to the compressed data
|
||||
@@ -77,6 +92,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
get
|
||||
{
|
||||
// Use the cached value, if it exists
|
||||
if (field > -1)
|
||||
return field;
|
||||
|
||||
|
||||
@@ -17,16 +17,49 @@ namespace SabreTools.Serialization.Wrappers
|
||||
#region Extension Properties
|
||||
|
||||
/// <inheritdoc cref="Executable.ObjectPageMap"/>
|
||||
public InformationBlock? InformationBlock => Model.InformationBlock;
|
||||
public InformationBlock InformationBlock => Model.InformationBlock;
|
||||
|
||||
/// <inheritdoc cref="Executable.ObjectPageMap"/>
|
||||
public ObjectPageMapEntry[]? ObjectPageMap => Model.ObjectPageMap;
|
||||
public ObjectPageMapEntry[] ObjectPageMap => Model.ObjectPageMap;
|
||||
|
||||
/// <inheritdoc cref="Executable.ResourceTable"/>
|
||||
public ResourceTableEntry[]? ResourceTable => Model.ResourceTable;
|
||||
public ResourceTableEntry[] ResourceTable => Model.ResourceTable;
|
||||
|
||||
/// <inheritdoc cref="Executable.Stub"/>
|
||||
public Data.Models.MSDOS.Executable? Stub => Model.Stub;
|
||||
public Data.Models.MSDOS.Executable Stub => Model.Stub;
|
||||
|
||||
/// <summary>
|
||||
/// Stub executable data, if it exists
|
||||
/// </summary>
|
||||
public byte[] StubExecutableData
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_stubExecutableDataLock)
|
||||
{
|
||||
// If we already have cached data, just use that immediately
|
||||
if (field != null)
|
||||
return field;
|
||||
|
||||
// Populate the raw stub executable data based on the source
|
||||
int endOfStubHeader = 0x40;
|
||||
int lengthOfStubExecutableData = (int)Stub.Header.NewExeHeaderAddr - endOfStubHeader;
|
||||
field = ReadRangeFromSource(endOfStubHeader, lengthOfStubExecutableData);
|
||||
|
||||
// Cache and return the stub executable data, even if null
|
||||
return field;
|
||||
}
|
||||
}
|
||||
} = null;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Instance Variables
|
||||
|
||||
/// <summary>
|
||||
/// Lock object for <see cref="StubExecutableData"/>
|
||||
/// </summary>
|
||||
private readonly object _stubExecutableDataLock = new();
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -34,19 +34,19 @@ namespace SabreTools.Serialization.Wrappers
|
||||
lock (_debugDataLock)
|
||||
{
|
||||
// Use the cached data if possible
|
||||
if (_debugData.Count != 0)
|
||||
return _debugData;
|
||||
if (field.Count != 0)
|
||||
return field;
|
||||
|
||||
// If we have no resource table, just return
|
||||
if (DebugDirectoryTable == null || DebugDirectoryTable.Length == 0)
|
||||
return _debugData;
|
||||
return field;
|
||||
|
||||
// Otherwise, build and return the cached dictionary
|
||||
ParseDebugTable();
|
||||
return _debugData;
|
||||
field = ParseDebugTable();
|
||||
return field;
|
||||
}
|
||||
}
|
||||
}
|
||||
} = [];
|
||||
|
||||
/// <inheritdoc cref="Models.PortableExecutable.DebugData.Table.Table"/>
|
||||
public Data.Models.PortableExecutable.DebugData.Entry[]? DebugDirectoryTable
|
||||
@@ -822,12 +822,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
#region Instance Variables
|
||||
|
||||
/// <summary>
|
||||
/// Cached debug data
|
||||
/// </summary>
|
||||
private readonly Dictionary<int, object> _debugData = [];
|
||||
|
||||
/// <summary>
|
||||
/// Lock object for <see cref="_debugData"/>
|
||||
/// Lock object for <see cref="DebugData"/>
|
||||
/// </summary>
|
||||
private readonly object _debugDataLock = new();
|
||||
|
||||
@@ -1200,11 +1195,14 @@ namespace SabreTools.Serialization.Wrappers
|
||||
/// <summary>
|
||||
/// Parse the debug directory table information
|
||||
/// </summary>
|
||||
private void ParseDebugTable()
|
||||
private Dictionary<int, object> ParseDebugTable()
|
||||
{
|
||||
// If there is no debug table
|
||||
if (DebugDirectoryTable == null || DebugDirectoryTable.Length == 0)
|
||||
return;
|
||||
return [];
|
||||
|
||||
// Create a new debug table
|
||||
Dictionary<int, object> debugData = [];
|
||||
|
||||
// Loop through all debug table entries
|
||||
for (int i = 0; i < DebugDirectoryTable.Length; i++)
|
||||
@@ -1223,7 +1221,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
}
|
||||
catch (EndOfStreamException)
|
||||
{
|
||||
return;
|
||||
return debugData;
|
||||
}
|
||||
|
||||
// If we have CodeView debug data, try to parse it
|
||||
@@ -1242,7 +1240,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
var nb10ProgramDatabase = entryData.ParseNB10ProgramDatabase(ref offset);
|
||||
if (nb10ProgramDatabase != null)
|
||||
{
|
||||
_debugData[i] = nb10ProgramDatabase;
|
||||
debugData[i] = nb10ProgramDatabase;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -1253,16 +1251,18 @@ namespace SabreTools.Serialization.Wrappers
|
||||
var rsdsProgramDatabase = entryData.ParseRSDSProgramDatabase(ref offset);
|
||||
if (rsdsProgramDatabase != null)
|
||||
{
|
||||
_debugData[i] = rsdsProgramDatabase;
|
||||
debugData[i] = rsdsProgramDatabase;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_debugData[i] = entryData;
|
||||
debugData[i] = entryData;
|
||||
}
|
||||
}
|
||||
|
||||
return debugData;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
get
|
||||
{
|
||||
// Use the cached value if we have it
|
||||
// Use the cached value, if it exists
|
||||
if (field != null)
|
||||
return field;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user