diff --git a/SabreTools.Serialization/Wrappers/NewExecutable.cs b/SabreTools.Serialization/Wrappers/NewExecutable.cs index 8b4a2dd1..080670c5 100644 --- a/SabreTools.Serialization/Wrappers/NewExecutable.cs +++ b/SabreTools.Serialization/Wrappers/NewExecutable.cs @@ -365,11 +365,11 @@ namespace SabreTools.Serialization.Wrappers #region Resources /// - /// Get the data for a single resource entry + /// Get a single resource entry /// /// Resource ID to retrieve - /// Resource data on success, null otherwise - public byte[]? GetResourceData(int id) + /// Resource on success, null otherwise + public Models.NewExecutable.ResourceTypeResourceEntry? GetResource(int id) { // If the header is invalid if (Header == null) @@ -398,17 +398,8 @@ namespace SabreTools.Serialization.Wrappers if (resource.ResourceID != id) continue; - // Skip empty entries - if (resource.Length == 0) - return []; - - // Verify the resource offset - int offset = resource.Offset << ResourceTable.AlignmentShiftCount; - if (offset < 0 || offset + resource.Length >= endOfFile) - return null; - - // Read the segment data and return - return ReadFromDataSource(offset, resource.Length); + // Return the resource + return resource; } } @@ -416,10 +407,109 @@ namespace SabreTools.Serialization.Wrappers return null; } + /// + /// Get the data for a single resource entry + /// + /// Resource ID to retrieve + /// Resource data on success, null otherwise + public byte[]? GetResourceData(int id) + { + // Get the end of the file, if possible + int endOfFile = GetEndOfFile(); + if (endOfFile == -1) + return null; + + // If the resource table is invalid + if (ResourceTable == null) + return null; + + // Get the matching resource + var resource = GetSegment(id); + if (resource == null) + return null; + + // Skip empty entries + if (resource.Length == 0) + return []; + + // Verify the resource offset + int offset = resource.Offset << ResourceTable.AlignmentShiftCount; + if (offset < 0 || offset + resource.Length >= endOfFile) + return null; + + // Read the segment data and return + return ReadFromDataSource(offset, resource.Length); + } + + /// + /// Get the data length for a single resource entry + /// + /// Resource ID to retrieve + /// Resource length on success, -1 otherwise + public int GetResourceLength(int id) + { + // Get the matching resource + var resource = GetSegment(id); + if (resource == null) + return -1; + + // Return the reported length + return resource.Length; + } + + /// + /// Get the data offset for a single resource entry + /// + /// Resource ID to retrieve + /// Resource offset on success, -1 otherwise + public int GetResourceOffset(int id) + { + // Get the end of the file, if possible + int endOfFile = GetEndOfFile(); + if (endOfFile == -1) + return -1; + + // If the resource table is invalid + if (ResourceTable == null) + return -1; + + // Get the matching resource + var resource = GetSegment(id); + if (resource == null) + return -1; + + // Verify the resource offset + int offset = resource.Offset << ResourceTable.AlignmentShiftCount; + if (offset < 0 || offset + resource.Length >= endOfFile) + return -1; + + // Return the verified offset + return offset; + } + #endregion #region Segments + /// + /// Get a single segment + /// + /// Segment index to retrieve + /// Segment on success, null otherwise + public Models.NewExecutable.SegmentTableEntry? GetSegment(int index) + { + // If the segment table is invalid + if (SegmentTable == null || SegmentTable.Length == 0) + return null; + + // If the index is invalid + if (index < 0 || index >= SegmentTable.Length) + return null; + + // Return the segment + return SegmentTable[index]; + } + /// /// Get the data for a single segment /// @@ -436,16 +526,12 @@ namespace SabreTools.Serialization.Wrappers if (endOfFile == -1) return null; - // If the segment table is invalid - if (SegmentTable == null || SegmentTable.Length == 0) + // Get the matching segment + var segment = GetSegment(index); + if (segment == null) return null; - // If the index is invalid - if (index < 0 || index >= Header.FileSegmentCount || index >= SegmentTable.Length) - return null; - - // Get the segment from the table - var segment = SegmentTable[index]; + // Verify the segment length if (segment.Length == 0) return []; @@ -458,6 +544,52 @@ namespace SabreTools.Serialization.Wrappers return ReadFromDataSource(offset, segment.Length); } + /// + /// Get the data length for a single segment + /// + /// Segment index to retrieve + /// Segment length on success, -1 otherwise + public int GetSegmentLength(int index) + { + // Get the matching segment + var segment = GetSegment(index); + if (segment == null) + return -1; + + // Return the reported length + return segment.Length; + } + + /// + /// Get the data offset for a single segment + /// + /// Segment index to retrieve + /// Segment offset on success, -1 otherwise + public int GetSegmentOffset(int index) + { + // If the header is invalid + if (Header == null) + return -1; + + // Get the end of the file, if possible + int endOfFile = GetEndOfFile(); + if (endOfFile == -1) + return -1; + + // Get the matching segment + var segment = GetSegment(index); + if (segment == null) + return -1; + + // Verify the segment offset + int offset = segment.Offset << Header.SegmentAlignmentShiftCount; + if (offset < 0 || offset + segment.Length >= endOfFile) + return -1; + + // Return the verified offset + return offset; + } + #endregion #region REMOVE -- DO NOT USE