diff --git a/SabreTools.Library/DatFiles/AttractMode.cs b/SabreTools.Library/DatFiles/AttractMode.cs
index 6410aaf8..b64d920b 100644
--- a/SabreTools.Library/DatFiles/AttractMode.cs
+++ b/SabreTools.Library/DatFiles/AttractMode.cs
@@ -59,53 +59,57 @@ namespace SabreTools.Library.DatFiles
{
// Get the current line, split and parse
svr.ReadNextLine();
- }
- catch (InvalidDataException ex)
- {
- Globals.Logger.Error(ex, $"Malformed line found in '{filename}' at line {svr.LineNumber}");
- if (throwOnError) throw ex;
- continue;
- }
- Rom rom = new Rom
- {
- Name = "-",
- Size = Constants.SizeZero,
- CRC = Constants.CRCZero,
- MD5 = Constants.MD5Zero,
- SHA1 = Constants.SHA1Zero,
- ItemStatus = ItemStatus.None,
-
- Machine = new Machine
+ Rom rom = new Rom
{
- Name = svr.Line[0], // #Name
- Description = svr.Line[1], // Title
- CloneOf = svr.Line[3], // CloneOf
- Year = svr.Line[4], // Year
- Manufacturer = svr.Line[5], // Manufacturer
- Category = svr.Line[6], // Category
- Players = svr.Line[7], // Players
- Rotation = svr.Line[8], // Rotation
- Control = svr.Line[9], // Control
- Status = svr.Line[10], // Status
- DisplayCount = svr.Line[11], // DisplayCount
- DisplayType = svr.Line[12], // DisplayType
- Comment = svr.Line[15], // Extra
- Buttons = svr.Line[16], // Buttons
- },
+ Name = "-",
+ Size = Constants.SizeZero,
+ CRC = Constants.CRCZero,
+ MD5 = Constants.MD5Zero,
+ SHA1 = Constants.SHA1Zero,
+ ItemStatus = ItemStatus.None,
- AltName = svr.Line[13], // AltRomname
- AltTitle = svr.Line[14], // AltTitle
+ Machine = new Machine
+ {
+ Name = svr.Line[0], // #Name
+ Description = svr.Line[1], // Title
+ CloneOf = svr.Line[3], // CloneOf
+ Year = svr.Line[4], // Year
+ Manufacturer = svr.Line[5], // Manufacturer
+ Category = svr.Line[6], // Category
+ Players = svr.Line[7], // Players
+ Rotation = svr.Line[8], // Rotation
+ Control = svr.Line[9], // Control
+ Status = svr.Line[10], // Status
+ DisplayCount = svr.Line[11], // DisplayCount
+ DisplayType = svr.Line[12], // DisplayType
+ Comment = svr.Line[15], // Extra
+ Buttons = svr.Line[16], // Buttons
+ },
- Source = new Source
+ AltName = svr.Line[13], // AltRomname
+ AltTitle = svr.Line[14], // AltTitle
+
+ Source = new Source
+ {
+ Index = indexId,
+ Name = filename,
+ },
+ };
+
+ // Now process and add the rom
+ ParseAddHelper(rom);
+ }
+ catch (Exception ex)
+ {
+ string message = $"'{filename}' - There was an error parsing line {svr.LineNumber} '{svr.CurrentLine}'";
+ Globals.Logger.Error(ex, message);
+ if (throwOnError)
{
- Index = indexId,
- Name = filename,
- },
- };
-
- // Now process and add the rom
- ParseAddHelper(rom);
+ svr.Dispose();
+ throw new Exception(message, ex);
+ }
+ }
}
svr.Dispose();
diff --git a/SabreTools.Library/DatFiles/ClrMamePro.cs b/SabreTools.Library/DatFiles/ClrMamePro.cs
index 1fe4c21c..992e6fb5 100644
--- a/SabreTools.Library/DatFiles/ClrMamePro.cs
+++ b/SabreTools.Library/DatFiles/ClrMamePro.cs
@@ -54,33 +54,46 @@ namespace SabreTools.Library.DatFiles
while (!cmpr.EndOfStream)
{
- cmpr.ReadNextLine();
-
- // Ignore everything not top-level
- if (cmpr.RowType != CmpRowType.TopLevel)
- continue;
-
- // Switch on the top-level name
- switch (cmpr.TopLevel.ToLowerInvariant())
+ try
{
- // Header values
- case "clrmamepro":
- case "romvault":
- ReadHeader(cmpr, keep);
- break;
+ cmpr.ReadNextLine();
- // Sets
- case "set": // Used by the most ancient DATs
- case "game": // Used by most CMP DATs
- case "machine": // Possibly used by MAME CMP DATs
- ReadSet(cmpr, false, filename, indexId);
- break;
- case "resource": // Used by some other DATs to denote a BIOS set
- ReadSet(cmpr, true, filename, indexId);
- break;
+ // Ignore everything not top-level
+ if (cmpr.RowType != CmpRowType.TopLevel)
+ continue;
- default:
- break;
+ // Switch on the top-level name
+ switch (cmpr.TopLevel.ToLowerInvariant())
+ {
+ // Header values
+ case "clrmamepro":
+ case "romvault":
+ ReadHeader(cmpr, keep);
+ break;
+
+ // Sets
+ case "set": // Used by the most ancient DATs
+ case "game": // Used by most CMP DATs
+ case "machine": // Possibly used by MAME CMP DATs
+ ReadSet(cmpr, false, filename, indexId);
+ break;
+ case "resource": // Used by some other DATs to denote a BIOS set
+ ReadSet(cmpr, true, filename, indexId);
+ break;
+
+ default:
+ break;
+ }
+ }
+ catch (Exception ex)
+ {
+ string message = $"'{filename}' - There was an error parsing line {cmpr.LineNumber} '{cmpr.CurrentLine}'";
+ Globals.Logger.Error(ex, message);
+ if (throwOnError)
+ {
+ cmpr.Dispose();
+ throw new Exception(message, ex);
+ }
}
}
diff --git a/SabreTools.Library/DatFiles/DatFile.cs b/SabreTools.Library/DatFiles/DatFile.cs
index c4539b9a..324d4646 100644
--- a/SabreTools.Library/DatFiles/DatFile.cs
+++ b/SabreTools.Library/DatFiles/DatFile.cs
@@ -1802,10 +1802,11 @@ namespace SabreTools.Library.DatFiles
/// Create a DatFile and parse a file into it
///
/// Name of the file to be parsed
- public static DatFile CreateAndParse(string filename)
+ /// True if the error that is thrown should be thrown back to the caller, false otherwise
+ public static DatFile CreateAndParse(string filename, bool throwOnError = false)
{
DatFile datFile = Create();
- datFile.Parse(new ParentablePath(filename));
+ datFile.Parse(new ParentablePath(filename), throwOnError: throwOnError);
return datFile;
}
@@ -1833,22 +1834,22 @@ namespace SabreTools.Library.DatFiles
///
/// Parse a DAT and return all found games and roms within
///
- /// Name of the file to be parsed
+ /// Name of the file to be parsed
/// Index ID for the DAT
/// True if full pathnames are to be kept, false otherwise (default)
/// True if original extension should be kept, false otherwise (default)
/// True if quotes are assumed in supported types (default), false otherwise
/// True if the error that is thrown should be thrown back to the caller, false otherwise
public void Parse(
- ParentablePath filename,
+ ParentablePath input,
int indexId = 0,
bool keep = false,
bool keepext = false,
bool quotes = true,
- bool throwOnError = false)
+ bool throwOnError = true)
{
// Get the current path from the filename
- string currentPath = filename.CurrentPath;
+ string currentPath = input.CurrentPath;
// Check the file extension first as a safeguard
if (!PathExtensions.HasValidDatExtension(currentPath))
@@ -1868,7 +1869,7 @@ namespace SabreTools.Library.DatFiles
}
catch (Exception ex)
{
- Globals.Logger.Error(ex, $"Error with file '{filename}'");
+ Globals.Logger.Error(ex, $"Error with file '{currentPath}'");
if (throwOnError) throw ex;
}
}
diff --git a/SabreTools.Library/DatFiles/DosCenter.cs b/SabreTools.Library/DatFiles/DosCenter.cs
index e55b5792..88396458 100644
--- a/SabreTools.Library/DatFiles/DosCenter.cs
+++ b/SabreTools.Library/DatFiles/DosCenter.cs
@@ -43,27 +43,40 @@ namespace SabreTools.Library.DatFiles
while (!cmpr.EndOfStream)
{
- cmpr.ReadNextLine();
-
- // Ignore everything not top-level
- if (cmpr.RowType != CmpRowType.TopLevel)
- continue;
-
- // Switch on the top-level name
- switch (cmpr.TopLevel.ToLowerInvariant())
+ try
{
- // Header values
- case "doscenter":
- ReadHeader(cmpr);
- break;
+ cmpr.ReadNextLine();
- // Sets
- case "game":
- ReadGame(cmpr, filename, indexId);
- break;
+ // Ignore everything not top-level
+ if (cmpr.RowType != CmpRowType.TopLevel)
+ continue;
- default:
- break;
+ // Switch on the top-level name
+ switch (cmpr.TopLevel.ToLowerInvariant())
+ {
+ // Header values
+ case "doscenter":
+ ReadHeader(cmpr);
+ break;
+
+ // Sets
+ case "game":
+ ReadGame(cmpr, filename, indexId);
+ break;
+
+ default:
+ break;
+ }
+ }
+ catch (Exception ex)
+ {
+ string message = $"'{filename}' - There was an error parsing line {cmpr.LineNumber} '{cmpr.CurrentLine}'";
+ Globals.Logger.Error(ex, message);
+ if (throwOnError)
+ {
+ cmpr.Dispose();
+ throw new Exception(message, ex);
+ }
}
}
diff --git a/SabreTools.Library/DatFiles/EverdriveSmdb.cs b/SabreTools.Library/DatFiles/EverdriveSmdb.cs
index 2d583629..07a0f0e9 100644
--- a/SabreTools.Library/DatFiles/EverdriveSmdb.cs
+++ b/SabreTools.Library/DatFiles/EverdriveSmdb.cs
@@ -33,51 +33,65 @@ namespace SabreTools.Library.DatFiles
/// True if the error that is thrown should be thrown back to the caller, false otherwise
protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
{
+ // TODO: Use SeparatedValueReader
// Open a file reader
Encoding enc = FileExtensions.GetEncoding(filename);
StreamReader sr = new StreamReader(FileExtensions.TryOpenRead(filename), enc);
while (!sr.EndOfStream)
{
- string line = sr.ReadLine();
-
- /*
- The gameinfo order is as follows
- 0 - SHA-256
- 1 - Machine Name/Filename
- 2 - SHA-1
- 3 - MD5
- 4 - CRC32
- */
-
- string[] gameinfo = line.Split('\t');
- string[] fullname = gameinfo[1].Split('/');
-
- Rom rom = new Rom
+ try
{
- Name = gameinfo[1].Substring(fullname[0].Length + 1),
- Size = null, // No size provided, but we don't want the size being 0
- CRC = gameinfo[4],
- MD5 = gameinfo[3],
- SHA1 = gameinfo[2],
- SHA256 = gameinfo[0],
- ItemStatus = ItemStatus.None,
+ string line = sr.ReadLine();
- Machine = new Machine
+ /*
+ The gameinfo order is as follows
+ 0 - SHA-256
+ 1 - Machine Name/Filename
+ 2 - SHA-1
+ 3 - MD5
+ 4 - CRC32
+ */
+
+ string[] gameinfo = line.Split('\t');
+ string[] fullname = gameinfo[1].Split('/');
+
+ Rom rom = new Rom
{
- Name = fullname[0],
- Description = fullname[0],
- },
+ Name = gameinfo[1].Substring(fullname[0].Length + 1),
+ Size = null, // No size provided, but we don't want the size being 0
+ CRC = gameinfo[4],
+ MD5 = gameinfo[3],
+ SHA1 = gameinfo[2],
+ SHA256 = gameinfo[0],
+ ItemStatus = ItemStatus.None,
- Source = new Source
+ Machine = new Machine
+ {
+ Name = fullname[0],
+ Description = fullname[0],
+ },
+
+ Source = new Source
+ {
+ Index = indexId,
+ Name = filename,
+ },
+ };
+
+ // Now process and add the rom
+ ParseAddHelper(rom);
+ }
+ catch (Exception ex)
+ {
+ string message = $"'{filename}' - There was an error parsing at position {sr.BaseStream.Position}";
+ Globals.Logger.Error(ex, message);
+ if (throwOnError)
{
- Index = indexId,
- Name = filename,
- },
- };
-
- // Now process and add the rom
- ParseAddHelper(rom);
+ sr.Dispose();
+ throw new Exception(message, ex);
+ }
+ }
}
sr.Dispose();
diff --git a/SabreTools.Library/DatFiles/Hashfile.cs b/SabreTools.Library/DatFiles/Hashfile.cs
index ce6e5437..63265042 100644
--- a/SabreTools.Library/DatFiles/Hashfile.cs
+++ b/SabreTools.Library/DatFiles/Hashfile.cs
@@ -43,56 +43,69 @@ namespace SabreTools.Library.DatFiles
while (!sr.EndOfStream)
{
- string line = sr.ReadLine();
-
- // Split the line and get the name and hash
- string[] split = line.Split(' ');
- string name = string.Empty;
- string hash = string.Empty;
-
- // If we have CRC, then it's an SFV file and the name is first are
- if (_hash.HasFlag(Hash.CRC))
+ try
{
- name = split[0].Replace("*", String.Empty);
- hash = split[1];
- }
- // Otherwise, the name is second
- else
- {
- name = split[1].Replace("*", String.Empty);
- hash = split[0];
- }
+ string line = sr.ReadLine();
- Rom rom = new Rom
- {
- Name = name,
- Size = null,
- CRC = (_hash.HasFlag(Hash.CRC) ? hash : null),
- MD5 = (_hash.HasFlag(Hash.MD5) ? hash : null),
+ // Split the line and get the name and hash
+ string[] split = line.Split(' ');
+ string name = string.Empty;
+ string hash = string.Empty;
+
+ // If we have CRC, then it's an SFV file and the name is first are
+ if (_hash.HasFlag(Hash.CRC))
+ {
+ name = split[0].Replace("*", String.Empty);
+ hash = split[1];
+ }
+ // Otherwise, the name is second
+ else
+ {
+ name = split[1].Replace("*", String.Empty);
+ hash = split[0];
+ }
+
+ Rom rom = new Rom
+ {
+ Name = name,
+ Size = null,
+ CRC = (_hash.HasFlag(Hash.CRC) ? hash : null),
+ MD5 = (_hash.HasFlag(Hash.MD5) ? hash : null),
#if NET_FRAMEWORK
- RIPEMD160 = (_hash.HasFlag(Hash.RIPEMD160) ? hash : null),
+ RIPEMD160 = (_hash.HasFlag(Hash.RIPEMD160) ? hash : null),
#endif
- SHA1 = (_hash.HasFlag(Hash.SHA1) ? hash : null),
- SHA256 = (_hash.HasFlag(Hash.SHA256) ? hash : null),
- SHA384 = (_hash.HasFlag(Hash.SHA384) ? hash : null),
- SHA512 = (_hash.HasFlag(Hash.SHA512) ? hash : null),
- SpamSum = (_hash.HasFlag(Hash.SpamSum) ? hash : null),
- ItemStatus = ItemStatus.None,
+ SHA1 = (_hash.HasFlag(Hash.SHA1) ? hash : null),
+ SHA256 = (_hash.HasFlag(Hash.SHA256) ? hash : null),
+ SHA384 = (_hash.HasFlag(Hash.SHA384) ? hash : null),
+ SHA512 = (_hash.HasFlag(Hash.SHA512) ? hash : null),
+ SpamSum = (_hash.HasFlag(Hash.SpamSum) ? hash : null),
+ ItemStatus = ItemStatus.None,
- Machine = new Machine
+ Machine = new Machine
+ {
+ Name = Path.GetFileNameWithoutExtension(filename),
+ },
+
+ Source = new Source
+ {
+ Index = indexId,
+ Name = filename,
+ },
+ };
+
+ // Now process and add the rom
+ ParseAddHelper(rom);
+ }
+ catch (Exception ex)
+ {
+ string message = $"'{filename}' - There was an error parsing at position {sr.BaseStream.Position}";
+ Globals.Logger.Error(ex, message);
+ if (throwOnError)
{
- Name = Path.GetFileNameWithoutExtension(filename),
- },
-
- Source = new Source
- {
- Index = indexId,
- Name = filename,
- },
- };
-
- // Now process and add the rom
- ParseAddHelper(rom);
+ sr.Dispose();
+ throw new Exception(message, ex);
+ }
+ }
}
sr.Dispose();
diff --git a/SabreTools.Library/DatFiles/ItemDictionary.cs b/SabreTools.Library/DatFiles/ItemDictionary.cs
index 4522cdbe..3710b01e 100644
--- a/SabreTools.Library/DatFiles/ItemDictionary.cs
+++ b/SabreTools.Library/DatFiles/ItemDictionary.cs
@@ -1410,13 +1410,13 @@ namespace SabreTools.Library.DatFiles
dirStats.ResetStatistics();
}
- Globals.Logger.Verbose($"Beginning stat collection for '{file}'", false);
+ Globals.Logger.Verbose($"Beginning stat collection for '{file.CurrentPath}'", false);
List games = new List();
DatFile datdata = DatFile.CreateAndParse(file.CurrentPath);
datdata.Items.BucketBy(Field.Machine_Name, DedupeType.None, norename: true);
// Output single DAT stats (if asked)
- Globals.Logger.User($"Adding stats for file '{file}'\n", false);
+ Globals.Logger.User($"Adding stats for file '{file.CurrentPath}'\n", false);
if (single)
{
reports.ForEach(report => report.ReplaceStatistics(datdata.Header.FileName, datdata.Items.Keys.Count, datdata.Items));
diff --git a/SabreTools.Library/DatFiles/Listrom.cs b/SabreTools.Library/DatFiles/Listrom.cs
index 8bd57f7a..a199d9c1 100644
--- a/SabreTools.Library/DatFiles/Listrom.cs
+++ b/SabreTools.Library/DatFiles/Listrom.cs
@@ -50,201 +50,214 @@ namespace SabreTools.Library.DatFiles
string gamename = string.Empty;
while (!sr.EndOfStream)
{
- string line = sr.ReadLine().Trim();
-
- // If we have a blank line, we just skip it
- if (string.IsNullOrWhiteSpace(line))
+ try
{
- continue;
- }
+ string line = sr.ReadLine().Trim();
- // If we have the descriptor line, ignore it
- else if (line == "Name Size Checksum")
- {
- continue;
- }
-
- // If we have the beginning of a game, set the name of the game
- else if (line.StartsWith("ROMs required for"))
- {
- gamename = Regex.Match(line, @"^ROMs required for \S*? string.Empty(.*?)string.Empty\.").Groups[1].Value;
- }
-
- // If we have a machine with no required roms (usually internal devices), skip it
- else if (line.StartsWith("No ROMs required for"))
- {
- continue;
- }
-
- // Otherwise, we assume we have a rom that we need to add
- else
- {
- // First, we preprocess the line so that the rom name is consistently correct
- string[] split = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
-
- // If the line doesn't have the 4 spaces of padding, check for 3
- if (split.Length == 1)
- split = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
-
- // If the split is still unsuccessful, log it and skip
- if (split.Length == 1)
- Globals.Logger.Warning($"Possibly malformed line: '{line}'");
-
- string romname = split[0];
- line = line.Substring(romname.Length);
-
- // Next we separate the ROM into pieces
- split = line.Split(new char[0], StringSplitOptions.RemoveEmptyEntries);
-
- // Standard Disks have 2 pieces (name, sha1)
- if (split.Length == 1)
+ // If we have a blank line, we just skip it
+ if (string.IsNullOrWhiteSpace(line))
{
- Disk disk = new Disk()
- {
- Name = romname,
- SHA1 = Sanitizer.CleanListromHashData(split[0]),
-
- Machine = new Machine
- {
- Name = gamename,
- },
-
- Source = new Source
- {
- Index = indexId,
- Name = filename,
- },
- };
-
- ParseAddHelper(disk);
+ continue;
}
- // Baddump Disks have 4 pieces (name, BAD, sha1, BAD_DUMP)
- else if (split.Length == 3 && line.EndsWith("BAD_DUMP"))
+ // If we have the descriptor line, ignore it
+ else if (line == "Name Size Checksum")
{
- Disk disk = new Disk()
- {
- Name = romname,
- SHA1 = Sanitizer.CleanListromHashData(split[1]),
- ItemStatus = ItemStatus.BadDump,
-
- Machine = new Machine
- {
- Name = gamename,
- },
-
- Source = new Source
- {
- Index = indexId,
- Name = filename,
- },
- };
-
- ParseAddHelper(disk);
+ continue;
}
- // Standard ROMs have 4 pieces (name, size, crc, sha1)
- else if (split.Length == 3)
+ // If we have the beginning of a game, set the name of the game
+ else if (line.StartsWith("ROMs required for"))
{
- Rom rom = new Rom()
- {
- Name = romname,
- Size = Sanitizer.CleanLong(split[0]),
- CRC = Sanitizer.CleanListromHashData(split[1]),
- SHA1 = Sanitizer.CleanListromHashData(split[2]),
-
- Machine = new Machine
- {
- Name = gamename,
- },
-
- Source = new Source
- {
- Index = indexId,
- Name = filename,
- },
- };
-
- ParseAddHelper(rom);
+ gamename = Regex.Match(line, @"^ROMs required for \S*? string.Empty(.*?)string.Empty\.").Groups[1].Value;
}
- // Nodump Disks have 5 pieces (name, NO, GOOD, DUMP, KNOWN)
- else if (split.Length == 4 && line.EndsWith("NO GOOD DUMP KNOWN"))
+ // If we have a machine with no required roms (usually internal devices), skip it
+ else if (line.StartsWith("No ROMs required for"))
{
- Disk disk = new Disk()
- {
- Name = romname,
- ItemStatus = ItemStatus.Nodump,
-
- Machine = new Machine
- {
- Name = gamename,
- },
-
- Source = new Source
- {
- Index = indexId,
- Name = filename,
- },
- };
-
- ParseAddHelper(disk);
+ continue;
}
- // Baddump ROMs have 6 pieces (name, size, BAD, crc, sha1, BAD_DUMP)
- else if (split.Length == 5 && line.EndsWith("BAD_DUMP"))
- {
- Rom rom = new Rom()
- {
- Name = romname,
- Size = Sanitizer.CleanLong(split[0]),
- CRC = Sanitizer.CleanListromHashData(split[2]),
- SHA1 = Sanitizer.CleanListromHashData(split[3]),
- ItemStatus = ItemStatus.BadDump,
-
- Machine = new Machine
- {
- Name = gamename,
- },
-
- Source = new Source
- {
- Index = indexId,
- Name = filename,
- },
- };
-
- ParseAddHelper(rom);
- }
-
- // Nodump ROMs have 6 pieces (name, size, NO, GOOD, DUMP, KNOWN)
- else if (split.Length == 5 && line.EndsWith("NO GOOD DUMP KNOWN"))
- {
- Rom rom = new Rom()
- {
- Name = romname,
- Size = Sanitizer.CleanLong(split[0]),
- ItemStatus = ItemStatus.Nodump,
-
- Machine = new Machine
- {
- Name = gamename,
- },
-
- Source = new Source
- {
- Index = indexId,
- Name = filename,
- },
- };
-
- ParseAddHelper(rom);
- }
-
- // If we have something else, it's invalid
+ // Otherwise, we assume we have a rom that we need to add
else
{
- Globals.Logger.Warning($"Invalid line detected: '{romname} {line}'");
+ // First, we preprocess the line so that the rom name is consistently correct
+ string[] split = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
+
+ // If the line doesn't have the 4 spaces of padding, check for 3
+ if (split.Length == 1)
+ split = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
+
+ // If the split is still unsuccessful, log it and skip
+ if (split.Length == 1)
+ Globals.Logger.Warning($"Possibly malformed line: '{line}'");
+
+ string romname = split[0];
+ line = line.Substring(romname.Length);
+
+ // Next we separate the ROM into pieces
+ split = line.Split(new char[0], StringSplitOptions.RemoveEmptyEntries);
+
+ // Standard Disks have 2 pieces (name, sha1)
+ if (split.Length == 1)
+ {
+ Disk disk = new Disk()
+ {
+ Name = romname,
+ SHA1 = Sanitizer.CleanListromHashData(split[0]),
+
+ Machine = new Machine
+ {
+ Name = gamename,
+ },
+
+ Source = new Source
+ {
+ Index = indexId,
+ Name = filename,
+ },
+ };
+
+ ParseAddHelper(disk);
+ }
+
+ // Baddump Disks have 4 pieces (name, BAD, sha1, BAD_DUMP)
+ else if (split.Length == 3 && line.EndsWith("BAD_DUMP"))
+ {
+ Disk disk = new Disk()
+ {
+ Name = romname,
+ SHA1 = Sanitizer.CleanListromHashData(split[1]),
+ ItemStatus = ItemStatus.BadDump,
+
+ Machine = new Machine
+ {
+ Name = gamename,
+ },
+
+ Source = new Source
+ {
+ Index = indexId,
+ Name = filename,
+ },
+ };
+
+ ParseAddHelper(disk);
+ }
+
+ // Standard ROMs have 4 pieces (name, size, crc, sha1)
+ else if (split.Length == 3)
+ {
+ Rom rom = new Rom()
+ {
+ Name = romname,
+ Size = Sanitizer.CleanLong(split[0]),
+ CRC = Sanitizer.CleanListromHashData(split[1]),
+ SHA1 = Sanitizer.CleanListromHashData(split[2]),
+
+ Machine = new Machine
+ {
+ Name = gamename,
+ },
+
+ Source = new Source
+ {
+ Index = indexId,
+ Name = filename,
+ },
+ };
+
+ ParseAddHelper(rom);
+ }
+
+ // Nodump Disks have 5 pieces (name, NO, GOOD, DUMP, KNOWN)
+ else if (split.Length == 4 && line.EndsWith("NO GOOD DUMP KNOWN"))
+ {
+ Disk disk = new Disk()
+ {
+ Name = romname,
+ ItemStatus = ItemStatus.Nodump,
+
+ Machine = new Machine
+ {
+ Name = gamename,
+ },
+
+ Source = new Source
+ {
+ Index = indexId,
+ Name = filename,
+ },
+ };
+
+ ParseAddHelper(disk);
+ }
+
+ // Baddump ROMs have 6 pieces (name, size, BAD, crc, sha1, BAD_DUMP)
+ else if (split.Length == 5 && line.EndsWith("BAD_DUMP"))
+ {
+ Rom rom = new Rom()
+ {
+ Name = romname,
+ Size = Sanitizer.CleanLong(split[0]),
+ CRC = Sanitizer.CleanListromHashData(split[2]),
+ SHA1 = Sanitizer.CleanListromHashData(split[3]),
+ ItemStatus = ItemStatus.BadDump,
+
+ Machine = new Machine
+ {
+ Name = gamename,
+ },
+
+ Source = new Source
+ {
+ Index = indexId,
+ Name = filename,
+ },
+ };
+
+ ParseAddHelper(rom);
+ }
+
+ // Nodump ROMs have 6 pieces (name, size, NO, GOOD, DUMP, KNOWN)
+ else if (split.Length == 5 && line.EndsWith("NO GOOD DUMP KNOWN"))
+ {
+ Rom rom = new Rom()
+ {
+ Name = romname,
+ Size = Sanitizer.CleanLong(split[0]),
+ ItemStatus = ItemStatus.Nodump,
+
+ Machine = new Machine
+ {
+ Name = gamename,
+ },
+
+ Source = new Source
+ {
+ Index = indexId,
+ Name = filename,
+ },
+ };
+
+ ParseAddHelper(rom);
+ }
+
+ // If we have something else, it's invalid
+ else
+ {
+ Globals.Logger.Warning($"Invalid line detected: '{romname} {line}'");
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ string message = $"'{filename}' - There was an error parsing at position {sr.BaseStream.Position}";
+ Globals.Logger.Error(ex, message);
+ if (throwOnError)
+ {
+ sr.Dispose();
+ throw new Exception(message, ex);
}
}
}
diff --git a/SabreTools.Library/DatFiles/Listxml.cs b/SabreTools.Library/DatFiles/Listxml.cs
index 1a6c5cff..705b0218 100644
--- a/SabreTools.Library/DatFiles/Listxml.cs
+++ b/SabreTools.Library/DatFiles/Listxml.cs
@@ -90,8 +90,12 @@ namespace SabreTools.Library.DatFiles
}
catch (Exception ex)
{
- Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}");
- if (throwOnError) throw ex;
+ Globals.Logger.Warning(ex, $"Exception found while parsing '{filename}'");
+ if (throwOnError)
+ {
+ xtr.Dispose();
+ throw ex;
+ }
// For XML errors, just skip the affected node
xtr?.Read();
diff --git a/SabreTools.Library/DatFiles/Logiqx.cs b/SabreTools.Library/DatFiles/Logiqx.cs
index 9106277a..0494c268 100644
--- a/SabreTools.Library/DatFiles/Logiqx.cs
+++ b/SabreTools.Library/DatFiles/Logiqx.cs
@@ -107,8 +107,12 @@ namespace SabreTools.Library.DatFiles
}
catch (Exception ex)
{
- Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}");
- if (throwOnError) throw ex;
+ Globals.Logger.Warning(ex, $"Exception found while parsing '{filename}'");
+ if (throwOnError)
+ {
+ xtr.Dispose();
+ throw ex;
+ }
// For XML errors, just skip the affected node
xtr?.Read();
diff --git a/SabreTools.Library/DatFiles/OfflineList.cs b/SabreTools.Library/DatFiles/OfflineList.cs
index cbf4b632..9b35f842 100644
--- a/SabreTools.Library/DatFiles/OfflineList.cs
+++ b/SabreTools.Library/DatFiles/OfflineList.cs
@@ -78,8 +78,12 @@ namespace SabreTools.Library.DatFiles
}
catch (Exception ex)
{
- Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}");
- if (throwOnError) throw ex;
+ Globals.Logger.Warning(ex, $"Exception found while parsing '{filename}'");
+ if (throwOnError)
+ {
+ xtr.Dispose();
+ throw ex;
+ }
// For XML errors, just skip the affected node
xtr?.Read();
diff --git a/SabreTools.Library/DatFiles/OpenMSX.cs b/SabreTools.Library/DatFiles/OpenMSX.cs
index 08ca3de5..3b696081 100644
--- a/SabreTools.Library/DatFiles/OpenMSX.cs
+++ b/SabreTools.Library/DatFiles/OpenMSX.cs
@@ -80,8 +80,12 @@ namespace SabreTools.Library.DatFiles
}
catch (Exception ex)
{
- Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}");
- if (throwOnError) throw ex;
+ Globals.Logger.Warning(ex, $"Exception found while parsing '{filename}'");
+ if (throwOnError)
+ {
+ xtr.Dispose();
+ throw ex;
+ }
// For XML errors, just skip the affected node
xtr?.Read();
diff --git a/SabreTools.Library/DatFiles/RomCenter.cs b/SabreTools.Library/DatFiles/RomCenter.cs
index 0b562dbe..9149beca 100644
--- a/SabreTools.Library/DatFiles/RomCenter.cs
+++ b/SabreTools.Library/DatFiles/RomCenter.cs
@@ -84,8 +84,13 @@ namespace SabreTools.Library.DatFiles
}
catch (Exception ex)
{
- Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}");
- if (throwOnError) throw ex;
+ string message = $"'{filename}' - There was an error parsing line {ir.LineNumber} '{ir.CurrentLine}'";
+ Globals.Logger.Error(ex, message);
+ if (throwOnError)
+ {
+ ir.Dispose();
+ throw new Exception(message, ex);
+ }
}
ir.Dispose();
@@ -304,7 +309,7 @@ namespace SabreTools.Library.DatFiles
}
// Roms are not valid row formats, usually
- string line = reader.Line;
+ string line = reader.CurrentLine;
// If we don't have a valid game, keep reading
if (!line.StartsWith("¬"))
diff --git a/SabreTools.Library/DatFiles/SabreXML.cs b/SabreTools.Library/DatFiles/SabreXML.cs
index 52bdf740..76c7454b 100644
--- a/SabreTools.Library/DatFiles/SabreXML.cs
+++ b/SabreTools.Library/DatFiles/SabreXML.cs
@@ -77,8 +77,12 @@ namespace SabreTools.Library.DatFiles
}
catch (Exception ex)
{
- Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}");
- if (throwOnError) throw ex;
+ Globals.Logger.Warning(ex, $"Exception found while parsing '{filename}'");
+ if (throwOnError)
+ {
+ xtr.Dispose();
+ throw ex;
+ }
// For XML errors, just skip the affected node
xtr?.Read();
diff --git a/SabreTools.Library/DatFiles/SeparatedValue.cs b/SabreTools.Library/DatFiles/SeparatedValue.cs
index 4b50af37..8c9c2794 100644
--- a/SabreTools.Library/DatFiles/SeparatedValue.cs
+++ b/SabreTools.Library/DatFiles/SeparatedValue.cs
@@ -65,8 +65,14 @@ namespace SabreTools.Library.DatFiles
}
catch (InvalidDataException ex)
{
- Globals.Logger.Warning($"Malformed line found in '{filename}' at line {svr.LineNumber}");
- if (throwOnError) throw ex;
+ string message = $"'{filename}' - There was an error parsing line {svr.LineNumber} '{svr.CurrentLine}'";
+ Globals.Logger.Error(ex, message);
+ if (throwOnError)
+ {
+ svr.Dispose();
+ throw new Exception(message, ex);
+ }
+
continue;
}
diff --git a/SabreTools.Library/DatFiles/SoftwareList.cs b/SabreTools.Library/DatFiles/SoftwareList.cs
index 294a9d7d..44f86b33 100644
--- a/SabreTools.Library/DatFiles/SoftwareList.cs
+++ b/SabreTools.Library/DatFiles/SoftwareList.cs
@@ -81,8 +81,12 @@ namespace SabreTools.Library.DatFiles
}
catch (Exception ex)
{
- Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}");
- if (throwOnError) throw ex;
+ Globals.Logger.Warning(ex, $"Exception found while parsing '{filename}'");
+ if (throwOnError)
+ {
+ xtr.Dispose();
+ throw ex;
+ }
// For XML errors, just skip the affected node
xtr?.Read();
diff --git a/SabreTools.Library/Filtering/ExtraIniItem.cs b/SabreTools.Library/Filtering/ExtraIniItem.cs
index 6705257a..832e305c 100644
--- a/SabreTools.Library/Filtering/ExtraIniItem.cs
+++ b/SabreTools.Library/Filtering/ExtraIniItem.cs
@@ -74,7 +74,7 @@ namespace SabreTools.Library.Filtering
{
// Get the key and value
string key = ir.Section;
- string value = ir.Line.Trim();
+ string value = ir.CurrentLine.Trim();
// If the section is "ROOT_FOLDER", then we use the value "true" instead.
// This is done because some INI files use the name of the file as the
diff --git a/SabreTools.Library/IO/ClrMameProReader.cs b/SabreTools.Library/IO/ClrMameProReader.cs
index 86e1b6aa..124c7654 100644
--- a/SabreTools.Library/IO/ClrMameProReader.cs
+++ b/SabreTools.Library/IO/ClrMameProReader.cs
@@ -16,6 +16,16 @@ namespace SabreTools.Library.IO
///
private StreamReader sr;
+ ///
+ /// Contents of the current line, unprocessed
+ ///
+ public string CurrentLine { get; private set; } = string.Empty;
+
+ ///
+ /// Get the current line number
+ ///
+ public long LineNumber { get; private set; } = 0;
+
///
/// Get if at end of stream
///
@@ -74,7 +84,6 @@ namespace SabreTools.Library.IO
public ClrMameProReader(string filename)
{
sr = new StreamReader(filename);
- DosCenter = true;
}
///
@@ -83,7 +92,6 @@ namespace SabreTools.Library.IO
public ClrMameProReader(Stream stream, Encoding encoding)
{
sr = new StreamReader(stream, encoding);
- DosCenter = true;
}
///
@@ -94,8 +102,11 @@ namespace SabreTools.Library.IO
if (!(sr.BaseStream?.CanRead ?? false) || sr.EndOfStream)
return false;
- string line = sr.ReadLine().Trim();
- ProcessLine(line);
+ CurrentLine = sr.ReadLine().Trim();
+ LineNumber++;
+
+ // TODO: Act like IniReader here
+ ProcessLine(CurrentLine);
return true;
}
diff --git a/SabreTools.Library/IO/IniReader.cs b/SabreTools.Library/IO/IniReader.cs
index 53527cfa..d946cb28 100644
--- a/SabreTools.Library/IO/IniReader.cs
+++ b/SabreTools.Library/IO/IniReader.cs
@@ -30,9 +30,14 @@ namespace SabreTools.Library.IO
public KeyValuePair? KeyValuePair { get; private set; } = null;
///
- /// Contents of the currently read line
+ /// Contents of the current line, unprocessed
///
- public string Line { get; private set; } = string.Empty;
+ public string CurrentLine { get; private set; } = string.Empty;
+
+ ///
+ /// Get the current line number
+ ///
+ public long LineNumber { get; private set; } = 0;
///
/// Current row type
@@ -73,7 +78,8 @@ namespace SabreTools.Library.IO
if (!(sr.BaseStream?.CanRead ?? false) || sr.EndOfStream)
return false;
- Line = sr.ReadLine().Trim();
+ CurrentLine = sr.ReadLine().Trim();
+ LineNumber++;
ProcessLine();
return true;
}
@@ -84,25 +90,25 @@ namespace SabreTools.Library.IO
private void ProcessLine()
{
// Comment
- if (Line.StartsWith(";"))
+ if (CurrentLine.StartsWith(";"))
{
KeyValuePair = null;
RowType = IniRowType.Comment;
}
// Section
- else if (Line.StartsWith("[") && Line.EndsWith("]"))
+ else if (CurrentLine.StartsWith("[") && CurrentLine.EndsWith("]"))
{
KeyValuePair = null;
RowType = IniRowType.SectionHeader;
- Section = Line.TrimStart('[').TrimEnd(']');
+ Section = CurrentLine.TrimStart('[').TrimEnd(']');
}
// KeyValuePair
- else if (Line.Contains("="))
+ else if (CurrentLine.Contains("="))
{
// Split the line by '=' for key-value pairs
- string[] data = Line.Split('=');
+ string[] data = CurrentLine.Split('=');
// If the value field contains an '=', we need to put them back in
string key = data[0].Trim();
@@ -113,10 +119,10 @@ namespace SabreTools.Library.IO
}
// Empty
- else if (string.IsNullOrEmpty(Line))
+ else if (string.IsNullOrEmpty(CurrentLine))
{
KeyValuePair = null;
- Line = string.Empty;
+ CurrentLine = string.Empty;
RowType = IniRowType.None;
}
@@ -127,7 +133,7 @@ namespace SabreTools.Library.IO
RowType = IniRowType.Invalid;
if (ValidateRows)
- throw new InvalidDataException($"Invalid INI row found, cannot continue: {Line}");
+ throw new InvalidDataException($"Invalid INI row found, cannot continue: {CurrentLine}");
}
}
diff --git a/SabreTools.Library/IO/SeparatedValueReader.cs b/SabreTools.Library/IO/SeparatedValueReader.cs
index 178998d0..cfe0941a 100644
--- a/SabreTools.Library/IO/SeparatedValueReader.cs
+++ b/SabreTools.Library/IO/SeparatedValueReader.cs
@@ -30,6 +30,16 @@ namespace SabreTools.Library.IO
}
}
+ ///
+ /// Contents of the current line, unprocessed
+ ///
+ public string CurrentLine { get; private set; } = string.Empty;
+
+ ///
+ /// Get the current line number
+ ///
+ public long LineNumber { get; private set; } = 0;
+
///
/// Assume the first row is a header
///
@@ -45,11 +55,6 @@ namespace SabreTools.Library.IO
///
public List Line { get; private set; } = null;
- ///
- /// Get the current line number
- ///
- public long LineNumber { get; private set; } = -1;
-
///
/// Assume that values are wrapped in quotes
///
@@ -104,6 +109,7 @@ namespace SabreTools.Library.IO
return false;
string fullLine = sr.ReadLine();
+ CurrentLine = fullLine;
LineNumber++;
// If we have quotes, we need to split specially