diff --git a/SabreTools.Serialization/Models/CDROM/Mode1.cs b/SabreTools.Serialization/Models/CDROM/Mode1.cs
index b34d24d7..6ab9cf3b 100644
--- a/SabreTools.Serialization/Models/CDROM/Mode1.cs
+++ b/SabreTools.Serialization/Models/CDROM/Mode1.cs
@@ -22,7 +22,7 @@ namespace SabreTools.Data.Models.CDROM
public byte[] Intermediate { get; set; } = new byte[8];
///
- /// Error Correction Code, 4 bytes
+ /// Error Correction Code, 276 bytes
///
public byte[] ECC { get; set; } = new byte[276];
}
diff --git a/SabreTools.Serialization/Models/CDROM/Mode2Form1.cs b/SabreTools.Serialization/Models/CDROM/Mode2Form1.cs
index 417fa1e7..3ad4fa36 100644
--- a/SabreTools.Serialization/Models/CDROM/Mode2Form1.cs
+++ b/SabreTools.Serialization/Models/CDROM/Mode2Form1.cs
@@ -22,7 +22,7 @@ namespace SabreTools.Data.Models.CDROM
public byte[] EDC { get; set; } = new byte[4];
///
- /// Error Correction Code, 4 bytes
+ /// Error Correction Code, 276 bytes
///
public byte[] ECC { get; set; } = new byte[276];
}
diff --git a/SabreTools.Serialization/Readers/CDROM.cs b/SabreTools.Serialization/Readers/CDROM.cs
new file mode 100644
index 00000000..2026d35e
--- /dev/null
+++ b/SabreTools.Serialization/Readers/CDROM.cs
@@ -0,0 +1,97 @@
+using System.IO;
+using SabreTools.Data.Extensions;
+using SabreTools.Data.Models.CDROM;
+using SabreTools.IO.Extensions;
+
+namespace SabreTools.Serialization.Readers
+{
+ ///
+ /// This intentionally does not inherit from
+ ///
+ public class CDROM
+ {
+ ///
+ /// Parse a Stream into a DataSector
+ ///
+ /// Stream to parse
+ /// Filled DataSector on success, null on error
+ /// Assumes a seekable stream
+ public static DataSector? ParseDataSector(Stream data)
+ {
+ SectorMode sectorMode = data.GetSectorMode();
+ return sectorMode switch
+ {
+ SectorMode.MODE0 => null, // TODO: Create data sector for Mode0
+ SectorMode.MODE1 => ParseMode1(data),
+ SectorMode.MODE2 => null, // TODO: Create a data sector for Mode2 formless
+ SectorMode.MODE2_FORM1 => ParseMode2Form1(data),
+ SectorMode.MODE2_FORM2 => ParseMode2Form2(data),
+
+ SectorMode.UNKNOWN => null,
+ _ => null,
+ };
+ }
+
+ ///
+ /// Parse a Stream into a Mode1
+ ///
+ /// Stream to parse
+ /// Filled Mode1 on success, null on error
+ public static Mode1 ParseMode1(Stream data)
+ {
+ var obj = new Mode1();
+
+ obj.SyncPattern = data.ReadBytes(12);
+ obj.Address = data.ReadBytes(3);
+ obj.Mode = data.ReadByteValue();
+
+ obj.UserData = data.ReadBytes(2048);
+ obj.EDC = data.ReadBytes(4);
+ obj.Intermediate = data.ReadBytes(8);
+ obj.ECC = data.ReadBytes(276);
+
+ return obj;
+ }
+
+ ///
+ /// Parse a Stream into a Mode2Form1
+ ///
+ /// Stream to parse
+ /// Filled Mode2Form1 on success, null on error
+ public static Mode2Form1 ParseMode2Form1(Stream data)
+ {
+ var obj = new Mode2Form1();
+
+ obj.SyncPattern = data.ReadBytes(12);
+ obj.Address = data.ReadBytes(3);
+ obj.Mode = data.ReadByteValue();
+
+ obj.Subheader = data.ReadBytes(8);
+ obj.UserData = data.ReadBytes(2048);
+ obj.EDC = data.ReadBytes(4);
+ obj.ECC = data.ReadBytes(276);
+
+ return obj;
+ }
+
+ ///
+ /// Parse a Stream into a Mode2Form2
+ ///
+ /// Stream to parse
+ /// Filled Mode2Form2 on success, null on error
+ public static Mode2Form2 ParseMode2Form2(Stream data)
+ {
+ var obj = new Mode2Form2();
+
+ obj.SyncPattern = data.ReadBytes(12);
+ obj.Address = data.ReadBytes(3);
+ obj.Mode = data.ReadByteValue();
+
+ obj.Subheader = data.ReadBytes(8);
+ obj.UserData = data.ReadBytes(2324);
+ obj.EDC = data.ReadBytes(4);
+
+ return obj;
+ }
+ }
+}