Make sure source data isn't locked unnecessarily

This commit is contained in:
Matt Nadareski
2025-09-02 23:56:29 -04:00
parent 72a1484a71
commit ecb09ce6f2
3 changed files with 52 additions and 38 deletions

View File

@@ -0,0 +1,40 @@
using System.Collections.Generic;
using System.Text;
using SabreTools.IO.Extensions;
namespace SabreTools.Serialization
{
// TODO: Move this to IO
public static class ByteArrayExtensions
{
/// <summary>
/// Read string data from the source
/// </summary>
/// <param name="charLimit">Number of characters needed to be a valid string, default 5</param>
/// <returns>String list containing the requested data, null on error</returns>
public static List<string>? ReadStringsFrom(this byte[]? input, int charLimit = 5)
{
// Validate the data
if (input == null)
return null;
// Check for ASCII strings
var asciiStrings = input.ReadStringsWithEncoding(charLimit, Encoding.ASCII);
// Check for UTF-8 strings
// We are limiting the check for Unicode characters with a second byte of 0x00 for now
var utf8Strings = input.ReadStringsWithEncoding(charLimit, Encoding.UTF8);
// Check for Unicode strings
// We are limiting the check for Unicode characters with a second byte of 0x00 for now
var unicodeStrings = input.ReadStringsWithEncoding(charLimit, Encoding.Unicode);
// Ignore duplicate strings across encodings
List<string> sourceStrings = [.. asciiStrings, .. utf8Strings, .. unicodeStrings];
// Sort the strings and return
sourceStrings.Sort();
return sourceStrings;
}
}
}

View File

@@ -178,30 +178,17 @@ namespace SabreTools.Serialization.Wrappers
if (Header == null || SegmentTable == null || ResourceTable?.ResourceTypes == null)
return null;
// Get the overlay address if possible
long endOfSectionData = OverlayAddress;
// If we didn't find the end of section data
if (endOfSectionData <= 0)
return null;
// If we're at the end of the file, cache an empty byte array
if (endOfSectionData >= dataLength)
// Get the overlay data, if possible
byte[]? overlayData = OverlayData;
if (overlayData == null || overlayData.Length == 0)
{
_overlayStrings = [];
return _overlayStrings;
}
lock (_sourceDataLock)
{
// TODO: Revisit the 16 MiB limit
// Cap the check for overlay strings to 16 MiB (arbitrary)
long overlayLength = Math.Min(dataLength - endOfSectionData, 16 * 1024 * 1024);
// Otherwise, cache and return the strings
_overlayStrings = _dataSource.ReadStringsFrom((int)endOfSectionData, (int)overlayLength, charLimit: 3);
return _overlayStrings;
}
// Otherwise, cache and return the strings
_overlayStrings = overlayData.ReadStringsFrom(charLimit: 3);
return _overlayStrings;
}
}
}

View File

@@ -353,30 +353,17 @@ namespace SabreTools.Serialization.Wrappers
if (SectionTable == null)
return null;
// Get the overlay address if possible
long endOfSectionData = OverlayAddress;
// If we didn't find the end of section data
if (endOfSectionData <= 0)
return null;
// If we're at the end of the file, cache an empty byte array
if (endOfSectionData >= dataLength)
// Get the overlay data, if possible
byte[]? overlayData = OverlayData;
if (overlayData == null || overlayData.Length == 0)
{
_overlayStrings = [];
return _overlayStrings;
}
lock (_sourceDataLock)
{
// TODO: Revisit the 16 MiB limit
// Cap the check for overlay strings to 16 MiB (arbitrary)
long overlayLength = Math.Min(dataLength - endOfSectionData, 16 * 1024 * 1024);
// Otherwise, cache and return the strings
_overlayStrings = _dataSource.ReadStringsFrom((int)endOfSectionData, (int)overlayLength, charLimit: 3);
return _overlayStrings;
}
// Otherwise, cache and return the strings
_overlayStrings = overlayData.ReadStringsFrom(charLimit: 3);
return _overlayStrings;
}
}
}