diff --git a/SabreTools.Serialization/Wrappers/BFPK.cs b/SabreTools.Serialization/Wrappers/BFPK.cs
index 2cb051ef..bcad47a9 100644
--- a/SabreTools.Serialization/Wrappers/BFPK.cs
+++ b/SabreTools.Serialization/Wrappers/BFPK.cs
@@ -167,7 +167,7 @@ namespace SabreTools.Serialization.Wrappers
using FileStream fs = File.OpenWrite(filename);
// Read the data block
- var data = _dataSource.ReadFrom(offset, compressedSize, retainPosition: true);
+ var data = ReadRangeFromSource(offset, compressedSize);
if (data == null)
return false;
diff --git a/SabreTools.Serialization/Wrappers/BSP.cs b/SabreTools.Serialization/Wrappers/BSP.cs
index c7d125e3..d8def264 100644
--- a/SabreTools.Serialization/Wrappers/BSP.cs
+++ b/SabreTools.Serialization/Wrappers/BSP.cs
@@ -128,7 +128,7 @@ namespace SabreTools.Serialization.Wrappers
// Read the data
var lump = Lumps[index];
- var data = _dataSource.ReadFrom(lump.Offset, lump.Length, retainPosition: true);
+ var data = ReadRangeFromSource(lump.Offset, lump.Length);
if (data == null)
return false;
diff --git a/SabreTools.Serialization/Wrappers/CFB.cs b/SabreTools.Serialization/Wrappers/CFB.cs
index a988b59c..9f2e59d9 100644
--- a/SabreTools.Serialization/Wrappers/CFB.cs
+++ b/SabreTools.Serialization/Wrappers/CFB.cs
@@ -322,7 +322,7 @@ namespace SabreTools.Serialization.Wrappers
return null;
// Try to read the sector data
- var sectorData = _dataSource.ReadFrom(sectorDataOffset, (int)SectorSize, retainPosition: true);
+ var sectorData = ReadRangeFromSource(sectorDataOffset, (int)SectorSize);
if (sectorData == null)
return null;
diff --git a/SabreTools.Serialization/Wrappers/GCF.cs b/SabreTools.Serialization/Wrappers/GCF.cs
index 47dc5f3c..293550a4 100644
--- a/SabreTools.Serialization/Wrappers/GCF.cs
+++ b/SabreTools.Serialization/Wrappers/GCF.cs
@@ -321,7 +321,7 @@ namespace SabreTools.Serialization.Wrappers
for (int i = 0; i < dataBlockOffsets.Count; i++)
{
int readSize = (int)Math.Min(BlockSize, fileSize);
- var data = _dataSource.ReadFrom((int)dataBlockOffsets[i], readSize, retainPosition: true);
+ var data = ReadRangeFromSource((int)dataBlockOffsets[i], readSize);
if (data == null)
return false;
diff --git a/SabreTools.Serialization/Wrappers/InstallShieldArchiveV3.cs b/SabreTools.Serialization/Wrappers/InstallShieldArchiveV3.cs
index 6354fa56..5d27a75b 100644
--- a/SabreTools.Serialization/Wrappers/InstallShieldArchiveV3.cs
+++ b/SabreTools.Serialization/Wrappers/InstallShieldArchiveV3.cs
@@ -240,7 +240,7 @@ namespace SabreTools.Serialization.Wrappers
long outputFileSize = file.UncompressedSize;
// Read the compressed data directly
- var compressedData = _dataSource.ReadFrom((int)fileOffset, (int)fileSize, retainPosition: true);
+ var compressedData = ReadRangeFromSource((int)fileOffset, (int)fileSize);
if (compressedData == null)
return false;
diff --git a/SabreTools.Serialization/Wrappers/LZKWAJ.cs b/SabreTools.Serialization/Wrappers/LZKWAJ.cs
index a6f1230a..aed3bcd7 100644
--- a/SabreTools.Serialization/Wrappers/LZKWAJ.cs
+++ b/SabreTools.Serialization/Wrappers/LZKWAJ.cs
@@ -111,7 +111,7 @@ namespace SabreTools.Serialization.Wrappers
return false;
// Read in the data as an array
- byte[]? contents = _dataSource.ReadFrom(DataOffset, (int)compressedSize, retainPosition: true);
+ byte[]? contents = ReadRangeFromSource(DataOffset, (int)compressedSize);
if (contents == null)
return false;
diff --git a/SabreTools.Serialization/Wrappers/LZQBasic.cs b/SabreTools.Serialization/Wrappers/LZQBasic.cs
index dd0416a6..30c30360 100644
--- a/SabreTools.Serialization/Wrappers/LZQBasic.cs
+++ b/SabreTools.Serialization/Wrappers/LZQBasic.cs
@@ -95,7 +95,7 @@ namespace SabreTools.Serialization.Wrappers
return false;
// Read in the data as an array
- byte[]? contents = _dataSource.ReadFrom(12, (int)compressedSize, retainPosition: true);
+ byte[]? contents = ReadRangeFromSource(12, (int)compressedSize);
if (contents == null)
return false;
diff --git a/SabreTools.Serialization/Wrappers/LZSZDD.cs b/SabreTools.Serialization/Wrappers/LZSZDD.cs
index 28749867..9973c879 100644
--- a/SabreTools.Serialization/Wrappers/LZSZDD.cs
+++ b/SabreTools.Serialization/Wrappers/LZSZDD.cs
@@ -111,7 +111,7 @@ namespace SabreTools.Serialization.Wrappers
return false;
// Read in the data as an array
- byte[]? contents = _dataSource.ReadFrom(14, (int)compressedSize, retainPosition: true);
+ byte[]? contents = ReadRangeFromSource(14, (int)compressedSize);
if (contents == null)
return false;
diff --git a/SabreTools.Serialization/Wrappers/LinearExecutable.cs b/SabreTools.Serialization/Wrappers/LinearExecutable.cs
index a894d134..ff6ff533 100644
--- a/SabreTools.Serialization/Wrappers/LinearExecutable.cs
+++ b/SabreTools.Serialization/Wrappers/LinearExecutable.cs
@@ -139,7 +139,7 @@ namespace SabreTools.Serialization.Wrappers
return [];
// Read the entry data and return
- return _dataSource.ReadFrom(offset, length, retainPosition: true);
+ return ReadRangeFromSource(offset, length);
}
///
@@ -315,7 +315,7 @@ namespace SabreTools.Serialization.Wrappers
if (length == -1)
length = Length;
- return _dataSource.ReadFrom(rangeStart, (int)length, retainPosition: true);
+ return ReadRangeFromSource(rangeStart, (int)length);
}
#endregion
diff --git a/SabreTools.Serialization/Wrappers/NewExecutable.cs b/SabreTools.Serialization/Wrappers/NewExecutable.cs
index 76915b9b..6f2a3af2 100644
--- a/SabreTools.Serialization/Wrappers/NewExecutable.cs
+++ b/SabreTools.Serialization/Wrappers/NewExecutable.cs
@@ -51,59 +51,56 @@ namespace SabreTools.Serialization.Wrappers
if (Header == null || SegmentTable == null || ResourceTable?.ResourceTypes == null)
return -1;
- lock (_sourceDataLock)
+ // Search through the segments table to find the furthest
+ long endOfSectionData = -1;
+ foreach (var entry in SegmentTable)
{
- // Search through the segments table to find the furthest
- long endOfSectionData = -1;
- foreach (var entry in SegmentTable)
- {
- // Get end of segment data
- long offset = (entry.Offset * (1 << Header.SegmentAlignmentShiftCount)) + entry.Length;
+ // Get end of segment data
+ long offset = (entry.Offset * (1 << Header.SegmentAlignmentShiftCount)) + entry.Length;
- // Read and find the end of the relocation data
+ // Read and find the end of the relocation data
#if NET20 || NET35
if ((entry.FlagWord & SegmentTableEntryFlag.RELOCINFO) != 0)
#else
- if (entry.FlagWord.HasFlag(SegmentTableEntryFlag.RELOCINFO))
+ if (entry.FlagWord.HasFlag(SegmentTableEntryFlag.RELOCINFO))
#endif
- {
- _dataSource.Seek(offset, SeekOrigin.Begin);
- var relocationData = Deserializers.NewExecutable.ParsePerSegmentData(_dataSource);
+ {
+ _dataSource.Seek(offset, SeekOrigin.Begin);
+ var relocationData = Deserializers.NewExecutable.ParsePerSegmentData(_dataSource);
- offset = _dataSource.Position;
- }
+ offset = _dataSource.Position;
+ }
+ if (offset > endOfSectionData)
+ endOfSectionData = offset;
+ }
+
+ // Search through the resources table to find the furthest
+ foreach (var entry in ResourceTable.ResourceTypes)
+ {
+ // Skip invalid entries
+ if (entry.ResourceCount == 0 || entry.Resources == null || entry.Resources.Length == 0)
+ continue;
+
+ foreach (var resource in entry.Resources)
+ {
+ int offset = (resource.Offset << ResourceTable.AlignmentShiftCount) + resource.Length;
if (offset > endOfSectionData)
endOfSectionData = offset;
}
-
- // Search through the resources table to find the furthest
- foreach (var entry in ResourceTable.ResourceTypes)
- {
- // Skip invalid entries
- if (entry.ResourceCount == 0 || entry.Resources == null || entry.Resources.Length == 0)
- continue;
-
- foreach (var resource in entry.Resources)
- {
- int offset = (resource.Offset << ResourceTable.AlignmentShiftCount) + resource.Length;
- if (offset > endOfSectionData)
- endOfSectionData = offset;
- }
- }
-
- // If we didn't find the end of section data
- if (endOfSectionData <= 0)
- endOfSectionData = -1;
-
- // Adjust the position of the data by 705 bytes
- // TODO: Investigate what the byte data is
- endOfSectionData += 705;
-
- // Cache and return the position
- _overlayAddress = endOfSectionData;
- return _overlayAddress.Value;
}
+
+ // If we didn't find the end of section data
+ if (endOfSectionData <= 0)
+ endOfSectionData = -1;
+
+ // Adjust the position of the data by 705 bytes
+ // TODO: Investigate what the byte data is
+ endOfSectionData += 705;
+
+ // Cache and return the position
+ _overlayAddress = endOfSectionData;
+ return _overlayAddress.Value;
}
}
}
@@ -146,12 +143,9 @@ namespace SabreTools.Serialization.Wrappers
}
// Otherwise, cache and return the data
- lock (_sourceDataLock)
- {
- long overlayLength = dataLength - endOfSectionData;
- _overlayData = _dataSource.ReadFrom((int)endOfSectionData, (int)overlayLength, retainPosition: true);
- return _overlayData;
- }
+ long overlayLength = dataLength - endOfSectionData;
+ _overlayData = ReadRangeFromSource((int)endOfSectionData, (int)overlayLength);
+ return _overlayData;
}
}
}
@@ -221,16 +215,13 @@ namespace SabreTools.Serialization.Wrappers
if (Stub?.Header?.NewExeHeaderAddr == null)
return null;
- lock (_sourceDataLock)
- {
- // Populate the raw stub executable data based on the source
- int endOfStubHeader = 0x40;
- int lengthOfStubExecutableData = (int)Stub.Header.NewExeHeaderAddr - endOfStubHeader;
- _stubExecutableData = _dataSource.ReadFrom(endOfStubHeader, lengthOfStubExecutableData, retainPosition: true);
+ // Populate the raw stub executable data based on the source
+ int endOfStubHeader = 0x40;
+ int lengthOfStubExecutableData = (int)Stub.Header.NewExeHeaderAddr - endOfStubHeader;
+ _stubExecutableData = ReadRangeFromSource(endOfStubHeader, lengthOfStubExecutableData);
- // Cache and return the stub executable data, even if null
- return _stubExecutableData;
- }
+ // Cache and return the stub executable data, even if null
+ return _stubExecutableData;
}
}
}
@@ -279,11 +270,6 @@ namespace SabreTools.Serialization.Wrappers
///
private readonly object _stubExecutableDataLock = new();
- ///
- /// Lock object for reading from the source
- ///
- private readonly object _sourceDataLock = new();
-
#endregion
#region Constructors
@@ -654,7 +640,7 @@ namespace SabreTools.Serialization.Wrappers
return [];
// Read the resource data and return
- return _dataSource.ReadFrom(offset, length, retainPosition: true);
+ return ReadRangeFromSource(offset, length);
}
///
@@ -746,7 +732,7 @@ namespace SabreTools.Serialization.Wrappers
return [];
// Read the segment data and return
- return _dataSource.ReadFrom(offset, length, retainPosition: true);
+ return ReadRangeFromSource(offset, length);
}
///
@@ -816,7 +802,7 @@ namespace SabreTools.Serialization.Wrappers
if (length == -1)
length = Length;
- return _dataSource.ReadFrom(rangeStart, (int)length, retainPosition: true);
+ return ReadRangeFromSource(rangeStart, (int)length);
}
#endregion
diff --git a/SabreTools.Serialization/Wrappers/PAK.cs b/SabreTools.Serialization/Wrappers/PAK.cs
index d2244028..4b9d7206 100644
--- a/SabreTools.Serialization/Wrappers/PAK.cs
+++ b/SabreTools.Serialization/Wrappers/PAK.cs
@@ -128,7 +128,7 @@ namespace SabreTools.Serialization.Wrappers
// Read the item data
var directoryItem = DirectoryItems[index];
- var data = _dataSource.ReadFrom((int)directoryItem.ItemOffset, (int)directoryItem.ItemLength, retainPosition: true);
+ var data = ReadRangeFromSource((int)directoryItem.ItemOffset, (int)directoryItem.ItemLength);
if (data == null)
return false;
diff --git a/SabreTools.Serialization/Wrappers/PFF.cs b/SabreTools.Serialization/Wrappers/PFF.cs
index 1ba60192..c0a44adf 100644
--- a/SabreTools.Serialization/Wrappers/PFF.cs
+++ b/SabreTools.Serialization/Wrappers/PFF.cs
@@ -159,7 +159,7 @@ namespace SabreTools.Serialization.Wrappers
using FileStream fs = File.OpenWrite(filename);
// Read the data block
- var data = _dataSource.ReadFrom(offset, size, retainPosition: true);
+ var data = ReadRangeFromSource(offset, size);
if (data == null)
return false;
diff --git a/SabreTools.Serialization/Wrappers/PortableExecutable.cs b/SabreTools.Serialization/Wrappers/PortableExecutable.cs
index 5703c0a8..0326eb42 100644
--- a/SabreTools.Serialization/Wrappers/PortableExecutable.cs
+++ b/SabreTools.Serialization/Wrappers/PortableExecutable.cs
@@ -42,11 +42,8 @@ namespace SabreTools.Serialization.Wrappers
return null;
// Otherwise, build and return the cached dictionary
- lock (_sourceDataLock)
- {
- ParseDebugTable();
- return _debugData;
- }
+ ParseDebugTable();
+ return _debugData;
}
}
}
@@ -90,11 +87,8 @@ namespace SabreTools.Serialization.Wrappers
}
// Read the first 128 bytes of the entry point
- lock (_sourceDataLock)
- {
- _entryPointData = _dataSource.ReadFrom(entryPointAddress, length: 128, retainPosition: true);
- return _entryPointData;
- }
+ _entryPointData = ReadRangeFromSource(entryPointAddress, length: 128);
+ return _entryPointData;
}
}
}
@@ -145,11 +139,8 @@ namespace SabreTools.Serialization.Wrappers
return _headerPaddingData;
}
- lock (_sourceDataLock)
- {
- _headerPaddingData = _dataSource.ReadFrom((int)headerStartAddress, headerLength, retainPosition: true);
- return _headerPaddingData;
- }
+ _headerPaddingData = ReadRangeFromSource((int)headerStartAddress, headerLength);
+ return _headerPaddingData;
}
}
}
@@ -197,11 +188,8 @@ namespace SabreTools.Serialization.Wrappers
return _headerPaddingStrings;
}
- lock (_sourceDataLock)
- {
- _headerPaddingStrings = _dataSource.ReadStringsFrom((int)headerStartAddress, headerLength, charLimit: 3);
- return _headerPaddingStrings;
- }
+ _headerPaddingStrings = _dataSource.ReadStringsFrom((int)headerStartAddress, headerLength, charLimit: 3);
+ return _headerPaddingStrings;
}
}
}
@@ -321,12 +309,9 @@ namespace SabreTools.Serialization.Wrappers
}
// Otherwise, cache and return the data
- lock (_sourceDataLock)
- {
- long overlayLength = dataLength - endOfSectionData;
- _overlayData = _dataSource.ReadFrom(endOfSectionData, (int)overlayLength, retainPosition: true);
- return _overlayData;
- }
+ long overlayLength = dataLength - endOfSectionData;
+ _overlayData = ReadRangeFromSource(endOfSectionData, (int)overlayLength);
+ return _overlayData;
}
}
}
@@ -432,16 +417,13 @@ namespace SabreTools.Serialization.Wrappers
if (Stub?.Header?.NewExeHeaderAddr == null)
return null;
- lock (_sourceDataLock)
- {
- // Populate the raw stub executable data based on the source
- int endOfStubHeader = 0x40;
- int lengthOfStubExecutableData = (int)Stub.Header.NewExeHeaderAddr - endOfStubHeader;
- _stubExecutableData = _dataSource.ReadFrom(endOfStubHeader, lengthOfStubExecutableData, retainPosition: true);
+ // Populate the raw stub executable data based on the source
+ int endOfStubHeader = 0x40;
+ int lengthOfStubExecutableData = (int)Stub.Header.NewExeHeaderAddr - endOfStubHeader;
+ _stubExecutableData = ReadRangeFromSource(endOfStubHeader, lengthOfStubExecutableData);
- // Cache and return the stub executable data, even if null
- return _stubExecutableData;
- }
+ // Cache and return the stub executable data, even if null
+ return _stubExecutableData;
}
}
}
@@ -777,11 +759,6 @@ namespace SabreTools.Serialization.Wrappers
///
private AssemblyManifest? _assemblyManifest = null;
- ///
- /// Lock object for reading from the source
- ///
- private readonly object _sourceDataLock = new();
-
#endregion
#region Constructors
@@ -1035,7 +1012,7 @@ namespace SabreTools.Serialization.Wrappers
byte[]? entryData;
try
{
- entryData = _dataSource.ReadFrom((int)address, (int)size, retainPosition: true);
+ entryData = ReadRangeFromSource((int)address, (int)size);
if (entryData == null || entryData.Length < 4)
continue;
}
@@ -1545,7 +1522,11 @@ namespace SabreTools.Serialization.Wrappers
// Read the section into a local array
int sectionLength = (int)section.VirtualSize;
- byte[]? sectionData = source.ReadFrom(offset, sectionLength, retainPosition: true);
+ byte[]? sectionData;
+ lock (source)
+ {
+ sectionData = source.ReadFrom(offset, sectionLength, retainPosition: true);
+ }
// Parse the section header
var header = WiseSectionHeader.Create(sectionData, 0);
@@ -2209,22 +2190,20 @@ namespace SabreTools.Serialization.Wrappers
// Set the section size
uint size = section.SizeOfRawData;
- lock (_sourceDataLock)
- {
- // Create the section data array if we have to
- _sectionData ??= new byte[SectionNames.Length][];
- // If we already have cached data, just use that immediately
- if (_sectionData[index] != null && _sectionData[index].Length > 0)
- return _sectionData[index];
+ // Create the section data array if we have to
+ _sectionData ??= new byte[SectionNames.Length][];
- // Populate the raw section data based on the source
- byte[]? sectionData = _dataSource.ReadFrom((int)address, (int)size, retainPosition: true);
+ // If we already have cached data, just use that immediately
+ if (_sectionData[index] != null && _sectionData[index].Length > 0)
+ return _sectionData[index];
- // Cache and return the section data, even if null
- _sectionData[index] = sectionData ?? [];
- return sectionData;
- }
+ // Populate the raw section data based on the source
+ byte[]? sectionData = ReadRangeFromSource((int)address, (int)size);
+
+ // Cache and return the section data, even if null
+ _sectionData[index] = sectionData ?? [];
+ return sectionData;
}
///
@@ -2304,15 +2283,13 @@ namespace SabreTools.Serialization.Wrappers
// Set the section size
uint size = section.SizeOfRawData;
- lock (_sourceDataLock)
- {
- // Populate the section string data based on the source
- List? sectionStringData = _dataSource.ReadStringsFrom((int)address, (int)size);
- // Cache and return the section string data, even if null
- _sectionStringData[index] = sectionStringData ?? [];
- return sectionStringData;
- }
+ // Populate the section string data based on the source
+ List? sectionStringData = _dataSource.ReadStringsFrom((int)address, (int)size);
+
+ // Cache and return the section string data, even if null
+ _sectionStringData[index] = sectionStringData ?? [];
+ return sectionStringData;
}
}
@@ -2382,22 +2359,19 @@ namespace SabreTools.Serialization.Wrappers
if (address == 0 || size == 0)
return null;
- lock (_sourceDataLock)
- {
- // Create the table data array if we have to
- _tableData ??= new byte[16][];
+ // Create the table data array if we have to
+ _tableData ??= new byte[16][];
- // If we already have cached data, just use that immediately
- if (_tableData[index] != null && _tableData[index].Length > 0)
- return _tableData[index];
+ // If we already have cached data, just use that immediately
+ if (_tableData[index] != null && _tableData[index].Length > 0)
+ return _tableData[index];
- // Populate the raw table data based on the source
- byte[]? tableData = _dataSource.ReadFrom((int)address, (int)size, retainPosition: true);
+ // Populate the raw table data based on the source
+ byte[]? tableData = ReadRangeFromSource((int)address, (int)size);
- // Cache and return the table data, even if null
- _tableData[index] = tableData ?? [];
- return tableData;
- }
+ // Cache and return the table data, even if null
+ _tableData[index] = tableData ?? [];
+ return tableData;
}
///
@@ -2427,22 +2401,19 @@ namespace SabreTools.Serialization.Wrappers
if (address == 0 || size == 0)
return null;
- lock (_sourceDataLock)
- {
- // Create the table string array if we have to
- _tableStringData ??= new List[16];
+ // Create the table string array if we have to
+ _tableStringData ??= new List[16];
- // If we already have cached data, just use that immediately
- if (_tableStringData[index] != null && _tableStringData[index].Count > 0)
- return _tableStringData[index];
+ // If we already have cached data, just use that immediately
+ if (_tableStringData[index] != null && _tableStringData[index].Count > 0)
+ return _tableStringData[index];
- // Populate the table string data based on the source
- List? tableStringData = _dataSource.ReadStringsFrom((int)address, (int)size);
+ // Populate the table string data based on the source
+ List? tableStringData = _dataSource.ReadStringsFrom((int)address, (int)size);
- // Cache and return the table string data, even if null
- _tableStringData[index] = tableStringData ?? [];
- return tableStringData;
- }
+ // Cache and return the table string data, even if null
+ _tableStringData[index] = tableStringData ?? [];
+ return tableStringData;
}
#endregion
diff --git a/SabreTools.Serialization/Wrappers/Quantum.cs b/SabreTools.Serialization/Wrappers/Quantum.cs
index b78f9777..f8660cdc 100644
--- a/SabreTools.Serialization/Wrappers/Quantum.cs
+++ b/SabreTools.Serialization/Wrappers/Quantum.cs
@@ -141,7 +141,7 @@ namespace SabreTools.Serialization.Wrappers
// Read the entire compressed data
int compressedDataOffset = (int)CompressedDataOffset;
long compressedDataLength = Length - compressedDataOffset;
- var compressedData = _dataSource.ReadFrom(compressedDataOffset, (int)compressedDataLength, retainPosition: true);
+ var compressedData = ReadRangeFromSource(compressedDataOffset, (int)compressedDataLength);
// Print a debug reminder
if (includeDebug) Console.WriteLine("Quantum archive extraction is unsupported");
diff --git a/SabreTools.Serialization/Wrappers/SGA.cs b/SabreTools.Serialization/Wrappers/SGA.cs
index de59af2e..e8cf7776 100644
--- a/SabreTools.Serialization/Wrappers/SGA.cs
+++ b/SabreTools.Serialization/Wrappers/SGA.cs
@@ -204,7 +204,7 @@ namespace SabreTools.Serialization.Wrappers
long outputFileSize = GetUncompressedSize(index);
// Read the compressed data directly
- var compressedData = _dataSource.ReadFrom((int)fileOffset, (int)fileSize, retainPosition: true);
+ var compressedData = ReadRangeFromSource((int)fileOffset, (int)fileSize);
if (compressedData == null)
return false;
diff --git a/SabreTools.Serialization/Wrappers/VBSP.cs b/SabreTools.Serialization/Wrappers/VBSP.cs
index 8fc16853..d9c79a47 100644
--- a/SabreTools.Serialization/Wrappers/VBSP.cs
+++ b/SabreTools.Serialization/Wrappers/VBSP.cs
@@ -128,7 +128,7 @@ namespace SabreTools.Serialization.Wrappers
// Read the data
var lump = Lumps[index];
- var data = _dataSource.ReadFrom(lump.Offset, lump.Length, retainPosition: true);
+ var data = ReadRangeFromSource(lump.Offset, lump.Length);
if (data == null)
return false;
diff --git a/SabreTools.Serialization/Wrappers/WAD3.cs b/SabreTools.Serialization/Wrappers/WAD3.cs
index ac562c36..6b625a8a 100644
--- a/SabreTools.Serialization/Wrappers/WAD3.cs
+++ b/SabreTools.Serialization/Wrappers/WAD3.cs
@@ -127,7 +127,7 @@ namespace SabreTools.Serialization.Wrappers
// Read the data -- TODO: Handle uncompressed lumps (see BSP.ExtractTexture)
var lump = DirEntries[index];
- var data = _dataSource.ReadFrom((int)lump.Offset, (int)lump.Length, retainPosition: true);
+ var data = ReadRangeFromSource((int)lump.Offset, (int)lump.Length);
if (data == null)
return false;
diff --git a/SabreTools.Serialization/Wrappers/WrapperBase.cs b/SabreTools.Serialization/Wrappers/WrapperBase.cs
index ea9746de..eb20a890 100644
--- a/SabreTools.Serialization/Wrappers/WrapperBase.cs
+++ b/SabreTools.Serialization/Wrappers/WrapperBase.cs
@@ -1,5 +1,6 @@
using System;
using System.IO;
+using SabreTools.IO.Extensions;
using SabreTools.IO.Streams;
using SabreTools.Serialization.Interfaces;
@@ -57,6 +58,11 @@ namespace SabreTools.Serialization.Wrappers
}
#endif
+ ///
+ /// Lock for accessing
+ ///
+ protected readonly object _dataSourceLock = new();
+
#endregion
#region Constructors
@@ -89,6 +95,33 @@ namespace SabreTools.Serialization.Wrappers
#endregion
+ #region Data
+
+ ///
+ /// Read a number of bytes from an offset fomr the data source, if possible
+ ///
+ /// Offset within the data source to start reading
+ /// Number of bytes to read from the offset
+ /// Filled byte array on success, null on error
+ ///
+ /// This method locks the data source to avoid potential conflicts in reading
+ /// from the data source. This should be the preferred way of reading in cases
+ /// where there may be multiple threads accessing the wrapper.
+ ///
+ /// This method will return a null array if the length is greater than what is left
+ /// in the stream. This is different behavior than a normal stream read that would
+ /// attempt to read as much as possible, returning the amount of bytes read.
+ ///
+ protected byte[]? ReadRangeFromSource(long offset, int length)
+ {
+ lock (_dataSourceLock)
+ {
+ return _dataSource.ReadFrom(offset, length, retainPosition: true);
+ }
+ }
+
+ #endregion
+
#region JSON Export
#if NETCOREAPP
diff --git a/SabreTools.Serialization/Wrappers/XZP.cs b/SabreTools.Serialization/Wrappers/XZP.cs
index 4f1b9805..ae557494 100644
--- a/SabreTools.Serialization/Wrappers/XZP.cs
+++ b/SabreTools.Serialization/Wrappers/XZP.cs
@@ -139,7 +139,7 @@ namespace SabreTools.Serialization.Wrappers
return false;
// Load the item data
- var data = _dataSource.ReadFrom((int)directoryEntry.EntryOffset, (int)directoryEntry.EntryLength, retainPosition: true);
+ var data = ReadRangeFromSource((int)directoryEntry.EntryOffset, (int)directoryEntry.EntryLength);
if (data == null)
return false;