diff --git a/SabreTools.Data.Extensions.Test/OperaFSExtensionsTests.cs b/SabreTools.Data.Extensions.Test/OperaFSExtensionsTests.cs index 64c21fa9..e2aa455c 100644 --- a/SabreTools.Data.Extensions.Test/OperaFSExtensionsTests.cs +++ b/SabreTools.Data.Extensions.Test/OperaFSExtensionsTests.cs @@ -1,27 +1,26 @@ -using SabreTools.Data.Models.OperaFS; -using SabreTools.Numerics; -using Xunit; - -namespace SabreTools.Data.Extensions.Test -{ - public class OperaFSExtensionsTests - { - [Fact] - public void DirectoryDescriptor_EqualsExactly_Empty() - { - var dir1 = new DirectoryDescriptor(); - var dir2 = new DirectoryDescriptor(); - bool actual = dir1.EqualsExactly(dir2); - Assert.True(actual); - } - - [Fact] - public void DirectoryRecord_EqualsExactly_Empty() - { - var dr1 = new DirectoryRecord(); - var dr2 = new DirectoryRecord(); - bool actual = dr1.EqualsExactly(dr2); - Assert.True(actual); - } - } -} +using SabreTools.Data.Models.OperaFS; +using Xunit; + +namespace SabreTools.Data.Extensions.Test +{ + public class OperaFSExtensionsTests + { + [Fact] + public void DirectoryDescriptor_EqualsExactly_Empty() + { + var dir1 = new DirectoryDescriptor(); + var dir2 = new DirectoryDescriptor(); + bool actual = dir1.EqualsExactly(dir2); + Assert.True(actual); + } + + [Fact] + public void DirectoryRecord_EqualsExactly_Empty() + { + var dr1 = new DirectoryRecord(); + var dr2 = new DirectoryRecord(); + bool actual = dr1.EqualsExactly(dr2); + Assert.True(actual); + } + } +} diff --git a/SabreTools.Data.Extensions/OperaFSExtensions.cs b/SabreTools.Data.Extensions/OperaFSExtensions.cs index 1f3b147d..b66c05ec 100644 --- a/SabreTools.Data.Extensions/OperaFSExtensions.cs +++ b/SabreTools.Data.Extensions/OperaFSExtensions.cs @@ -1,6 +1,5 @@ using SabreTools.Data.Models.OperaFS; using SabreTools.Matching; -using SabreTools.Numerics; namespace SabreTools.Data.Extensions { @@ -26,7 +25,7 @@ namespace SabreTools.Data.Extensions return false; if (dir1.DirectoryRecords.Length != dir2.DirectoryRecords.Length) return false; - + for (int i = 0; i < dir1.DirectoryRecords.Length; i++) { if (!dir1.DirectoryRecords[i].EqualsExactly(dir2.DirectoryRecords[i])) @@ -66,7 +65,7 @@ namespace SabreTools.Data.Extensions return false; if (dr1.AvatarList.Length != dr2.AvatarList.Length) return false; - + for (int i = 0; i < dr1.AvatarList.Length; i++) { if (dr1.AvatarList[i] != dr2.AvatarList[i]) diff --git a/SabreTools.Serialization.Readers/OperaFS.cs b/SabreTools.Serialization.Readers/OperaFS.cs index c3cbab00..21e56f7d 100644 --- a/SabreTools.Serialization.Readers/OperaFS.cs +++ b/SabreTools.Serialization.Readers/OperaFS.cs @@ -63,7 +63,7 @@ namespace SabreTools.Serialization.Readers public static VolumeDescriptor ParseVolumeDescriptor(Stream data) { var volumeDescriptor = new VolumeDescriptor(); - + volumeDescriptor.RecordType = data.ReadByteValue(); volumeDescriptor.VolumeSyncBytes = data.ReadBytes(5); volumeDescriptor.StructureVersion = data.ReadByteValue(); @@ -77,7 +77,7 @@ namespace SabreTools.Serialization.Readers volumeDescriptor.RootDirectoryBlockCount = data.ReadUInt32BigEndian(); volumeDescriptor.RootDirectoryBlockSize = data.ReadUInt32BigEndian(); volumeDescriptor.RootDirectoryLastAvatarIndex = data.ReadUInt32BigEndian(); - + for (int i = 0; i < 8; i++) { volumeDescriptor.RootDirectoryAvatarList[i] = data.ReadUInt32BigEndian(); @@ -107,7 +107,7 @@ namespace SabreTools.Serialization.Readers { var directories = new Dictionary(); - data.SeekIfPossible(initialOffset + volumeDescriptor.RootDirectoryAvatarList[0] * Constants.SectorSize, SeekOrigin.Begin); + data.SeekIfPossible(initialOffset + (volumeDescriptor.RootDirectoryAvatarList[0] * Constants.SectorSize), SeekOrigin.Begin); var rootDirectory = ParseDirectory(data); for (int i = 0; i <= volumeDescriptor.RootDirectoryLastAvatarIndex; i++) { @@ -139,13 +139,13 @@ namespace SabreTools.Serialization.Readers if ((dr.DirectoryRecordFlags & DirectoryRecordFlags.DIRECTORY) == 0) continue; - data.SeekIfPossible(initialOffset + dr.AvatarList[0] * Constants.SectorSize, SeekOrigin.Begin); + data.SeekIfPossible(initialOffset + (dr.AvatarList[0] * Constants.SectorSize), SeekOrigin.Begin); var directory = ParseDirectory(data); directories.Add(dr.AvatarList[0], directory); for (int i = 1; i <= dr.LastAvatarIndex; i++) { // Read avatar - data.SeekIfPossible(initialOffset + dr.AvatarList[i] * Constants.SectorSize, SeekOrigin.Begin); + data.SeekIfPossible(initialOffset + (dr.AvatarList[i] * Constants.SectorSize), SeekOrigin.Begin); var avatar = ParseDirectory(data); // Add reference to original directory if avatar is identical @@ -200,7 +200,7 @@ namespace SabreTools.Serialization.Readers } } - directory.DirectoryRecords = directoryRecords.ToArray(); + directory.DirectoryRecords = [.. directoryRecords]; return directory; } @@ -213,7 +213,7 @@ namespace SabreTools.Serialization.Readers public static DirectoryRecord ParseDirectoryRecord(Stream data) { var directoryRecord = new DirectoryRecord(); - + directoryRecord.DirectoryRecordFlags = (DirectoryRecordFlags)data.ReadUInt32BigEndian(); directoryRecord.UniqueIdentifier = data.ReadBytes(4); directoryRecord.Type = data.ReadBytes(4); @@ -224,7 +224,7 @@ namespace SabreTools.Serialization.Readers directoryRecord.Gap = data.ReadUInt32BigEndian(); directoryRecord.Filename = data.ReadBytes(32); directoryRecord.LastAvatarIndex = data.ReadUInt32BigEndian(); - + directoryRecord.AvatarList = new uint[directoryRecord.LastAvatarIndex + 1]; for (int i = 0; i <= directoryRecord.LastAvatarIndex; i++) { diff --git a/SabreTools.Wrappers.Test/OperaDiscImageTests.cs b/SabreTools.Wrappers.Test/OperaDiscImageTests.cs index 41ce6fc9..cf2807e3 100644 --- a/SabreTools.Wrappers.Test/OperaDiscImageTests.cs +++ b/SabreTools.Wrappers.Test/OperaDiscImageTests.cs @@ -1,60 +1,60 @@ -using System.IO; -using System.Linq; -using Xunit; - -namespace SabreTools.Wrappers.Test -{ - public class OperaDiscImageTests - { - [Fact] - public void NullArray_Null() - { - byte[]? data = null; - int offset = 0; - var actual = OperaDiscImage.Create(data, offset); - Assert.Null(actual); - } - - [Fact] - public void EmptyArray_Null() - { - byte[]? data = []; - int offset = 0; - var actual = OperaDiscImage.Create(data, offset); - Assert.Null(actual); - } - - [Fact] - public void InvalidArray_Null() - { - byte[]? data = [.. Enumerable.Repeat(0xFF, 1024)]; - int offset = 0; - var actual = OperaDiscImage.Create(data, offset); - Assert.Null(actual); - } - - [Fact] - public void NullStream_Null() - { - Stream? data = null; - var actual = OperaDiscImage.Create(data); - Assert.Null(actual); - } - - [Fact] - public void EmptyStream_Null() - { - Stream? data = new MemoryStream([]); - var actual = OperaDiscImage.Create(data); - Assert.Null(actual); - } - - [Fact] - public void InvalidStream_Null() - { - Stream? data = new MemoryStream([.. Enumerable.Repeat(0xFF, 1024)]); - var actual = OperaDiscImage.Create(data); - Assert.Null(actual); - } - } -} +using System.IO; +using System.Linq; +using Xunit; + +namespace SabreTools.Wrappers.Test +{ + public class OperaDiscImageTests + { + [Fact] + public void NullArray_Null() + { + byte[]? data = null; + int offset = 0; + var actual = OperaDiscImage.Create(data, offset); + Assert.Null(actual); + } + + [Fact] + public void EmptyArray_Null() + { + byte[]? data = []; + int offset = 0; + var actual = OperaDiscImage.Create(data, offset); + Assert.Null(actual); + } + + [Fact] + public void InvalidArray_Null() + { + byte[]? data = [.. Enumerable.Repeat(0xFF, 1024)]; + int offset = 0; + var actual = OperaDiscImage.Create(data, offset); + Assert.Null(actual); + } + + [Fact] + public void NullStream_Null() + { + Stream? data = null; + var actual = OperaDiscImage.Create(data); + Assert.Null(actual); + } + + [Fact] + public void EmptyStream_Null() + { + Stream? data = new MemoryStream([]); + var actual = OperaDiscImage.Create(data); + Assert.Null(actual); + } + + [Fact] + public void InvalidStream_Null() + { + Stream? data = new MemoryStream([.. Enumerable.Repeat(0xFF, 1024)]); + var actual = OperaDiscImage.Create(data); + Assert.Null(actual); + } + } +} diff --git a/SabreTools.Wrappers/OperaDiscImage.cs b/SabreTools.Wrappers/OperaDiscImage.cs index 1f01e12f..c0355bbd 100644 --- a/SabreTools.Wrappers/OperaDiscImage.cs +++ b/SabreTools.Wrappers/OperaDiscImage.cs @@ -1,97 +1,97 @@ -using System.IO; -using SabreTools.Data.Models.OperaFS; - -namespace SabreTools.Wrappers -{ - public partial class OperaDiscImage : OperaFS - { - #region Descriptive Properties - - /// - public override string DescriptionString => "3DO / M2 (Opera) Disc Image"; - - #endregion - - #region Constructors - - /// - public OperaDiscImage(FileSystem model, byte[] data) : base(model, data) { } - - /// - public OperaDiscImage(FileSystem model, byte[] data, int offset) : base(model, data, offset) { } - - /// - public OperaDiscImage(FileSystem model, byte[] data, int offset, int length) : base(model, data, offset, length) { } - - /// - public OperaDiscImage(FileSystem model, Stream data) : base(model, data) { } - - /// - public OperaDiscImage(FileSystem model, Stream data, long offset) : base(model, data, offset) { } - - /// - public OperaDiscImage(FileSystem model, Stream data, long offset, long length) : base(model, data, offset, length) { } - - #endregion - - #region Static Constructors - - /// - /// Create a OperaDiscImage filesystem from a byte array and offset - /// - /// Byte array representing the OperaDiscImage filesystem - /// Offset within the array to parse - /// A OperaDiscImage filesystem wrapper on success, null on failure - public static new OperaDiscImage? Create(byte[]? data, int offset) - { - // If the data is invalid - if (data is null || data.Length == 0) - return null; - - // If the offset is out of bounds - if (offset < 0 || offset >= data.Length) - return null; - - // Create a memory stream and use that - var dataStream = new MemoryStream(data, offset, data.Length - offset); - return Create(dataStream); - } - - /// - /// Create a OperaDiscImage filesystem from a Stream - /// - /// Seekable Stream representing the OperaDiscImage filesystem - /// A OperaDiscImage filesystem wrapper on success, null on failure - public static new OperaDiscImage? Create(Stream? data) - { - // If the data is invalid - if (data is null || !data.CanRead || !data.CanSeek) - return null; - - try - { - // Create user data sub-stream - var userData = new Data.Extensions.CDROMExtensions.UserDataStream(data); - - // Cache the current offset - long currentOffset = userData.Position; - - // Deserialize just the sub-stream - var model = new Serialization.Readers.OperaFS().Deserialize(userData); - if (model is null) - return null; - - // Reset stream - userData.Seek(currentOffset, SeekOrigin.Begin); - - return new OperaDiscImage(model, userData, userData.Position); - } - catch - { - return null; - } - } - - #endregion - } -} +using System.IO; +using SabreTools.Data.Models.OperaFS; + +namespace SabreTools.Wrappers +{ + public partial class OperaDiscImage : OperaFS + { + #region Descriptive Properties + + /// + public override string DescriptionString => "3DO / M2 (Opera) Disc Image"; + + #endregion + + #region Constructors + + /// + public OperaDiscImage(FileSystem model, byte[] data) : base(model, data) { } + + /// + public OperaDiscImage(FileSystem model, byte[] data, int offset) : base(model, data, offset) { } + + /// + public OperaDiscImage(FileSystem model, byte[] data, int offset, int length) : base(model, data, offset, length) { } + + /// + public OperaDiscImage(FileSystem model, Stream data) : base(model, data) { } + + /// + public OperaDiscImage(FileSystem model, Stream data, long offset) : base(model, data, offset) { } + + /// + public OperaDiscImage(FileSystem model, Stream data, long offset, long length) : base(model, data, offset, length) { } + + #endregion + + #region Static Constructors + + /// + /// Create a OperaDiscImage filesystem from a byte array and offset + /// + /// Byte array representing the OperaDiscImage filesystem + /// Offset within the array to parse + /// A OperaDiscImage filesystem wrapper on success, null on failure + public static new OperaDiscImage? Create(byte[]? data, int offset) + { + // If the data is invalid + if (data is null || data.Length == 0) + return null; + + // If the offset is out of bounds + if (offset < 0 || offset >= data.Length) + return null; + + // Create a memory stream and use that + var dataStream = new MemoryStream(data, offset, data.Length - offset); + return Create(dataStream); + } + + /// + /// Create a OperaDiscImage filesystem from a Stream + /// + /// Seekable Stream representing the OperaDiscImage filesystem + /// A OperaDiscImage filesystem wrapper on success, null on failure + public static new OperaDiscImage? Create(Stream? data) + { + // If the data is invalid + if (data is null || !data.CanRead || !data.CanSeek) + return null; + + try + { + // Create user data sub-stream + var userData = new Data.Extensions.CDROMExtensions.UserDataStream(data); + + // Cache the current offset + long currentOffset = userData.Position; + + // Deserialize just the sub-stream + var model = new Serialization.Readers.OperaFS().Deserialize(userData); + if (model is null) + return null; + + // Reset stream + userData.Seek(currentOffset, SeekOrigin.Begin); + + return new OperaDiscImage(model, userData, userData.Position); + } + catch + { + return null; + } + } + + #endregion + } +} diff --git a/SabreTools.Wrappers/OperaFS.Extraction.cs b/SabreTools.Wrappers/OperaFS.Extraction.cs index 451d2e1a..4b4f6b4f 100644 --- a/SabreTools.Wrappers/OperaFS.Extraction.cs +++ b/SabreTools.Wrappers/OperaFS.Extraction.cs @@ -2,10 +2,8 @@ using System; using System.Collections.Generic; using System.IO; using System.Text; -using SabreTools.Data.Extensions; using SabreTools.Data.Models.OperaFS; using SabreTools.IO.Extensions; -using SabreTools.Matching; using SabreTools.Numerics.Extensions; namespace SabreTools.Wrappers diff --git a/SabreTools.Wrappers/OperaFS.Printing.cs b/SabreTools.Wrappers/OperaFS.Printing.cs index 7b28dfa9..53563a47 100644 --- a/SabreTools.Wrappers/OperaFS.Printing.cs +++ b/SabreTools.Wrappers/OperaFS.Printing.cs @@ -52,7 +52,7 @@ namespace SabreTools.Wrappers builder.AppendLine(vd.StructureVersion, " Structure Version"); builder.AppendLine((byte)vd.VolumeFlags, " Volume Flags"); - if ((byte)vd.VolumeFlags != 0) + if (vd.VolumeFlags != 0) { builder.AppendLine(" Volume Flags (Parsed)"); builder.AppendLine((vd.VolumeFlags & VolumeFlags.M2) == VolumeFlags.M2, " M2 Disc (or M1 Data Disc)");