Use auto-fields where possible

This commit is contained in:
Matt Nadareski
2025-11-14 09:48:00 -05:00
parent ad3113987b
commit 0638998773
8 changed files with 218 additions and 345 deletions

View File

@@ -37,8 +37,8 @@ namespace SabreTools.Serialization.Wrappers
get
{
// Use the cached value, if it exists
if (_miniStreamData != null)
return _miniStreamData;
if (field != null)
return field;
// If there are no directory entries
if (DirectoryEntries == null || DirectoryEntries.Length == 0)
@@ -48,11 +48,10 @@ namespace SabreTools.Serialization.Wrappers
var startingSector = (SectorNumber)DirectoryEntries[0].StartingSectorLocation;
// Get the mini stream data
_miniStreamData = GetFATSectorChainData(startingSector);
return _miniStreamData ?? [];
field = GetFATSectorChainData(startingSector);
return field ?? [];
}
}
private byte[]? _miniStreamData;
} = null;
/// <summary>
/// Normal sector size in bytes

View File

@@ -14,6 +14,33 @@ namespace SabreTools.Serialization.Wrappers
#region Extension Properties
/// <inheritdoc cref="Models.GCF.DataBlockHeader.BlockSize"/>
public uint BlockSize => Model.DataBlockHeader.BlockSize;
/// <summary>
/// Set of all data block offsets
/// </summary>
public long[]? DataBlockOffsets
{
get
{
// Use the cached value if we have it
if (field != null)
return field;
// Otherwise, build the data block set
field = new long[Model.DataBlockHeader.BlockCount];
for (int i = 0; i < Model.DataBlockHeader.BlockCount; i++)
{
long dataBlockOffset = Model.DataBlockHeader.FirstBlockOffset + (i * Model.DataBlockHeader.BlockSize);
field[i] = dataBlockOffset;
}
// Return the set of data blocks
return field;
}
} = null;
/// <summary>
/// Set of all files and their information
/// </summary>
@@ -22,8 +49,8 @@ namespace SabreTools.Serialization.Wrappers
get
{
// Use the cached value if we have it
if (_files != null)
return _files;
if (field != null)
return field;
// If we don't have a required property
if (Model.DirectoryEntries == null || Model.DirectoryMapEntries == null)
@@ -69,7 +96,7 @@ namespace SabreTools.Serialization.Wrappers
// Traverse the block entries
index = directoryMapEntry.FirstBlockIndex;
while (index != Model.DataBlockHeader?.BlockCount)
while (index != Model.DataBlockHeader.BlockCount)
{
var nextBlock = Model.BlockEntries[index];
blockEntries.Add(nextBlock);
@@ -109,55 +136,10 @@ namespace SabreTools.Serialization.Wrappers
}
// Set and return the file infos
_files = [.. files];
return _files;
field = [.. files];
return field;
}
}
/// <summary>
/// Set of all data block offsets
/// </summary>
public long[]? DataBlockOffsets
{
get
{
// Use the cached value if we have it
if (_dataBlockOffsets != null)
return _dataBlockOffsets;
// If we don't have a block count, offset, or size
if (Model.DataBlockHeader?.BlockCount == null || Model.DataBlockHeader?.FirstBlockOffset == null || Model.DataBlockHeader?.BlockSize == null)
return null;
// Otherwise, build the data block set
_dataBlockOffsets = new long[Model.DataBlockHeader.BlockCount];
for (int i = 0; i < Model.DataBlockHeader.BlockCount; i++)
{
long dataBlockOffset = Model.DataBlockHeader.FirstBlockOffset + (i * Model.DataBlockHeader.BlockSize);
_dataBlockOffsets[i] = dataBlockOffset;
}
// Return the set of data blocks
return _dataBlockOffsets;
}
}
/// <inheritdoc cref="Models.GCF.DataBlockHeader.BlockSize"/>
public uint BlockSize => Model.DataBlockHeader?.BlockSize ?? 0;
#endregion
#region Instance Variables
/// <summary>
/// Set of all files and their information
/// </summary>
private FileInfo[]? _files = null;
/// <summary>
/// Set of all data block offsets
/// </summary>
private long[]? _dataBlockOffsets = null;
} = null;
#endregion

View File

@@ -77,8 +77,8 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
if (_dataOffset > -1)
return _dataOffset;
if (field > -1)
return field;
// Minimum offset is 10 bytes:
// - ID1 (1)
@@ -88,20 +88,20 @@ namespace SabreTools.Serialization.Wrappers
// - LastModifiedTime (4)
// - ExtraFlags (1)
// - OperatingSystem (1)
_dataOffset = 10;
field = 10;
// Add extra lengths
_dataOffset += Header.ExtraLength;
field += Header.ExtraLength;
if (Header.OriginalFileName != null)
_dataOffset += Header.OriginalFileName.Length + 1;
field += Header.OriginalFileName.Length + 1;
if (Header.FileComment != null)
_dataOffset += Header.FileComment.Length + 1;
field += Header.FileComment.Length + 1;
if (Header.CRC16 != null)
_dataOffset += 2;
field += 2;
return _dataOffset;
return field;
}
}
} = -1;
/// <inheritdoc cref="Archive.Header"/>
public Header Header => Model.Header;
@@ -152,15 +152,6 @@ namespace SabreTools.Serialization.Wrappers
#endregion
#region Instance Variables
/// <summary>
/// Offset to the compressed data
/// </summary>
private long _dataOffset = -1;
#endregion
#region Constructors
/// <inheritdoc/>

View File

@@ -39,11 +39,11 @@ namespace SabreTools.Serialization.Wrappers
get
{
// Return the prebuilt map
if (_fileDirMap != null)
return _fileDirMap;
if (field != null)
return field;
// Build the file map
_fileDirMap = [];
field = [];
int fileId = 0;
for (int i = 0; i < Directories.Length; i++)
@@ -51,14 +51,13 @@ namespace SabreTools.Serialization.Wrappers
var dir = Directories[i];
for (int j = 0; j < dir.FileCount; j++)
{
_fileDirMap[fileId++] = i;
field[fileId++] = i;
}
}
return _fileDirMap;
return field;
}
}
private Dictionary<int, int>? _fileDirMap = null;
} = null;
/// <summary>
/// Map of all files found in the archive
@@ -68,11 +67,11 @@ namespace SabreTools.Serialization.Wrappers
get
{
// Return the prebuilt map
if (_fileNameMap != null)
return _fileNameMap;
if (field != null)
return field;
// Build the file map
_fileNameMap = [];
field = [];
for (int fileIndex = 0; fileIndex < Files.Length; fileIndex++)
{
// Get the current file
@@ -90,13 +89,14 @@ namespace SabreTools.Serialization.Wrappers
);
// Add to the map
_fileNameMap[filename] = file;
field[filename] = file;
}
return _fileNameMap;
return field;
}
}
private Dictionary<string, Data.Models.InstallShieldArchiveV3.File>? _fileNameMap = null;
private set;
} = null;
/// <summary>
/// Data offset for all archives

View File

@@ -30,12 +30,7 @@ namespace SabreTools.Serialization.Wrappers
/// Media unit size in bytes
/// </summary>
public uint MediaUnitSize
{
get
{
return (uint)(0x200 * Math.Pow(2, Model.Header.PartitionFlags[(int)NCSDFlags.MediaUnitSize]));
}
}
=> (uint)(0x200 * Math.Pow(2, Model.Header.PartitionFlags[(int)NCSDFlags.MediaUnitSize]));
/// <summary>
/// Partitions data table

View File

@@ -37,15 +37,15 @@ namespace SabreTools.Serialization.Wrappers
lock (_overlayAddressLock)
{
// Use the cached data if possible
if (_overlayAddress != null)
return _overlayAddress.Value;
if (field >= 0)
return field;
// Get the available source length, if possible
long dataLength = Length;
if (dataLength == -1)
{
_overlayAddress = -1;
return _overlayAddress.Value;
field = -1;
return field;
}
// Search through the segments table to find the furthest
@@ -99,11 +99,11 @@ namespace SabreTools.Serialization.Wrappers
endOfSectionData += 705;
// Cache and return the position
_overlayAddress = endOfSectionData;
return _overlayAddress.Value;
field = endOfSectionData;
return field;
}
}
}
} = -1;
/// <summary>
/// Overlay data, if it exists
@@ -117,15 +117,15 @@ namespace SabreTools.Serialization.Wrappers
lock (_overlayDataLock)
{
// Use the cached data if possible
if (_overlayData != null)
return _overlayData;
if (field != null)
return field;
// Get the available source length, if possible
long dataLength = Length;
if (dataLength == -1)
{
_overlayData = [];
return _overlayData;
field = [];
return field;
}
// Get the overlay address and size if possible
@@ -135,25 +135,25 @@ namespace SabreTools.Serialization.Wrappers
// If we didn't find the address or size
if (endOfSectionData <= 0 || overlaySize <= 0)
{
_overlayData = [];
return _overlayData;
field = [];
return field;
}
// If we're at the end of the file, cache an empty byte array
if (endOfSectionData >= dataLength)
{
_overlayData = [];
return _overlayData;
field = [];
return field;
}
// Otherwise, cache and return the data
overlaySize = Math.Min(overlaySize, 0x10000);
_overlayData = ReadRangeFromSource((int)endOfSectionData, (int)overlaySize);
return _overlayData;
field = ReadRangeFromSource((int)endOfSectionData, (int)overlaySize);
return field;
}
}
}
} = null;
/// <summary>
/// Size of the overlay data, if it exists
@@ -166,15 +166,15 @@ namespace SabreTools.Serialization.Wrappers
lock (_overlaySizeLock)
{
// Use the cached data if possible
if (_overlaySize >= 0)
return _overlaySize;
if (field >= 0)
return field;
// Get the available source length, if possible
long dataLength = Length;
if (dataLength == -1)
{
_overlaySize = 0;
return _overlaySize;
field = 0;
return field;
}
// Get the overlay address if possible
@@ -183,23 +183,23 @@ namespace SabreTools.Serialization.Wrappers
// If we didn't find the end of section data
if (endOfSectionData <= 0)
{
_overlaySize = 0;
return _overlaySize;
field = 0;
return field;
}
// If we're at the end of the file, cache an empty byte array
if (endOfSectionData >= dataLength)
{
_overlaySize = 0;
return _overlaySize;
field = 0;
return field;
}
// Otherwise, cache and return the data
_overlaySize = dataLength - endOfSectionData;
return _overlaySize;
field = dataLength - endOfSectionData;
return field;
}
}
}
} = -1;
/// <summary>
/// Overlay strings, if they exist
@@ -211,31 +211,31 @@ namespace SabreTools.Serialization.Wrappers
lock (_overlayStringsLock)
{
// Use the cached data if possible
if (_overlayStrings != null)
return _overlayStrings;
if (field != null)
return field;
// Get the available source length, if possible
long dataLength = Length;
if (dataLength == -1)
{
_overlayStrings = [];
return _overlayStrings;
field = [];
return field;
}
// Get the overlay data, if possible
var overlayData = OverlayData;
if (overlayData.Length == 0)
{
_overlayStrings = [];
return _overlayStrings;
field = [];
return field;
}
// Otherwise, cache and return the strings
_overlayStrings = overlayData.ReadStringsFrom(charLimit: 3) ?? [];
return _overlayStrings;
field = overlayData.ReadStringsFrom(charLimit: 3) ?? [];
return field;
}
}
}
} = null;
/// <inheritdoc cref="Executable.ResidentNameTable"/>
public ResidentNameTableEntry[] ResidentNameTable => Model.ResidentNameTable;
@@ -259,71 +259,46 @@ namespace SabreTools.Serialization.Wrappers
lock (_stubExecutableDataLock)
{
// If we already have cached data, just use that immediately
if (_stubExecutableData != null)
return _stubExecutableData;
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;
_stubExecutableData = ReadRangeFromSource(endOfStubHeader, lengthOfStubExecutableData);
field = ReadRangeFromSource(endOfStubHeader, lengthOfStubExecutableData);
// Cache and return the stub executable data, even if null
return _stubExecutableData;
return field;
}
}
}
} = null;
#endregion
#region Instance Variables
/// <summary>
/// Address of the overlay, if it exists
/// </summary>
private long? _overlayAddress = null;
/// <summary>
/// Lock object for <see cref="_overlayAddress"/>
/// Lock object for <see cref="OverlayAddress"/>
/// </summary>
private readonly object _overlayAddressLock = new();
/// <summary>
/// Overlay data, if it exists
/// </summary>
private byte[]? _overlayData = null;
/// <summary>
/// Lock object for <see cref="_overlayData"/>
/// Lock object for <see cref="OverlayData"/>
/// </summary>
private readonly object _overlayDataLock = new();
/// <summary>
/// Size of the overlay data, if it exists
/// </summary>
private long _overlaySize = -1;
/// <summary>
/// Lock object for <see cref="_overlaySize"/>
/// Lock object for <see cref="OverlaySize"/>
/// </summary>
private readonly object _overlaySizeLock = new();
/// <summary>
/// Overlay strings, if they exist
/// </summary>
private List<string>? _overlayStrings = null;
/// <summary>
/// Lock object for <see cref="_overlayStrings"/>
/// Lock object for <see cref="OverlayStrings"/>
/// </summary>
private readonly object _overlayStringsLock = new();
/// <summary>
/// Stub executable data, if it exists
/// </summary>
private byte[]? _stubExecutableData = null;
/// <summary>
/// Lock object for <see cref="_stubExecutableData"/>
/// Lock object for <see cref="StubExecutableData"/>
/// </summary>
private readonly object _stubExecutableDataLock = new();

View File

@@ -63,31 +63,31 @@ namespace SabreTools.Serialization.Wrappers
lock (_entryPointDataLock)
{
// If we already have cached data, just use that immediately
if (_entryPointData != null)
return _entryPointData;
if (field != null)
return field;
// If we have no entry point
int entryPointAddress = (int)OptionalHeader.AddressOfEntryPoint.ConvertVirtualAddress(SectionTable);
if (entryPointAddress == 0)
{
_entryPointData = [];
return _entryPointData;
field = [];
return field;
}
// If the entry point matches with the start of a section, use that
int entryPointSection = FindEntryPointSectionIndex();
if (entryPointSection >= 0 && OptionalHeader.AddressOfEntryPoint == SectionTable[entryPointSection].VirtualAddress)
{
_entryPointData = GetSectionData(entryPointSection) ?? [];
return _entryPointData;
field = GetSectionData(entryPointSection) ?? [];
return field;
}
// Read the first 128 bytes of the entry point
_entryPointData = ReadRangeFromSource(entryPointAddress, length: 128) ?? [];
return _entryPointData;
field = ReadRangeFromSource(entryPointAddress, length: 128) ?? [];
return field;
}
}
}
} = null;
/// <inheritdoc cref="Executable.ExportAddressTable"/>
public Data.Models.PortableExecutable.Export.AddressTableEntry[]? ExportTable => Model.ExportAddressTable;
@@ -114,8 +114,8 @@ namespace SabreTools.Serialization.Wrappers
lock (_headerPaddingDataLock)
{
// If we already have cached data, just use that immediately
if (_headerPaddingData != null)
return _headerPaddingData;
if (field != null)
return field;
// TODO: Don't scan the known header data as well
@@ -137,15 +137,15 @@ namespace SabreTools.Serialization.Wrappers
int headerLength = (int)(firstSectionAddress - headerStartAddress);
if (headerLength <= 0)
{
_headerPaddingData = [];
return _headerPaddingData;
field = [];
return field;
}
_headerPaddingData = ReadRangeFromSource((int)headerStartAddress, headerLength) ?? [];
return _headerPaddingData;
field = ReadRangeFromSource((int)headerStartAddress, headerLength) ?? [];
return field;
}
}
}
} = null;
/// <summary>
/// Header padding strings, if they exist
@@ -157,23 +157,23 @@ namespace SabreTools.Serialization.Wrappers
lock (_headerPaddingStringsLock)
{
// If we already have cached data, just use that immediately
if (_headerPaddingStrings != null)
return _headerPaddingStrings;
if (field != null)
return field;
// Get the header padding data, if possible
byte[] headerPaddingData = HeaderPaddingData;
if (headerPaddingData.Length == 0)
{
_headerPaddingStrings = [];
return _headerPaddingStrings;
field = [];
return field;
}
// Otherwise, cache and return the strings
_headerPaddingStrings = headerPaddingData.ReadStringsFrom(charLimit: 3) ?? [];
return _headerPaddingStrings;
field = headerPaddingData.ReadStringsFrom(charLimit: 3) ?? [];
return field;
}
}
}
} = null;
/// <inheritdoc cref="Executable.ImportAddressTables"/>
public Dictionary<int, Data.Models.PortableExecutable.Import.AddressTableEntry[]?>? ImportAddressTables => Model.ImportAddressTables;
@@ -197,8 +197,8 @@ namespace SabreTools.Serialization.Wrappers
lock (_matroschkaPackageLock)
{
// Use the cached data if possible
if (_matroschkaPackage != null)
return _matroschkaPackage;
if (field != null)
return field;
// Check to see if creation has already been attempted
if (_matroschkaPackageFailed)
@@ -249,14 +249,14 @@ namespace SabreTools.Serialization.Wrappers
}
// Parse the package
_matroschkaPackage = SecuROMMatroschkaPackage.Create(sectionData, 0);
if (_matroschkaPackage?.Entries == null)
field = SecuROMMatroschkaPackage.Create(sectionData, 0);
if (field?.Entries == null)
_matroschkaPackageFailed = true;
return _matroschkaPackage;
return field;
}
}
}
} = null;
/// <inheritdoc cref="Executable.OptionalHeader"/>
public Data.Models.PortableExecutable.OptionalHeader OptionalHeader => Model.OptionalHeader;
@@ -272,15 +272,15 @@ namespace SabreTools.Serialization.Wrappers
lock (_overlayAddressLock)
{
// Use the cached data if possible
if (_overlayAddress != null)
return _overlayAddress.Value;
if (field >= 0)
return field;
// Get the available source length, if possible
long dataLength = Length;
if (dataLength == -1)
{
_overlayAddress = -1;
return _overlayAddress.Value;
field = -1;
return field;
}
// If we have certificate data, use that as the end
@@ -304,11 +304,11 @@ namespace SabreTools.Serialization.Wrappers
endOfSectionData = -1;
// Cache and return the position
_overlayAddress = endOfSectionData;
return _overlayAddress.Value;
field = endOfSectionData;
return field;
}
}
}
} = -1;
/// <summary>
/// Overlay data, if it exists
@@ -322,15 +322,15 @@ namespace SabreTools.Serialization.Wrappers
lock (_overlayDataLock)
{
// Use the cached data if possible
if (_overlayData != null)
return _overlayData;
if (field != null)
return field;
// Get the available source length, if possible
long dataLength = Length;
if (dataLength == -1)
{
_overlayData = [];
return _overlayData;
field = [];
return field;
}
// If we have certificate data, use that as the end
@@ -348,25 +348,25 @@ namespace SabreTools.Serialization.Wrappers
// If we didn't find the address or size
if (endOfSectionData <= 0 || overlaySize <= 0)
{
_overlayData = [];
return _overlayData;
field = [];
return field;
}
// If we're at the end of the file, cache an empty byte array
if (endOfSectionData >= dataLength)
{
_overlayData = [];
return _overlayData;
field = [];
return field;
}
// Otherwise, cache and return the data
overlaySize = Math.Min(overlaySize, 0x10000);
_overlayData = ReadRangeFromSource(endOfSectionData, (int)overlaySize) ?? [];
return _overlayData;
field = ReadRangeFromSource(endOfSectionData, (int)overlaySize) ?? [];
return field;
}
}
}
} = null;
/// <summary>
/// Size of the overlay data, if it exists
@@ -379,15 +379,15 @@ namespace SabreTools.Serialization.Wrappers
lock (_overlaySizeLock)
{
// Use the cached data if possible
if (_overlaySize >= 0)
return _overlaySize;
if (field >= 0)
return field;
// Get the available source length, if possible
long dataLength = Length;
if (dataLength == -1)
{
_overlaySize = 0;
return _overlaySize;
field = 0;
return field;
}
// If we have certificate data, use that as the end
@@ -404,23 +404,23 @@ namespace SabreTools.Serialization.Wrappers
// If we didn't find the end of section data
if (endOfSectionData <= 0)
{
_overlaySize = 0;
return _overlaySize;
field = 0;
return field;
}
// If we're at the end of the file, cache an empty byte array
if (endOfSectionData >= dataLength)
{
_overlaySize = 0;
return _overlaySize;
field = 0;
return field;
}
// Otherwise, cache and return the length
_overlaySize = dataLength - endOfSectionData;
return _overlaySize;
field = dataLength - endOfSectionData;
return field;
}
}
}
} = -1;
/// <summary>
/// Overlay strings, if they exist
@@ -432,23 +432,23 @@ namespace SabreTools.Serialization.Wrappers
lock (_overlayStringsLock)
{
// Use the cached data if possible
if (_overlayStrings != null)
return _overlayStrings;
if (field != null)
return field;
// Get the overlay data, if possible
var overlayData = OverlayData;
if (overlayData.Length == 0)
{
_overlayStrings = [];
return _overlayStrings;
field = [];
return field;
}
// Otherwise, cache and return the strings
_overlayStrings = overlayData.ReadStringsFrom(charLimit: 3) ?? [];
return _overlayStrings;
field = overlayData.ReadStringsFrom(charLimit: 3) ?? [];
return field;
}
}
}
} = null;
/// <inheritdoc cref="Executable.ResourceDirectoryTable"/>
public Data.Models.PortableExecutable.Resource.DirectoryTable? ResourceDirectoryTable => Model.ResourceDirectoryTable;
@@ -463,23 +463,23 @@ namespace SabreTools.Serialization.Wrappers
lock (_sectionNamesLock)
{
// Use the cached data if possible
if (_sectionNames != null)
return _sectionNames;
if (field != null)
return field;
// Otherwise, build and return the cached array
_sectionNames = new string[SectionTable.Length];
for (int i = 0; i < _sectionNames.Length; i++)
field = new string[SectionTable.Length];
for (int i = 0; i < field.Length; i++)
{
// TODO: Handle long section names with leading `/`
var section = SectionTable[i];
string sectionNameString = Encoding.UTF8.GetString(section.Name).TrimEnd('\0');
_sectionNames[i] = sectionNameString;
field[i] = sectionNameString;
}
return _sectionNames;
return field;
}
}
}
} = null;
/// <inheritdoc cref="Executable.SectionTable"/>
public SectionHeader[] SectionTable => Model.SectionTable;
@@ -494,8 +494,8 @@ namespace SabreTools.Serialization.Wrappers
lock (_sectionTableTrailerDataLock)
{
// If we already have cached data, just use that immediately
if (_sectionTableTrailerData != null)
return _sectionTableTrailerData;
if (field != null)
return field;
// Get the offset from the end of the section table
long endOfSectionTable = Stub.Header.NewExeHeaderAddr
@@ -508,11 +508,11 @@ namespace SabreTools.Serialization.Wrappers
int trailerDataSize = alignment - (int)(endOfSectionTable % alignment);
// Cache and return the section table trailer data, even if null
_sectionTableTrailerData = ReadRangeFromSource(endOfSectionTable, trailerDataSize);
return _sectionTableTrailerData;
field = ReadRangeFromSource(endOfSectionTable, trailerDataSize);
return field;
}
}
}
} = null;
/// <inheritdoc cref="Executable.Stub"/>
public Data.Models.MSDOS.Executable Stub => Model.Stub;
@@ -527,19 +527,19 @@ namespace SabreTools.Serialization.Wrappers
lock (_stubExecutableDataLock)
{
// If we already have cached data, just use that immediately
if (_stubExecutableData != null)
return _stubExecutableData;
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;
_stubExecutableData = ReadRangeFromSource(endOfStubHeader, lengthOfStubExecutableData);
field = ReadRangeFromSource(endOfStubHeader, lengthOfStubExecutableData);
// Cache and return the stub executable data, even if null
return _stubExecutableData;
return field;
}
}
}
} = null;
/// <summary>
/// Dictionary of resource data
@@ -579,8 +579,8 @@ namespace SabreTools.Serialization.Wrappers
lock (_wiseSectionHeaderLock)
{
// If we already have cached data, just use that immediately
if (_wiseSectionHeader != null)
return _wiseSectionHeader;
if (field != null)
return field;
// If the header will not be found due to missing section data
if (_wiseSectionHeaderMissing)
@@ -623,14 +623,14 @@ namespace SabreTools.Serialization.Wrappers
}
// Parse the section header
_wiseSectionHeader = WiseSectionHeader.Create(sectionData, 0);
if (_wiseSectionHeader == null)
field = WiseSectionHeader.Create(sectionData, 0);
if (field == null)
_wiseSectionHeaderMissing = true;
return _wiseSectionHeader;
return field;
}
}
}
} = null;
#region Version Information
@@ -832,87 +832,47 @@ namespace SabreTools.Serialization.Wrappers
private readonly object _debugDataLock = new();
/// <summary>
/// Entry point data, if it exists and isn't aligned to a section
/// </summary>
private byte[]? _entryPointData = null;
/// <summary>
/// Lock object for <see cref="_entryPointData"/>
/// Lock object for <see cref="EntryPointData"/>
/// </summary>
private readonly object _entryPointDataLock = new();
/// <summary>
/// Header padding data, if it exists
/// </summary>
private byte[]? _headerPaddingData = null;
/// <summary>
/// Lock object for <see cref="_headerPaddingData"/>
/// Lock object for <see cref="HeaderPaddingData"/>
/// </summary>
private readonly object _headerPaddingDataLock = new();
/// <summary>
/// Header padding strings, if they exist
/// </summary>
private List<string>? _headerPaddingStrings = null;
/// <summary>
/// Lock object for <see cref="_headerPaddingStrings"/>
/// Lock object for <see cref="HeaderPaddingStrings"/>
/// </summary>
private readonly object _headerPaddingStringsLock = new();
/// <summary>
/// Matroschka Package wrapper, if it exists
/// </summary>
private SecuROMMatroschkaPackage? _matroschkaPackage = null;
/// <summary>
/// Lock object for <see cref="_matroschkaPackage"/>
/// Lock object for <see cref="MatroschkaPackage"/>
/// </summary>
private readonly object _matroschkaPackageLock = new();
/// <summary>
/// Cached attempt at creation for <see cref="_matroschkaPackage"/>
/// Cached attempt at creation for <see cref="MatroschkaPackage"/>
/// </summary>
private bool _matroschkaPackageFailed = false;
/// <summary>
/// Address of the overlay, if it exists
/// </summary>
private long? _overlayAddress = null;
/// <summary>
/// Lock object for <see cref="_overlayAddress"/>
/// Lock object for <see cref="OverlayAddress"/>
/// </summary>
private readonly object _overlayAddressLock = new();
/// <summary>
/// Overlay data, if it exists
/// </summary>
private byte[]? _overlayData = null;
/// <summary>
/// Lock object for <see cref="_overlayData"/>
/// Lock object for <see cref="OverlayData"/>
/// </summary>
private readonly object _overlayDataLock = new();
/// <summary>
/// Size of the overlay data, if it exists
/// </summary>
private long _overlaySize = -1;
/// <summary>
/// Lock object for <see cref="_overlaySize"/>
/// Lock object for <see cref="OverlaySize"/>
/// </summary>
private readonly object _overlaySizeLock = new();
/// <summary>
/// Overlay strings, if they exist
/// </summary>
private List<string>? _overlayStrings = null;
/// <summary>
/// Lock object for <see cref="_overlayStrings"/>
/// Lock object for <see cref="OverlayStrings"/>
/// </summary>
private readonly object _overlayStringsLock = new();
@@ -927,12 +887,7 @@ namespace SabreTools.Serialization.Wrappers
private readonly object _resourceDataLock = new();
/// <summary>
/// Sanitized section names
/// </summary>
private string[]? _sectionNames = null;
/// <summary>
/// Lock object for <see cref="_sectionNames"/>
/// Lock object for <see cref="SectionNames"/>
/// </summary>
private readonly object _sectionNamesLock = new();
@@ -952,22 +907,12 @@ namespace SabreTools.Serialization.Wrappers
private readonly object _sectionStringDataLock = new();
/// <summary>
/// Data after the section table, if it exists
/// </summary>
private byte[]? _sectionTableTrailerData = null;
/// <summary>
/// Lock object for <see cref="_sectionTableTrailerData"/>
/// Lock object for <see cref="SectionTableTrailerData"/>
/// </summary>
private readonly object _sectionTableTrailerDataLock = new();
/// <summary>
/// Stub executable data, if it exists
/// </summary>
private byte[]? _stubExecutableData = null;
/// <summary>
/// Lock object for <see cref="_stubExecutableData"/>
/// Lock object for <see cref="StubExecutableData"/>
/// </summary>
private readonly object _stubExecutableDataLock = new();
@@ -982,17 +927,12 @@ namespace SabreTools.Serialization.Wrappers
private readonly List<string>?[] _tableStringData = new List<string>?[16];
/// <summary>
/// Wise section wrapper, if it exists
/// </summary>
private WiseSectionHeader? _wiseSectionHeader = null;
/// <summary>
/// Lock object for <see cref="_wiseSectionHeader"/>
/// Lock object for <see cref="WiseSection"/>
/// </summary>
private readonly object _wiseSectionHeaderLock = new();
/// <summary>
/// Indicates if <see cref="_wiseSectionHeader"/> cannot be found
/// Indicates if <see cref="WiseSection"/> cannot be found
/// </summary>
private bool _wiseSectionHeaderMissing = false;

View File

@@ -23,8 +23,8 @@ namespace SabreTools.Serialization.Wrappers
get
{
// Use the cached value if we have it
if (_archiveFilenames != null)
return _archiveFilenames;
if (field != null)
return field;
// If we don't have a source filename
if (string.IsNullOrEmpty(Filename))
@@ -57,7 +57,7 @@ namespace SabreTools.Serialization.Wrappers
}
// Build the list of archive filenames to populate
_archiveFilenames = new string[archiveCount];
field = new string[archiveCount];
// Loop through and create the archive filenames
for (int i = 0; i < archiveCount; i++)
@@ -68,28 +68,19 @@ namespace SabreTools.Serialization.Wrappers
#else
string archiveFileName = $"{fileName.Substring(0, fileName.Length - 3)}{i.ToString().PadLeft(3, '0')}.{extension}";
#endif
_archiveFilenames[i] = archiveFileName;
field[i] = archiveFileName;
}
// Return the array
return _archiveFilenames;
return field;
}
}
} = null;
/// <inheritdoc cref="Models.VPK.File.DirectoryItems"/>
public Data.Models.VPK.DirectoryItem[] DirectoryItems => Model.DirectoryItems;
#endregion
#region Instance Variables
/// <summary>
/// Array of archive filenames attached to the given VPK
/// </summary>
private string[]? _archiveFilenames = null;
#endregion
#region Constructors
/// <inheritdoc/>