diff --git a/SabreTools.Serialization.Test/Readers/CDROMVolumeTests.cs b/SabreTools.Serialization.Test/Readers/CDROMVolumeTests.cs deleted file mode 100644 index cb60ed61..00000000 --- a/SabreTools.Serialization.Test/Readers/CDROMVolumeTests.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System.IO; -using System.Linq; -using SabreTools.Serialization.Readers; -using Xunit; - -namespace SabreTools.Serialization.Test.Readers -{ - public class CDROMVolumeTests - { - [Fact] - public void NullArray_Null() - { - byte[]? data = null; - int offset = 0; - var deserializer = new CDROMVolume(); - - var actual = deserializer.Deserialize(data, offset); - Assert.Null(actual); - } - - [Fact] - public void EmptyArray_Null() - { - byte[]? data = []; - int offset = 0; - var deserializer = new CDROMVolume(); - - var actual = deserializer.Deserialize(data, offset); - Assert.Null(actual); - } - - [Fact] - public void InvalidArray_Null() - { - byte[]? data = [.. Enumerable.Repeat(0xFF, 1024)]; - int offset = 0; - var deserializer = new CDROMVolume(); - - var actual = deserializer.Deserialize(data, offset); - Assert.Null(actual); - } - - [Fact] - public void NullStream_Null() - { - Stream? data = null; - var deserializer = new CDROMVolume(); - - var actual = deserializer.Deserialize(data); - Assert.Null(actual); - } - - [Fact] - public void EmptyStream_Null() - { - Stream? data = new MemoryStream([]); - var deserializer = new CDROMVolume(); - - var actual = deserializer.Deserialize(data); - Assert.Null(actual); - } - - [Fact] - public void InvalidStream_Null() - { - Stream? data = new MemoryStream([.. Enumerable.Repeat(0xFF, 1024)]); - var deserializer = new CDROMVolume(); - - var actual = deserializer.Deserialize(data); - Assert.Null(actual); - } - } -} diff --git a/SabreTools.Serialization/Extensions/CDROM.cs b/SabreTools.Serialization/Extensions/CDROM.cs new file mode 100644 index 00000000..bbe6e882 --- /dev/null +++ b/SabreTools.Serialization/Extensions/CDROM.cs @@ -0,0 +1,275 @@ +using System; +using System.IO; +using SabreTools.Data.Models.CDROM; +using SabreTools.IO; +using SabreTools.IO.Extensions; + +namespace SabreTools.Data.Extensions +{ + public static class CDROM + { + /// + /// Creates a stream that provides only the user data of a CDROM stream + /// + public class ISO9660Stream : Stream + { + // Base CDROM stream (2352-byte sector) + private readonly Stream _baseStream; + + // State variables + private long _position = 0; + private SectorMode _currentMode = SectorMode.UNKNOWN; + private long _userDataStart = 16; + private long _userDataEnd = 2064; + private long _isoSectorSize = Constants.Mode1DataSize; + + public ISO9660Stream(Stream inputStream) + { + if (!inputStream.CanSeek || !inputStream.CanRead) + throw new ArgumentException("Stream must be readable and seekable.", nameof(inputStream)); + _baseStream = inputStream; + } + + public override bool CanRead => true; + public override bool CanSeek => true; + public override bool CanWrite => false; + + public override void Flush() + { + _baseStream.Flush(); + } + + public override long Length + { + get + { + return (_baseStream.Length / Constants.CDROMSectorSize) * _isoSectorSize; + } + } + + public override void SetLength(long value) + { + throw new NotSupportedException("Setting the length of this stream is not supported."); + } + + public override void Write(byte[] buffer, int offset, int count) + { + throw new NotSupportedException("Writing to this stream is not supported."); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _baseStream.Dispose(); + } + base.Dispose(disposing); + } + + public override long Position + { + // Get the position of the underlying ISO9660 stream + get + { + // Get the user data location based on the current sector mode + SetState(_position); + + // Get the number of ISO sectors before current position + long isoPosition = (_position / Constants.CDROMSectorSize) * _isoSectorSize; + + // Add the within-sector position + long remainder = _position % Constants.CDROMSectorSize; + if (remainder > _userDataEnd) + isoPosition += _isoSectorSize; + else if (remainder > _userDataStart) + isoPosition += remainder - _userDataStart; + + return isoPosition; + } + set + { + // Seek to the underlying ISO9660 position + Seek(value, SeekOrigin.Begin); + } + } + + public override int Read(byte[] buffer, int offset, int count) + { + bool readEntireSector = false; + int totalRead = 0; + int remaining = count; + + while (remaining > 0 && _position < _baseStream.Length) + { + // Determine location of current sector + long baseStreamOffset = (_position / Constants.CDROMSectorSize) * Constants.CDROMSectorSize; + + // Set the current sector's mode and user data location + SetState(baseStreamOffset); + + // Deal with case where base position is not in ISO stream + long remainder = _position % Constants.CDROMSectorSize; + long sectorOffset = remainder - _userDataStart; + if (remainder < _userDataStart) + { + baseStreamOffset += _userDataStart; + sectorOffset = 0; + _position += _userDataStart; + } + else if (remainder >= _userDataEnd) + { + baseStreamOffset += Constants.CDROMSectorSize; + sectorOffset = 0; + _position += Constants.CDROMSectorSize - _userDataEnd + _userDataStart; + } + else + baseStreamOffset += remainder; + + // Sanity check on read location before seeking + if (baseStreamOffset < 0 || baseStreamOffset > _baseStream.Length) + { + throw new ArgumentOutOfRangeException(nameof(offset), "Attempted to seek outside the stream boundaries."); + } + + // Seek to target position in base CDROM stream + _baseStream.Seek(baseStreamOffset, SeekOrigin.Begin); + + // Read the remaining bytes, up to max of one ISO sector (2048 bytes) + int bytesToRead = (int)Math.Min(remaining, _isoSectorSize - sectorOffset); + + // Don't overshoot end of stream + bytesToRead = (int)Math.Min(bytesToRead, _baseStream.Length - _position); + + if (bytesToRead == (_isoSectorSize - sectorOffset)) + readEntireSector = true; + else + readEntireSector = false; + + // Finish reading if no more bytes to be read + if (bytesToRead <= 0) + break; + + // Read up to 2048 bytes from base CDROM stream + int bytesRead = _baseStream.Read(buffer, offset + totalRead, bytesToRead); + + // Update state for base stream + _position = _baseStream.Position; + if (readEntireSector) + _position += (Constants.CDROMSectorSize - _userDataEnd) + _userDataStart; + + // Update state for ISO stream + totalRead += bytesRead; + remaining -= bytesRead; + + if (bytesRead == 0) + break; + } + + return totalRead; + } + + public override long Seek(long offset, SeekOrigin origin) + { + // Get the intended position for the ISO9660 stream + long targetPosition; + switch (origin) + { + case SeekOrigin.Begin: + targetPosition = offset; + break; + case SeekOrigin.Current: + targetPosition = Position + offset; + break; + case SeekOrigin.End: + targetPosition = Length + offset; + break; + default: + throw new ArgumentException("Invalid SeekOrigin.", nameof(origin)); + } + + // Get the number of ISO sectors before current position + long newPosition = (targetPosition / _isoSectorSize) * Constants.CDROMSectorSize; + + // Set the current sector's mode and user data location + SetState(newPosition); + + // Add the within-sector position + newPosition += _userDataStart + (targetPosition % _isoSectorSize); + + if (newPosition < 0 || newPosition > _baseStream.Length) + { + throw new ArgumentOutOfRangeException(nameof(offset), "Attempted to seek outside the stream boundaries."); + } + + _position = _baseStream.Seek(newPosition, SeekOrigin.Begin); + return Position; + } + + private void SetState(long sectorLocation) + { + long oldPosition = _baseStream.Position; + long modePosition = (sectorLocation - sectorLocation % Constants.CDROMSectorSize) + 15; + _baseStream.Seek(modePosition, SeekOrigin.Begin); + byte modeByte = _baseStream.ReadByteValue(); + if (modeByte == 0) + _currentMode = SectorMode.MODE0; + else if (modeByte == 1) + _currentMode = SectorMode.MODE1; + else if (modeByte == 2) + { + _baseStream.Seek(modePosition + 3, SeekOrigin.Begin); + byte submode = _baseStream.ReadByteValue(); + if ((submode & 0x20) == 0x20) + _currentMode = SectorMode.MODE2_FORM2; + else + _currentMode = SectorMode.MODE2_FORM1; + } + else + _currentMode = SectorMode.UNKNOWN; + + // Set the user data location variables + switch (_currentMode) + { + case SectorMode.MODE1: + _userDataStart = 16; + _userDataEnd = 2064; + //_isoSectorSize = Constants.Mode1DataSize; + break; + + case SectorMode.MODE2_FORM1: + _userDataStart = 24; + _userDataEnd = 2072; + //_isoSectorSize = Constants.Form1DataSize; + break; + + case SectorMode.MODE2_FORM2: + _userDataStart = 24; + _userDataEnd = 2072; + // TODO: Support flexible sector length + //_userDataEnd = 2348; + //_isoSectorSize = Constants.Form2DataSize; + break; + + case SectorMode.MODE0: + case SectorMode.MODE2: + _userDataStart = 16; + _userDataEnd = 2064; + // TODO: Support flexible sector length + //_userDataEnd = 2352; + //_isoSectorSize = Constants.Mode0DataSize; + break; + + case SectorMode.UNKNOWN: + _userDataStart = 16; + _userDataEnd = 2064; + //_isoSectorSize = Constants.Mode1DataSize; + break; + } + + _baseStream.Seek(oldPosition, SeekOrigin.Begin); + + return; + } + } + } +} diff --git a/SabreTools.Serialization/Models/CDROM/CDROM.cs b/SabreTools.Serialization/Models/CDROM/CDROM.cs index 82527c1b..20bb2a50 100644 --- a/SabreTools.Serialization/Models/CDROM/CDROM.cs +++ b/SabreTools.Serialization/Models/CDROM/CDROM.cs @@ -1,15 +1,16 @@ namespace SabreTools.Data.Models.CDROM { /// - /// A CD-ROM disc image, made up of multiple data tracks, ISO 10149 / ECMA-130 - /// Specifically not a mixed-mode CD disc image, pure CD-ROM disc + /// A CD-ROM disc image, made up of data sectors, ISO 10149 / ECMA-130 + /// Intentionally not a mixed-mode CD disc image, pure CD-ROM disc (no audio sectors) + /// This model intentionally does not take tracks into consideration /// /// public sealed class CDROM { /// - /// CD-ROM data tracks + /// CD-ROM data sectors /// - public DataTrack[] Tracks { get; set; } = []; + public DataSector[] Sectors { get; set; } = []; } } diff --git a/SabreTools.Serialization/Models/CDROM/Constants.cs b/SabreTools.Serialization/Models/CDROM/Constants.cs new file mode 100644 index 00000000..3b3a677c --- /dev/null +++ b/SabreTools.Serialization/Models/CDROM/Constants.cs @@ -0,0 +1,34 @@ +namespace SabreTools.Data.Models.CDROM +{ + /// + /// CDROM constant values + /// + /// + public static class Constants + { + /// + /// Size of a complete CDROM data sector + /// + public const long CDROMSectorSize = 2352; + + /// + /// Size of user data length for Mode0 / Mode2 Formless + /// + public const long Mode0DataSize = 2336; + + /// + /// Size of user data length for Mode1 / Mode2 Form1 + /// + public const long Mode1DataSize = 2048; + + /// + /// Size of user data length for Mode1 / Mode2 Form1 + /// + public const long Form1DataSize = 2048; + + /// + /// Size of user data length for Mode2 Form2 + /// + public const long Form2DataSize = 2324; + } +} diff --git a/SabreTools.Serialization/Models/CDROM/Sector.cs b/SabreTools.Serialization/Models/CDROM/DataSector.cs similarity index 86% rename from SabreTools.Serialization/Models/CDROM/Sector.cs rename to SabreTools.Serialization/Models/CDROM/DataSector.cs index dc58db82..9e2914e0 100644 --- a/SabreTools.Serialization/Models/CDROM/Sector.cs +++ b/SabreTools.Serialization/Models/CDROM/DataSector.cs @@ -1,10 +1,10 @@ namespace SabreTools.Data.Models.CDROM { /// - /// A CD-ROM sector + /// A CD-ROM data sector /// /// - public abstract class Sector + public abstract class DataSector { /// /// Sync pattern, 12 bytes diff --git a/SabreTools.Serialization/Models/CDROM/DataTrack.cs b/SabreTools.Serialization/Models/CDROM/DataTrack.cs deleted file mode 100644 index 95bf5cbf..00000000 --- a/SabreTools.Serialization/Models/CDROM/DataTrack.cs +++ /dev/null @@ -1,21 +0,0 @@ -using SabreTools.Data.Models.ISO9660; - -namespace SabreTools.Data.Models.CDROM -{ - /// - /// A CD-ROM data track containing a ISO9660 / ECMA-119 filesystem - /// - /// - public sealed class DataTrack - { - /// - /// CD-ROM data sectors - /// - public Sector[] Sectors { get; set; } = []; - - /// - /// ISO9660 volume within the data track - /// - public Volume Volume { get; set; } = new(); - } -} diff --git a/SabreTools.Serialization/Models/CDROM/Mode1.cs b/SabreTools.Serialization/Models/CDROM/Mode1.cs index 703d2e72..b34d24d7 100644 --- a/SabreTools.Serialization/Models/CDROM/Mode1.cs +++ b/SabreTools.Serialization/Models/CDROM/Mode1.cs @@ -4,7 +4,7 @@ namespace SabreTools.Data.Models.CDROM /// A CD-ROM Mode1 sector /// /// - public sealed class Mode1 : Sector + public sealed class Mode1 : DataSector { /// /// User Data, 2048 bytes diff --git a/SabreTools.Serialization/Models/CDROM/Mode2Form1.cs b/SabreTools.Serialization/Models/CDROM/Mode2Form1.cs index 7b1316ac..417fa1e7 100644 --- a/SabreTools.Serialization/Models/CDROM/Mode2Form1.cs +++ b/SabreTools.Serialization/Models/CDROM/Mode2Form1.cs @@ -4,7 +4,7 @@ namespace SabreTools.Data.Models.CDROM /// A CD-ROM Mode 2 Form 1 sector /// /// - public sealed class Mode2Form1 : Sector + public sealed class Mode2Form1 : DataSector { /// /// Mode 2 subheader, 8 bytes diff --git a/SabreTools.Serialization/Models/CDROM/Mode2Form2.cs b/SabreTools.Serialization/Models/CDROM/Mode2Form2.cs index c93df04c..d3604d81 100644 --- a/SabreTools.Serialization/Models/CDROM/Mode2Form2.cs +++ b/SabreTools.Serialization/Models/CDROM/Mode2Form2.cs @@ -5,7 +5,7 @@ namespace SabreTools.Data.Models.CDROM /// Larger user data at expense of no error correction, just error detection /// /// - public sealed class Mode2Form2 : Sector + public sealed class Mode2Form2 : DataSector { /// /// Mode 2 subheader, 8 bytes diff --git a/SabreTools.Serialization/Models/ISO9660/Constants.cs b/SabreTools.Serialization/Models/ISO9660/Constants.cs index 3ceb1166..72ca1bbd 100644 --- a/SabreTools.Serialization/Models/ISO9660/Constants.cs +++ b/SabreTools.Serialization/Models/ISO9660/Constants.cs @@ -1,7 +1,7 @@ namespace SabreTools.Data.Models.ISO9660 { /// - /// ISO9660 filesystem extent + /// ISO9660 constant values and arrays /// /// public static class Constants diff --git a/SabreTools.Serialization/Readers/CDROMVolume.cs b/SabreTools.Serialization/Readers/CDROMVolume.cs deleted file mode 100644 index 73874b57..00000000 --- a/SabreTools.Serialization/Readers/CDROMVolume.cs +++ /dev/null @@ -1,170 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using SabreTools.Data.Models.CDROM; -using SabreTools.Data.Models.ISO9660; -using SabreTools.IO.Extensions; - -namespace SabreTools.Serialization.Readers -{ - public class CDROMVolume : ISO9660 - { - #region Constants - - private const int SectorSize = 2352; - - #endregion - - /// - public override Volume? Deserialize(Stream? data) - { - // If the data is invalid - if (data == null || !data.CanRead) - return null; - - // Simple check for a valid stream length - if (SectorSize * (Constants.SystemAreaSectors + 2) > data.Length - data.Position) - return null; - - try - { - // Create a new Volume to fill - var volume = new Volume(); - - // Read the System Area - volume.SystemArea = ParseCDROMSystemArea(data); - - // Read the set of Volume Descriptors - var vdSet = ParseCDROMVolumeDescriptorSet(data); - if (vdSet == null || vdSet.Length == 0) - return null; - - volume.VolumeDescriptorSet = vdSet; - - // Only the VolumeDescriptorSet can be read using the CDROMVolume Reader - // TODO: CDROM Reader that outputs CDROM.DataTrack that uses custom Stream to wrap ISO9660 for Volume - - return volume; - } - catch - { - // Ignore the actual error - return null; - } - } - - /// - /// Parse a Stream into the System Area - /// - /// Stream to parse - /// Filled byte[] on success, null on error - public static byte[] ParseCDROMSystemArea(Stream data) - { - var systemArea = new byte[Constants.SystemAreaSectors * Constants.MinimumSectorSize]; - // Process in sectors - for (int i = 0; i < Constants.SystemAreaSectors; i++) - { - // Ignore sector header - var mode = SkipSectorHeader(data); - - // Read user data - var userData = data.ReadBytes(Constants.MinimumSectorSize); - - // Copy user data into System Area - Buffer.BlockCopy(userData, 0, systemArea, i * Constants.MinimumSectorSize, Constants.MinimumSectorSize); - - // Ignore sector trailer - SkipSectorTrailer(data, mode); - } - - return systemArea; - } - - /// - /// Parse a CD-ROM Stream into the System Area - /// - /// Stream to parse - /// Filled byte[] on success, null on error - public static VolumeDescriptor[]? ParseCDROMVolumeDescriptorSet(Stream data) - { - var obj = new List(); - - bool setTerminated = false; - while (data.Position < data.Length) - { - // Ignore sector header - var mode = SkipSectorHeader(data); - - var volumeDescriptor = ParseVolumeDescriptor(data, Constants.MinimumSectorSize); - - // Ignore sector trailer - SkipSectorTrailer(data, mode); - - // If no valid volume descriptor could be read, return the current set - if (volumeDescriptor == null) - return [.. obj]; - - // If the set has already been terminated and the returned volume descriptor is not another terminator, - // assume the read volume descriptor is not a valid volume descriptor and return the current set - if (setTerminated && volumeDescriptor.Type != VolumeDescriptorType.VOLUME_DESCRIPTOR_SET_TERMINATOR) - { - // Reset stream to before the just-read volume descriptor - data.SeekIfPossible(-SectorSize, SeekOrigin.Current); - return [.. obj]; - } - - // Add the valid read volume descriptor to the set - obj.Add(volumeDescriptor); - - // If the set terminator was read, set the set terminated flag (further set terminators may be present) - if (!setTerminated && volumeDescriptor.Type == VolumeDescriptorType.VOLUME_DESCRIPTOR_SET_TERMINATOR) - setTerminated = true; - } - - return [.. obj]; - } - - /// - /// Skip the header bytes of a CD-ROM sector - /// - private static SectorMode SkipSectorHeader(Stream data) - { - // Ignore sector header - _ = data.ReadBytes(15); - - // Read sector mode - byte mode = data.ReadByteValue(); - if (mode == 0) - return SectorMode.MODE0; - else if (mode == 1) - return SectorMode.MODE1; - else if (mode == 2) - { - // Ignore subheader - var subheader = data.ReadBytes(8); - if ((subheader[2] & 0x20) == 0x20) - return SectorMode.MODE2_FORM2; - else - return SectorMode.MODE2_FORM1; - } - else - return SectorMode.UNKNOWN; - } - - /// - /// Skip the trailer bytes of a CD-ROM sector - /// - private static void SkipSectorTrailer(Stream data, SectorMode mode) - { - if (mode == SectorMode.MODE1 || mode == SectorMode.MODE0 || mode == SectorMode.UNKNOWN) - { - _ = data.ReadBytes(288); - } - else if (mode == SectorMode.MODE2 || mode == SectorMode.MODE2_FORM1 || mode == SectorMode.MODE2_FORM2) - { - // TODO: Better deal with Form 2 - _ = data.ReadBytes(280); - } - } - } -} diff --git a/SabreTools.Serialization/Wrappers/CDROM.Extraction.cs b/SabreTools.Serialization/Wrappers/CDROM.Extraction.cs deleted file mode 100644 index caa9fc12..00000000 --- a/SabreTools.Serialization/Wrappers/CDROM.Extraction.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace SabreTools.Serialization.Wrappers -{ - public partial class CDROM : IExtractable - { - /// - public override bool Extract(string outputDirectory, bool includeDebug) - => false; - } -} diff --git a/SabreTools.Serialization/Wrappers/CDROM.Printing.cs b/SabreTools.Serialization/Wrappers/CDROM.Printing.cs deleted file mode 100644 index d1c4ab98..00000000 --- a/SabreTools.Serialization/Wrappers/CDROM.Printing.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Text; -using SabreTools.Data.Extensions; - -namespace SabreTools.Serialization.Wrappers -{ - public partial class CDROM : IPrintable - { - /// - public new void PrintInformation(StringBuilder builder) - { - builder.AppendLine("CD-ROM Data Track Information:"); - builder.AppendLine("-------------------------"); - builder.AppendLine(); - - if (Model.SystemArea == null || Model.SystemArea.Length == 0) - builder.AppendLine(Model.SystemArea, "System Area"); - else if (Array.TrueForAll(Model.SystemArea, b => b == 0)) - builder.AppendLine("Zeroed", "System Area"); - else - builder.AppendLine("Not Zeroed", "System Area"); - builder.AppendLine(); - - Print(builder, Model.VolumeDescriptorSet); - } - } -} diff --git a/SabreTools.Serialization/Wrappers/CDROM.cs b/SabreTools.Serialization/Wrappers/CDROM.cs index 6ce07a52..76070d47 100644 --- a/SabreTools.Serialization/Wrappers/CDROM.cs +++ b/SabreTools.Serialization/Wrappers/CDROM.cs @@ -8,7 +8,7 @@ public partial class CDROM : ISO9660 #region Descriptive Properties /// - public override string DescriptionString => "CD-ROM Data Track"; + public override string DescriptionString => "CD-ROM ISO 9660 Volume"; #endregion @@ -37,9 +37,9 @@ public CDROM(Volume model, Stream data, long offset, long length) : base(model, #region Static Constructors /// - /// Create an CDROM data track from a byte array and offset + /// Create a CDROM data track from a byte array and offset /// - /// Byte array representing the archive + /// Byte array representing the CDROM data track /// Offset within the array to parse /// A CDROM data track wrapper on success, null on failure public new static CDROM? Create(byte[]? data, int offset) @@ -58,26 +58,33 @@ public CDROM(Volume model, Stream data, long offset, long length) : base(model, } /// - /// Create an CDROM data track from a Stream + /// Create a CDROM data track from a Stream /// - /// Stream representing the archive + /// Seekable Stream representing the CDROM data track /// A CDROM data track wrapper on success, null on failure public new static CDROM? Create(Stream? data) { // If the data is invalid - if (data == null || !data.CanRead) + if (data == null || !data.CanRead || !data.CanSeek) return null; try { + // Create user data sub-stream + SabreTools.Data.Extensions.CDROM.ISO9660Stream userData = new(data); + // Cache the current offset - long currentOffset = data.Position; + long currentOffset = userData.Position; - var model = new Readers.CDROMVolume().Deserialize(data); + // Deserialize just the sub-stream + var model = new Readers.ISO9660().Deserialize(userData); if (model == null) return null; - return new CDROM(model, data, currentOffset); + // Reset stream + userData.Seek(currentOffset, SeekOrigin.Begin); + + return new CDROM(model, userData, userData.Position); } catch { diff --git a/SabreTools.Serialization/Wrappers/ISO9660.Printing.cs b/SabreTools.Serialization/Wrappers/ISO9660.Printing.cs index d9a1f9b5..375e79ae 100644 --- a/SabreTools.Serialization/Wrappers/ISO9660.Printing.cs +++ b/SabreTools.Serialization/Wrappers/ISO9660.Printing.cs @@ -20,13 +20,7 @@ public void PrintInformation(StringBuilder builder) builder.AppendLine("-------------------------"); builder.AppendLine(); - if (Model.SystemArea.Length == 0) - builder.AppendLine(Model.SystemArea, "System Area"); - else if (Array.TrueForAll(Model.SystemArea, b => b == 0)) - builder.AppendLine("Zeroed", "System Area"); - else - builder.AppendLine("Not Zeroed", "System Area"); - builder.AppendLine(); + Print(builder, Model.SystemArea); Print(builder, Model.VolumeDescriptorSet); @@ -36,6 +30,17 @@ public void PrintInformation(StringBuilder builder) Print(builder, Model.DirectoryDescriptors, encoding); } + protected static void Print(StringBuilder builder, byte[]? systemArea) + { + if (systemArea == null || systemArea.Length == 0) + builder.AppendLine(systemArea, " System Area"); + else if (Array.TrueForAll(systemArea, b => b == 0)) + builder.AppendLine("Zeroed", " System Area"); + else + builder.AppendLine("Not Zeroed", " System Area"); + builder.AppendLine(); + } + #region Volume Descriptors protected static void Print(StringBuilder builder, VolumeDescriptor[] vdSet) diff --git a/SabreTools.Serialization/Wrappers/ISO9660.cs b/SabreTools.Serialization/Wrappers/ISO9660.cs index b2626ea9..c0d153e2 100644 --- a/SabreTools.Serialization/Wrappers/ISO9660.cs +++ b/SabreTools.Serialization/Wrappers/ISO9660.cs @@ -56,7 +56,7 @@ public ISO9660(Volume model, Stream data, long offset, long length) : base(model /// /// Create an ISO9660 Volume from a byte array and offset /// - /// Byte array representing the archive + /// Byte array representing the ISO9660 Volume /// Offset within the array to parse /// An ISO 9660 Volume wrapper on success, null on failure public static ISO9660? Create(byte[]? data, int offset) @@ -77,7 +77,7 @@ public ISO9660(Volume model, Stream data, long offset, long length) : base(model /// /// Create an ISO9660 Volume from a Stream /// - /// Stream representing the archive + /// Stream representing the ISO9660 Volume /// An ISO9660 Volume wrapper on success, null on failure public static ISO9660? Create(Stream? data) {