diff --git a/SabreTools.Models/SeparatedValue/Row.cs b/SabreTools.Models/SeparatedValue/Row.cs index 1786cea4..44979ffb 100644 --- a/SabreTools.Models/SeparatedValue/Row.cs +++ b/SabreTools.Models/SeparatedValue/Row.cs @@ -6,55 +6,55 @@ namespace SabreTools.Models.SeparatedValue public class Row { /// File Name - public string FileName { get; set; } + public string? FileName { get; set; } /// Internal Name - public string InternalName { get; set; } + public string? InternalName { get; set; } /// Description - public string Description { get; set; } + public string? Description { get; set; } /// Game Name public string GameName { get; set; } /// Game Description - public string GameDescription { get; set; } + public string? GameDescription { get; set; } /// Type public string Type { get; set; } /// Rom Name - public string RomName { get; set; } + public string? RomName { get; set; } /// Disk Name - public string DiskName { get; set; } + public string? DiskName { get; set; } /// Size, Numeric - public string Size { get; set; } + public string? Size { get; set; } /// CRC - public string CRC { get; set; } + public string? CRC { get; set; } /// MD5 - public string MD5 { get; set; } + public string? MD5 { get; set; } /// SHA1 - public string SHA1 { get; set; } + public string? SHA1 { get; set; } /// SHA256 - public string SHA256 { get; set; } + public string? SHA256 { get; set; } /// SHA384, Optional - public string SHA384 { get; set; } + public string? SHA384 { get; set; } /// SHA512, Optional - public string SHA512 { get; set; } + public string? SHA512 { get; set; } /// SpamSum, Optional - public string SpamSum { get; set; } + public string? SpamSum { get; set; } /// Status, Nodump - public string Status { get; set; } + public string? Status { get; set; } #region DO NOT USE IN PRODUCTION diff --git a/SabreTools.Serialization/AttractMode.Deserializer.cs b/SabreTools.Serialization/AttractMode.Deserializer.cs index 39a8031c..83de3bdb 100644 --- a/SabreTools.Serialization/AttractMode.Deserializer.cs +++ b/SabreTools.Serialization/AttractMode.Deserializer.cs @@ -19,16 +19,8 @@ namespace SabreTools.Serialization /// Deserialized data on success, null on failure public static MetadataFile? Deserialize(string path) { - try - { - using var stream = PathProcessor.OpenStream(path); - return Deserialize(stream); - } - catch - { - // TODO: Handle logging the exception - return default; - } + using var stream = PathProcessor.OpenStream(path); + return Deserialize(stream); } /// @@ -38,103 +30,95 @@ namespace SabreTools.Serialization /// Deserialized data on success, null on failure public static MetadataFile? Deserialize(Stream? stream) { - try + // If the stream is null + if (stream == null) + return default; + + // Setup the reader and output + var reader = new SeparatedValueReader(stream, Encoding.UTF8) { - // If the stream is null - if (stream == null) - return default; + Separator = ';', + VerifyFieldCount = false, + }; + var dat = new MetadataFile(); - // Setup the reader and output - var reader = new SeparatedValueReader(stream, Encoding.UTF8) + // Read the header values first + if (!reader.ReadHeader()) + return null; + + dat.Header = reader.HeaderValues.ToArray(); + + // Loop through the rows and parse out values + var rows = new List(); + while (!reader.EndOfStream) + { + // If we have no next line + if (!reader.ReadNextLine()) + break; + + // Parse the line into a row + Row? row = null; + if (reader.Line.Count < HeaderWithRomnameCount) { - Separator = ';', - VerifyFieldCount = false, - }; - var dat = new MetadataFile(); + row = new Row + { + Name = reader.Line[0], + Title = reader.Line[1], + Emulator = reader.Line[2], + CloneOf = reader.Line[3], + Year = reader.Line[4], + Manufacturer = reader.Line[5], + Category = reader.Line[6], + Players = reader.Line[7], + Rotation = reader.Line[8], + Control = reader.Line[9], + Status = reader.Line[10], + DisplayCount = reader.Line[11], + DisplayType = reader.Line[12], + AltRomname = reader.Line[13], + AltTitle = reader.Line[14], + Extra = reader.Line[15], + Buttons = reader.Line[16], + }; - // Read the header values first - if (!reader.ReadHeader()) - return null; - - dat.Header = reader.HeaderValues.ToArray(); - - // Loop through the rows and parse out values - var rows = new List(); - while (!reader.EndOfStream) + // If we have additional fields + if (reader.Line.Count > HeaderWithoutRomnameCount) + row.ADDITIONAL_ELEMENTS = reader.Line.Skip(HeaderWithoutRomnameCount).ToArray(); + } + else { - // If we have no next line - if (!reader.ReadNextLine()) - break; - - // Parse the line into a row - Row? row = null; - if (reader.Line.Count < HeaderWithRomnameCount) + row = new Row { - row = new Row - { - Name = reader.Line[0], - Title = reader.Line[1], - Emulator = reader.Line[2], - CloneOf = reader.Line[3], - Year = reader.Line[4], - Manufacturer = reader.Line[5], - Category = reader.Line[6], - Players = reader.Line[7], - Rotation = reader.Line[8], - Control = reader.Line[9], - Status = reader.Line[10], - DisplayCount = reader.Line[11], - DisplayType = reader.Line[12], - AltRomname = reader.Line[13], - AltTitle = reader.Line[14], - Extra = reader.Line[15], - Buttons = reader.Line[16], - }; + Name = reader.Line[0], + Title = reader.Line[1], + Emulator = reader.Line[2], + CloneOf = reader.Line[3], + Year = reader.Line[4], + Manufacturer = reader.Line[5], + Category = reader.Line[6], + Players = reader.Line[7], + Rotation = reader.Line[8], + Control = reader.Line[9], + Status = reader.Line[10], + DisplayCount = reader.Line[11], + DisplayType = reader.Line[12], + AltRomname = reader.Line[13], + AltTitle = reader.Line[14], + Extra = reader.Line[15], + Buttons = reader.Line[16], + }; - // If we have additional fields - if (reader.Line.Count > HeaderWithoutRomnameCount) - row.ADDITIONAL_ELEMENTS = reader.Line.Skip(HeaderWithoutRomnameCount).ToArray(); - } - else - { - row = new Row - { - Name = reader.Line[0], - Title = reader.Line[1], - Emulator = reader.Line[2], - CloneOf = reader.Line[3], - Year = reader.Line[4], - Manufacturer = reader.Line[5], - Category = reader.Line[6], - Players = reader.Line[7], - Rotation = reader.Line[8], - Control = reader.Line[9], - Status = reader.Line[10], - DisplayCount = reader.Line[11], - DisplayType = reader.Line[12], - AltRomname = reader.Line[13], - AltTitle = reader.Line[14], - Extra = reader.Line[15], - Buttons = reader.Line[16], - }; - - // If we have additional fields - if (reader.Line.Count > HeaderWithRomnameCount) - row.ADDITIONAL_ELEMENTS = reader.Line.Skip(HeaderWithRomnameCount).ToArray(); - } - - rows.Add(row); + // If we have additional fields + if (reader.Line.Count > HeaderWithRomnameCount) + row.ADDITIONAL_ELEMENTS = reader.Line.Skip(HeaderWithRomnameCount).ToArray(); } - // Assign the rows to the Dat and return - dat.Row = rows.ToArray(); - return dat; - } - catch - { - // TODO: Handle logging the exception - return default; + rows.Add(row); } + + // Assign the rows to the Dat and return + dat.Row = rows.ToArray(); + return dat; } } } \ No newline at end of file diff --git a/SabreTools.Serialization/AttractMode.Serializer.cs b/SabreTools.Serialization/AttractMode.Serializer.cs index c51880de..24a91777 100644 --- a/SabreTools.Serialization/AttractMode.Serializer.cs +++ b/SabreTools.Serialization/AttractMode.Serializer.cs @@ -19,22 +19,14 @@ namespace SabreTools.Serialization /// True on successful serialization, false otherwise public static bool SerializeToFile(MetadataFile? metadataFile, string path) { - try - { - using var stream = SerializeToStream(metadataFile); - if (stream == null) - return false; - - using var fs = File.OpenWrite(path); - stream.Seek(0, SeekOrigin.Begin); - stream.CopyTo(fs); - return true; - } - catch - { - // TODO: Handle logging the exception + using var stream = SerializeToStream(metadataFile); + if (stream == null) return false; - } + + using var fs = File.OpenWrite(path); + stream.Seek(0, SeekOrigin.Begin); + stream.CopyTo(fs); + return true; } /// @@ -44,31 +36,28 @@ namespace SabreTools.Serialization /// Stream containing serialized data on success, null otherwise public static Stream? SerializeToStream(MetadataFile? metadataFile) { - try - { - // If the metadata file is null - if (metadataFile == null) - return null; - - // Setup the writer and output - var stream = new MemoryStream(); - var writer = new SeparatedValueWriter(stream, Encoding.UTF8) { Separator = ';', Quotes = false }; - - // TODO: Include flag to write out long or short header - // Write the short header - writer.WriteString(HeaderWithoutRomname); // TODO: Convert to array of values - - // Write out the rows, if they exist - WriteRows(metadataFile.Row, writer); - - // Return the stream - return stream; - } - catch - { - // TODO: Handle logging the exception + // If the metadata file is null + if (metadataFile == null) return null; - } + + // Setup the writer and output + var stream = new MemoryStream(); + var writer = new SeparatedValueWriter(stream, Encoding.UTF8) + { + Separator = ';', + Quotes = false, + VerifyFieldCount = false, + }; + + // TODO: Include flag to write out long or short header + // Write the short header + writer.WriteString(HeaderWithoutRomname); // TODO: Convert to array of values + + // Write out the rows, if they exist + WriteRows(metadataFile.Row, writer); + + // Return the stream + return stream; } /// @@ -85,7 +74,7 @@ namespace SabreTools.Serialization // Loop through and write out the rows foreach (var row in rows) { - var rowArray = new string[] + var rowArray = new string?[] { row.Name, row.Title, diff --git a/SabreTools.Serialization/ClrMamePro.Deserializer.cs b/SabreTools.Serialization/ClrMamePro.Deserializer.cs index 0c282fc2..adf70d7f 100644 --- a/SabreTools.Serialization/ClrMamePro.Deserializer.cs +++ b/SabreTools.Serialization/ClrMamePro.Deserializer.cs @@ -19,16 +19,8 @@ namespace SabreTools.Serialization /// Deserialized data on success, null on failure public static MetadataFile? Deserialize(string path, bool quotes) { - try - { - using var stream = PathProcessor.OpenStream(path); - return Deserialize(stream, quotes); - } - catch - { - // TODO: Handle logging the exception - return default; - } + using var stream = PathProcessor.OpenStream(path); + return Deserialize(stream, quotes); } /// @@ -39,305 +31,297 @@ namespace SabreTools.Serialization /// Deserialized data on success, null on failure public static MetadataFile? Deserialize(Stream? stream, bool quotes) { - try + // If the stream is null + if (stream == null) + return default; + + // Setup the reader and output + var reader = new ClrMameProReader(stream, Encoding.UTF8) { Quotes = quotes }; + var dat = new MetadataFile(); + + // Loop through and parse out the values + string lastTopLevel = reader.TopLevel; + + GameBase? game = null; + var games = new List(); + var releases = new List(); + var biosSets = new List(); + var roms = new List(); + var disks = new List(); + var medias = new List(); + var samples = new List(); + var archives = new List(); + var chips = new List(); + var dipSwitches = new List(); + + var additional = new List(); + var headerAdditional = new List(); + var gameAdditional = new List(); + while (!reader.EndOfStream) { - // If the stream is null - if (stream == null) - return default; + // If we have no next line + if (!reader.ReadNextLine()) + break; - // Setup the reader and output - var reader = new ClrMameProReader(stream, Encoding.UTF8) { Quotes = quotes }; - var dat = new MetadataFile(); - - // Loop through and parse out the values - string lastTopLevel = reader.TopLevel; - - GameBase? game = null; - var games = new List(); - var releases = new List(); - var biosSets = new List(); - var roms = new List(); - var disks = new List(); - var medias = new List(); - var samples = new List(); - var archives = new List(); - var chips = new List(); - var dipSwitches = new List(); - - var additional = new List(); - var headerAdditional = new List(); - var gameAdditional = new List(); - while (!reader.EndOfStream) + // Ignore certain row types + switch (reader.RowType) { - // If we have no next line - if (!reader.ReadNextLine()) - break; - - // Ignore certain row types - switch (reader.RowType) - { - case CmpRowType.None: - case CmpRowType.Comment: - continue; - case CmpRowType.EndTopLevel: - switch (lastTopLevel) - { - case "doscenter": - dat.ClrMamePro!.ADDITIONAL_ELEMENTS = headerAdditional.ToArray(); - headerAdditional.Clear(); - break; - case "game": - case "machine": - case "resource": - case "set": - game!.Release = releases.ToArray(); - game.BiosSet = biosSets.ToArray(); - game.Rom = roms.ToArray(); - game.Disk = disks.ToArray(); - game.Media = medias.ToArray(); - game.Sample = samples.ToArray(); - game.Archive = archives.ToArray(); - game.Chip = chips.ToArray(); - game.DipSwitch = dipSwitches.ToArray(); - game.ADDITIONAL_ELEMENTS = gameAdditional.ToArray(); - - games.Add(game); - game = null; - - releases.Clear(); - biosSets.Clear(); - roms.Clear(); - disks.Clear(); - medias.Clear(); - samples.Clear(); - archives.Clear(); - chips.Clear(); - dipSwitches.Clear(); - gameAdditional.Clear(); - break; - default: - // No-op - break; - } - continue; - } - - // If we're at the root - if (reader.RowType == CmpRowType.TopLevel) - { - lastTopLevel = reader.TopLevel; - switch (reader.TopLevel) + case CmpRowType.None: + case CmpRowType.Comment: + continue; + case CmpRowType.EndTopLevel: + switch (lastTopLevel) { - case "clrmamepro": - dat.ClrMamePro = new Models.ClrMamePro.ClrMamePro(); + case "doscenter": + dat.ClrMamePro!.ADDITIONAL_ELEMENTS = headerAdditional.ToArray(); + headerAdditional.Clear(); break; case "game": - game = new Game(); - break; case "machine": - game = new Machine(); - break; case "resource": - game = new Resource(); - break; case "set": - game = new Set(); + game!.Release = releases.ToArray(); + game.BiosSet = biosSets.ToArray(); + game.Rom = roms.ToArray(); + game.Disk = disks.ToArray(); + game.Media = medias.ToArray(); + game.Sample = samples.ToArray(); + game.Archive = archives.ToArray(); + game.Chip = chips.ToArray(); + game.DipSwitch = dipSwitches.ToArray(); + game.ADDITIONAL_ELEMENTS = gameAdditional.ToArray(); + + games.Add(game); + game = null; + + releases.Clear(); + biosSets.Clear(); + roms.Clear(); + disks.Clear(); + medias.Clear(); + samples.Clear(); + archives.Clear(); + chips.Clear(); + dipSwitches.Clear(); + gameAdditional.Clear(); break; default: - additional.Add(reader.CurrentLine); + // No-op break; } - } + continue; + } - // If we're in the doscenter block - else if (reader.TopLevel == "clrmamepro" - && reader.RowType == CmpRowType.Standalone) + // If we're at the root + if (reader.RowType == CmpRowType.TopLevel) + { + lastTopLevel = reader.TopLevel; + switch (reader.TopLevel) { - // Create the block if we haven't already - dat.ClrMamePro ??= new Models.ClrMamePro.ClrMamePro(); - - switch (reader.Standalone?.Key?.ToLowerInvariant()) - { - case "name": - dat.ClrMamePro.Name = reader.Standalone?.Value; - break; - case "description": - dat.ClrMamePro.Description = reader.Standalone?.Value; - break; - case "rootdir": - dat.ClrMamePro.RootDir = reader.Standalone?.Value; - break; - case "category": - dat.ClrMamePro.Category = reader.Standalone?.Value; - break; - case "version": - dat.ClrMamePro.Version = reader.Standalone?.Value; - break; - case "date": - dat.ClrMamePro.Date = reader.Standalone?.Value; - break; - case "author": - dat.ClrMamePro.Author = reader.Standalone?.Value; - break; - case "homepage": - dat.ClrMamePro.Homepage = reader.Standalone?.Value; - break; - case "url": - dat.ClrMamePro.Url = reader.Standalone?.Value; - break; - case "comment": - dat.ClrMamePro.Comment = reader.Standalone?.Value; - break; - case "header": - dat.ClrMamePro.Header = reader.Standalone?.Value; - break; - case "type": - dat.ClrMamePro.Type = reader.Standalone?.Value; - break; - case "forcemerging": - dat.ClrMamePro.ForceMerging = reader.Standalone?.Value; - break; - case "forcezipping": - dat.ClrMamePro.ForceZipping = reader.Standalone?.Value; - break; - case "forcepacking": - dat.ClrMamePro.ForcePacking = reader.Standalone?.Value; - break; - default: - headerAdditional.Add(reader.CurrentLine); - break; - } - } - - // If we're in a game, machine, resource, or set block - else if ((reader.TopLevel == "game" - || reader.TopLevel == "machine" - || reader.TopLevel == "resource" - || reader.TopLevel == "set") - && reader.RowType == CmpRowType.Standalone) - { - // Create the block if we haven't already - game ??= reader.TopLevel switch - { - "game" => new Game(), - "machine" => new Machine(), - "resource" => new Resource(), - "set" => new Set(), - _ => throw new FormatException($"Unknown top-level block: {reader.TopLevel}"), - }; - - switch (reader.Standalone?.Key?.ToLowerInvariant()) - { - case "name": - game.Name = reader.Standalone?.Value; - break; - case "description": - game.Description = reader.Standalone?.Value; - break; - case "year": - game.Year = reader.Standalone?.Value; - break; - case "manufacturer": - game.Manufacturer = reader.Standalone?.Value; - break; - case "category": - game.Category = reader.Standalone?.Value; - break; - case "cloneof": - game.CloneOf = reader.Standalone?.Value; - break; - case "romof": - game.RomOf = reader.Standalone?.Value; - break; - case "sampleof": - game.SampleOf = reader.Standalone?.Value; - break; - case "sample": - var sample = new Sample - { - Name = reader.Standalone?.Value ?? string.Empty, - ADDITIONAL_ELEMENTS = Array.Empty() - }; - samples.Add(sample); - break; - default: - gameAdditional.Add(reader.CurrentLine); - break; - } - } - - // If we're in an item block - else if ((reader.TopLevel == "game" - || reader.TopLevel == "machine" - || reader.TopLevel == "resource" - || reader.TopLevel == "set") - && game != null - && reader.RowType == CmpRowType.Internal) - { - // Create the block - switch (reader.InternalName) - { - case "release": - releases.Add(CreateRelease(reader)); - break; - case "biosset": - biosSets.Add(CreateBiosSet(reader)); - break; - case "rom": - roms.Add(CreateRom(reader)); - break; - case "disk": - disks.Add(CreateDisk(reader)); - break; - case "media": - medias.Add(CreateMedia(reader)); - break; - case "sample": - samples.Add(CreateSample(reader)); - break; - case "archive": - archives.Add(CreateArchive(reader)); - break; - case "chip": - chips.Add(CreateChip(reader)); - break; - case "video": - game.Video = CreateVideo(reader); - break; - case "sound": - game.Sound = CreateSound(reader); - break; - case "input": - game.Input = CreateInput(reader); - break; - case "dipswitch": - dipSwitches.Add(CreateDipSwitch(reader)); - break; - case "driver": - game.Driver = CreateDriver(reader); - break; - default: - gameAdditional.Add(reader.CurrentLine); - continue; - } - } - - else - { - additional.Add(reader.CurrentLine); + case "clrmamepro": + dat.ClrMamePro = new Models.ClrMamePro.ClrMamePro(); + break; + case "game": + game = new Game(); + break; + case "machine": + game = new Machine(); + break; + case "resource": + game = new Resource(); + break; + case "set": + game = new Set(); + break; + default: + additional.Add(reader.CurrentLine); + break; } } - // Add extra pieces and return - dat.Game = games.ToArray(); - dat.ADDITIONAL_ELEMENTS = additional.ToArray(); - return dat; - } - catch - { - // TODO: Handle logging the exception - return default; + // If we're in the doscenter block + else if (reader.TopLevel == "clrmamepro" + && reader.RowType == CmpRowType.Standalone) + { + // Create the block if we haven't already + dat.ClrMamePro ??= new Models.ClrMamePro.ClrMamePro(); + + switch (reader.Standalone?.Key?.ToLowerInvariant()) + { + case "name": + dat.ClrMamePro.Name = reader.Standalone?.Value; + break; + case "description": + dat.ClrMamePro.Description = reader.Standalone?.Value; + break; + case "rootdir": + dat.ClrMamePro.RootDir = reader.Standalone?.Value; + break; + case "category": + dat.ClrMamePro.Category = reader.Standalone?.Value; + break; + case "version": + dat.ClrMamePro.Version = reader.Standalone?.Value; + break; + case "date": + dat.ClrMamePro.Date = reader.Standalone?.Value; + break; + case "author": + dat.ClrMamePro.Author = reader.Standalone?.Value; + break; + case "homepage": + dat.ClrMamePro.Homepage = reader.Standalone?.Value; + break; + case "url": + dat.ClrMamePro.Url = reader.Standalone?.Value; + break; + case "comment": + dat.ClrMamePro.Comment = reader.Standalone?.Value; + break; + case "header": + dat.ClrMamePro.Header = reader.Standalone?.Value; + break; + case "type": + dat.ClrMamePro.Type = reader.Standalone?.Value; + break; + case "forcemerging": + dat.ClrMamePro.ForceMerging = reader.Standalone?.Value; + break; + case "forcezipping": + dat.ClrMamePro.ForceZipping = reader.Standalone?.Value; + break; + case "forcepacking": + dat.ClrMamePro.ForcePacking = reader.Standalone?.Value; + break; + default: + headerAdditional.Add(reader.CurrentLine); + break; + } + } + + // If we're in a game, machine, resource, or set block + else if ((reader.TopLevel == "game" + || reader.TopLevel == "machine" + || reader.TopLevel == "resource" + || reader.TopLevel == "set") + && reader.RowType == CmpRowType.Standalone) + { + // Create the block if we haven't already + game ??= reader.TopLevel switch + { + "game" => new Game(), + "machine" => new Machine(), + "resource" => new Resource(), + "set" => new Set(), + _ => throw new FormatException($"Unknown top-level block: {reader.TopLevel}"), + }; + + switch (reader.Standalone?.Key?.ToLowerInvariant()) + { + case "name": + game.Name = reader.Standalone?.Value; + break; + case "description": + game.Description = reader.Standalone?.Value; + break; + case "year": + game.Year = reader.Standalone?.Value; + break; + case "manufacturer": + game.Manufacturer = reader.Standalone?.Value; + break; + case "category": + game.Category = reader.Standalone?.Value; + break; + case "cloneof": + game.CloneOf = reader.Standalone?.Value; + break; + case "romof": + game.RomOf = reader.Standalone?.Value; + break; + case "sampleof": + game.SampleOf = reader.Standalone?.Value; + break; + case "sample": + var sample = new Sample + { + Name = reader.Standalone?.Value ?? string.Empty, + ADDITIONAL_ELEMENTS = Array.Empty() + }; + samples.Add(sample); + break; + default: + gameAdditional.Add(reader.CurrentLine); + break; + } + } + + // If we're in an item block + else if ((reader.TopLevel == "game" + || reader.TopLevel == "machine" + || reader.TopLevel == "resource" + || reader.TopLevel == "set") + && game != null + && reader.RowType == CmpRowType.Internal) + { + // Create the block + switch (reader.InternalName) + { + case "release": + releases.Add(CreateRelease(reader)); + break; + case "biosset": + biosSets.Add(CreateBiosSet(reader)); + break; + case "rom": + roms.Add(CreateRom(reader)); + break; + case "disk": + disks.Add(CreateDisk(reader)); + break; + case "media": + medias.Add(CreateMedia(reader)); + break; + case "sample": + samples.Add(CreateSample(reader)); + break; + case "archive": + archives.Add(CreateArchive(reader)); + break; + case "chip": + chips.Add(CreateChip(reader)); + break; + case "video": + game.Video = CreateVideo(reader); + break; + case "sound": + game.Sound = CreateSound(reader); + break; + case "input": + game.Input = CreateInput(reader); + break; + case "dipswitch": + dipSwitches.Add(CreateDipSwitch(reader)); + break; + case "driver": + game.Driver = CreateDriver(reader); + break; + default: + gameAdditional.Add(reader.CurrentLine); + continue; + } + } + + else + { + additional.Add(reader.CurrentLine); + } } + + // Add extra pieces and return + dat.Game = games.ToArray(); + dat.ADDITIONAL_ELEMENTS = additional.ToArray(); + return dat; } /// diff --git a/SabreTools.Serialization/ClrMamePro.Serializer.cs b/SabreTools.Serialization/ClrMamePro.Serializer.cs index 52fa24b4..0724201e 100644 --- a/SabreTools.Serialization/ClrMamePro.Serializer.cs +++ b/SabreTools.Serialization/ClrMamePro.Serializer.cs @@ -20,22 +20,14 @@ namespace SabreTools.Serialization /// True on successful serialization, false otherwise public static bool SerializeToFile(MetadataFile? metadataFile, string path, bool quotes) { - try - { - using var stream = SerializeToStream(metadataFile, quotes); - if (stream == null) - return false; - - using var fs = File.OpenWrite(path); - stream.Seek(0, SeekOrigin.Begin); - stream.CopyTo(fs); - return true; - } - catch - { - // TODO: Handle logging the exception + using var stream = SerializeToStream(metadataFile, quotes); + if (stream == null) return false; - } + + using var fs = File.OpenWrite(path); + stream.Seek(0, SeekOrigin.Begin); + stream.CopyTo(fs); + return true; } /// @@ -46,30 +38,22 @@ namespace SabreTools.Serialization /// Stream containing serialized data on success, null otherwise public static Stream? SerializeToStream(MetadataFile? metadataFile, bool quotes) { - try - { - // If the metadata file is null - if (metadataFile == null) - return null; - - // Setup the writer and output - var stream = new MemoryStream(); - var writer = new ClrMameProWriter(stream, Encoding.UTF8) { Quotes = quotes }; - - // Write the header, if it exists - WriteHeader(metadataFile.ClrMamePro, writer); - - // Write out the games, if they exist - WriteGames(metadataFile.Game, writer); - - // Return the stream - return stream; - } - catch - { - // TODO: Handle logging the exception + // If the metadata file is null + if (metadataFile == null) return null; - } + + // Setup the writer and output + var stream = new MemoryStream(); + var writer = new ClrMameProWriter(stream, Encoding.UTF8) { Quotes = quotes }; + + // Write the header, if it exists + WriteHeader(metadataFile.ClrMamePro, writer); + + // Write out the games, if they exist + WriteGames(metadataFile.Game, writer); + + // Return the stream + return stream; } /// diff --git a/SabreTools.Serialization/EverdriveSMDB.Deserializer.cs b/SabreTools.Serialization/EverdriveSMDB.Deserializer.cs index f736d9f2..9d99757e 100644 --- a/SabreTools.Serialization/EverdriveSMDB.Deserializer.cs +++ b/SabreTools.Serialization/EverdriveSMDB.Deserializer.cs @@ -19,16 +19,8 @@ namespace SabreTools.Serialization /// Deserialized data on success, null on failure public static MetadataFile? Deserialize(string path) { - try - { - using var stream = PathProcessor.OpenStream(path); - return Deserialize(stream); - } - catch - { - // TODO: Handle logging the exception - return default; - } + using var stream = PathProcessor.OpenStream(path); + return Deserialize(stream); } /// @@ -38,59 +30,51 @@ namespace SabreTools.Serialization /// Deserialized data on success, null on failure public static MetadataFile? Deserialize(Stream? stream) { - try - { - // If the stream is null - if (stream == null) - return default; - - // Setup the reader and output - var reader = new SeparatedValueReader(stream, Encoding.UTF8) - { - Header = false, - Separator = '\t', - VerifyFieldCount = false, - }; - var dat = new MetadataFile(); - - // Loop through the rows and parse out values - var rows = new List(); - while (!reader.EndOfStream) - { - // If we have no next line - if (!reader.ReadNextLine()) - break; - - // Parse the line into a row - var row = new Row - { - SHA256 = reader.Line[0], - Name = reader.Line[1], - SHA1 = reader.Line[2], - MD5 = reader.Line[3], - CRC32 = reader.Line[4], - }; - - // If we have the size field - if (reader.Line.Count > 5) - row.Size = reader.Line[5]; - - // If we have additional fields - if (reader.Line.Count > 6) - row.ADDITIONAL_ELEMENTS = reader.Line.Skip(5).ToArray(); - - rows.Add(row); - } - - // Assign the rows to the Dat and return - dat.Row = rows.ToArray(); - return dat; - } - catch - { - // TODO: Handle logging the exception + // If the stream is null + if (stream == null) return default; + + // Setup the reader and output + var reader = new SeparatedValueReader(stream, Encoding.UTF8) + { + Header = false, + Separator = '\t', + VerifyFieldCount = false, + }; + var dat = new MetadataFile(); + + // Loop through the rows and parse out values + var rows = new List(); + while (!reader.EndOfStream) + { + // If we have no next line + if (!reader.ReadNextLine()) + break; + + // Parse the line into a row + var row = new Row + { + SHA256 = reader.Line[0], + Name = reader.Line[1], + SHA1 = reader.Line[2], + MD5 = reader.Line[3], + CRC32 = reader.Line[4], + }; + + // If we have the size field + if (reader.Line.Count > 5) + row.Size = reader.Line[5]; + + // If we have additional fields + if (reader.Line.Count > 6) + row.ADDITIONAL_ELEMENTS = reader.Line.Skip(5).ToArray(); + + rows.Add(row); } + + // Assign the rows to the Dat and return + dat.Row = rows.ToArray(); + return dat; } } } \ No newline at end of file diff --git a/SabreTools.Serialization/EverdriveSMDB.Serializer.cs b/SabreTools.Serialization/EverdriveSMDB.Serializer.cs index ed18821f..6cb44db6 100644 --- a/SabreTools.Serialization/EverdriveSMDB.Serializer.cs +++ b/SabreTools.Serialization/EverdriveSMDB.Serializer.cs @@ -20,22 +20,14 @@ namespace SabreTools.Serialization /// True on successful serialization, false otherwise public static bool SerializeToFile(MetadataFile? metadataFile, string path) { - try - { - using var stream = SerializeToStream(metadataFile); - if (stream == null) - return false; - - using var fs = File.OpenWrite(path); - stream.Seek(0, SeekOrigin.Begin); - stream.CopyTo(fs); - return true; - } - catch - { - // TODO: Handle logging the exception + using var stream = SerializeToStream(metadataFile); + if (stream == null) return false; - } + + using var fs = File.OpenWrite(path); + stream.Seek(0, SeekOrigin.Begin); + stream.CopyTo(fs); + return true; } /// @@ -45,27 +37,19 @@ namespace SabreTools.Serialization /// Stream containing serialized data on success, null otherwise public static Stream? SerializeToStream(MetadataFile? metadataFile) { - try - { - // If the metadata file is null - if (metadataFile == null) - return null; - - // Setup the writer and output - var stream = new MemoryStream(); - var writer = new SeparatedValueWriter(stream, Encoding.UTF8) { Separator = '\t', Quotes = false }; - - // Write out the rows, if they exist - WriteRows(metadataFile.Row, writer); - - // Return the stream - return stream; - } - catch - { - // TODO: Handle logging the exception + // If the metadata file is null + if (metadataFile == null) return null; - } + + // Setup the writer and output + var stream = new MemoryStream(); + var writer = new SeparatedValueWriter(stream, Encoding.UTF8) { Separator = '\t', Quotes = false }; + + // Write out the rows, if they exist + WriteRows(metadataFile.Row, writer); + + // Return the stream + return stream; } /// diff --git a/SabreTools.Serialization/Hashfile.Deserializer.cs b/SabreTools.Serialization/Hashfile.Deserializer.cs index a2e2900e..54261d1d 100644 --- a/SabreTools.Serialization/Hashfile.Deserializer.cs +++ b/SabreTools.Serialization/Hashfile.Deserializer.cs @@ -19,16 +19,8 @@ namespace SabreTools.Serialization /// Deserialized data on success, null on failure public static Models.Hashfile.Hashfile? Deserialize(string path, Hash hash) { - try - { - using var stream = PathProcessor.OpenStream(path); - return Deserialize(stream, hash); - } - catch - { - // TODO: Handle logging the exception - return default; - } + using var stream = PathProcessor.OpenStream(path); + return Deserialize(stream, hash); } /// @@ -39,122 +31,114 @@ namespace SabreTools.Serialization /// Deserialized data on success, null on failure public static Models.Hashfile.Hashfile? Deserialize(Stream? stream, Hash hash) { - try + // If the stream is null + if (stream == null) + return default; + + // Setup the reader and output + var reader = new StreamReader(stream); + var dat = new Models.Hashfile.Hashfile(); + var additional = new List(); + + // Loop through the rows and parse out values + var hashes = new List(); + while (!reader.EndOfStream) { - // If the stream is null - if (stream == null) - return default; + // Read and split the line + string? line = reader.ReadLine(); + string[]? lineParts = line?.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); + if (lineParts == null) + continue; - // Setup the reader and output - var reader = new StreamReader(stream); - var dat = new Models.Hashfile.Hashfile(); - var additional = new List(); - - // Loop through the rows and parse out values - var hashes = new List(); - while (!reader.EndOfStream) - { - // Read and split the line - string? line = reader.ReadLine(); - string[]? lineParts = line?.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); - if (lineParts == null) - continue; - - // Parse the line into a hash - switch (hash) - { - case Hash.CRC: - var sfv = new Models.Hashfile.SFV - { - File = string.Join(" ", lineParts[..^1]), - Hash = string.Join(" ", lineParts[^1]), - }; - hashes.Add(sfv); - break; - case Hash.MD5: - var md5 = new Models.Hashfile.MD5 - { - Hash = lineParts[0], - File = string.Join(" ", lineParts[1..]), - }; - hashes.Add(md5); - break; - case Hash.SHA1: - var sha1 = new Models.Hashfile.SHA1 - { - Hash = lineParts[0], - File = string.Join(" ", lineParts[1..]), - }; - hashes.Add(sha1); - break; - case Hash.SHA256: - var sha256 = new Models.Hashfile.SHA256 - { - Hash = lineParts[0], - File = string.Join(" ", lineParts[1..]), - }; - hashes.Add(sha256); - break; - case Hash.SHA384: - var sha384 = new Models.Hashfile.SHA384 - { - Hash = lineParts[0], - File = string.Join(" ", lineParts[1..]), - }; - hashes.Add(sha384); - break; - case Hash.SHA512: - var sha512 = new Models.Hashfile.SHA512 - { - Hash = lineParts[0], - File = string.Join(" ", lineParts[1..]), - }; - hashes.Add(sha512); - break; - case Hash.SpamSum: - var spamSum = new Models.Hashfile.SpamSum - { - Hash = lineParts[0], - File = string.Join(" ", lineParts[1..]), - }; - hashes.Add(spamSum); - break; - } - } - - // Assign the hashes to the hashfile and return + // Parse the line into a hash switch (hash) { case Hash.CRC: - dat.SFV = hashes.Cast().ToArray(); + var sfv = new Models.Hashfile.SFV + { + File = string.Join(" ", lineParts[..^1]), + Hash = string.Join(" ", lineParts[^1]), + }; + hashes.Add(sfv); break; case Hash.MD5: - dat.MD5 = hashes.Cast().ToArray(); + var md5 = new Models.Hashfile.MD5 + { + Hash = lineParts[0], + File = string.Join(" ", lineParts[1..]), + }; + hashes.Add(md5); break; case Hash.SHA1: - dat.SHA1 = hashes.Cast().ToArray(); + var sha1 = new Models.Hashfile.SHA1 + { + Hash = lineParts[0], + File = string.Join(" ", lineParts[1..]), + }; + hashes.Add(sha1); break; case Hash.SHA256: - dat.SHA256 = hashes.Cast().ToArray(); + var sha256 = new Models.Hashfile.SHA256 + { + Hash = lineParts[0], + File = string.Join(" ", lineParts[1..]), + }; + hashes.Add(sha256); break; case Hash.SHA384: - dat.SHA384 = hashes.Cast().ToArray(); + var sha384 = new Models.Hashfile.SHA384 + { + Hash = lineParts[0], + File = string.Join(" ", lineParts[1..]), + }; + hashes.Add(sha384); break; case Hash.SHA512: - dat.SHA512 = hashes.Cast().ToArray(); + var sha512 = new Models.Hashfile.SHA512 + { + Hash = lineParts[0], + File = string.Join(" ", lineParts[1..]), + }; + hashes.Add(sha512); break; case Hash.SpamSum: - dat.SpamSum = hashes.Cast().ToArray(); + var spamSum = new Models.Hashfile.SpamSum + { + Hash = lineParts[0], + File = string.Join(" ", lineParts[1..]), + }; + hashes.Add(spamSum); break; } - dat.ADDITIONAL_ELEMENTS = additional.ToArray(); - return dat; } - catch + + // Assign the hashes to the hashfile and return + switch (hash) { - // TODO: Handle logging the exception - return default; + case Hash.CRC: + dat.SFV = hashes.Cast().ToArray(); + break; + case Hash.MD5: + dat.MD5 = hashes.Cast().ToArray(); + break; + case Hash.SHA1: + dat.SHA1 = hashes.Cast().ToArray(); + break; + case Hash.SHA256: + dat.SHA256 = hashes.Cast().ToArray(); + break; + case Hash.SHA384: + dat.SHA384 = hashes.Cast().ToArray(); + break; + case Hash.SHA512: + dat.SHA512 = hashes.Cast().ToArray(); + break; + case Hash.SpamSum: + dat.SpamSum = hashes.Cast().ToArray(); + break; } + dat.ADDITIONAL_ELEMENTS = additional.ToArray(); + return dat; } } } \ No newline at end of file diff --git a/SabreTools.Serialization/Hashfile.Serializer.cs b/SabreTools.Serialization/Hashfile.Serializer.cs index 6f66f3d1..83343910 100644 --- a/SabreTools.Serialization/Hashfile.Serializer.cs +++ b/SabreTools.Serialization/Hashfile.Serializer.cs @@ -22,22 +22,14 @@ namespace SabreTools.Serialization /// True on successful serialization, false otherwise public static bool SerializeToFile(Models.Hashfile.Hashfile? hashfile, string path, Hash hash) { - try - { - using var stream = SerializeToStream(hashfile, hash); - if (stream == null) - return false; - - using var fs = File.OpenWrite(path); - stream.Seek(0, SeekOrigin.Begin); - stream.CopyTo(fs); - return true; - } - catch - { - // TODO: Handle logging the exception + using var stream = SerializeToStream(hashfile, hash); + if (stream == null) return false; - } + + using var fs = File.OpenWrite(path); + stream.Seek(0, SeekOrigin.Begin); + stream.CopyTo(fs); + return true; } /// @@ -48,52 +40,49 @@ namespace SabreTools.Serialization /// Stream containing serialized data on success, null otherwise public static Stream? SerializeToStream(Models.Hashfile.Hashfile? hashfile, Hash hash) { - try - { - // If the metadata file is null - if (hashfile == null) - return null; - - // Setup the writer and output - var stream = new MemoryStream(); - var writer = new SeparatedValueWriter(stream, Encoding.UTF8) { Separator = ' ', Quotes = false }; - - // Write out the items, if they exist - switch (hash) - { - case Hash.CRC: - WriteSFV(hashfile.SFV, writer); - break; - case Hash.MD5: - WriteMD5(hashfile.MD5, writer); - break; - case Hash.SHA1: - WriteSHA1(hashfile.SHA1, writer); - break; - case Hash.SHA256: - WriteSHA256(hashfile.SHA256, writer); - break; - case Hash.SHA384: - WriteSHA384(hashfile.SHA384, writer); - break; - case Hash.SHA512: - WriteSHA512(hashfile.SHA512, writer); - break; - case Hash.SpamSum: - WriteSpamSum(hashfile.SpamSum, writer); - break; - default: - throw new ArgumentOutOfRangeException(nameof(hash)); - } - - // Return the stream - return stream; - } - catch - { - // TODO: Handle logging the exception + // If the metadata file is null + if (hashfile == null) return null; + + // Setup the writer and output + var stream = new MemoryStream(); + var writer = new SeparatedValueWriter(stream, Encoding.UTF8) + { + Separator = ' ', + Quotes = false, + VerifyFieldCount = false, + }; + + // Write out the items, if they exist + switch (hash) + { + case Hash.CRC: + WriteSFV(hashfile.SFV, writer); + break; + case Hash.MD5: + WriteMD5(hashfile.MD5, writer); + break; + case Hash.SHA1: + WriteSHA1(hashfile.SHA1, writer); + break; + case Hash.SHA256: + WriteSHA256(hashfile.SHA256, writer); + break; + case Hash.SHA384: + WriteSHA384(hashfile.SHA384, writer); + break; + case Hash.SHA512: + WriteSHA512(hashfile.SHA512, writer); + break; + case Hash.SpamSum: + WriteSpamSum(hashfile.SpamSum, writer); + break; + default: + throw new ArgumentOutOfRangeException(nameof(hash)); } + + // Return the stream + return stream; } /// diff --git a/SabreTools.Serialization/Listrom.cs b/SabreTools.Serialization/Listrom.cs index ced6e48d..c976c6b7 100644 --- a/SabreTools.Serialization/Listrom.cs +++ b/SabreTools.Serialization/Listrom.cs @@ -18,16 +18,8 @@ namespace SabreTools.Serialization /// Deserialized data on success, null on failure public static MetadataFile? Deserialize(string path) { - try - { - using var stream = PathProcessor.OpenStream(path); - return Deserialize(stream); - } - catch - { - // TODO: Handle logging the exception - return default; - } + using var stream = PathProcessor.OpenStream(path); + return Deserialize(stream); } /// @@ -37,161 +29,153 @@ namespace SabreTools.Serialization /// Deserialized data on success, null on failure public static MetadataFile? Deserialize(Stream? stream) { - try - { - // If the stream is null - if (stream == null) - return default; - - // Setup the reader and output - var reader = new StreamReader(stream, Encoding.UTF8); - var dat = new MetadataFile(); - - Set? set = null; - var sets = new List(); - var rows = new List(); - - var additional = new List(); - while (!reader.EndOfStream) - { - // Read the line and don't split yet - string? line = reader.ReadLine(); - if (string.IsNullOrWhiteSpace(line)) - { - // If we have a set to process - if (set != null) - { - set.Row = rows.ToArray(); - sets.Add(set); - set = null; - rows.Clear(); - } - - continue; - } - - // Set lines are unique - if (line.StartsWith("ROMs required for driver")) - { - string driver = line["ROMs required for driver".Length..].Trim('"', ' ', '.'); - set = new Set { Driver = driver }; - continue; - } - else if (line.StartsWith("No ROMs required for driver")) - { - string driver = line["No ROMs required for driver".Length..].Trim('"', ' ', '.'); - set = new Set { Driver = driver }; - continue; - } - else if (line.StartsWith("ROMs required for device")) - { - string device = line["ROMs required for device".Length..].Trim('"', ' ', '.'); - set = new Set { Device = device }; - continue; - } - else if (line.StartsWith("No ROMs required for device")) - { - string device = line["No ROMs required for device".Length..].Trim('"', ' ', '.'); - set = new Set { Device = device }; - continue; - } - else if (line.Equals("Name Size Checksum", StringComparison.OrdinalIgnoreCase)) - { - // No-op - continue; - } - - // Split the line for the name iteratively - string[]? lineParts = line?.Split(" ", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); - if (lineParts?.Length == 1) - lineParts = line?.Split(" ", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); - if (lineParts?.Length == 1) - lineParts = line?.Split(" ", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); - if (lineParts?.Length == 1) - lineParts = line?.Split(" ", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); - - // Read the name and set the rest of the line for processing - string name = lineParts[0]; - string trimmedLine = line[name.Length..]; - - lineParts = trimmedLine?.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); - - // The number of items in the row explains what type of row it is - var row = new Row(); - switch (lineParts.Length) - { - // Normal CHD (Name, SHA1) - case 1: - row.Name = name; - row.SHA1 = lineParts[0]["SHA1".Length..].Trim('(', ')'); - break; - - // Normal ROM (Name, Size, CRC, SHA1) - case 3 when line.Contains("CRC"): - row.Name = name; - row.Size = lineParts[0]; - row.CRC = lineParts[1]["CRC".Length..].Trim('(', ')'); - row.SHA1 = lineParts[2]["SHA1".Length..].Trim('(', ')'); - break; - - // Bad CHD (Name, BAD, SHA1, BAD_DUMP) - case 3 when line.Contains("BAD_DUMP"): - row.Name = name; - row.Bad = true; - row.SHA1 = lineParts[1]["SHA1".Length..].Trim('(', ')'); - break; - - // Nodump CHD (Name, NO GOOD DUMP KNOWN) - case 4 when line.Contains("NO GOOD DUMP KNOWN"): - row.Name = name; - row.NoGoodDumpKnown = true; - break; - - // Bad ROM (Name, Size, BAD, CRC, SHA1, BAD_DUMP) - case 5 when line.Contains("BAD_DUMP"): - row.Name = name; - row.Size = lineParts[0]; - row.Bad = true; - row.CRC = lineParts[2]["CRC".Length..].Trim('(', ')'); - row.SHA1 = lineParts[3]["SHA1".Length..].Trim('(', ')'); - break; - - // Nodump ROM (Name, Size, NO GOOD DUMP KNOWN) - case 5 when line.Contains("NO GOOD DUMP KNOWN"): - row.Name = name; - row.Size = lineParts[0]; - row.NoGoodDumpKnown = true; - break; - - default: - row = null; - additional.Add(line); - break; - } - - if (row != null) - rows.Add(row); - } - - // If we have a set to process - if (set != null) - { - set.Row = rows.ToArray(); - sets.Add(set); - set = null; - rows.Clear(); - } - - // Add extra pieces and return - dat.Set = sets.ToArray(); - dat.ADDITIONAL_ELEMENTS = additional.ToArray(); - return dat; - } - catch - { - // TODO: Handle logging the exception + // If the stream is null + if (stream == null) return default; + + // Setup the reader and output + var reader = new StreamReader(stream, Encoding.UTF8); + var dat = new MetadataFile(); + + Set? set = null; + var sets = new List(); + var rows = new List(); + + var additional = new List(); + while (!reader.EndOfStream) + { + // Read the line and don't split yet + string? line = reader.ReadLine(); + if (string.IsNullOrWhiteSpace(line)) + { + // If we have a set to process + if (set != null) + { + set.Row = rows.ToArray(); + sets.Add(set); + set = null; + rows.Clear(); + } + + continue; + } + + // Set lines are unique + if (line.StartsWith("ROMs required for driver")) + { + string driver = line["ROMs required for driver".Length..].Trim('"', ' ', '.'); + set = new Set { Driver = driver }; + continue; + } + else if (line.StartsWith("No ROMs required for driver")) + { + string driver = line["No ROMs required for driver".Length..].Trim('"', ' ', '.'); + set = new Set { Driver = driver }; + continue; + } + else if (line.StartsWith("ROMs required for device")) + { + string device = line["ROMs required for device".Length..].Trim('"', ' ', '.'); + set = new Set { Device = device }; + continue; + } + else if (line.StartsWith("No ROMs required for device")) + { + string device = line["No ROMs required for device".Length..].Trim('"', ' ', '.'); + set = new Set { Device = device }; + continue; + } + else if (line.Equals("Name Size Checksum", StringComparison.OrdinalIgnoreCase)) + { + // No-op + continue; + } + + // Split the line for the name iteratively + string[]? lineParts = line?.Split(" ", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); + if (lineParts?.Length == 1) + lineParts = line?.Split(" ", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); + if (lineParts?.Length == 1) + lineParts = line?.Split(" ", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); + if (lineParts?.Length == 1) + lineParts = line?.Split(" ", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); + + // Read the name and set the rest of the line for processing + string name = lineParts[0]; + string trimmedLine = line[name.Length..]; + + lineParts = trimmedLine?.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); + + // The number of items in the row explains what type of row it is + var row = new Row(); + switch (lineParts.Length) + { + // Normal CHD (Name, SHA1) + case 1: + row.Name = name; + row.SHA1 = lineParts[0]["SHA1".Length..].Trim('(', ')'); + break; + + // Normal ROM (Name, Size, CRC, SHA1) + case 3 when line.Contains("CRC"): + row.Name = name; + row.Size = lineParts[0]; + row.CRC = lineParts[1]["CRC".Length..].Trim('(', ')'); + row.SHA1 = lineParts[2]["SHA1".Length..].Trim('(', ')'); + break; + + // Bad CHD (Name, BAD, SHA1, BAD_DUMP) + case 3 when line.Contains("BAD_DUMP"): + row.Name = name; + row.Bad = true; + row.SHA1 = lineParts[1]["SHA1".Length..].Trim('(', ')'); + break; + + // Nodump CHD (Name, NO GOOD DUMP KNOWN) + case 4 when line.Contains("NO GOOD DUMP KNOWN"): + row.Name = name; + row.NoGoodDumpKnown = true; + break; + + // Bad ROM (Name, Size, BAD, CRC, SHA1, BAD_DUMP) + case 5 when line.Contains("BAD_DUMP"): + row.Name = name; + row.Size = lineParts[0]; + row.Bad = true; + row.CRC = lineParts[2]["CRC".Length..].Trim('(', ')'); + row.SHA1 = lineParts[3]["SHA1".Length..].Trim('(', ')'); + break; + + // Nodump ROM (Name, Size, NO GOOD DUMP KNOWN) + case 5 when line.Contains("NO GOOD DUMP KNOWN"): + row.Name = name; + row.Size = lineParts[0]; + row.NoGoodDumpKnown = true; + break; + + default: + row = null; + additional.Add(line); + break; + } + + if (row != null) + rows.Add(row); } + + // If we have a set to process + if (set != null) + { + set.Row = rows.ToArray(); + sets.Add(set); + set = null; + rows.Clear(); + } + + // Add extra pieces and return + dat.Set = sets.ToArray(); + dat.ADDITIONAL_ELEMENTS = additional.ToArray(); + return dat; } } } \ No newline at end of file diff --git a/SabreTools.Serialization/RomCenter.cs b/SabreTools.Serialization/RomCenter.cs index 81fc02be..7cce3521 100644 --- a/SabreTools.Serialization/RomCenter.cs +++ b/SabreTools.Serialization/RomCenter.cs @@ -19,16 +19,8 @@ namespace SabreTools.Serialization /// Deserialized data on success, null on failure public static MetadataFile? Deserialize(string path) { - try - { - using var stream = PathProcessor.OpenStream(path); - return Deserialize(stream); - } - catch - { - // TODO: Handle logging the exception - return default; - } + using var stream = PathProcessor.OpenStream(path); + return Deserialize(stream); } /// @@ -38,203 +30,195 @@ namespace SabreTools.Serialization /// Deserialized data on success, null on failure public static MetadataFile? Deserialize(Stream? stream) { - try - { - // If the stream is null - if (stream == null) - return default; - - // Setup the reader and output - var reader = new IniReader(stream, Encoding.UTF8) - { - ValidateRows = false, - }; - var dat = new MetadataFile(); - - // Loop through and parse out the values - var roms = new List(); - var additional = new List(); - var creditsAdditional = new List(); - var datAdditional = new List(); - var emulatorAdditional = new List(); - var gamesAdditional = new List(); - while (!reader.EndOfStream) - { - // If we have no next line - if (!reader.ReadNextLine()) - break; - - // Ignore certain row types - switch (reader.RowType) - { - case IniRowType.None: - case IniRowType.Comment: - continue; - case IniRowType.SectionHeader: - switch (reader.Section.ToLowerInvariant()) - { - case "credits": - dat.Credits ??= new Credits(); - break; - case "dat": - dat.Dat ??= new Dat(); - break; - case "emulator": - dat.Emulator ??= new Emulator(); - break; - case "games": - dat.Games ??= new Games(); - break; - default: - additional.Add(reader.CurrentLine); - break; - } - continue; - } - - // If we're in credits - if (reader.Section.ToLowerInvariant() == "credits") - { - // Create the section if we haven't already - dat.Credits ??= new Credits(); - - switch (reader.KeyValuePair?.Key?.ToLowerInvariant()) - { - case "author": - dat.Credits.Author = reader.KeyValuePair?.Value; - break; - case "version": - dat.Credits.Version = reader.KeyValuePair?.Value; - break; - case "email": - dat.Credits.Email = reader.KeyValuePair?.Value; - break; - case "homepage": - dat.Credits.Homepage = reader.KeyValuePair?.Value; - break; - case "url": - dat.Credits.Url = reader.KeyValuePair?.Value; - break; - case "date": - dat.Credits.Date = reader.KeyValuePair?.Value; - break; - case "comment": - dat.Credits.Comment = reader.KeyValuePair?.Value; - break; - default: - creditsAdditional.Add(reader.CurrentLine); - break; - } - } - - // If we're in dat - else if (reader.Section.ToLowerInvariant() == "dat") - { - // Create the section if we haven't already - dat.Dat ??= new Dat(); - - switch (reader.KeyValuePair?.Key?.ToLowerInvariant()) - { - case "version": - dat.Dat.Version = reader.KeyValuePair?.Value; - break; - case "plugin": - dat.Dat.Plugin = reader.KeyValuePair?.Value; - break; - case "split": - dat.Dat.Split = reader.KeyValuePair?.Value; - break; - case "merge": - dat.Dat.Merge = reader.KeyValuePair?.Value; - break; - default: - datAdditional.Add(reader.CurrentLine); - break; - } - } - - // If we're in emulator - else if (reader.Section.ToLowerInvariant() == "emulator") - { - // Create the section if we haven't already - dat.Emulator ??= new Emulator(); - - switch (reader.KeyValuePair?.Key?.ToLowerInvariant()) - { - case "refname": - dat.Emulator.RefName = reader.KeyValuePair?.Value; - break; - case "version": - dat.Emulator.Version = reader.KeyValuePair?.Value; - break; - default: - emulatorAdditional.Add(reader.CurrentLine); - break; - } - } - - // If we're in games - else if (reader.Section.ToLowerInvariant() == "games") - { - // Create the section if we haven't already - dat.Games ??= new Games(); - - // If the line doesn't contain the delimiter - if (!reader.CurrentLine.Contains('¬')) - { - gamesAdditional.Add(reader.CurrentLine); - continue; - } - - // Otherwise, separate out the line - string[] splitLine = reader.CurrentLine.Split('¬'); - var rom = new Rom - { - // EMPTY = splitLine[0] - ParentName = splitLine[1], - ParentDescription = splitLine[2], - GameName = splitLine[3], - GameDescription = splitLine[4], - RomName = splitLine[5], - RomCRC = splitLine[6], - RomSize = splitLine[7], - RomOf = splitLine[8], - MergeName = splitLine[9], - // EMPTY = splitLine[10] - }; - - if (splitLine.Length > 11) - rom.ADDITIONAL_ELEMENTS = splitLine.Skip(11).ToArray(); - - roms.Add(rom); - } - - else - { - additional.Add(item: reader.CurrentLine); - } - } - - // Add extra pieces and return - dat.ADDITIONAL_ELEMENTS = additional.ToArray(); - if (dat.Credits != null) - dat.Credits.ADDITIONAL_ELEMENTS = creditsAdditional.ToArray(); - if (dat.Dat != null) - dat.Dat.ADDITIONAL_ELEMENTS = datAdditional.ToArray(); - if (dat.Emulator != null) - dat.Emulator.ADDITIONAL_ELEMENTS = emulatorAdditional.ToArray(); - if (dat.Games != null) - { - dat.Games.Rom = roms.ToArray(); - dat.Games.ADDITIONAL_ELEMENTS = gamesAdditional.ToArray(); - } - return dat; - } - catch - { - // TODO: Handle logging the exception + // If the stream is null + if (stream == null) return default; + + // Setup the reader and output + var reader = new IniReader(stream, Encoding.UTF8) + { + ValidateRows = false, + }; + var dat = new MetadataFile(); + + // Loop through and parse out the values + var roms = new List(); + var additional = new List(); + var creditsAdditional = new List(); + var datAdditional = new List(); + var emulatorAdditional = new List(); + var gamesAdditional = new List(); + while (!reader.EndOfStream) + { + // If we have no next line + if (!reader.ReadNextLine()) + break; + + // Ignore certain row types + switch (reader.RowType) + { + case IniRowType.None: + case IniRowType.Comment: + continue; + case IniRowType.SectionHeader: + switch (reader.Section.ToLowerInvariant()) + { + case "credits": + dat.Credits ??= new Credits(); + break; + case "dat": + dat.Dat ??= new Dat(); + break; + case "emulator": + dat.Emulator ??= new Emulator(); + break; + case "games": + dat.Games ??= new Games(); + break; + default: + additional.Add(reader.CurrentLine); + break; + } + continue; + } + + // If we're in credits + if (reader.Section.ToLowerInvariant() == "credits") + { + // Create the section if we haven't already + dat.Credits ??= new Credits(); + + switch (reader.KeyValuePair?.Key?.ToLowerInvariant()) + { + case "author": + dat.Credits.Author = reader.KeyValuePair?.Value; + break; + case "version": + dat.Credits.Version = reader.KeyValuePair?.Value; + break; + case "email": + dat.Credits.Email = reader.KeyValuePair?.Value; + break; + case "homepage": + dat.Credits.Homepage = reader.KeyValuePair?.Value; + break; + case "url": + dat.Credits.Url = reader.KeyValuePair?.Value; + break; + case "date": + dat.Credits.Date = reader.KeyValuePair?.Value; + break; + case "comment": + dat.Credits.Comment = reader.KeyValuePair?.Value; + break; + default: + creditsAdditional.Add(reader.CurrentLine); + break; + } + } + + // If we're in dat + else if (reader.Section.ToLowerInvariant() == "dat") + { + // Create the section if we haven't already + dat.Dat ??= new Dat(); + + switch (reader.KeyValuePair?.Key?.ToLowerInvariant()) + { + case "version": + dat.Dat.Version = reader.KeyValuePair?.Value; + break; + case "plugin": + dat.Dat.Plugin = reader.KeyValuePair?.Value; + break; + case "split": + dat.Dat.Split = reader.KeyValuePair?.Value; + break; + case "merge": + dat.Dat.Merge = reader.KeyValuePair?.Value; + break; + default: + datAdditional.Add(reader.CurrentLine); + break; + } + } + + // If we're in emulator + else if (reader.Section.ToLowerInvariant() == "emulator") + { + // Create the section if we haven't already + dat.Emulator ??= new Emulator(); + + switch (reader.KeyValuePair?.Key?.ToLowerInvariant()) + { + case "refname": + dat.Emulator.RefName = reader.KeyValuePair?.Value; + break; + case "version": + dat.Emulator.Version = reader.KeyValuePair?.Value; + break; + default: + emulatorAdditional.Add(reader.CurrentLine); + break; + } + } + + // If we're in games + else if (reader.Section.ToLowerInvariant() == "games") + { + // Create the section if we haven't already + dat.Games ??= new Games(); + + // If the line doesn't contain the delimiter + if (!reader.CurrentLine.Contains('¬')) + { + gamesAdditional.Add(reader.CurrentLine); + continue; + } + + // Otherwise, separate out the line + string[] splitLine = reader.CurrentLine.Split('¬'); + var rom = new Rom + { + // EMPTY = splitLine[0] + ParentName = splitLine[1], + ParentDescription = splitLine[2], + GameName = splitLine[3], + GameDescription = splitLine[4], + RomName = splitLine[5], + RomCRC = splitLine[6], + RomSize = splitLine[7], + RomOf = splitLine[8], + MergeName = splitLine[9], + // EMPTY = splitLine[10] + }; + + if (splitLine.Length > 11) + rom.ADDITIONAL_ELEMENTS = splitLine.Skip(11).ToArray(); + + roms.Add(rom); + } + + else + { + additional.Add(item: reader.CurrentLine); + } } + + // Add extra pieces and return + dat.ADDITIONAL_ELEMENTS = additional.ToArray(); + if (dat.Credits != null) + dat.Credits.ADDITIONAL_ELEMENTS = creditsAdditional.ToArray(); + if (dat.Dat != null) + dat.Dat.ADDITIONAL_ELEMENTS = datAdditional.ToArray(); + if (dat.Emulator != null) + dat.Emulator.ADDITIONAL_ELEMENTS = emulatorAdditional.ToArray(); + if (dat.Games != null) + { + dat.Games.Rom = roms.ToArray(); + dat.Games.ADDITIONAL_ELEMENTS = gamesAdditional.ToArray(); + } + return dat; } } } \ No newline at end of file diff --git a/SabreTools.Serialization/SeparatedValue.Deserializer.cs b/SabreTools.Serialization/SeparatedValue.Deserializer.cs index a2bf2d24..f93bd78d 100644 --- a/SabreTools.Serialization/SeparatedValue.Deserializer.cs +++ b/SabreTools.Serialization/SeparatedValue.Deserializer.cs @@ -20,16 +20,8 @@ namespace SabreTools.Serialization /// Deserialized data on success, null on failure public static MetadataFile? Deserialize(string path, char delim) { - try - { - using var stream = PathProcessor.OpenStream(path); - return Deserialize(stream, delim); - } - catch - { - // TODO: Handle logging the exception - return default; - } + using var stream = PathProcessor.OpenStream(path); + return Deserialize(stream, delim); } /// @@ -40,100 +32,92 @@ namespace SabreTools.Serialization /// Deserialized data on success, null on failure public static MetadataFile? Deserialize(Stream? stream, char delim) { - try - { - // If the stream is null - if (stream == null) - return default; - - // Setup the reader and output - var reader = new SeparatedValueReader(stream, Encoding.UTF8) - { - Header = true, - Separator = delim, - VerifyFieldCount = false, - }; - var dat = new MetadataFile(); - - // Read the header values first - if (!reader.ReadHeader()) - return null; - - dat.Header = reader.HeaderValues.ToArray(); - - // Loop through the rows and parse out values - var rows = new List(); - while (!reader.EndOfStream) - { - // If we have no next line - if (!reader.ReadNextLine()) - break; - - // Parse the line into a row - Row? row = null; - if (reader.Line.Count < HeaderWithExtendedHashesCount) - { - row = new Row - { - FileName = reader.Line[0], - InternalName = reader.Line[1], - Description = reader.Line[2], - GameName = reader.Line[3], - GameDescription = reader.Line[4], - Type = reader.Line[5], - RomName = reader.Line[6], - DiskName = reader.Line[7], - Size = reader.Line[8], - CRC = reader.Line[9], - MD5 = reader.Line[10], - SHA1 = reader.Line[11], - SHA256 = reader.Line[12], - Status = reader.Line[13], - }; - - // If we have additional fields - if (reader.Line.Count > HeaderWithoutExtendedHashesCount) - row.ADDITIONAL_ELEMENTS = reader.Line.Skip(HeaderWithoutExtendedHashesCount).ToArray(); - } - else - { - row = new Row - { - FileName = reader.Line[0], - InternalName = reader.Line[1], - Description = reader.Line[2], - GameName = reader.Line[3], - GameDescription = reader.Line[4], - Type = reader.Line[5], - RomName = reader.Line[6], - DiskName = reader.Line[7], - Size = reader.Line[8], - CRC = reader.Line[9], - MD5 = reader.Line[10], - SHA1 = reader.Line[11], - SHA256 = reader.Line[12], - SHA384 = reader.Line[13], - SHA512 = reader.Line[14], - SpamSum = reader.Line[15], - Status = reader.Line[16], - }; - - // If we have additional fields - if (reader.Line.Count > HeaderWithExtendedHashesCount) - row.ADDITIONAL_ELEMENTS = reader.Line.Skip(HeaderWithExtendedHashesCount).ToArray(); - } - rows.Add(row); - } - - // Assign the rows to the Dat and return - dat.Row = rows.ToArray(); - return dat; - } - catch - { - // TODO: Handle logging the exception + // If the stream is null + if (stream == null) return default; + + // Setup the reader and output + var reader = new SeparatedValueReader(stream, Encoding.UTF8) + { + Header = true, + Separator = delim, + VerifyFieldCount = false, + }; + var dat = new MetadataFile(); + + // Read the header values first + if (!reader.ReadHeader()) + return null; + + dat.Header = reader.HeaderValues.ToArray(); + + // Loop through the rows and parse out values + var rows = new List(); + while (!reader.EndOfStream) + { + // If we have no next line + if (!reader.ReadNextLine()) + break; + + // Parse the line into a row + Row? row = null; + if (reader.Line.Count < HeaderWithExtendedHashesCount) + { + row = new Row + { + FileName = reader.Line[0], + InternalName = reader.Line[1], + Description = reader.Line[2], + GameName = reader.Line[3], + GameDescription = reader.Line[4], + Type = reader.Line[5], + RomName = reader.Line[6], + DiskName = reader.Line[7], + Size = reader.Line[8], + CRC = reader.Line[9], + MD5 = reader.Line[10], + SHA1 = reader.Line[11], + SHA256 = reader.Line[12], + Status = reader.Line[13], + }; + + // If we have additional fields + if (reader.Line.Count > HeaderWithoutExtendedHashesCount) + row.ADDITIONAL_ELEMENTS = reader.Line.Skip(HeaderWithoutExtendedHashesCount).ToArray(); + } + else + { + row = new Row + { + FileName = reader.Line[0], + InternalName = reader.Line[1], + Description = reader.Line[2], + GameName = reader.Line[3], + GameDescription = reader.Line[4], + Type = reader.Line[5], + RomName = reader.Line[6], + DiskName = reader.Line[7], + Size = reader.Line[8], + CRC = reader.Line[9], + MD5 = reader.Line[10], + SHA1 = reader.Line[11], + SHA256 = reader.Line[12], + SHA384 = reader.Line[13], + SHA512 = reader.Line[14], + SpamSum = reader.Line[15], + Status = reader.Line[16], + }; + + // If we have additional fields + if (reader.Line.Count > HeaderWithExtendedHashesCount) + row.ADDITIONAL_ELEMENTS = reader.Line.Skip(HeaderWithExtendedHashesCount).ToArray(); + } + rows.Add(row); } + + // Assign the rows to the Dat and return + dat.Row = rows.ToArray(); + return dat; } } } \ No newline at end of file diff --git a/SabreTools.Serialization/SeparatedValue.Serializer.cs b/SabreTools.Serialization/SeparatedValue.Serializer.cs index d9d91b93..008284b6 100644 --- a/SabreTools.Serialization/SeparatedValue.Serializer.cs +++ b/SabreTools.Serialization/SeparatedValue.Serializer.cs @@ -20,22 +20,14 @@ namespace SabreTools.Serialization /// True on successful serialization, false otherwise public static bool SerializeToFile(MetadataFile? metadataFile, string path, char delim) { - try - { - using var stream = SerializeToStream(metadataFile, delim); - if (stream == null) - return false; - - using var fs = File.OpenWrite(path); - stream.Seek(0, SeekOrigin.Begin); - stream.CopyTo(fs); - return true; - } - catch - { - // TODO: Handle logging the exception + using var stream = SerializeToStream(metadataFile, delim); + if (stream == null) return false; - } + + using var fs = File.OpenWrite(path); + stream.Seek(0, SeekOrigin.Begin); + stream.CopyTo(fs); + return true; } /// @@ -46,31 +38,23 @@ namespace SabreTools.Serialization /// Stream containing serialized data on success, null otherwise public static Stream? SerializeToStream(MetadataFile? metadataFile, char delim) { - try - { - // If the metadata file is null - if (metadataFile == null) - return null; - - // Setup the writer and output - var stream = new MemoryStream(); - var writer = new SeparatedValueWriter(stream, Encoding.UTF8) { Separator = delim, Quotes = true }; - - // TODO: Include flag to write out long or short header - // Write the short header - WriteHeader(writer); - - // Write out the rows, if they exist - WriteRows(metadataFile.Row, writer); - - // Return the stream - return stream; - } - catch - { - // TODO: Handle logging the exception + // If the metadata file is null + if (metadataFile == null) return null; - } + + // Setup the writer and output + var stream = new MemoryStream(); + var writer = new SeparatedValueWriter(stream, Encoding.UTF8) { Separator = delim, Quotes = true }; + + // TODO: Include flag to write out long or short header + // Write the short header + WriteHeader(writer); + + // Write out the rows, if they exist + WriteRows(metadataFile.Row, writer); + + // Return the stream + return stream; } /// @@ -79,7 +63,7 @@ namespace SabreTools.Serialization /// SeparatedValueWriter representing the output private static void WriteHeader(SeparatedValueWriter writer) { - var headerArray = new string[] + var headerArray = new string?[] { "File Name", "Internal Name", @@ -118,7 +102,7 @@ namespace SabreTools.Serialization // Loop through and write out the rows foreach (var row in rows) { - var rowArray = new string[] + var rowArray = new string?[] { row.FileName, row.InternalName, diff --git a/SabreTools.Serialization/XmlSerializer.Deserializer.cs b/SabreTools.Serialization/XmlSerializer.Deserializer.cs index 775e43c6..d174f454 100644 --- a/SabreTools.Serialization/XmlSerializer.Deserializer.cs +++ b/SabreTools.Serialization/XmlSerializer.Deserializer.cs @@ -16,16 +16,8 @@ namespace SabreTools.Serialization /// Deserialized data on success, null on failure public static T? Deserialize(string path) { - try - { - using var stream = PathProcessor.OpenStream(path); - return Deserialize(stream); - } - catch - { - // TODO: Handle logging the exception - return default; - } + using var stream = PathProcessor.OpenStream(path); + return Deserialize(stream); } /// @@ -35,30 +27,22 @@ namespace SabreTools.Serialization /// Deserialized data on success, null on failure public static T? Deserialize(Stream? stream) { - try - { - // If the stream is null - if (stream == null) - return default; - - // Setup the serializer and the reader - var serializer = new XmlSerializer(typeof(T)); - var settings = new XmlReaderSettings - { - CheckCharacters = false, - DtdProcessing = DtdProcessing.Ignore, - }; - var streamReader = new StreamReader(stream); - var xmlReader = XmlReader.Create(streamReader, settings); - - // Perform the deserialization and return - return (T?)serializer.Deserialize(xmlReader); - } - catch - { - // TODO: Handle logging the exception + // If the stream is null + if (stream == null) return default; - } + + // Setup the serializer and the reader + var serializer = new XmlSerializer(typeof(T)); + var settings = new XmlReaderSettings + { + CheckCharacters = false, + DtdProcessing = DtdProcessing.Ignore, + }; + var streamReader = new StreamReader(stream); + var xmlReader = XmlReader.Create(streamReader, settings); + + // Perform the deserialization and return + return (T?)serializer.Deserialize(xmlReader); } } } \ No newline at end of file diff --git a/SabreTools.Serialization/XmlSerializer.Serializer.cs b/SabreTools.Serialization/XmlSerializer.Serializer.cs index 4db954dd..763c07ff 100644 --- a/SabreTools.Serialization/XmlSerializer.Serializer.cs +++ b/SabreTools.Serialization/XmlSerializer.Serializer.cs @@ -17,21 +17,13 @@ namespace SabreTools.Serialization /// True on successful serialization, false otherwise public static bool SerializeToFile(T? obj, string path) { - try - { - using var stream = SerializeToStream(obj); - if (stream == null) - return false; - - using var fs = File.OpenWrite(path); - stream.CopyTo(fs); - return true; - } - catch - { - // TODO: Handle logging the exception + using var stream = SerializeToStream(obj); + if (stream == null) return false; - } + + using var fs = File.OpenWrite(path); + stream.CopyTo(fs); + return true; } /// @@ -41,31 +33,23 @@ namespace SabreTools.Serialization /// Stream containing serialized data on success, null otherwise public static Stream? SerializeToStream(T? obj) { - try - { - // If the object is null - if (obj == null) - return null; - - // Setup the serializer and the reader - var serializer = new XmlSerializer(typeof(T)); - var settings = new XmlWriterSettings - { - CheckCharacters = false, - }; - var stream = new MemoryStream(); - var streamWriter = new StreamWriter(stream); - var xmlWriter = XmlWriter.Create(streamWriter, settings); - - // Perform the deserialization and return - serializer.Serialize(xmlWriter, obj); - return stream; - } - catch - { - // TODO: Handle logging the exception + // If the object is null + if (obj == null) return null; - } + + // Setup the serializer and the reader + var serializer = new XmlSerializer(typeof(T)); + var settings = new XmlWriterSettings + { + CheckCharacters = false, + }; + var stream = new MemoryStream(); + var streamWriter = new StreamWriter(stream); + var xmlWriter = XmlWriter.Create(streamWriter, settings); + + // Perform the deserialization and return + serializer.Serialize(xmlWriter, obj); + return stream; } } } \ No newline at end of file