Make less things use global throw state

This commit is contained in:
Matt Nadareski
2020-09-15 14:23:40 -07:00
parent 91f659dca2
commit f506915a04
19 changed files with 1713 additions and 2503 deletions

View File

@@ -29,7 +29,8 @@ namespace SabreTools.Library.DatFiles
/// <param name="filename">Name of the file to be parsed</param> /// <param name="filename">Name of the file to be parsed</param>
/// <param name="indexId">Index ID for the DAT</param> /// <param name="indexId">Index ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
protected override void ParseFile(string filename, int indexId, bool keep) /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
{ {
// Open a file reader // Open a file reader
Encoding enc = FileExtensions.GetEncoding(filename); Encoding enc = FileExtensions.GetEncoding(filename);
@@ -62,9 +63,7 @@ namespace SabreTools.Library.DatFiles
catch (InvalidDataException ex) catch (InvalidDataException ex)
{ {
Globals.Logger.Warning($"Malformed line found in '{filename}' at line {svr.LineNumber}"); Globals.Logger.Warning($"Malformed line found in '{filename}' at line {svr.LineNumber}");
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
continue; continue;
} }
@@ -117,8 +116,9 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="outfile">Name of the file to write to</param> /// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param> /// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns> /// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false) public override bool WriteToFile(string outfile, bool ignoreblanks = false, bool throwOnError = false)
{ {
try try
{ {
@@ -170,9 +170,7 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Error(ex.ToString()); Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
return false; return false;
} }
@@ -183,46 +181,32 @@ namespace SabreTools.Library.DatFiles
/// Write out DAT header using the supplied StreamWriter /// Write out DAT header using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="svw">SeparatedValueWriter to output to</param> /// <param name="svw">SeparatedValueWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteHeader(SeparatedValueWriter svw)
private bool WriteHeader(SeparatedValueWriter svw)
{ {
try string[] headers = new string[]
{ {
string[] headers = new string[] "#Name",
{ "Title",
"#Name", "Emulator",
"Title", "CloneOf",
"Emulator", "Year",
"CloneOf", "Manufacturer",
"Year", "Category",
"Manufacturer", "Players",
"Category", "Rotation",
"Players", "Control",
"Rotation", "Status",
"Control", "DisplayCount",
"Status", "DisplayType",
"DisplayCount", "AltRomname",
"DisplayType", "AltTitle",
"AltRomname", "Extra",
"AltTitle", "Buttons",
"Extra", };
"Buttons",
};
svw.WriteHeader(headers); svw.WriteHeader(headers);
svw.Flush(); svw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
@@ -230,24 +214,22 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="svw">SeparatedValueWriter to output to</param> /// <param name="svw">SeparatedValueWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
private bool WriteDatItem(SeparatedValueWriter svw, DatItem datItem) private void WriteDatItem(SeparatedValueWriter svw, DatItem datItem)
{ {
try // No game should start with a path separator
datItem.Machine.Name = datItem.Machine.Name.TrimStart(Path.DirectorySeparatorChar);
// Pre-process the item name
ProcessItemName(datItem, true);
// Build the state
switch (datItem.ItemType)
{ {
// No game should start with a path separator case ItemType.Rom:
datItem.Machine.Name = datItem.Machine.Name.TrimStart(Path.DirectorySeparatorChar); var rom = datItem as Rom;
string[] fields = new string[]
// Pre-process the item name {
ProcessItemName(datItem, true);
// Build the state
switch (datItem.ItemType)
{
case ItemType.Rom:
var rom = datItem as Rom;
string[] fields = new string[]
{
rom.Machine.Name, rom.Machine.Name,
rom.Machine.Description, rom.Machine.Description,
Header.FileName, Header.FileName,
@@ -265,24 +247,13 @@ namespace SabreTools.Library.DatFiles
rom.AltTitle, rom.AltTitle,
rom.Machine.Comment, rom.Machine.Comment,
rom.Machine.Buttons, rom.Machine.Buttons,
}; };
svw.WriteValues(fields); svw.WriteValues(fields);
break; break;
}
svw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
} }
return true; svw.Flush();
} }
} }
} }

View File

@@ -31,7 +31,8 @@ namespace SabreTools.Library.DatFiles
/// <param name="filename">Name of the file to be parsed</param> /// <param name="filename">Name of the file to be parsed</param>
/// <param name="indexId">Index ID for the DAT</param> /// <param name="indexId">Index ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
protected override void ParseFile(string filename, int indexId, bool keep) /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
{ {
// Open a file reader // Open a file reader
Encoding enc = FileExtensions.GetEncoding(filename); Encoding enc = FileExtensions.GetEncoding(filename);
@@ -412,8 +413,9 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="outfile">Name of the file to write to</param> /// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param> /// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns> /// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false) public override bool WriteToFile(string outfile, bool ignoreblanks = false, bool throwOnError = false)
{ {
try try
{ {
@@ -480,9 +482,7 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Error(ex.ToString()); Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
return false; return false;
} }
@@ -493,41 +493,27 @@ namespace SabreTools.Library.DatFiles
/// Write out DAT header using the supplied StreamWriter /// Write out DAT header using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="cmpw">ClrMameProWriter to output to</param> /// <param name="cmpw">ClrMameProWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteHeader(ClrMameProWriter cmpw)
private bool WriteHeader(ClrMameProWriter cmpw)
{ {
try cmpw.WriteStartElement("clrmamepro");
{
cmpw.WriteStartElement("clrmamepro");
cmpw.WriteRequiredStandalone("name", Header.Name); cmpw.WriteRequiredStandalone("name", Header.Name);
cmpw.WriteRequiredStandalone("description", Header.Description); cmpw.WriteRequiredStandalone("description", Header.Description);
cmpw.WriteOptionalStandalone("category", Header.Category); cmpw.WriteOptionalStandalone("category", Header.Category);
cmpw.WriteRequiredStandalone("version", Header.Version); cmpw.WriteRequiredStandalone("version", Header.Version);
cmpw.WriteOptionalStandalone("date", Header.Date); cmpw.WriteOptionalStandalone("date", Header.Date);
cmpw.WriteRequiredStandalone("author", Header.Author); cmpw.WriteRequiredStandalone("author", Header.Author);
cmpw.WriteOptionalStandalone("email", Header.Email); cmpw.WriteOptionalStandalone("email", Header.Email);
cmpw.WriteOptionalStandalone("homepage", Header.Homepage); cmpw.WriteOptionalStandalone("homepage", Header.Homepage);
cmpw.WriteOptionalStandalone("url", Header.Url); cmpw.WriteOptionalStandalone("url", Header.Url);
cmpw.WriteOptionalStandalone("comment", Header.Comment); cmpw.WriteOptionalStandalone("comment", Header.Comment);
cmpw.WriteOptionalStandalone("forcezipping", Header.ForcePacking.FromPackingFlag(true), false); cmpw.WriteOptionalStandalone("forcezipping", Header.ForcePacking.FromPackingFlag(true), false);
cmpw.WriteOptionalStandalone("forcemerging", Header.ForceMerging.FromMergingFlag(false), false); cmpw.WriteOptionalStandalone("forcemerging", Header.ForceMerging.FromMergingFlag(false), false);
// End clrmamepro // End clrmamepro
cmpw.WriteEndElement(); cmpw.WriteEndElement();
cmpw.Flush(); cmpw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
@@ -535,37 +521,23 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="cmpw">ClrMameProWriter to output to</param> /// <param name="cmpw">ClrMameProWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> private void WriteStartGame(ClrMameProWriter cmpw, DatItem datItem)
private bool WriteStartGame(ClrMameProWriter cmpw, DatItem datItem)
{ {
try // No game should start with a path separator
{ datItem.Machine.Name = datItem.Machine.Name.TrimStart(Path.DirectorySeparatorChar);
// No game should start with a path separator
datItem.Machine.Name = datItem.Machine.Name.TrimStart(Path.DirectorySeparatorChar);
// Build the state // Build the state
cmpw.WriteStartElement(datItem.Machine.MachineType == MachineType.Bios ? "resource" : "game"); cmpw.WriteStartElement(datItem.Machine.MachineType == MachineType.Bios ? "resource" : "game");
cmpw.WriteRequiredStandalone("name", datItem.Machine.Name); cmpw.WriteRequiredStandalone("name", datItem.Machine.Name);
cmpw.WriteOptionalStandalone("romof", datItem.Machine.RomOf); cmpw.WriteOptionalStandalone("romof", datItem.Machine.RomOf);
cmpw.WriteOptionalStandalone("cloneof", datItem.Machine.CloneOf); cmpw.WriteOptionalStandalone("cloneof", datItem.Machine.CloneOf);
cmpw.WriteOptionalStandalone("description", datItem.Machine.Description ?? datItem.Machine.Name); cmpw.WriteOptionalStandalone("description", datItem.Machine.Description ?? datItem.Machine.Name);
cmpw.WriteOptionalStandalone("year", datItem.Machine.Year); cmpw.WriteOptionalStandalone("year", datItem.Machine.Year);
cmpw.WriteOptionalStandalone("manufacturer", datItem.Machine.Manufacturer); cmpw.WriteOptionalStandalone("manufacturer", datItem.Machine.Manufacturer);
cmpw.WriteOptionalStandalone("category", datItem.Machine.Category); cmpw.WriteOptionalStandalone("category", datItem.Machine.Category);
cmpw.Flush(); cmpw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
@@ -573,29 +545,15 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="cmpw">ClrMameProWriter to output to</param> /// <param name="cmpw">ClrMameProWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> private void WriteEndGame(ClrMameProWriter cmpw, DatItem datItem)
private bool WriteEndGame(ClrMameProWriter cmpw, DatItem datItem)
{ {
try // Build the state
{ cmpw.WriteOptionalStandalone("sampleof", datItem.Machine.SampleOf);
// Build the state
cmpw.WriteOptionalStandalone("sampleof", datItem.Machine.SampleOf);
// End game // End game
cmpw.WriteEndElement(); cmpw.WriteEndElement();
cmpw.Flush(); cmpw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
@@ -604,131 +562,103 @@ namespace SabreTools.Library.DatFiles
/// <param name="datFile">DatFile to write out from</param> /// <param name="datFile">DatFile to write out from</param>
/// <param name="cmpw">ClrMameProWriter to output to</param> /// <param name="cmpw">ClrMameProWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> private void WriteDatItem(ClrMameProWriter cmpw, DatItem datItem)
private bool WriteDatItem(ClrMameProWriter cmpw, DatItem datItem)
{ {
try // Pre-process the item name
ProcessItemName(datItem, true);
// Build the state
switch (datItem.ItemType)
{ {
// Pre-process the item name case ItemType.Archive:
ProcessItemName(datItem, true); var archive = datItem as Archive;
cmpw.WriteStartElement("archive");
cmpw.WriteRequiredAttributeString("name", archive.Name);
cmpw.WriteEndElement();
break;
// Build the state case ItemType.BiosSet:
switch (datItem.ItemType) var biosSet = datItem as BiosSet;
{ cmpw.WriteStartElement("biosset");
case ItemType.Archive: cmpw.WriteRequiredAttributeString("name", biosSet.Name);
var archive = datItem as Archive; cmpw.WriteOptionalAttributeString("description", biosSet.Description);
cmpw.WriteStartElement("archive"); cmpw.WriteOptionalAttributeString("default", biosSet.Default?.ToString().ToLowerInvariant());
cmpw.WriteRequiredAttributeString("name", archive.Name); cmpw.WriteEndElement();
cmpw.WriteEndElement(); break;
break;
case ItemType.BiosSet: case ItemType.Disk:
var biosSet = datItem as BiosSet; var disk = datItem as Disk;
cmpw.WriteStartElement("biosset"); cmpw.WriteStartElement("disk");
cmpw.WriteRequiredAttributeString("name", biosSet.Name); cmpw.WriteRequiredAttributeString("name", disk.Name);
cmpw.WriteOptionalAttributeString("description", biosSet.Description); cmpw.WriteOptionalAttributeString("md5", disk.MD5?.ToLowerInvariant());
cmpw.WriteOptionalAttributeString("default", biosSet.Default?.ToString().ToLowerInvariant()); cmpw.WriteOptionalAttributeString("sha1", disk.SHA1?.ToLowerInvariant());
cmpw.WriteEndElement(); cmpw.WriteOptionalAttributeString("flags", disk.ItemStatus.FromItemStatus(false));
break; cmpw.WriteEndElement();
break;
case ItemType.Disk: case ItemType.Media:
var disk = datItem as Disk; var media = datItem as Media;
cmpw.WriteStartElement("disk"); cmpw.WriteStartElement("media");
cmpw.WriteRequiredAttributeString("name", disk.Name); cmpw.WriteRequiredAttributeString("name", media.Name);
cmpw.WriteOptionalAttributeString("md5", disk.MD5?.ToLowerInvariant()); cmpw.WriteOptionalAttributeString("md5", media.MD5?.ToLowerInvariant());
cmpw.WriteOptionalAttributeString("sha1", disk.SHA1?.ToLowerInvariant()); cmpw.WriteOptionalAttributeString("sha1", media.SHA1?.ToLowerInvariant());
cmpw.WriteOptionalAttributeString("flags", disk.ItemStatus.FromItemStatus(false)); cmpw.WriteOptionalAttributeString("sha256", media.SHA256?.ToLowerInvariant());
cmpw.WriteEndElement(); cmpw.WriteOptionalAttributeString("spamsum", media.SpamSum?.ToLowerInvariant());
break; cmpw.WriteEndElement();
break;
case ItemType.Media: case ItemType.Release:
var media = datItem as Media; var release = datItem as Release;
cmpw.WriteStartElement("media"); cmpw.WriteStartElement("release");
cmpw.WriteRequiredAttributeString("name", media.Name); cmpw.WriteRequiredAttributeString("name", release.Name);
cmpw.WriteOptionalAttributeString("md5", media.MD5?.ToLowerInvariant()); cmpw.WriteOptionalAttributeString("region", release.Region);
cmpw.WriteOptionalAttributeString("sha1", media.SHA1?.ToLowerInvariant()); cmpw.WriteOptionalAttributeString("language", release.Language);
cmpw.WriteOptionalAttributeString("sha256", media.SHA256?.ToLowerInvariant()); cmpw.WriteOptionalAttributeString("date", release.Date);
cmpw.WriteOptionalAttributeString("spamsum", media.SpamSum?.ToLowerInvariant()); cmpw.WriteOptionalAttributeString("default", release.Default?.ToString().ToLowerInvariant());
cmpw.WriteEndElement(); cmpw.WriteEndElement();
break; break;
case ItemType.Release: case ItemType.Rom:
var release = datItem as Release; var rom = datItem as Rom;
cmpw.WriteStartElement("release"); cmpw.WriteStartElement("rom");
cmpw.WriteRequiredAttributeString("name", release.Name); cmpw.WriteRequiredAttributeString("name", rom.Name);
cmpw.WriteOptionalAttributeString("region", release.Region); cmpw.WriteOptionalAttributeString("size", rom.Size?.ToString());
cmpw.WriteOptionalAttributeString("language", release.Language); cmpw.WriteOptionalAttributeString("crc", rom.CRC?.ToLowerInvariant());
cmpw.WriteOptionalAttributeString("date", release.Date); cmpw.WriteOptionalAttributeString("md5", rom.MD5?.ToLowerInvariant());
cmpw.WriteOptionalAttributeString("default", release.Default?.ToString().ToLowerInvariant());
cmpw.WriteEndElement();
break;
case ItemType.Rom:
var rom = datItem as Rom;
cmpw.WriteStartElement("rom");
cmpw.WriteRequiredAttributeString("name", rom.Name);
cmpw.WriteOptionalAttributeString("size", rom.Size?.ToString());
cmpw.WriteOptionalAttributeString("crc", rom.CRC?.ToLowerInvariant());
cmpw.WriteOptionalAttributeString("md5", rom.MD5?.ToLowerInvariant());
#if NET_FRAMEWORK #if NET_FRAMEWORK
cmpw.WriteOptionalAttributeString("ripemd160", rom.RIPEMD160?.ToLowerInvariant()); cmpw.WriteOptionalAttributeString("ripemd160", rom.RIPEMD160?.ToLowerInvariant());
#endif #endif
cmpw.WriteOptionalAttributeString("sha1", rom.SHA1?.ToLowerInvariant()); cmpw.WriteOptionalAttributeString("sha1", rom.SHA1?.ToLowerInvariant());
cmpw.WriteOptionalAttributeString("sha256", rom.SHA256?.ToLowerInvariant()); cmpw.WriteOptionalAttributeString("sha256", rom.SHA256?.ToLowerInvariant());
cmpw.WriteOptionalAttributeString("sha384", rom.SHA384?.ToLowerInvariant()); cmpw.WriteOptionalAttributeString("sha384", rom.SHA384?.ToLowerInvariant());
cmpw.WriteOptionalAttributeString("sha512", rom.SHA512?.ToLowerInvariant()); cmpw.WriteOptionalAttributeString("sha512", rom.SHA512?.ToLowerInvariant());
cmpw.WriteOptionalAttributeString("spamsum", rom.SpamSum?.ToLowerInvariant()); cmpw.WriteOptionalAttributeString("spamsum", rom.SpamSum?.ToLowerInvariant());
cmpw.WriteOptionalAttributeString("date", rom.Date); cmpw.WriteOptionalAttributeString("date", rom.Date);
cmpw.WriteOptionalAttributeString("flags", rom.ItemStatus.FromItemStatus(false)); cmpw.WriteOptionalAttributeString("flags", rom.ItemStatus.FromItemStatus(false));
cmpw.WriteEndElement(); cmpw.WriteEndElement();
break; break;
case ItemType.Sample: case ItemType.Sample:
var sample = datItem as Sample; var sample = datItem as Sample;
cmpw.WriteStartElement("sample"); cmpw.WriteStartElement("sample");
cmpw.WriteRequiredAttributeString("name", sample.Name); cmpw.WriteRequiredAttributeString("name", sample.Name);
cmpw.WriteEndElement(); cmpw.WriteEndElement();
break; break;
}
cmpw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
} }
return true; cmpw.Flush();
} }
/// <summary> /// <summary>
/// Write out DAT footer using the supplied StreamWriter /// Write out DAT footer using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="cmpw">ClrMameProWriter to output to</param> /// <param name="cmpw">ClrMameProWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteFooter(ClrMameProWriter cmpw)
private bool WriteFooter(ClrMameProWriter cmpw)
{ {
try // End game
{ cmpw.WriteEndElement();
// End game
cmpw.WriteEndElement();
cmpw.Flush(); cmpw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
} }
} }

View File

@@ -1823,10 +1823,16 @@ namespace SabreTools.Library.DatFiles
/// <param name="indexId">Index ID for the DAT</param> /// <param name="indexId">Index ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
/// <param name="keepext">True if original extension should be kept, false otherwise (default)</param> /// <param name="keepext">True if original extension should be kept, false otherwise (default)</param>
public void Parse(string filename, int indexId = 0, bool keep = false, bool keepext = false) /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
public void Parse(
string filename,
int indexId = 0,
bool keep = false,
bool keepext = false,
bool throwOnError = false)
{ {
ParentablePath path = new ParentablePath(filename.Trim('"')); ParentablePath path = new ParentablePath(filename.Trim('"'));
Parse(path, indexId, keep, keepext); Parse(path, indexId, keep, keepext, throwOnError);
} }
/// <summary> /// <summary>
@@ -1836,7 +1842,13 @@ namespace SabreTools.Library.DatFiles
/// <param name="indexId">Index ID for the DAT</param> /// <param name="indexId">Index ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
/// <param name="keepext">True if original extension should be kept, false otherwise (default)</param> /// <param name="keepext">True if original extension should be kept, false otherwise (default)</param>
public void Parse(ParentablePath filename, int indexId = 0, bool keep = false, bool keepext = false) /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
public void Parse(
ParentablePath filename,
int indexId = 0,
bool keep = false,
bool keepext = false,
bool throwOnError = false)
{ {
// Get the current path from the filename // Get the current path from the filename
string currentPath = filename.CurrentPath; string currentPath = filename.CurrentPath;
@@ -1855,13 +1867,12 @@ namespace SabreTools.Library.DatFiles
// Now parse the correct type of DAT // Now parse the correct type of DAT
try try
{ {
Create(currentPath.GetDatFormat(), this)?.ParseFile(currentPath, indexId, keep); Create(currentPath.GetDatFormat(), this)?.ParseFile(currentPath, indexId, keep, throwOnError);
} }
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Error($"Error with file '{filename}': {ex}"); Globals.Logger.Error($"Error with file '{filename}': {ex}");
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
} }
} }
@@ -1976,7 +1987,8 @@ namespace SabreTools.Library.DatFiles
/// <param name="filename">Name of the file to be parsed</param> /// <param name="filename">Name of the file to be parsed</param>
/// <param name="indexId">Index ID for the DAT</param> /// <param name="indexId">Index ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
protected abstract void ParseFile(string filename, int indexId, bool keep); /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
protected abstract void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false);
#endregion #endregion
@@ -3452,8 +3464,14 @@ namespace SabreTools.Library.DatFiles
/// <param name="stats">True if DAT statistics should be output on write, false otherwise (default)</param> /// <param name="stats">True if DAT statistics should be output on write, false otherwise (default)</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param> /// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <param name="overwrite">True if files should be overwritten (default), false if they should be renamed instead</param> /// <param name="overwrite">True if files should be overwritten (default), false if they should be renamed instead</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns> /// <returns>True if the DAT was written correctly, false otherwise</returns>
public bool Write(string outDir, bool norename = true, bool stats = false, bool ignoreblanks = false, bool overwrite = true) public bool Write(string outDir,
bool norename = true,
bool stats = false,
bool ignoreblanks = false,
bool overwrite = true,
bool throwOnError = false)
{ {
// If we have nothing writable, abort // If we have nothing writable, abort
if (!HasWritable()) if (!HasWritable())
@@ -3504,7 +3522,7 @@ namespace SabreTools.Library.DatFiles
string outfile = outfiles[datFormat]; string outfile = outfiles[datFormat];
try try
{ {
Create(datFormat, this)?.WriteToFile(outfile, ignoreblanks); Create(datFormat, this)?.WriteToFile(outfile, ignoreblanks, throwOnError);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -3532,8 +3550,9 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="outfile">Name of the file to write to</param> /// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param> /// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns> /// <returns>True if the DAT was written correctly, false otherwise</returns>
public abstract bool WriteToFile(string outfile, bool ignoreblanks = false); public abstract bool WriteToFile(string outfile, bool ignoreblanks = false, bool throwOnError = false);
/// <summary> /// <summary>
/// Create a prefix or postfix from inputs /// Create a prefix or postfix from inputs

View File

@@ -31,7 +31,8 @@ namespace SabreTools.Library.DatFiles
/// <param name="filename">Name of the file to be parsed</param> /// <param name="filename">Name of the file to be parsed</param>
/// <param name="indexId">Index ID for the DAT</param> /// <param name="indexId">Index ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
protected override void ParseFile(string filename, int indexId, bool keep) /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
{ {
// Open a file reader // Open a file reader
Encoding enc = FileExtensions.GetEncoding(filename); Encoding enc = FileExtensions.GetEncoding(filename);
@@ -246,14 +247,14 @@ namespace SabreTools.Library.DatFiles
} }
} }
/// <summary> /// <summary>
/// Create and open an output file for writing direct from a dictionary /// Create and open an output file for writing direct from a dictionary
/// </summary> /// </summary>
/// <param name="outfile">Name of the file to write to</param> /// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param> /// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns> /// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false) public override bool WriteToFile(string outfile, bool ignoreblanks = false, bool throwOnError = false)
{ {
try try
{ {
@@ -322,9 +323,7 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Error(ex.ToString()); Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
return false; return false;
} }
@@ -335,36 +334,22 @@ namespace SabreTools.Library.DatFiles
/// Write out DAT header using the supplied StreamWriter /// Write out DAT header using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="cmpw">ClrMameProWriter to output to</param> /// <param name="cmpw">ClrMameProWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteHeader(ClrMameProWriter cmpw)
private bool WriteHeader(ClrMameProWriter cmpw)
{ {
try // Build the state
{ cmpw.WriteStartElement("DOSCenter");
// Build the state
cmpw.WriteStartElement("DOSCenter");
cmpw.WriteRequiredStandalone("Name:", Header.Name, false); cmpw.WriteRequiredStandalone("Name:", Header.Name, false);
cmpw.WriteRequiredStandalone("Description:", Header.Description, false); cmpw.WriteRequiredStandalone("Description:", Header.Description, false);
cmpw.WriteRequiredStandalone("Version:", Header.Version, false); cmpw.WriteRequiredStandalone("Version:", Header.Version, false);
cmpw.WriteRequiredStandalone("Date:", Header.Date, false); cmpw.WriteRequiredStandalone("Date:", Header.Date, false);
cmpw.WriteRequiredStandalone("Author:", Header.Author, false); cmpw.WriteRequiredStandalone("Author:", Header.Author, false);
cmpw.WriteRequiredStandalone("Homepage:", Header.Homepage, false); cmpw.WriteRequiredStandalone("Homepage:", Header.Homepage, false);
cmpw.WriteRequiredStandalone("Comment:", Header.Comment, false); cmpw.WriteRequiredStandalone("Comment:", Header.Comment, false);
cmpw.WriteEndElement(); cmpw.WriteEndElement();
cmpw.Flush(); cmpw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
@@ -372,56 +357,28 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="cmpw">ClrMameProWriter to output to</param> /// <param name="cmpw">ClrMameProWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> private void WriteStartGame(ClrMameProWriter cmpw, DatItem datItem)
private bool WriteStartGame(ClrMameProWriter cmpw, DatItem datItem)
{ {
try // No game should start with a path separator
{ datItem.Machine.Name = datItem.Machine.Name.TrimStart(Path.DirectorySeparatorChar);
// No game should start with a path separator
datItem.Machine.Name = datItem.Machine.Name.TrimStart(Path.DirectorySeparatorChar);
// Build the state // Build the state
cmpw.WriteStartElement("game"); cmpw.WriteStartElement("game");
cmpw.WriteRequiredStandalone("name", $"{datItem.Machine.Name}.zip", true); cmpw.WriteRequiredStandalone("name", $"{datItem.Machine.Name}.zip", true);
cmpw.Flush(); cmpw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
/// Write out Game end using the supplied StreamWriter /// Write out Game end using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="cmpw">ClrMameProWriter to output to</param> /// <param name="cmpw">ClrMameProWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteEndGame(ClrMameProWriter cmpw)
private bool WriteEndGame(ClrMameProWriter cmpw)
{ {
try // End game
{ cmpw.WriteEndElement();
// End game
cmpw.WriteEndElement();
cmpw.Flush(); cmpw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
@@ -429,40 +386,26 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="cmpw">ClrMameProWriter to output to</param> /// <param name="cmpw">ClrMameProWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> private void WriteDatItem(ClrMameProWriter cmpw, DatItem datItem)
private bool WriteDatItem(ClrMameProWriter cmpw, DatItem datItem)
{ {
try // Pre-process the item name
ProcessItemName(datItem, true);
// Build the state
switch (datItem.ItemType)
{ {
// Pre-process the item name case ItemType.Rom:
ProcessItemName(datItem, true); var rom = datItem as Rom;
cmpw.WriteStartElement("file");
// Build the state cmpw.WriteRequiredAttributeString("name", rom.Name);
switch (datItem.ItemType) cmpw.WriteOptionalAttributeString("size", rom.Size?.ToString());
{ cmpw.WriteOptionalAttributeString("date", rom.Date);
case ItemType.Rom: cmpw.WriteOptionalAttributeString("crc", rom.CRC?.ToLowerInvariant());
var rom = datItem as Rom; cmpw.WriteEndElement();
cmpw.WriteStartElement("file"); break;
cmpw.WriteRequiredAttributeString("name", rom.Name);
cmpw.WriteOptionalAttributeString("size", rom.Size?.ToString());
cmpw.WriteOptionalAttributeString("date", rom.Date);
cmpw.WriteOptionalAttributeString("crc", rom.CRC?.ToLowerInvariant());
cmpw.WriteEndElement();
break;
}
cmpw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
} }
return true; cmpw.Flush();
} }
/// <summary> /// <summary>
@@ -470,25 +413,12 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="cmpw">ClrMameProWriter to output to</param> /// <param name="cmpw">ClrMameProWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> /// <returns>True if the data was written, false on error</returns>
private bool WriteFooter(ClrMameProWriter cmpw) private void WriteFooter(ClrMameProWriter cmpw)
{ {
try // End game
{ cmpw.WriteEndElement();
// End game
cmpw.WriteEndElement();
cmpw.Flush(); cmpw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
} }
} }

View File

@@ -30,7 +30,8 @@ namespace SabreTools.Library.DatFiles
/// <param name="filename">Name of the file to be parsed</param> /// <param name="filename">Name of the file to be parsed</param>
/// <param name="indexId">Index ID for the DAT</param> /// <param name="indexId">Index ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
protected override void ParseFile(string filename, int indexId, bool keep) /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
{ {
// Open a file reader // Open a file reader
Encoding enc = FileExtensions.GetEncoding(filename); Encoding enc = FileExtensions.GetEncoding(filename);
@@ -87,8 +88,9 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="outfile">Name of the file to write to</param> /// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param> /// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns> /// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false) public override bool WriteToFile(string outfile, bool ignoreblanks = false, bool throwOnError = false)
{ {
try try
{ {

View File

@@ -34,7 +34,8 @@ namespace SabreTools.Library.DatFiles
/// <param name="filename">Name of the file to be parsed</param> /// <param name="filename">Name of the file to be parsed</param>
/// <param name="indexId">Index ID for the DAT</param> /// <param name="indexId">Index ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
protected override void ParseFile(string filename, int indexId, bool keep) /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
{ {
// Open a file reader // Open a file reader
Encoding enc = FileExtensions.GetEncoding(filename); Encoding enc = FileExtensions.GetEncoding(filename);
@@ -102,8 +103,9 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="outfile">Name of the file to write to</param> /// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param> /// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns> /// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false) public override bool WriteToFile(string outfile, bool ignoreblanks = false, bool throwOnError = false)
{ {
try try
{ {
@@ -152,9 +154,7 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Error(ex.ToString()); Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
return false; return false;
} }
@@ -162,201 +162,187 @@ namespace SabreTools.Library.DatFiles
} }
/// <summary> /// <summary>
/// Write out DatItem using the supplied StreamWriter /// Write out DatItem using the supplied SeparatedValueWriter
/// </summary> /// </summary>
/// <param name="svw">SeparatedValueWriter to output to</param> /// <param name="svw">SeparatedValueWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> private void WriteDatItem(SeparatedValueWriter svw, DatItem datItem)
private bool WriteDatItem(SeparatedValueWriter svw, DatItem datItem)
{ {
try // Build the state
string[] fields = new string[2];
// Get the name field
string name = string.Empty;
switch (datItem.ItemType)
{ {
// Build the state case ItemType.Disk:
string[] fields = new string[2]; var disk = datItem as Disk;
if (Header.GameName)
name = $"{disk.Machine.Name}{Path.DirectorySeparatorChar}";
// Get the name field name += disk.Name;
string name = string.Empty; break;
switch (datItem.ItemType)
{
case ItemType.Disk:
var disk = datItem as Disk;
if (Header.GameName)
name = $"{disk.Machine.Name}{Path.DirectorySeparatorChar}";
name += disk.Name; case ItemType.Media:
break; var media = datItem as Media;
if (Header.GameName)
name = $"{media.Machine.Name}{Path.DirectorySeparatorChar}";
case ItemType.Media: name += media.Name;
var media = datItem as Media; break;
if (Header.GameName)
name = $"{media.Machine.Name}{Path.DirectorySeparatorChar}";
name += media.Name; case ItemType.Rom:
break; var rom = datItem as Rom;
if (Header.GameName)
name = $"{rom.Machine.Name}{Path.DirectorySeparatorChar}";
case ItemType.Rom: name += rom.Name;
var rom = datItem as Rom; break;
if (Header.GameName) }
name = $"{rom.Machine.Name}{Path.DirectorySeparatorChar}";
name += rom.Name; // Get the hash field and set final fields
break; string hash = string.Empty;
} switch (_hash)
{
case Hash.CRC:
switch (datItem.ItemType)
{
case ItemType.Rom:
var rom = datItem as Rom;
fields[0] = name;
fields[1] = rom.CRC;
break;
}
// Get the hash field and set final fields break;
string hash = string.Empty;
switch (_hash)
{
case Hash.CRC:
switch (datItem.ItemType)
{
case ItemType.Rom:
var rom = datItem as Rom;
fields[0] = name;
fields[1] = rom.CRC;
break;
}
break; case Hash.MD5:
switch (datItem.ItemType)
{
case ItemType.Disk:
var disk = datItem as Disk;
fields[0] = disk.MD5;
fields[1] = name;
break;
case Hash.MD5: case ItemType.Media:
switch (datItem.ItemType) var media = datItem as Media;
{ fields[0] = media.MD5;
case ItemType.Disk: fields[1] = name;
var disk = datItem as Disk; break;
fields[0] = disk.MD5;
fields[1] = name;
break;
case ItemType.Media: case ItemType.Rom:
var media = datItem as Media; var rom = datItem as Rom;
fields[0] = media.MD5; fields[0] = rom.MD5;
fields[1] = name; fields[1] = name;
break; break;
}
case ItemType.Rom: break;
var rom = datItem as Rom;
fields[0] = rom.MD5;
fields[1] = name;
break;
}
break;
#if NET_FRAMEWORK #if NET_FRAMEWORK
case Hash.RIPEMD160: case Hash.RIPEMD160:
switch (datItem.ItemType) switch (datItem.ItemType)
{ {
case ItemType.Rom: case ItemType.Rom:
var rom = datItem as Rom; var rom = datItem as Rom;
fields[0] = rom.RIPEMD160; fields[0] = rom.RIPEMD160;
fields[1] = name; fields[1] = name;
break; break;
} }
break; break;
#endif #endif
case Hash.SHA1: case Hash.SHA1:
switch (datItem.ItemType) switch (datItem.ItemType)
{ {
case ItemType.Disk: case ItemType.Disk:
var disk = datItem as Disk; var disk = datItem as Disk;
fields[0] = disk.SHA1; fields[0] = disk.SHA1;
fields[1] = name; fields[1] = name;
break; break;
case ItemType.Media: case ItemType.Media:
var media = datItem as Media; var media = datItem as Media;
fields[0] = media.SHA1; fields[0] = media.SHA1;
fields[1] = name; fields[1] = name;
break; break;
case ItemType.Rom: case ItemType.Rom:
var rom = datItem as Rom; var rom = datItem as Rom;
fields[0] = rom.SHA1; fields[0] = rom.SHA1;
fields[1] = name; fields[1] = name;
break; break;
} }
break; break;
case Hash.SHA256: case Hash.SHA256:
switch (datItem.ItemType) switch (datItem.ItemType)
{ {
case ItemType.Media: case ItemType.Media:
var media = datItem as Media; var media = datItem as Media;
fields[0] = media.SHA256; fields[0] = media.SHA256;
fields[1] = name; fields[1] = name;
break; break;
case ItemType.Rom: case ItemType.Rom:
var rom = datItem as Rom; var rom = datItem as Rom;
fields[0] = rom.SHA256; fields[0] = rom.SHA256;
fields[1] = name; fields[1] = name;
break; break;
} }
break; break;
case Hash.SHA384: case Hash.SHA384:
switch (datItem.ItemType) switch (datItem.ItemType)
{ {
case ItemType.Rom: case ItemType.Rom:
var rom = datItem as Rom; var rom = datItem as Rom;
fields[0] = rom.SHA384; fields[0] = rom.SHA384;
fields[1] = name; fields[1] = name;
break; break;
} }
break; break;
case Hash.SHA512: case Hash.SHA512:
switch (datItem.ItemType) switch (datItem.ItemType)
{ {
case ItemType.Rom: case ItemType.Rom:
var rom = datItem as Rom; var rom = datItem as Rom;
fields[0] = rom.SHA512; fields[0] = rom.SHA512;
fields[1] = name; fields[1] = name;
break; break;
} }
break; break;
case Hash.SpamSum: case Hash.SpamSum:
switch (datItem.ItemType) switch (datItem.ItemType)
{ {
case ItemType.Media: case ItemType.Media:
var media = datItem as Media; var media = datItem as Media;
fields[0] = media.SpamSum; fields[0] = media.SpamSum;
fields[1] = name; fields[1] = name;
break; break;
case ItemType.Rom: case ItemType.Rom:
var rom = datItem as Rom; var rom = datItem as Rom;
fields[0] = rom.SpamSum; fields[0] = rom.SpamSum;
fields[1] = name; fields[1] = name;
break; break;
} }
break; break;
}
// If we had at least one field filled in
if (!string.IsNullOrEmpty(fields[0]) || !string.IsNullOrEmpty(fields[1]))
svw.WriteValues(fields);
svw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
} }
return true; // If we had at least one field filled in
if (!string.IsNullOrEmpty(fields[0]) || !string.IsNullOrEmpty(fields[1]))
svw.WriteValues(fields);
svw.Flush();
} }
} }
} }

View File

@@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
@@ -32,6 +31,7 @@ namespace SabreTools.Library.DatFiles
/// <param name="filename">Name of the file to be parsed</param> /// <param name="filename">Name of the file to be parsed</param>
/// <param name="indexId">Index ID for the DAT</param> /// <param name="indexId">Index ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
/// <remarks> /// <remarks>
/// In a new style MAME listrom DAT, each game has the following format: /// In a new style MAME listrom DAT, each game has the following format:
/// ///
@@ -41,7 +41,7 @@ namespace SabreTools.Library.DatFiles
/// 6331.sound-u8 32 BAD CRC(1d298cb0) SHA1(bb0bb62365402543e3154b9a77be9c75010e6abc) BAD_DUMP /// 6331.sound-u8 32 BAD CRC(1d298cb0) SHA1(bb0bb62365402543e3154b9a77be9c75010e6abc) BAD_DUMP
/// 16v8h-blue.u24 279 NO GOOD DUMP KNOWN /// 16v8h-blue.u24 279 NO GOOD DUMP KNOWN
/// </remarks> /// </remarks>
protected override void ParseFile(string filename, int indexId, bool keep) protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
{ {
// Open a file reader // Open a file reader
Encoding enc = FileExtensions.GetEncoding(filename); Encoding enc = FileExtensions.GetEncoding(filename);
@@ -255,8 +255,9 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="outfile">Name of the file to write to</param> /// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param> /// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns> /// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false) public override bool WriteToFile(string outfile, bool ignoreblanks = false, bool throwOnError = false)
{ {
try try
{ {
@@ -314,9 +315,7 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Error(ex.ToString()); Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
return false; return false;
} }
@@ -328,56 +327,28 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="sw">StreamWriter to output to</param> /// <param name="sw">StreamWriter to output to</param>
/// <param name="rom">DatItem object to be output</param> /// <param name="rom">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> private void WriteStartGame(StreamWriter sw, DatItem rom)
private bool WriteStartGame(StreamWriter sw, DatItem rom)
{ {
try // No game should start with a path separator
{ rom.Machine.Name = rom.Machine.Name.TrimStart(Path.DirectorySeparatorChar);
// No game should start with a path separator
rom.Machine.Name = rom.Machine.Name.TrimStart(Path.DirectorySeparatorChar);
// Build the state // Build the state
sw.Write($"ROMs required for driver \"{rom.Machine.Name}\".\n"); sw.Write($"ROMs required for driver \"{rom.Machine.Name}\".\n");
sw.Write("Name Size Checksum\n"); sw.Write("Name Size Checksum\n");
sw.Flush(); sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
/// Write out Game end using the supplied StreamWriter /// Write out Game end using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="sw">StreamWriter to output to</param> /// <param name="sw">StreamWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteEndGame(StreamWriter sw)
private bool WriteEndGame(StreamWriter sw)
{ {
try // End driver
{ sw.Write("\n");
// End driver
sw.Write("\n");
sw.Flush(); sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
@@ -385,96 +356,82 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="sw">StreamWriter to output to</param> /// <param name="sw">StreamWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> private void WriteDatItem(StreamWriter sw, DatItem datItem)
private bool WriteDatItem(StreamWriter sw, DatItem datItem)
{ {
try // Pre-process the item name
ProcessItemName(datItem, true);
// Build the state
switch (datItem.ItemType)
{ {
// Pre-process the item name case ItemType.Disk:
ProcessItemName(datItem, true); var disk = datItem as Disk;
// Build the state // The name is padded out to a particular length
switch (datItem.ItemType) if (disk.Name.Length < 43)
{ sw.Write(disk.Name.PadRight(43, ' '));
case ItemType.Disk: else
var disk = datItem as Disk; sw.Write($"{disk.Name} ");
// The name is padded out to a particular length // If we have a baddump, put the first indicator
if (disk.Name.Length < 43) if (disk.ItemStatus == ItemStatus.BadDump)
sw.Write(disk.Name.PadRight(43, ' ')); sw.Write(" BAD");
else
sw.Write($"{disk.Name} ");
// If we have a baddump, put the first indicator // If we have a nodump, write out the indicator
if (disk.ItemStatus == ItemStatus.BadDump) if (disk.ItemStatus == ItemStatus.Nodump)
sw.Write(" BAD"); sw.Write(" NO GOOD DUMP KNOWN");
// If we have a nodump, write out the indicator // Otherwise, write out the SHA-1 hash
if (disk.ItemStatus == ItemStatus.Nodump) else if (!string.IsNullOrWhiteSpace(disk.SHA1))
sw.Write(" NO GOOD DUMP KNOWN"); sw.Write($" SHA1({disk.SHA1 ?? string.Empty})");
// Otherwise, write out the SHA-1 hash // If we have a baddump, put the second indicator
else if (!string.IsNullOrWhiteSpace(disk.SHA1)) if (disk.ItemStatus == ItemStatus.BadDump)
sw.Write($" SHA1({disk.SHA1 ?? string.Empty})"); sw.Write(" BAD_DUMP");
// If we have a baddump, put the second indicator sw.Write("\n");
if (disk.ItemStatus == ItemStatus.BadDump) break;
sw.Write(" BAD_DUMP");
sw.Write("\n"); case ItemType.Rom:
break; var rom = datItem as Rom;
case ItemType.Rom: // The name is padded out to a particular length
var rom = datItem as Rom; if (rom.Name.Length < 43)
sw.Write(rom.Name.PadRight(43 - rom.Size?.ToString().Length ?? 0, ' '));
else
sw.Write($"{rom.Name} ");
// The name is padded out to a particular length // If we don't have a nodump, write out the size
if (rom.Name.Length < 43) if (rom.ItemStatus != ItemStatus.Nodump)
sw.Write(rom.Name.PadRight(43 - rom.Size?.ToString().Length ?? 0, ' ')); sw.Write(rom.Size?.ToString() ?? string.Empty);
else
sw.Write($"{rom.Name} ");
// If we don't have a nodump, write out the size // If we have a baddump, put the first indicator
if (rom.ItemStatus != ItemStatus.Nodump) if (rom.ItemStatus == ItemStatus.BadDump)
sw.Write(rom.Size?.ToString() ?? string.Empty); sw.Write(" BAD");
// If we have a baddump, put the first indicator // If we have a nodump, write out the indicator
if (rom.ItemStatus == ItemStatus.BadDump) if (rom.ItemStatus == ItemStatus.Nodump)
sw.Write(" BAD"); {
sw.Write(" NO GOOD DUMP KNOWN");
}
// Otherwise, write out the CRC and SHA-1 hashes
else
{
if (!string.IsNullOrWhiteSpace(rom.CRC))
sw.Write($" CRC({rom.CRC ?? string.Empty})");
if (!string.IsNullOrWhiteSpace(rom.SHA1))
sw.Write($" SHA1({rom.SHA1 ?? string.Empty})");
}
// If we have a nodump, write out the indicator // If we have a baddump, put the second indicator
if (rom.ItemStatus == ItemStatus.Nodump) if (rom.ItemStatus == ItemStatus.BadDump)
{ sw.Write(" BAD_DUMP");
sw.Write(" NO GOOD DUMP KNOWN");
}
// Otherwise, write out the CRC and SHA-1 hashes
else
{
if (!string.IsNullOrWhiteSpace(rom.CRC))
sw.Write($" CRC({rom.CRC ?? string.Empty})");
if (!string.IsNullOrWhiteSpace(rom.SHA1))
sw.Write($" SHA1({rom.SHA1 ?? string.Empty})");
}
// If we have a baddump, put the second indicator sw.Write("\n");
if (rom.ItemStatus == ItemStatus.BadDump) break;
sw.Write(" BAD_DUMP");
sw.Write("\n");
break;
}
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
} }
return true; sw.Flush();
} }
} }
} }

View File

@@ -32,9 +32,8 @@ namespace SabreTools.Library.DatFiles
/// <param name="filename">Name of the file to be parsed</param> /// <param name="filename">Name of the file to be parsed</param>
/// <param name="indexId">Index ID for the DAT</param> /// <param name="indexId">Index ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
/// <remarks> /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
/// </remarks> protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
protected override void ParseFile(string filename, int indexId, bool keep)
{ {
// Prepare all internal variables // Prepare all internal variables
XmlReader xtr = filename.GetXmlTextReader(); XmlReader xtr = filename.GetXmlTextReader();
@@ -92,8 +91,7 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}"); Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}");
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
// For XML errors, just skip the affected node // For XML errors, just skip the affected node
xtr?.Read(); xtr?.Read();
@@ -1133,8 +1131,9 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="outfile">Name of the file to write to</param> /// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param> /// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns> /// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false) public override bool WriteToFile(string outfile, bool ignoreblanks = false, bool throwOnError = false)
{ {
try try
{ {
@@ -1203,9 +1202,7 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Error(ex.ToString()); Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
return false; return false;
} }
@@ -1216,30 +1213,16 @@ namespace SabreTools.Library.DatFiles
/// Write out DAT header using the supplied StreamWriter /// Write out DAT header using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteHeader(XmlTextWriter xtw)
private bool WriteHeader(XmlTextWriter xtw)
{ {
try xtw.WriteStartDocument();
{
xtw.WriteStartDocument();
xtw.WriteStartElement("mame"); xtw.WriteStartElement("mame");
xtw.WriteRequiredAttributeString("build", Header.Name); xtw.WriteRequiredAttributeString("build", Header.Name);
xtw.WriteOptionalAttributeString("debug", Header.Debug.FromYesNo()); xtw.WriteOptionalAttributeString("debug", Header.Debug.FromYesNo());
xtw.WriteOptionalAttributeString("mameconfig", Header.MameConfig); xtw.WriteOptionalAttributeString("mameconfig", Header.MameConfig);
xtw.Flush(); xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
@@ -1248,76 +1231,49 @@ namespace SabreTools.Library.DatFiles
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> /// <returns>True if the data was written, false on error</returns>
private bool WriteStartGame(XmlTextWriter xtw, DatItem datItem) private void WriteStartGame(XmlTextWriter xtw, DatItem datItem)
{ {
try // No game should start with a path separator
{ datItem.Machine.Name = datItem.Machine.Name.TrimStart(Path.DirectorySeparatorChar);
// No game should start with a path separator
datItem.Machine.Name = datItem.Machine.Name.TrimStart(Path.DirectorySeparatorChar);
// Build the state // Build the state
xtw.WriteStartElement("machine"); xtw.WriteStartElement("machine");
xtw.WriteRequiredAttributeString("name", datItem.Machine.Name); xtw.WriteRequiredAttributeString("name", datItem.Machine.Name);
xtw.WriteOptionalAttributeString("sourcefile", datItem.Machine.SourceFile); xtw.WriteOptionalAttributeString("sourcefile", datItem.Machine.SourceFile);
if (datItem.Machine.MachineType.HasFlag(MachineType.Bios)) if (datItem.Machine.MachineType.HasFlag(MachineType.Bios))
xtw.WriteAttributeString("isbios", "yes"); xtw.WriteAttributeString("isbios", "yes");
if (datItem.Machine.MachineType.HasFlag(MachineType.Device)) if (datItem.Machine.MachineType.HasFlag(MachineType.Device))
xtw.WriteAttributeString("isdevice", "yes"); xtw.WriteAttributeString("isdevice", "yes");
if (datItem.Machine.MachineType.HasFlag(MachineType.Mechanical)) if (datItem.Machine.MachineType.HasFlag(MachineType.Mechanical))
xtw.WriteAttributeString("ismechanical", "yes"); xtw.WriteAttributeString("ismechanical", "yes");
xtw.WriteOptionalAttributeString("runnable", datItem.Machine.Runnable.FromRunnable()); xtw.WriteOptionalAttributeString("runnable", datItem.Machine.Runnable.FromRunnable());
if (!string.Equals(datItem.Machine.Name, datItem.Machine.CloneOf, StringComparison.OrdinalIgnoreCase)) if (!string.Equals(datItem.Machine.Name, datItem.Machine.CloneOf, StringComparison.OrdinalIgnoreCase))
xtw.WriteOptionalAttributeString("cloneof", datItem.Machine.CloneOf); xtw.WriteOptionalAttributeString("cloneof", datItem.Machine.CloneOf);
if (!string.Equals(datItem.Machine.Name, datItem.Machine.RomOf, StringComparison.OrdinalIgnoreCase)) if (!string.Equals(datItem.Machine.Name, datItem.Machine.RomOf, StringComparison.OrdinalIgnoreCase))
xtw.WriteOptionalAttributeString("romof", datItem.Machine.RomOf); xtw.WriteOptionalAttributeString("romof", datItem.Machine.RomOf);
if (!string.Equals(datItem.Machine.Name, datItem.Machine.SampleOf, StringComparison.OrdinalIgnoreCase)) if (!string.Equals(datItem.Machine.Name, datItem.Machine.SampleOf, StringComparison.OrdinalIgnoreCase))
xtw.WriteOptionalAttributeString("sampleof", datItem.Machine.SampleOf); xtw.WriteOptionalAttributeString("sampleof", datItem.Machine.SampleOf);
xtw.WriteOptionalElementString("description", datItem.Machine.Description); xtw.WriteOptionalElementString("description", datItem.Machine.Description);
xtw.WriteOptionalElementString("year", datItem.Machine.Year); xtw.WriteOptionalElementString("year", datItem.Machine.Year);
xtw.WriteOptionalElementString("manufacturer", datItem.Machine.Manufacturer); xtw.WriteOptionalElementString("manufacturer", datItem.Machine.Manufacturer);
xtw.Flush(); xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
/// Write out Game start using the supplied StreamWriter /// Write out Game start using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteEndGame(XmlTextWriter xtw)
private bool WriteEndGame(XmlTextWriter xtw)
{ {
try // End machine
{ xtw.WriteEndElement();
// End machine
xtw.WriteEndElement();
xtw.Flush(); xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
@@ -1325,409 +1281,381 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> private void WriteDatItem(XmlTextWriter xtw, DatItem datItem)
private bool WriteDatItem(XmlTextWriter xtw, DatItem datItem)
{ {
try // Pre-process the item name
ProcessItemName(datItem, true);
// Build the state
switch (datItem.ItemType)
{ {
// Pre-process the item name case ItemType.Adjuster:
ProcessItemName(datItem, true); var adjuster = datItem as Adjuster;
xtw.WriteStartElement("adjuster");
// Build the state xtw.WriteRequiredAttributeString("name", adjuster.Name);
switch (datItem.ItemType) xtw.WriteOptionalAttributeString("default", adjuster.Default.FromYesNo());
{ if (adjuster.Conditions != null)
case ItemType.Adjuster: {
var adjuster = datItem as Adjuster; foreach (var adjusterCondition in adjuster.Conditions)
xtw.WriteStartElement("adjuster");
xtw.WriteRequiredAttributeString("name", adjuster.Name);
xtw.WriteOptionalAttributeString("default", adjuster.Default.FromYesNo());
if (adjuster.Conditions != null)
{ {
foreach (var adjusterCondition in adjuster.Conditions) xtw.WriteStartElement("condition");
{ xtw.WriteOptionalAttributeString("tag", adjusterCondition.Tag);
xtw.WriteStartElement("condition"); xtw.WriteOptionalAttributeString("mask", adjusterCondition.Mask);
xtw.WriteOptionalAttributeString("tag", adjusterCondition.Tag); xtw.WriteOptionalAttributeString("relation", adjusterCondition.Relation.FromRelation());
xtw.WriteOptionalAttributeString("mask", adjusterCondition.Mask); xtw.WriteOptionalAttributeString("value", adjusterCondition.Value);
xtw.WriteOptionalAttributeString("relation", adjusterCondition.Relation.FromRelation()); xtw.WriteEndElement();
xtw.WriteOptionalAttributeString("value", adjusterCondition.Value);
xtw.WriteEndElement();
}
} }
xtw.WriteEndElement(); }
break; xtw.WriteEndElement();
break;
case ItemType.BiosSet: case ItemType.BiosSet:
var biosSet = datItem as BiosSet; var biosSet = datItem as BiosSet;
xtw.WriteStartElement("biosset"); xtw.WriteStartElement("biosset");
xtw.WriteRequiredAttributeString("name", biosSet.Name); xtw.WriteRequiredAttributeString("name", biosSet.Name);
xtw.WriteOptionalAttributeString("description", biosSet.Description); xtw.WriteOptionalAttributeString("description", biosSet.Description);
xtw.WriteOptionalAttributeString("default", biosSet.Default?.ToString().ToLowerInvariant()); xtw.WriteOptionalAttributeString("default", biosSet.Default?.ToString().ToLowerInvariant());
xtw.WriteEndElement(); xtw.WriteEndElement();
break; break;
case ItemType.Chip: case ItemType.Chip:
var chip = datItem as Chip; var chip = datItem as Chip;
xtw.WriteStartElement("chip"); xtw.WriteStartElement("chip");
xtw.WriteRequiredAttributeString("name", chip.Name); xtw.WriteRequiredAttributeString("name", chip.Name);
xtw.WriteOptionalAttributeString("tag", chip.Tag); xtw.WriteOptionalAttributeString("tag", chip.Tag);
xtw.WriteOptionalAttributeString("type", chip.ChipType.FromChipType()); xtw.WriteOptionalAttributeString("type", chip.ChipType.FromChipType());
xtw.WriteOptionalAttributeString("clock", chip.Clock?.ToString()); xtw.WriteOptionalAttributeString("clock", chip.Clock?.ToString());
xtw.WriteEndElement(); xtw.WriteEndElement();
break; break;
case ItemType.Condition: case ItemType.Condition:
var condition = datItem as Condition; var condition = datItem as Condition;
xtw.WriteStartElement("condition"); xtw.WriteStartElement("condition");
xtw.WriteOptionalAttributeString("tag", condition.Tag); xtw.WriteOptionalAttributeString("tag", condition.Tag);
xtw.WriteOptionalAttributeString("mask", condition.Mask); xtw.WriteOptionalAttributeString("mask", condition.Mask);
xtw.WriteOptionalAttributeString("relation", condition.Relation.FromRelation()); xtw.WriteOptionalAttributeString("relation", condition.Relation.FromRelation());
xtw.WriteOptionalAttributeString("value", condition.Value); xtw.WriteOptionalAttributeString("value", condition.Value);
xtw.WriteEndElement(); xtw.WriteEndElement();
break; break;
case ItemType.Configuration: case ItemType.Configuration:
var configuration = datItem as Configuration; var configuration = datItem as Configuration;
xtw.WriteStartElement("configuration"); xtw.WriteStartElement("configuration");
xtw.WriteOptionalAttributeString("name", configuration.Name); xtw.WriteOptionalAttributeString("name", configuration.Name);
xtw.WriteOptionalAttributeString("tag", configuration.Tag); xtw.WriteOptionalAttributeString("tag", configuration.Tag);
xtw.WriteOptionalAttributeString("mask", configuration.Mask); xtw.WriteOptionalAttributeString("mask", configuration.Mask);
if (configuration.Conditions != null) if (configuration.Conditions != null)
{
foreach (var configurationCondition in configuration.Conditions)
{ {
foreach (var configurationCondition in configuration.Conditions) xtw.WriteStartElement("condition");
{ xtw.WriteOptionalAttributeString("tag", configurationCondition.Tag);
xtw.WriteStartElement("condition"); xtw.WriteOptionalAttributeString("mask", configurationCondition.Mask);
xtw.WriteOptionalAttributeString("tag", configurationCondition.Tag); xtw.WriteOptionalAttributeString("relation", configurationCondition.Relation.FromRelation());
xtw.WriteOptionalAttributeString("mask", configurationCondition.Mask); xtw.WriteOptionalAttributeString("value", configurationCondition.Value);
xtw.WriteOptionalAttributeString("relation", configurationCondition.Relation.FromRelation()); xtw.WriteEndElement();
xtw.WriteOptionalAttributeString("value", configurationCondition.Value);
xtw.WriteEndElement();
}
} }
if (configuration.Locations != null) }
if (configuration.Locations != null)
{
foreach (var location in configuration.Locations)
{ {
foreach (var location in configuration.Locations) xtw.WriteStartElement("conflocation");
{ xtw.WriteOptionalAttributeString("name", location.Name);
xtw.WriteStartElement("conflocation"); xtw.WriteOptionalAttributeString("number", location.Number?.ToString());
xtw.WriteOptionalAttributeString("name", location.Name); xtw.WriteOptionalAttributeString("inverted", location.Inverted.FromYesNo());
xtw.WriteOptionalAttributeString("number", location.Number?.ToString()); xtw.WriteEndElement();
xtw.WriteOptionalAttributeString("inverted", location.Inverted.FromYesNo());
xtw.WriteEndElement();
}
} }
if (configuration.Settings != null) }
if (configuration.Settings != null)
{
foreach (var setting in configuration.Settings)
{ {
foreach (var setting in configuration.Settings) xtw.WriteStartElement("confsetting");
{ xtw.WriteOptionalAttributeString("name", setting.Name);
xtw.WriteStartElement("confsetting"); xtw.WriteOptionalAttributeString("value", setting.Value);
xtw.WriteOptionalAttributeString("name", setting.Name); xtw.WriteOptionalAttributeString("default", setting.Default.FromYesNo());
xtw.WriteOptionalAttributeString("value", setting.Value); xtw.WriteEndElement();
xtw.WriteOptionalAttributeString("default", setting.Default.FromYesNo());
xtw.WriteEndElement();
}
} }
xtw.WriteEndElement(); }
break; xtw.WriteEndElement();
break;
case ItemType.Device: case ItemType.Device:
var device = datItem as Device; var device = datItem as Device;
xtw.WriteStartElement("device"); xtw.WriteStartElement("device");
xtw.WriteOptionalAttributeString("type", device.DeviceType.FromDeviceType()); xtw.WriteOptionalAttributeString("type", device.DeviceType.FromDeviceType());
xtw.WriteOptionalAttributeString("tag", device.Tag); xtw.WriteOptionalAttributeString("tag", device.Tag);
xtw.WriteOptionalAttributeString("fixed_image", device.FixedImage); xtw.WriteOptionalAttributeString("fixed_image", device.FixedImage);
xtw.WriteOptionalAttributeString("mandatory", device.Mandatory?.ToString()); xtw.WriteOptionalAttributeString("mandatory", device.Mandatory?.ToString());
xtw.WriteOptionalAttributeString("interface", device.Interface); xtw.WriteOptionalAttributeString("interface", device.Interface);
if (device.Instances != null) if (device.Instances != null)
{
foreach (var instance in device.Instances)
{ {
foreach (var instance in device.Instances) xtw.WriteStartElement("instance");
{ xtw.WriteOptionalAttributeString("name", instance.Name);
xtw.WriteStartElement("instance"); xtw.WriteOptionalAttributeString("briefname", instance.BriefName);
xtw.WriteOptionalAttributeString("name", instance.Name); xtw.WriteEndElement();
xtw.WriteOptionalAttributeString("briefname", instance.BriefName);
xtw.WriteEndElement();
}
} }
if (device.Extensions != null) }
if (device.Extensions != null)
{
foreach (var extension in device.Extensions)
{ {
foreach (var extension in device.Extensions) xtw.WriteStartElement("extension");
{ xtw.WriteOptionalAttributeString("name", extension.Name);
xtw.WriteStartElement("extension"); xtw.WriteEndElement();
xtw.WriteOptionalAttributeString("name", extension.Name);
xtw.WriteEndElement();
}
} }
xtw.WriteEndElement(); }
break; xtw.WriteEndElement();
break;
case ItemType.DeviceReference: case ItemType.DeviceReference:
var deviceRef = datItem as DeviceReference; var deviceRef = datItem as DeviceReference;
xtw.WriteStartElement("device_ref"); xtw.WriteStartElement("device_ref");
xtw.WriteRequiredAttributeString("name", deviceRef.Name); xtw.WriteRequiredAttributeString("name", deviceRef.Name);
xtw.WriteEndElement(); xtw.WriteEndElement();
break; break;
case ItemType.DipSwitch: case ItemType.DipSwitch:
var dipSwitch = datItem as DipSwitch; var dipSwitch = datItem as DipSwitch;
xtw.WriteStartElement("dipswitch"); xtw.WriteStartElement("dipswitch");
xtw.WriteOptionalAttributeString("name", dipSwitch.Name); xtw.WriteOptionalAttributeString("name", dipSwitch.Name);
xtw.WriteOptionalAttributeString("tag", dipSwitch.Tag); xtw.WriteOptionalAttributeString("tag", dipSwitch.Tag);
xtw.WriteOptionalAttributeString("mask", dipSwitch.Mask); xtw.WriteOptionalAttributeString("mask", dipSwitch.Mask);
if (dipSwitch.Conditions != null) if (dipSwitch.Conditions != null)
{
foreach (var dipSwitchCondition in dipSwitch.Conditions)
{ {
foreach (var dipSwitchCondition in dipSwitch.Conditions) xtw.WriteStartElement("condition");
{ xtw.WriteOptionalAttributeString("tag", dipSwitchCondition.Tag);
xtw.WriteStartElement("condition"); xtw.WriteOptionalAttributeString("mask", dipSwitchCondition.Mask);
xtw.WriteOptionalAttributeString("tag", dipSwitchCondition.Tag); xtw.WriteOptionalAttributeString("relation", dipSwitchCondition.Relation.FromRelation());
xtw.WriteOptionalAttributeString("mask", dipSwitchCondition.Mask); xtw.WriteOptionalAttributeString("value", dipSwitchCondition.Value);
xtw.WriteOptionalAttributeString("relation", dipSwitchCondition.Relation.FromRelation()); xtw.WriteEndElement();
xtw.WriteOptionalAttributeString("value", dipSwitchCondition.Value);
xtw.WriteEndElement();
}
} }
if (dipSwitch.Locations != null) }
if (dipSwitch.Locations != null)
{
foreach (var location in dipSwitch.Locations)
{ {
foreach (var location in dipSwitch.Locations) xtw.WriteStartElement("diplocation");
{ xtw.WriteOptionalAttributeString("name", location.Name);
xtw.WriteStartElement("diplocation"); xtw.WriteOptionalAttributeString("number", location.Number?.ToString());
xtw.WriteOptionalAttributeString("name", location.Name); xtw.WriteOptionalAttributeString("inverted", location.Inverted.FromYesNo());
xtw.WriteOptionalAttributeString("number", location.Number?.ToString()); xtw.WriteEndElement();
xtw.WriteOptionalAttributeString("inverted", location.Inverted.FromYesNo());
xtw.WriteEndElement();
}
} }
if (dipSwitch.Values != null) }
if (dipSwitch.Values != null)
{
foreach (var value in dipSwitch.Values)
{ {
foreach (var value in dipSwitch.Values) xtw.WriteStartElement("dipvalue");
xtw.WriteOptionalAttributeString("name", value.Name);
xtw.WriteOptionalAttributeString("value", value.Value);
xtw.WriteOptionalAttributeString("default", value.Default.FromYesNo());
if (value.Conditions != null)
{ {
xtw.WriteStartElement("dipvalue"); foreach (var dipValueCondition in value.Conditions)
xtw.WriteOptionalAttributeString("name", value.Name);
xtw.WriteOptionalAttributeString("value", value.Value);
xtw.WriteOptionalAttributeString("default", value.Default.FromYesNo());
if (value.Conditions != null)
{ {
foreach (var dipValueCondition in value.Conditions) xtw.WriteStartElement("condition");
{ xtw.WriteOptionalAttributeString("tag", dipValueCondition.Tag);
xtw.WriteStartElement("condition"); xtw.WriteOptionalAttributeString("mask", dipValueCondition.Mask);
xtw.WriteOptionalAttributeString("tag", dipValueCondition.Tag); xtw.WriteOptionalAttributeString("relation", dipValueCondition.Relation.FromRelation());
xtw.WriteOptionalAttributeString("mask", dipValueCondition.Mask); xtw.WriteOptionalAttributeString("value", dipValueCondition.Value);
xtw.WriteOptionalAttributeString("relation", dipValueCondition.Relation.FromRelation()); xtw.WriteEndElement();
xtw.WriteOptionalAttributeString("value", dipValueCondition.Value);
xtw.WriteEndElement();
}
} }
xtw.WriteEndElement();
} }
xtw.WriteEndElement();
} }
xtw.WriteEndElement(); }
break; xtw.WriteEndElement();
break;
case ItemType.Disk: case ItemType.Disk:
var disk = datItem as Disk; var disk = datItem as Disk;
xtw.WriteStartElement("disk"); xtw.WriteStartElement("disk");
xtw.WriteRequiredAttributeString("name", disk.Name); xtw.WriteRequiredAttributeString("name", disk.Name);
xtw.WriteOptionalAttributeString("sha1", disk.SHA1?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("sha1", disk.SHA1?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("merge", disk.MergeTag); xtw.WriteOptionalAttributeString("merge", disk.MergeTag);
xtw.WriteOptionalAttributeString("region", disk.Region); xtw.WriteOptionalAttributeString("region", disk.Region);
xtw.WriteOptionalAttributeString("index", disk.Index); xtw.WriteOptionalAttributeString("index", disk.Index);
xtw.WriteOptionalAttributeString("writable", disk.Writable.FromYesNo()); xtw.WriteOptionalAttributeString("writable", disk.Writable.FromYesNo());
xtw.WriteOptionalAttributeString("status", disk.ItemStatus.FromItemStatus(false)); xtw.WriteOptionalAttributeString("status", disk.ItemStatus.FromItemStatus(false));
xtw.WriteOptionalAttributeString("optional", disk.Optional.FromYesNo()); xtw.WriteOptionalAttributeString("optional", disk.Optional.FromYesNo());
xtw.WriteEndElement(); xtw.WriteEndElement();
break; break;
case ItemType.Display: case ItemType.Display:
var display = datItem as Display; var display = datItem as Display;
xtw.WriteStartElement("display"); xtw.WriteStartElement("display");
xtw.WriteOptionalAttributeString("tag", display.Tag); xtw.WriteOptionalAttributeString("tag", display.Tag);
xtw.WriteOptionalAttributeString("type", display.DisplayType.FromDisplayType()); xtw.WriteOptionalAttributeString("type", display.DisplayType.FromDisplayType());
xtw.WriteOptionalAttributeString("rotate", display.Rotate?.ToString()); xtw.WriteOptionalAttributeString("rotate", display.Rotate?.ToString());
xtw.WriteOptionalAttributeString("flipx", display.FlipX.FromYesNo()); xtw.WriteOptionalAttributeString("flipx", display.FlipX.FromYesNo());
xtw.WriteOptionalAttributeString("width", display.Width?.ToString()); xtw.WriteOptionalAttributeString("width", display.Width?.ToString());
xtw.WriteOptionalAttributeString("height", display.Height?.ToString()); xtw.WriteOptionalAttributeString("height", display.Height?.ToString());
xtw.WriteOptionalAttributeString("refresh", display.Refresh?.ToString("N6")); xtw.WriteOptionalAttributeString("refresh", display.Refresh?.ToString("N6"));
xtw.WriteOptionalAttributeString("pixclock", display.PixClock?.ToString()); xtw.WriteOptionalAttributeString("pixclock", display.PixClock?.ToString());
xtw.WriteOptionalAttributeString("htotal", display.HTotal?.ToString()); xtw.WriteOptionalAttributeString("htotal", display.HTotal?.ToString());
xtw.WriteOptionalAttributeString("hbend", display.HBEnd?.ToString()); xtw.WriteOptionalAttributeString("hbend", display.HBEnd?.ToString());
xtw.WriteOptionalAttributeString("hstart", display.HBStart?.ToString()); xtw.WriteOptionalAttributeString("hstart", display.HBStart?.ToString());
xtw.WriteOptionalAttributeString("vtotal", display.VTotal?.ToString()); xtw.WriteOptionalAttributeString("vtotal", display.VTotal?.ToString());
xtw.WriteOptionalAttributeString("vbend", display.VBEnd?.ToString()); xtw.WriteOptionalAttributeString("vbend", display.VBEnd?.ToString());
xtw.WriteOptionalAttributeString("vbstart", display.VBStart?.ToString()); xtw.WriteOptionalAttributeString("vbstart", display.VBStart?.ToString());
xtw.WriteEndElement(); xtw.WriteEndElement();
break; break;
case ItemType.Driver: case ItemType.Driver:
var driver = datItem as Driver; var driver = datItem as Driver;
xtw.WriteStartElement("driver"); xtw.WriteStartElement("driver");
xtw.WriteOptionalAttributeString("status", driver.Status.FromSupportStatus()); xtw.WriteOptionalAttributeString("status", driver.Status.FromSupportStatus());
xtw.WriteOptionalAttributeString("emulation", driver.Emulation.FromSupportStatus()); xtw.WriteOptionalAttributeString("emulation", driver.Emulation.FromSupportStatus());
xtw.WriteOptionalAttributeString("cocktail", driver.Cocktail.FromSupportStatus()); xtw.WriteOptionalAttributeString("cocktail", driver.Cocktail.FromSupportStatus());
xtw.WriteOptionalAttributeString("savestate", driver.SaveState.FromSupported(true)); xtw.WriteOptionalAttributeString("savestate", driver.SaveState.FromSupported(true));
xtw.WriteEndElement(); xtw.WriteEndElement();
break; break;
case ItemType.Feature: case ItemType.Feature:
var feature = datItem as Feature; var feature = datItem as Feature;
xtw.WriteStartElement("feature"); xtw.WriteStartElement("feature");
xtw.WriteOptionalAttributeString("type", feature.Type.FromFeatureType()); xtw.WriteOptionalAttributeString("type", feature.Type.FromFeatureType());
xtw.WriteOptionalAttributeString("status", feature.Status.FromFeatureStatus()); xtw.WriteOptionalAttributeString("status", feature.Status.FromFeatureStatus());
xtw.WriteOptionalAttributeString("overall", feature.Overall.FromFeatureStatus()); xtw.WriteOptionalAttributeString("overall", feature.Overall.FromFeatureStatus());
xtw.WriteEndElement(); xtw.WriteEndElement();
break; break;
case ItemType.Input: case ItemType.Input:
var input = datItem as Input; var input = datItem as Input;
xtw.WriteStartElement("input"); xtw.WriteStartElement("input");
xtw.WriteOptionalAttributeString("service", input.Service.FromYesNo()); xtw.WriteOptionalAttributeString("service", input.Service.FromYesNo());
xtw.WriteOptionalAttributeString("tilt", input.Tilt.FromYesNo()); xtw.WriteOptionalAttributeString("tilt", input.Tilt.FromYesNo());
xtw.WriteOptionalAttributeString("players", input.Players?.ToString()); xtw.WriteOptionalAttributeString("players", input.Players?.ToString());
xtw.WriteOptionalAttributeString("coins", input.Coins?.ToString()); xtw.WriteOptionalAttributeString("coins", input.Coins?.ToString());
if (input.Controls != null) if (input.Controls != null)
{
foreach (var control in input.Controls)
{ {
foreach (var control in input.Controls) xtw.WriteStartElement("control");
{ xtw.WriteOptionalAttributeString("type", control.ControlType.FromControlType());
xtw.WriteStartElement("control"); xtw.WriteOptionalAttributeString("player", control.Player?.ToString());
xtw.WriteOptionalAttributeString("type", control.ControlType.FromControlType()); xtw.WriteOptionalAttributeString("buttons", control.Buttons?.ToString());
xtw.WriteOptionalAttributeString("player", control.Player?.ToString()); xtw.WriteOptionalAttributeString("reqbuttons", control.RequiredButtons?.ToString());
xtw.WriteOptionalAttributeString("buttons", control.Buttons?.ToString()); xtw.WriteOptionalAttributeString("minimum", control.Minimum?.ToString());
xtw.WriteOptionalAttributeString("reqbuttons", control.RequiredButtons?.ToString()); xtw.WriteOptionalAttributeString("maximum", control.Maximum?.ToString());
xtw.WriteOptionalAttributeString("minimum", control.Minimum?.ToString()); xtw.WriteOptionalAttributeString("sensitivity", control.Sensitivity?.ToString());
xtw.WriteOptionalAttributeString("maximum", control.Maximum?.ToString()); xtw.WriteOptionalAttributeString("keydelta", control.KeyDelta?.ToString());
xtw.WriteOptionalAttributeString("sensitivity", control.Sensitivity?.ToString()); xtw.WriteOptionalAttributeString("reverse", control.Reverse.FromYesNo());
xtw.WriteOptionalAttributeString("keydelta", control.KeyDelta?.ToString()); xtw.WriteOptionalAttributeString("ways", control.Ways);
xtw.WriteOptionalAttributeString("reverse", control.Reverse.FromYesNo()); xtw.WriteOptionalAttributeString("ways2", control.Ways2);
xtw.WriteOptionalAttributeString("ways", control.Ways); xtw.WriteOptionalAttributeString("ways3", control.Ways3);
xtw.WriteOptionalAttributeString("ways2", control.Ways2); xtw.WriteEndElement();
xtw.WriteOptionalAttributeString("ways3", control.Ways3);
xtw.WriteEndElement();
}
} }
xtw.WriteEndElement(); }
break; xtw.WriteEndElement();
break;
case ItemType.Port: case ItemType.Port:
var port = datItem as Port; var port = datItem as Port;
xtw.WriteStartElement("port"); xtw.WriteStartElement("port");
xtw.WriteOptionalAttributeString("tag", port.Tag); xtw.WriteOptionalAttributeString("tag", port.Tag);
if (port.Analogs != null) if (port.Analogs != null)
{
foreach (var analog in port.Analogs)
{ {
foreach (var analog in port.Analogs) xtw.WriteStartElement("analog");
{ xtw.WriteOptionalAttributeString("mask", analog.Mask);
xtw.WriteStartElement("analog"); xtw.WriteEndElement();
xtw.WriteOptionalAttributeString("mask", analog.Mask);
xtw.WriteEndElement();
}
} }
xtw.WriteEndElement(); }
break; xtw.WriteEndElement();
break;
case ItemType.RamOption: case ItemType.RamOption:
var ramOption = datItem as RamOption; var ramOption = datItem as RamOption;
xtw.WriteStartElement("ramoption"); xtw.WriteStartElement("ramoption");
xtw.WriteRequiredAttributeString("name", ramOption.Name); xtw.WriteRequiredAttributeString("name", ramOption.Name);
xtw.WriteOptionalAttributeString("default", ramOption.Default.FromYesNo()); xtw.WriteOptionalAttributeString("default", ramOption.Default.FromYesNo());
xtw.WriteRaw(ramOption.Content ?? string.Empty); xtw.WriteRaw(ramOption.Content ?? string.Empty);
xtw.WriteFullEndElement(); xtw.WriteFullEndElement();
break; break;
case ItemType.Rom: case ItemType.Rom:
var rom = datItem as Rom; var rom = datItem as Rom;
xtw.WriteStartElement("rom"); xtw.WriteStartElement("rom");
xtw.WriteRequiredAttributeString("name", rom.Name); xtw.WriteRequiredAttributeString("name", rom.Name);
xtw.WriteOptionalAttributeString("size", rom.Size?.ToString()); xtw.WriteOptionalAttributeString("size", rom.Size?.ToString());
xtw.WriteOptionalAttributeString("crc", rom.CRC?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("crc", rom.CRC?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha1", rom.SHA1?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("sha1", rom.SHA1?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("bios", rom.Bios); xtw.WriteOptionalAttributeString("bios", rom.Bios);
xtw.WriteOptionalAttributeString("merge", rom.MergeTag); xtw.WriteOptionalAttributeString("merge", rom.MergeTag);
xtw.WriteOptionalAttributeString("region", rom.Region); xtw.WriteOptionalAttributeString("region", rom.Region);
xtw.WriteOptionalAttributeString("offset", rom.Offset); xtw.WriteOptionalAttributeString("offset", rom.Offset);
xtw.WriteOptionalAttributeString("status", rom.ItemStatus.FromItemStatus(false)); xtw.WriteOptionalAttributeString("status", rom.ItemStatus.FromItemStatus(false));
xtw.WriteOptionalAttributeString("optional", rom.Optional.FromYesNo()); xtw.WriteOptionalAttributeString("optional", rom.Optional.FromYesNo());
xtw.WriteEndElement(); xtw.WriteEndElement();
break; break;
case ItemType.Sample: case ItemType.Sample:
var sample = datItem as Sample; var sample = datItem as Sample;
xtw.WriteStartElement("sample"); xtw.WriteStartElement("sample");
xtw.WriteRequiredAttributeString("name", sample.Name); xtw.WriteRequiredAttributeString("name", sample.Name);
xtw.WriteEndElement(); xtw.WriteEndElement();
break; break;
case ItemType.Slot: case ItemType.Slot:
var slot = datItem as Slot; var slot = datItem as Slot;
xtw.WriteStartElement("slot"); xtw.WriteStartElement("slot");
xtw.WriteOptionalAttributeString("name", slot.Name); xtw.WriteOptionalAttributeString("name", slot.Name);
if (slot.SlotOptions != null) if (slot.SlotOptions != null)
{
foreach (var slotOption in slot.SlotOptions)
{ {
foreach (var slotOption in slot.SlotOptions) xtw.WriteStartElement("slotoption");
{ xtw.WriteOptionalAttributeString("name", slotOption.Name);
xtw.WriteStartElement("slotoption"); xtw.WriteOptionalAttributeString("devname", slotOption.DeviceName);
xtw.WriteOptionalAttributeString("name", slotOption.Name); xtw.WriteOptionalAttributeString("default", slotOption.Default.FromYesNo());
xtw.WriteOptionalAttributeString("devname", slotOption.DeviceName); xtw.WriteEndElement();
xtw.WriteOptionalAttributeString("default", slotOption.Default.FromYesNo());
xtw.WriteEndElement();
}
} }
xtw.WriteEndElement(); }
break; xtw.WriteEndElement();
break;
case ItemType.SoftwareList: case ItemType.SoftwareList:
var softwareList = datItem as DatItems.SoftwareList; var softwareList = datItem as DatItems.SoftwareList;
xtw.WriteStartElement("softwarelist"); xtw.WriteStartElement("softwarelist");
xtw.WriteRequiredAttributeString("name", softwareList.Name); xtw.WriteRequiredAttributeString("name", softwareList.Name);
xtw.WriteOptionalAttributeString("status", softwareList.Status.FromSoftwareListStatus()); xtw.WriteOptionalAttributeString("status", softwareList.Status.FromSoftwareListStatus());
xtw.WriteOptionalAttributeString("filter", softwareList.Filter); xtw.WriteOptionalAttributeString("filter", softwareList.Filter);
xtw.WriteEndElement(); xtw.WriteEndElement();
break; break;
case ItemType.Sound: case ItemType.Sound:
var sound = datItem as Sound; var sound = datItem as Sound;
xtw.WriteStartElement("sound"); xtw.WriteStartElement("sound");
xtw.WriteOptionalAttributeString("channels", sound.Channels?.ToString()); xtw.WriteOptionalAttributeString("channels", sound.Channels?.ToString());
xtw.WriteEndElement(); xtw.WriteEndElement();
break; break;
}
xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
} }
return true; xtw.Flush();
} }
/// <summary> /// <summary>
/// Write out DAT footer using the supplied StreamWriter /// Write out DAT footer using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteFooter(XmlTextWriter xtw)
private bool WriteFooter(XmlTextWriter xtw)
{ {
try // End machine
{ xtw.WriteEndElement();
// End machine
xtw.WriteEndElement();
// End mame // End mame
xtw.WriteEndElement(); xtw.WriteEndElement();
xtw.Flush(); xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
} }
} }

View File

@@ -38,7 +38,8 @@ namespace SabreTools.Library.DatFiles
/// <param name="filename">Name of the file to be parsed</param> /// <param name="filename">Name of the file to be parsed</param>
/// <param name="indexId">Index ID for the DAT</param> /// <param name="indexId">Index ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
protected override void ParseFile(string filename, int indexId, bool keep) /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
{ {
// Prepare all internal variables // Prepare all internal variables
XmlReader xtr = filename.GetXmlTextReader(); XmlReader xtr = filename.GetXmlTextReader();
@@ -107,8 +108,7 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}"); Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}");
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
// For XML errors, just skip the affected node // For XML errors, just skip the affected node
xtr?.Read(); xtr?.Read();
@@ -663,8 +663,9 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="outfile">Name of the file to write to</param> /// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param> /// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns> /// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false) public override bool WriteToFile(string outfile, bool ignoreblanks = false, bool throwOnError = false)
{ {
try try
{ {
@@ -733,9 +734,7 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Error(ex.ToString()); Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
return false; return false;
} }
@@ -746,83 +745,69 @@ namespace SabreTools.Library.DatFiles
/// Write out DAT header using the supplied StreamWriter /// Write out DAT header using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteHeader(XmlTextWriter xtw)
private bool WriteHeader(XmlTextWriter xtw)
{ {
try xtw.WriteStartDocument();
xtw.WriteDocType("datafile", "-//Logiqx//DTD ROM Management Datafile//EN", "http://www.logiqx.com/Dats/datafile.dtd", null);
xtw.WriteStartElement("datafile");
xtw.WriteOptionalAttributeString("build", Header.Build);
xtw.WriteOptionalAttributeString("debug", Header.Debug.FromYesNo());
xtw.WriteStartElement("header");
xtw.WriteRequiredElementString("name", Header.Name);
xtw.WriteRequiredElementString("description", Header.Description);
xtw.WriteOptionalElementString("rootdir", Header.RootDir);
xtw.WriteOptionalElementString("category", Header.Category);
xtw.WriteRequiredElementString("version", Header.Version);
xtw.WriteOptionalElementString("date", Header.Date);
xtw.WriteRequiredElementString("author", Header.Author);
xtw.WriteOptionalElementString("email", Header.Email);
xtw.WriteOptionalElementString("homepage", Header.Homepage);
xtw.WriteOptionalElementString("url", Header.Url);
xtw.WriteOptionalElementString("comment", Header.Comment);
xtw.WriteOptionalElementString("type", Header.Type);
if (Header.ForcePacking != PackingFlag.None
|| Header.ForceMerging != MergingFlag.None
|| Header.ForceNodump != NodumpFlag.None
|| !string.IsNullOrWhiteSpace(Header.HeaderSkipper))
{ {
xtw.WriteStartDocument(); xtw.WriteStartElement("clrmamepro");
xtw.WriteDocType("datafile", "-//Logiqx//DTD ROM Management Datafile//EN", "http://www.logiqx.com/Dats/datafile.dtd", null);
xtw.WriteStartElement("datafile"); xtw.WriteOptionalAttributeString("forcepacking", Header.ForcePacking.FromPackingFlag(false));
xtw.WriteOptionalAttributeString("build", Header.Build); xtw.WriteOptionalAttributeString("forcemerging", Header.ForceMerging.FromMergingFlag(false));
xtw.WriteOptionalAttributeString("debug", Header.Debug.FromYesNo()); xtw.WriteOptionalAttributeString("forcenodump", Header.ForceNodump.FromNodumpFlag());
xtw.WriteOptionalAttributeString("header", Header.HeaderSkipper);
xtw.WriteStartElement("header"); // End clrmamepro
xtw.WriteRequiredElementString("name", Header.Name);
xtw.WriteRequiredElementString("description", Header.Description);
xtw.WriteOptionalElementString("rootdir", Header.RootDir);
xtw.WriteOptionalElementString("category", Header.Category);
xtw.WriteRequiredElementString("version", Header.Version);
xtw.WriteOptionalElementString("date", Header.Date);
xtw.WriteRequiredElementString("author", Header.Author);
xtw.WriteOptionalElementString("email", Header.Email);
xtw.WriteOptionalElementString("homepage", Header.Homepage);
xtw.WriteOptionalElementString("url", Header.Url);
xtw.WriteOptionalElementString("comment", Header.Comment);
xtw.WriteOptionalElementString("type", Header.Type);
if (Header.ForcePacking != PackingFlag.None
|| Header.ForceMerging != MergingFlag.None
|| Header.ForceNodump != NodumpFlag.None
|| !string.IsNullOrWhiteSpace(Header.HeaderSkipper))
{
xtw.WriteStartElement("clrmamepro");
xtw.WriteOptionalAttributeString("forcepacking", Header.ForcePacking.FromPackingFlag(false));
xtw.WriteOptionalAttributeString("forcemerging", Header.ForceMerging.FromMergingFlag(false));
xtw.WriteOptionalAttributeString("forcenodump", Header.ForceNodump.FromNodumpFlag());
xtw.WriteOptionalAttributeString("header", Header.HeaderSkipper);
// End clrmamepro
xtw.WriteEndElement();
}
if (Header.System != null
|| Header.RomMode != MergingFlag.None || Header.LockRomMode != null
|| Header.BiosMode != MergingFlag.None || Header.LockBiosMode != null
|| Header.SampleMode != MergingFlag.None || Header.LockSampleMode != null)
{
xtw.WriteStartElement("romcenter");
xtw.WriteOptionalAttributeString("plugin", Header.System);
xtw.WriteOptionalAttributeString("rommode", Header.RomMode.FromMergingFlag(true));
xtw.WriteOptionalAttributeString("biosmode", Header.BiosMode.FromMergingFlag(true));
xtw.WriteOptionalAttributeString("samplemode", Header.SampleMode.FromMergingFlag(true));
xtw.WriteOptionalAttributeString("lockrommode", Header.LockRomMode.FromYesNo());
xtw.WriteOptionalAttributeString("lockbiosmode", Header.LockBiosMode.FromYesNo());
xtw.WriteOptionalAttributeString("locksamplemode", Header.LockSampleMode.FromYesNo());
// End romcenter
xtw.WriteEndElement();
}
// End header
xtw.WriteEndElement(); xtw.WriteEndElement();
xtw.Flush();
} }
catch (Exception ex)
if (Header.System != null
|| Header.RomMode != MergingFlag.None || Header.LockRomMode != null
|| Header.BiosMode != MergingFlag.None || Header.LockBiosMode != null
|| Header.SampleMode != MergingFlag.None || Header.LockSampleMode != null)
{ {
Globals.Logger.Error(ex.ToString()); xtw.WriteStartElement("romcenter");
if (Globals.ThrowOnError)
throw ex;
return false; xtw.WriteOptionalAttributeString("plugin", Header.System);
xtw.WriteOptionalAttributeString("rommode", Header.RomMode.FromMergingFlag(true));
xtw.WriteOptionalAttributeString("biosmode", Header.BiosMode.FromMergingFlag(true));
xtw.WriteOptionalAttributeString("samplemode", Header.SampleMode.FromMergingFlag(true));
xtw.WriteOptionalAttributeString("lockrommode", Header.LockRomMode.FromYesNo());
xtw.WriteOptionalAttributeString("lockbiosmode", Header.LockBiosMode.FromYesNo());
xtw.WriteOptionalAttributeString("locksamplemode", Header.LockSampleMode.FromYesNo());
// End romcenter
xtw.WriteEndElement();
} }
return true; // End header
xtw.WriteEndElement();
xtw.Flush();
} }
/// <summary> /// <summary>
@@ -830,111 +815,83 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> private void WriteStartGame(XmlTextWriter xtw, DatItem datItem)
private bool WriteStartGame(XmlTextWriter xtw, DatItem datItem)
{ {
try // No game should start with a path separator
datItem.Machine.Name = datItem.Machine.Name.TrimStart(Path.DirectorySeparatorChar);
// Build the state
xtw.WriteStartElement(_deprecated ? "game" : "machine");
xtw.WriteRequiredAttributeString("name", datItem.Machine.Name);
if (datItem.Machine.MachineType.HasFlag(MachineType.Bios))
xtw.WriteAttributeString("isbios", "yes");
if (datItem.Machine.MachineType.HasFlag(MachineType.Device))
xtw.WriteAttributeString("isdevice", "yes");
if (datItem.Machine.MachineType.HasFlag(MachineType.Mechanical))
xtw.WriteAttributeString("ismechanical", "yes");
xtw.WriteOptionalAttributeString("runnable", datItem.Machine.Runnable.FromRunnable());
if (!string.Equals(datItem.Machine.Name, datItem.Machine.CloneOf, StringComparison.OrdinalIgnoreCase))
xtw.WriteOptionalAttributeString("cloneof", datItem.Machine.CloneOf);
if (!string.Equals(datItem.Machine.Name, datItem.Machine.RomOf, StringComparison.OrdinalIgnoreCase))
xtw.WriteOptionalAttributeString("romof", datItem.Machine.RomOf);
if (!string.Equals(datItem.Machine.Name, datItem.Machine.SampleOf, StringComparison.OrdinalIgnoreCase))
xtw.WriteOptionalAttributeString("sampleof", datItem.Machine.SampleOf);
xtw.WriteOptionalElementString("comment", datItem.Machine.Comment);
xtw.WriteOptionalElementString("description", datItem.Machine.Description);
xtw.WriteOptionalElementString("year", datItem.Machine.Year);
xtw.WriteOptionalElementString("publisher", datItem.Machine.Publisher);
xtw.WriteOptionalElementString("manufacturer", datItem.Machine.Manufacturer);
xtw.WriteOptionalElementString("category", datItem.Machine.Category);
if (datItem.Machine.TitleID != null
|| datItem.Machine.Developer != null
|| datItem.Machine.Genre != null
|| datItem.Machine.Subgenre != null
|| datItem.Machine.Ratings != null
|| datItem.Machine.Score != null
|| datItem.Machine.Enabled != null
|| datItem.Machine.Crc != null
|| datItem.Machine.RelatedTo != null)
{ {
// No game should start with a path separator xtw.WriteStartElement("trurip");
datItem.Machine.Name = datItem.Machine.Name.TrimStart(Path.DirectorySeparatorChar);
// Build the state xtw.WriteOptionalElementString("titleid", datItem.Machine.TitleID);
xtw.WriteStartElement(_deprecated ? "game" : "machine");
xtw.WriteRequiredAttributeString("name", datItem.Machine.Name);
if (datItem.Machine.MachineType.HasFlag(MachineType.Bios))
xtw.WriteAttributeString("isbios", "yes");
if (datItem.Machine.MachineType.HasFlag(MachineType.Device))
xtw.WriteAttributeString("isdevice", "yes");
if (datItem.Machine.MachineType.HasFlag(MachineType.Mechanical))
xtw.WriteAttributeString("ismechanical", "yes");
xtw.WriteOptionalAttributeString("runnable", datItem.Machine.Runnable.FromRunnable());
if (!string.Equals(datItem.Machine.Name, datItem.Machine.CloneOf, StringComparison.OrdinalIgnoreCase))
xtw.WriteOptionalAttributeString("cloneof", datItem.Machine.CloneOf);
if (!string.Equals(datItem.Machine.Name, datItem.Machine.RomOf, StringComparison.OrdinalIgnoreCase))
xtw.WriteOptionalAttributeString("romof", datItem.Machine.RomOf);
if (!string.Equals(datItem.Machine.Name, datItem.Machine.SampleOf, StringComparison.OrdinalIgnoreCase))
xtw.WriteOptionalAttributeString("sampleof", datItem.Machine.SampleOf);
xtw.WriteOptionalElementString("comment", datItem.Machine.Comment);
xtw.WriteOptionalElementString("description", datItem.Machine.Description);
xtw.WriteOptionalElementString("year", datItem.Machine.Year);
xtw.WriteOptionalElementString("publisher", datItem.Machine.Publisher); xtw.WriteOptionalElementString("publisher", datItem.Machine.Publisher);
xtw.WriteOptionalElementString("manufacturer", datItem.Machine.Manufacturer); xtw.WriteOptionalElementString("developer", datItem.Machine.Developer);
xtw.WriteOptionalElementString("category", datItem.Machine.Category); xtw.WriteOptionalElementString("year", datItem.Machine.Year);
xtw.WriteOptionalElementString("genre", datItem.Machine.Genre);
xtw.WriteOptionalElementString("subgenre", datItem.Machine.Subgenre);
xtw.WriteOptionalElementString("ratings", datItem.Machine.Ratings);
xtw.WriteOptionalElementString("score", datItem.Machine.Score);
xtw.WriteOptionalElementString("players", datItem.Machine.Players);
xtw.WriteOptionalElementString("enabled", datItem.Machine.Enabled);
xtw.WriteOptionalElementString("titleid", datItem.Machine.TitleID);
xtw.WriteOptionalElementString("crc", datItem.Machine.Crc.FromYesNo());
xtw.WriteOptionalElementString("source", datItem.Machine.SourceFile);
xtw.WriteOptionalElementString("cloneof", datItem.Machine.CloneOf);
xtw.WriteOptionalElementString("relatedto", datItem.Machine.RelatedTo);
if (datItem.Machine.TitleID != null // End trurip
|| datItem.Machine.Developer != null xtw.WriteEndElement();
|| datItem.Machine.Genre != null
|| datItem.Machine.Subgenre != null
|| datItem.Machine.Ratings != null
|| datItem.Machine.Score != null
|| datItem.Machine.Enabled != null
|| datItem.Machine.Crc != null
|| datItem.Machine.RelatedTo != null)
{
xtw.WriteStartElement("trurip");
xtw.WriteOptionalElementString("titleid", datItem.Machine.TitleID);
xtw.WriteOptionalElementString("publisher", datItem.Machine.Publisher);
xtw.WriteOptionalElementString("developer", datItem.Machine.Developer);
xtw.WriteOptionalElementString("year", datItem.Machine.Year);
xtw.WriteOptionalElementString("genre", datItem.Machine.Genre);
xtw.WriteOptionalElementString("subgenre", datItem.Machine.Subgenre);
xtw.WriteOptionalElementString("ratings", datItem.Machine.Ratings);
xtw.WriteOptionalElementString("score", datItem.Machine.Score);
xtw.WriteOptionalElementString("players", datItem.Machine.Players);
xtw.WriteOptionalElementString("enabled", datItem.Machine.Enabled);
xtw.WriteOptionalElementString("titleid", datItem.Machine.TitleID);
xtw.WriteOptionalElementString("crc", datItem.Machine.Crc.FromYesNo());
xtw.WriteOptionalElementString("source", datItem.Machine.SourceFile);
xtw.WriteOptionalElementString("cloneof", datItem.Machine.CloneOf);
xtw.WriteOptionalElementString("relatedto", datItem.Machine.RelatedTo);
// End trurip
xtw.WriteEndElement();
}
xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
} }
return true; xtw.Flush();
} }
/// <summary> /// <summary>
/// Write out Game end using the supplied StreamWriter /// Write out Game end using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteEndGame(XmlTextWriter xtw)
private bool WriteEndGame(XmlTextWriter xtw)
{ {
try // End machine
{ xtw.WriteEndElement();
// End machine
xtw.WriteEndElement();
xtw.Flush(); xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
@@ -942,135 +899,107 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> private void WriteDatItem(XmlTextWriter xtw, DatItem datItem)
private bool WriteDatItem(XmlTextWriter xtw, DatItem datItem)
{ {
try // Pre-process the item name
ProcessItemName(datItem, true);
// Build the state
switch (datItem.ItemType)
{ {
// Pre-process the item name case ItemType.Archive:
ProcessItemName(datItem, true); var archive = datItem as Archive;
xtw.WriteStartElement("archive");
xtw.WriteRequiredAttributeString("name", archive.Name);
xtw.WriteEndElement();
break;
// Build the state case ItemType.BiosSet:
switch (datItem.ItemType) var biosSet = datItem as BiosSet;
{ xtw.WriteStartElement("biosset");
case ItemType.Archive: xtw.WriteRequiredAttributeString("name", biosSet.Name);
var archive = datItem as Archive; xtw.WriteOptionalAttributeString("description", biosSet.Description);
xtw.WriteStartElement("archive"); xtw.WriteOptionalAttributeString("default", biosSet.Default.FromYesNo());
xtw.WriteRequiredAttributeString("name", archive.Name); xtw.WriteEndElement();
xtw.WriteEndElement(); break;
break;
case ItemType.BiosSet: case ItemType.Disk:
var biosSet = datItem as BiosSet; var disk = datItem as Disk;
xtw.WriteStartElement("biosset"); xtw.WriteStartElement("disk");
xtw.WriteRequiredAttributeString("name", biosSet.Name); xtw.WriteRequiredAttributeString("name", disk.Name);
xtw.WriteOptionalAttributeString("description", biosSet.Description); xtw.WriteOptionalAttributeString("md5", disk.MD5?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("default", biosSet.Default.FromYesNo()); xtw.WriteOptionalAttributeString("sha1", disk.SHA1?.ToLowerInvariant());
xtw.WriteEndElement(); xtw.WriteOptionalAttributeString("status", disk.ItemStatus.FromItemStatus(false));
break; xtw.WriteEndElement();
break;
case ItemType.Disk: case ItemType.Media:
var disk = datItem as Disk; var media = datItem as Media;
xtw.WriteStartElement("disk"); xtw.WriteStartElement("media");
xtw.WriteRequiredAttributeString("name", disk.Name); xtw.WriteRequiredAttributeString("name", media.Name);
xtw.WriteOptionalAttributeString("md5", disk.MD5?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("md5", media.MD5?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha1", disk.SHA1?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("sha1", media.SHA1?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("status", disk.ItemStatus.FromItemStatus(false)); xtw.WriteOptionalAttributeString("sha256", media.SHA256?.ToLowerInvariant());
xtw.WriteEndElement(); xtw.WriteOptionalAttributeString("spamsum", media.SpamSum?.ToLowerInvariant());
break; xtw.WriteEndElement();
break;
case ItemType.Media: case ItemType.Release:
var media = datItem as Media; var release = datItem as Release;
xtw.WriteStartElement("media"); xtw.WriteStartElement("release");
xtw.WriteRequiredAttributeString("name", media.Name); xtw.WriteRequiredAttributeString("name", release.Name);
xtw.WriteOptionalAttributeString("md5", media.MD5?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("region", release.Region);
xtw.WriteOptionalAttributeString("sha1", media.SHA1?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("language", release.Language);
xtw.WriteOptionalAttributeString("sha256", media.SHA256?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("date", release.Date);
xtw.WriteOptionalAttributeString("spamsum", media.SpamSum?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("default", release.Default.FromYesNo());
xtw.WriteEndElement(); xtw.WriteEndElement();
break; break;
case ItemType.Release: case ItemType.Rom:
var release = datItem as Release; var rom = datItem as Rom;
xtw.WriteStartElement("release"); xtw.WriteStartElement("rom");
xtw.WriteRequiredAttributeString("name", release.Name); xtw.WriteRequiredAttributeString("name", rom.Name);
xtw.WriteOptionalAttributeString("region", release.Region); xtw.WriteAttributeString("size", rom.Size?.ToString());
xtw.WriteOptionalAttributeString("language", release.Language); xtw.WriteOptionalAttributeString("crc", rom.CRC?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("date", release.Date); xtw.WriteOptionalAttributeString("md5", rom.MD5?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("default", release.Default.FromYesNo());
xtw.WriteEndElement();
break;
case ItemType.Rom:
var rom = datItem as Rom;
xtw.WriteStartElement("rom");
xtw.WriteRequiredAttributeString("name", rom.Name);
xtw.WriteAttributeString("size", rom.Size?.ToString());
xtw.WriteOptionalAttributeString("crc", rom.CRC?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("md5", rom.MD5?.ToLowerInvariant());
#if NET_FRAMEWORK #if NET_FRAMEWORK
xtw.WriteOptionalAttributeString("ripemd160", rom.RIPEMD160?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("ripemd160", rom.RIPEMD160?.ToLowerInvariant());
#endif #endif
xtw.WriteOptionalAttributeString("sha1", rom.SHA1?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("sha1", rom.SHA1?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha256", rom.SHA256?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("sha256", rom.SHA256?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha384", rom.SHA384?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("sha384", rom.SHA384?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha512", rom.SHA512?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("sha512", rom.SHA512?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("spamsum", rom.SpamSum?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("spamsum", rom.SpamSum?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("date", rom.Date); xtw.WriteOptionalAttributeString("date", rom.Date);
xtw.WriteOptionalAttributeString("status", rom.ItemStatus.FromItemStatus(false)); xtw.WriteOptionalAttributeString("status", rom.ItemStatus.FromItemStatus(false));
xtw.WriteOptionalAttributeString("inverted", rom.Inverted.FromYesNo()); xtw.WriteOptionalAttributeString("inverted", rom.Inverted.FromYesNo());
xtw.WriteEndElement(); xtw.WriteEndElement();
break; break;
case ItemType.Sample: case ItemType.Sample:
var sample = datItem as Sample; var sample = datItem as Sample;
xtw.WriteStartElement("sample"); xtw.WriteStartElement("sample");
xtw.WriteRequiredAttributeString("name", sample.Name); xtw.WriteRequiredAttributeString("name", sample.Name);
xtw.WriteEndElement(); xtw.WriteEndElement();
break; break;
}
xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
} }
return true; xtw.Flush();
} }
/// <summary> /// <summary>
/// Write out DAT footer using the supplied StreamWriter /// Write out DAT footer using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteFooter(XmlTextWriter xtw)
private bool WriteFooter(XmlTextWriter xtw)
{ {
try // End machine
{ xtw.WriteEndElement();
// End machine
xtw.WriteEndElement();
// End datafile // End datafile
xtw.WriteEndElement(); xtw.WriteEndElement();
xtw.Flush(); xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
} }
} }

View File

@@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Text; using System.Text;
using SabreTools.Library.Data; using SabreTools.Library.Data;
@@ -30,7 +29,8 @@ namespace SabreTools.Library.DatFiles
/// <param name="filename">Name of the file to be parsed</param> /// <param name="filename">Name of the file to be parsed</param>
/// <param name="indexId">Index ID for the DAT</param> /// <param name="indexId">Index ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
protected override void ParseFile(string filename, int indexId, bool keep) /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
{ {
// There is no consistent way to parse a missfile... // There is no consistent way to parse a missfile...
throw new NotImplementedException(); throw new NotImplementedException();
@@ -41,8 +41,9 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="outfile">Name of the file to write to</param> /// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param> /// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns> /// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false) public override bool WriteToFile(string outfile, bool ignoreblanks = false, bool throwOnError = false)
{ {
try try
{ {
@@ -92,9 +93,7 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Error(ex.ToString()); Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
return false; return false;
} }
@@ -107,37 +106,23 @@ namespace SabreTools.Library.DatFiles
/// <param name="sw">StreamWriter to output to</param> /// <param name="sw">StreamWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <param name="lastgame">The name of the last game to be output</param> /// <param name="lastgame">The name of the last game to be output</param>
/// <returns>True if the data was written, false on error</returns> private void WriteDatItem(StreamWriter sw, DatItem datItem, string lastgame)
private bool WriteDatItem(StreamWriter sw, DatItem datItem, string lastgame)
{ {
try // Process the item name
ProcessItemName(datItem, false, forceRomName: false);
// Romba mode automatically uses item name
if (Header.OutputDepot?.IsActive == true || Header.UseRomName)
{ {
// Process the item name sw.Write($"{datItem.GetName() ?? string.Empty}\n");
ProcessItemName(datItem, false, forceRomName: false);
// Romba mode automatically uses item name
if (Header.OutputDepot?.IsActive == true || Header.UseRomName)
{
sw.Write($"{datItem.GetName() ?? string.Empty}\n");
}
else if (!Header.UseRomName && datItem.Machine.Name != lastgame)
{
sw.Write($"{datItem.Machine.Name}\n");
lastgame = datItem.Machine.Name;
}
sw.Flush();
} }
catch (Exception ex) else if (!Header.UseRomName && datItem.Machine.Name != lastgame)
{ {
Globals.Logger.Error(ex.ToString()); sw.Write($"{datItem.Machine.Name}\n");
if (Globals.ThrowOnError) lastgame = datItem.Machine.Name;
throw ex;
return false;
} }
return true; sw.Flush();
} }
} }
} }

View File

@@ -32,7 +32,8 @@ namespace SabreTools.Library.DatFiles
/// <param name="filename">Name of the file to be parsed</param> /// <param name="filename">Name of the file to be parsed</param>
/// <param name="indexId">Index ID for the DAT</param> /// <param name="indexId">Index ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
protected override void ParseFile(string filename, int indexId, bool keep) /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
{ {
XmlReader xtr = filename.GetXmlTextReader(); XmlReader xtr = filename.GetXmlTextReader();
@@ -78,8 +79,7 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}"); Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}");
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
// For XML errors, just skip the affected node // For XML errors, just skip the affected node
xtr?.Read(); xtr?.Read();
@@ -659,8 +659,9 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="outfile">Name of the file to write to</param> /// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param> /// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns> /// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false) public override bool WriteToFile(string outfile, bool ignoreblanks = false, bool throwOnError = false)
{ {
try try
{ {
@@ -721,9 +722,7 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Error(ex.ToString()); Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
return false; return false;
} }
@@ -734,127 +733,113 @@ namespace SabreTools.Library.DatFiles
/// Write out DAT header using the supplied StreamWriter /// Write out DAT header using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteHeader(XmlTextWriter xtw)
private bool WriteHeader(XmlTextWriter xtw)
{ {
try xtw.WriteStartDocument(false);
xtw.WriteStartElement("dat");
xtw.WriteAttributeString("xsi", "xmlns", "http://www.w3.org/2001/XMLSchema-instance");
xtw.WriteAttributeString("noNamespaceSchemaLocation", "xsi", "datas.xsd");
xtw.WriteStartElement("configuration");
xtw.WriteRequiredElementString("datName", Header.Name);
xtw.WriteElementString("datVersion", Items.TotalCount.ToString());
xtw.WriteRequiredElementString("system", Header.System);
xtw.WriteRequiredElementString("screenshotsWidth", Header.ScreenshotsWidth);
xtw.WriteRequiredElementString("screenshotsHeight", Header.ScreenshotsHeight);
if (Header.Infos != null)
{ {
xtw.WriteStartDocument(false); xtw.WriteStartElement("infos");
xtw.WriteStartElement("dat"); foreach (var info in Header.Infos)
xtw.WriteAttributeString("xsi", "xmlns", "http://www.w3.org/2001/XMLSchema-instance");
xtw.WriteAttributeString("noNamespaceSchemaLocation", "xsi", "datas.xsd");
xtw.WriteStartElement("configuration");
xtw.WriteRequiredElementString("datName", Header.Name);
xtw.WriteElementString("datVersion", Items.TotalCount.ToString());
xtw.WriteRequiredElementString("system", Header.System);
xtw.WriteRequiredElementString("screenshotsWidth", Header.ScreenshotsWidth);
xtw.WriteRequiredElementString("screenshotsHeight", Header.ScreenshotsHeight);
if (Header.Infos != null)
{ {
xtw.WriteStartElement("infos"); xtw.WriteStartElement(info.Name);
xtw.WriteAttributeString("visible", info.Visible?.ToString());
foreach (var info in Header.Infos) xtw.WriteAttributeString("inNamingOption", info.InNamingOption?.ToString());
{ xtw.WriteAttributeString("default", info.Default?.ToString());
xtw.WriteStartElement(info.Name);
xtw.WriteAttributeString("visible", info.Visible?.ToString());
xtw.WriteAttributeString("inNamingOption", info.InNamingOption?.ToString());
xtw.WriteAttributeString("default", info.Default?.ToString());
xtw.WriteEndElement();
}
// End infos
xtw.WriteEndElement();
}
if (Header.CanOpen != null)
{
xtw.WriteStartElement("canOpen");
foreach (string extension in Header.CanOpen)
{
xtw.WriteElementString("extension", extension);
}
// End canOpen
xtw.WriteEndElement(); xtw.WriteEndElement();
} }
xtw.WriteStartElement("newDat"); // End infos
xtw.WriteRequiredElementString("datVersionURL", Header.Url);
xtw.WriteStartElement("datUrl");
xtw.WriteAttributeString("fileName", $"{Header.FileName ?? string.Empty}.zip");
xtw.WriteString(Header.Url);
xtw.WriteEndElement(); xtw.WriteEndElement();
xtw.WriteRequiredElementString("imURL", Header.Url);
// End newDat
xtw.WriteEndElement();
xtw.WriteStartElement("search");
xtw.WriteStartElement("to");
xtw.WriteAttributeString("value", "location");
xtw.WriteAttributeString("default", "true");
xtw.WriteAttributeString("auto", "true");
xtw.WriteEndElement();
xtw.WriteStartElement("to");
xtw.WriteAttributeString("value", "romSize");
xtw.WriteAttributeString("default", "true");
xtw.WriteAttributeString("auto", "false");
xtw.WriteEndElement();
xtw.WriteStartElement("to");
xtw.WriteAttributeString("value", "languages");
xtw.WriteAttributeString("default", "true");
xtw.WriteAttributeString("auto", "true");
xtw.WriteEndElement();
xtw.WriteStartElement("to");
xtw.WriteAttributeString("value", "saveType");
xtw.WriteAttributeString("default", "false");
xtw.WriteAttributeString("auto", "false");
xtw.WriteEndElement();
xtw.WriteStartElement("to");
xtw.WriteAttributeString("value", "publisher");
xtw.WriteAttributeString("default", "false");
xtw.WriteAttributeString("auto", "true");
xtw.WriteEndElement();
xtw.WriteStartElement("to");
xtw.WriteAttributeString("value", "sourceRom");
xtw.WriteAttributeString("default", "false");
xtw.WriteAttributeString("auto", "true");
xtw.WriteEndElement();
// End search
xtw.WriteEndElement();
xtw.WriteRequiredElementString("romTitle", Header.RomTitle ?? "%u - %n");
// End configuration
xtw.WriteEndElement();
xtw.WriteStartElement("games");
xtw.Flush();
} }
catch (Exception ex)
if (Header.CanOpen != null)
{ {
Globals.Logger.Error(ex.ToString()); xtw.WriteStartElement("canOpen");
if (Globals.ThrowOnError)
throw ex;
return false; foreach (string extension in Header.CanOpen)
{
xtw.WriteElementString("extension", extension);
}
// End canOpen
xtw.WriteEndElement();
} }
return true; xtw.WriteStartElement("newDat");
xtw.WriteRequiredElementString("datVersionURL", Header.Url);
xtw.WriteStartElement("datUrl");
xtw.WriteAttributeString("fileName", $"{Header.FileName ?? string.Empty}.zip");
xtw.WriteString(Header.Url);
xtw.WriteEndElement();
xtw.WriteRequiredElementString("imURL", Header.Url);
// End newDat
xtw.WriteEndElement();
xtw.WriteStartElement("search");
xtw.WriteStartElement("to");
xtw.WriteAttributeString("value", "location");
xtw.WriteAttributeString("default", "true");
xtw.WriteAttributeString("auto", "true");
xtw.WriteEndElement();
xtw.WriteStartElement("to");
xtw.WriteAttributeString("value", "romSize");
xtw.WriteAttributeString("default", "true");
xtw.WriteAttributeString("auto", "false");
xtw.WriteEndElement();
xtw.WriteStartElement("to");
xtw.WriteAttributeString("value", "languages");
xtw.WriteAttributeString("default", "true");
xtw.WriteAttributeString("auto", "true");
xtw.WriteEndElement();
xtw.WriteStartElement("to");
xtw.WriteAttributeString("value", "saveType");
xtw.WriteAttributeString("default", "false");
xtw.WriteAttributeString("auto", "false");
xtw.WriteEndElement();
xtw.WriteStartElement("to");
xtw.WriteAttributeString("value", "publisher");
xtw.WriteAttributeString("default", "false");
xtw.WriteAttributeString("auto", "true");
xtw.WriteEndElement();
xtw.WriteStartElement("to");
xtw.WriteAttributeString("value", "sourceRom");
xtw.WriteAttributeString("default", "false");
xtw.WriteAttributeString("auto", "true");
xtw.WriteEndElement();
// End search
xtw.WriteEndElement();
xtw.WriteRequiredElementString("romTitle", Header.RomTitle ?? "%u - %n");
// End configuration
xtw.WriteEndElement();
xtw.WriteStartElement("games");
xtw.Flush();
} }
/// <summary> /// <summary>
@@ -863,69 +848,56 @@ namespace SabreTools.Library.DatFiles
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> /// <returns>True if the data was written, false on error</returns>
private bool WriteDatItem(XmlTextWriter xtw, DatItem datItem) private void WriteDatItem(XmlTextWriter xtw, DatItem datItem)
{ {
try // Pre-process the item name
ProcessItemName(datItem, true);
// Build the state
xtw.WriteStartElement("game");
xtw.WriteElementString("imageNumber", "1");
xtw.WriteElementString("releaseNumber", "1");
xtw.WriteRequiredElementString("title", datItem.GetName() ?? string.Empty);
xtw.WriteElementString("saveType", "None");
if (datItem.ItemType == ItemType.Rom)
{ {
// Pre-process the item name var rom = datItem as Rom;
ProcessItemName(datItem, true); xtw.WriteRequiredElementString("romSize", rom.Size?.ToString());
}
// Build the state xtw.WriteRequiredElementString("publisher", datItem.Machine.Publisher);
xtw.WriteStartElement("game"); xtw.WriteElementString("location", "0");
xtw.WriteElementString("imageNumber", "1"); xtw.WriteElementString("sourceRom", "None");
xtw.WriteElementString("releaseNumber", "1"); xtw.WriteElementString("language", "0");
xtw.WriteRequiredElementString("title", datItem.GetName() ?? string.Empty);
xtw.WriteElementString("saveType", "None");
if (datItem.ItemType == ItemType.Rom) if (datItem.ItemType == ItemType.Rom)
{
var rom = datItem as Rom;
string tempext = "." + PathExtensions.GetNormalizedExtension(rom.Name);
xtw.WriteStartElement("files");
if (!string.IsNullOrWhiteSpace(rom.CRC))
{ {
var rom = datItem as Rom; xtw.WriteStartElement("romCRC");
xtw.WriteRequiredElementString("romSize", rom.Size?.ToString()); xtw.WriteRequiredAttributeString("extension", tempext);
} xtw.WriteString(rom.CRC?.ToUpperInvariant());
xtw.WriteRequiredElementString("publisher", datItem.Machine.Publisher);
xtw.WriteElementString("location", "0");
xtw.WriteElementString("sourceRom", "None");
xtw.WriteElementString("language", "0");
if (datItem.ItemType == ItemType.Rom)
{
var rom = datItem as Rom;
string tempext = "." + PathExtensions.GetNormalizedExtension(rom.Name);
xtw.WriteStartElement("files");
if (!string.IsNullOrWhiteSpace(rom.CRC))
{
xtw.WriteStartElement("romCRC");
xtw.WriteRequiredAttributeString("extension", tempext);
xtw.WriteString(rom.CRC?.ToUpperInvariant());
xtw.WriteEndElement();
}
// End files
xtw.WriteEndElement(); xtw.WriteEndElement();
} }
xtw.WriteElementString("im1CRC", "00000000"); // End files
xtw.WriteElementString("im2CRC", "00000000");
xtw.WriteRequiredElementString("comment", datItem.Machine.Comment);
xtw.WriteRequiredElementString("duplicateID", datItem.Machine.CloneOf);
// End game
xtw.WriteEndElement(); xtw.WriteEndElement();
xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
} }
return true; xtw.WriteElementString("im1CRC", "00000000");
xtw.WriteElementString("im2CRC", "00000000");
xtw.WriteRequiredElementString("comment", datItem.Machine.Comment);
xtw.WriteRequiredElementString("duplicateID", datItem.Machine.CloneOf);
// End game
xtw.WriteEndElement();
xtw.Flush();
} }
/// <summary> /// <summary>
@@ -933,54 +905,41 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> /// <returns>True if the data was written, false on error</returns>
private bool WriteFooter(XmlTextWriter xtw) private void WriteFooter(XmlTextWriter xtw)
{ {
try // End games
{ xtw.WriteEndElement();
// End games
xtw.WriteEndElement();
xtw.WriteStartElement("gui"); xtw.WriteStartElement("gui");
xtw.WriteStartElement("images"); xtw.WriteStartElement("images");
xtw.WriteAttributeString("width", "487"); xtw.WriteAttributeString("width", "487");
xtw.WriteAttributeString("height", "162"); xtw.WriteAttributeString("height", "162");
xtw.WriteStartElement("image"); xtw.WriteStartElement("image");
xtw.WriteAttributeString("x", "0"); xtw.WriteAttributeString("x", "0");
xtw.WriteAttributeString("y", "0"); xtw.WriteAttributeString("y", "0");
xtw.WriteAttributeString("width", "240"); xtw.WriteAttributeString("width", "240");
xtw.WriteAttributeString("height", "160"); xtw.WriteAttributeString("height", "160");
xtw.WriteEndElement(); xtw.WriteEndElement();
xtw.WriteStartElement("image"); xtw.WriteStartElement("image");
xtw.WriteAttributeString("x", "245"); xtw.WriteAttributeString("x", "245");
xtw.WriteAttributeString("y", "0"); xtw.WriteAttributeString("y", "0");
xtw.WriteAttributeString("width", "240"); xtw.WriteAttributeString("width", "240");
xtw.WriteAttributeString("height", "160"); xtw.WriteAttributeString("height", "160");
xtw.WriteEndElement(); xtw.WriteEndElement();
// End images // End images
xtw.WriteEndElement(); xtw.WriteEndElement();
// End gui // End gui
xtw.WriteEndElement(); xtw.WriteEndElement();
// End dat // End dat
xtw.WriteEndElement(); xtw.WriteEndElement();
xtw.Flush(); xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
} }
} }

View File

@@ -32,7 +32,8 @@ namespace SabreTools.Library.DatFiles
/// <param name="filename">Name of the file to be parsed</param> /// <param name="filename">Name of the file to be parsed</param>
/// <param name="indexId">Index ID for the DAT</param> /// <param name="indexId">Index ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
protected override void ParseFile(string filename, int indexId, bool keep) /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
{ {
// Prepare all internal variables // Prepare all internal variables
XmlReader xtr = filename.GetXmlTextReader(); XmlReader xtr = filename.GetXmlTextReader();
@@ -80,8 +81,7 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}"); Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}");
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
// For XML errors, just skip the affected node // For XML errors, just skip the affected node
xtr?.Read(); xtr?.Read();
@@ -513,8 +513,9 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="outfile">Name of the file to write to</param> /// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param> /// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns> /// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false) public override bool WriteToFile(string outfile, bool ignoreblanks = false, bool throwOnError = false)
{ {
try try
{ {
@@ -583,9 +584,7 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Error(ex.ToString()); Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
return false; return false;
} }
@@ -596,18 +595,15 @@ namespace SabreTools.Library.DatFiles
/// Write out DAT header using the supplied StreamWriter /// Write out DAT header using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteHeader(XmlTextWriter xtw)
private bool WriteHeader(XmlTextWriter xtw)
{ {
try xtw.WriteStartDocument();
{ xtw.WriteDocType("softwaredb", null, "softwaredb1.dtd", null);
xtw.WriteStartDocument();
xtw.WriteDocType("softwaredb", null, "softwaredb1.dtd", null);
xtw.WriteStartElement("softwaredb"); xtw.WriteStartElement("softwaredb");
xtw.WriteRequiredAttributeString("timestamp", Header.Date); xtw.WriteRequiredAttributeString("timestamp", Header.Date);
//TODO: Figure out how to fix the issue with removed formatting after this point //TODO: Figure out how to fix the issue with removed formatting after this point
// xtw.WriteComment("Credits"); // xtw.WriteComment("Credits");
// xtw.WriteCData(@"The softwaredb.xml file contains information about rom mapper types // xtw.WriteCData(@"The softwaredb.xml file contains information about rom mapper types
@@ -621,18 +617,7 @@ namespace SabreTools.Library.DatFiles
//- p_gimeno and diedel for their help adding and valdiating ROM additions //- p_gimeno and diedel for their help adding and valdiating ROM additions
//- GDX for additional ROM info and validations and corrections"); //- GDX for additional ROM info and validations and corrections");
xtw.Flush(); xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
@@ -640,61 +625,33 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> private void WriteStartGame(XmlTextWriter xtw, DatItem datItem)
private bool WriteStartGame(XmlTextWriter xtw, DatItem datItem)
{ {
try // No game should start with a path separator
{ datItem.Machine.Name = datItem.Machine.Name.TrimStart(Path.DirectorySeparatorChar);
// No game should start with a path separator
datItem.Machine.Name = datItem.Machine.Name.TrimStart(Path.DirectorySeparatorChar);
// Build the state // Build the state
xtw.WriteStartElement("software"); xtw.WriteStartElement("software");
xtw.WriteRequiredElementString("title", datItem.Machine.Name); xtw.WriteRequiredElementString("title", datItem.Machine.Name);
xtw.WriteRequiredElementString("genmsxid", datItem.Machine.GenMSXID); xtw.WriteRequiredElementString("genmsxid", datItem.Machine.GenMSXID);
xtw.WriteRequiredElementString("system", datItem.Machine.System); xtw.WriteRequiredElementString("system", datItem.Machine.System);
xtw.WriteRequiredElementString("company", datItem.Machine.Manufacturer); xtw.WriteRequiredElementString("company", datItem.Machine.Manufacturer);
xtw.WriteRequiredElementString("year", datItem.Machine.Year); xtw.WriteRequiredElementString("year", datItem.Machine.Year);
xtw.WriteRequiredElementString("country", datItem.Machine.Country); xtw.WriteRequiredElementString("country", datItem.Machine.Country);
xtw.Flush(); xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
/// Write out Game start using the supplied StreamWriter /// Write out Game start using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteEndGame(XmlTextWriter xtw)
private bool WriteEndGame(XmlTextWriter xtw)
{ {
try // End software
{ xtw.WriteEndElement();
// End software
xtw.WriteEndElement();
xtw.Flush(); xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
@@ -702,106 +659,78 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> private void WriteDatItem(XmlTextWriter xtw, DatItem datItem)
private bool WriteDatItem(XmlTextWriter xtw, DatItem datItem)
{ {
try // Pre-process the item name
ProcessItemName(datItem, true);
// Build the state
switch (datItem.ItemType)
{ {
// Pre-process the item name case ItemType.Rom:
ProcessItemName(datItem, true); var rom = datItem as Rom;
xtw.WriteStartElement("dump");
// Build the state if (rom.Original != null)
switch (datItem.ItemType) {
{ xtw.WriteStartElement("original");
case ItemType.Rom: xtw.WriteAttributeString("value", rom.Original.Value == true ? "true" : "false");
var rom = datItem as Rom; xtw.WriteString(rom.Original.Content);
xtw.WriteStartElement("dump");
if (rom.Original != null)
{
xtw.WriteStartElement("original");
xtw.WriteAttributeString("value", rom.Original.Value == true ? "true" : "false");
xtw.WriteString(rom.Original.Content);
xtw.WriteEndElement();
}
switch (rom.OpenMSXSubType)
{
// Default to Rom for converting from other formats
case OpenMSXSubType.Rom:
case OpenMSXSubType.NULL:
xtw.WriteStartElement(rom.OpenMSXSubType.FromOpenMSXSubType());
xtw.WriteRequiredElementString("hash", rom.SHA1?.ToLowerInvariant());
xtw.WriteOptionalElementString("start", rom.Offset);
xtw.WriteOptionalElementString("type", rom.OpenMSXType);
xtw.WriteOptionalElementString("remark", rom.Remark);
xtw.WriteEndElement();
break;
case OpenMSXSubType.MegaRom:
xtw.WriteStartElement(rom.OpenMSXSubType.FromOpenMSXSubType());
xtw.WriteRequiredElementString("hash", rom.SHA1?.ToLowerInvariant());
xtw.WriteOptionalElementString("start", rom.Offset);
xtw.WriteOptionalElementString("type", rom.OpenMSXType);
xtw.WriteOptionalElementString("remark", rom.Remark);
xtw.WriteEndElement();
break;
case OpenMSXSubType.SCCPlusCart:
xtw.WriteStartElement(rom.OpenMSXSubType.FromOpenMSXSubType());
xtw.WriteOptionalElementString("boot", rom.Boot);
xtw.WriteRequiredElementString("hash", rom.SHA1?.ToLowerInvariant());
xtw.WriteOptionalElementString("remark", rom.Remark);
xtw.WriteEndElement();
break;
}
// End dump
xtw.WriteEndElement(); xtw.WriteEndElement();
break; }
}
xtw.Flush(); switch (rom.OpenMSXSubType)
} {
catch (Exception ex) // Default to Rom for converting from other formats
{ case OpenMSXSubType.Rom:
Globals.Logger.Error(ex.ToString()); case OpenMSXSubType.NULL:
if (Globals.ThrowOnError) xtw.WriteStartElement(rom.OpenMSXSubType.FromOpenMSXSubType());
throw ex; xtw.WriteRequiredElementString("hash", rom.SHA1?.ToLowerInvariant());
xtw.WriteOptionalElementString("start", rom.Offset);
xtw.WriteOptionalElementString("type", rom.OpenMSXType);
xtw.WriteOptionalElementString("remark", rom.Remark);
xtw.WriteEndElement();
break;
return false; case OpenMSXSubType.MegaRom:
xtw.WriteStartElement(rom.OpenMSXSubType.FromOpenMSXSubType());
xtw.WriteRequiredElementString("hash", rom.SHA1?.ToLowerInvariant());
xtw.WriteOptionalElementString("start", rom.Offset);
xtw.WriteOptionalElementString("type", rom.OpenMSXType);
xtw.WriteOptionalElementString("remark", rom.Remark);
xtw.WriteEndElement();
break;
case OpenMSXSubType.SCCPlusCart:
xtw.WriteStartElement(rom.OpenMSXSubType.FromOpenMSXSubType());
xtw.WriteOptionalElementString("boot", rom.Boot);
xtw.WriteRequiredElementString("hash", rom.SHA1?.ToLowerInvariant());
xtw.WriteOptionalElementString("remark", rom.Remark);
xtw.WriteEndElement();
break;
}
// End dump
xtw.WriteEndElement();
break;
} }
return true; xtw.Flush();
} }
/// <summary> /// <summary>
/// Write out DAT footer using the supplied StreamWriter /// Write out DAT footer using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteFooter(XmlTextWriter xtw)
private bool WriteFooter(XmlTextWriter xtw)
{ {
try // End software
{ xtw.WriteEndElement();
// End software
xtw.WriteEndElement();
// End softwaredb // End softwaredb
xtw.WriteEndElement(); xtw.WriteEndElement();
xtw.Flush(); xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
} }
} }

View File

@@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Text; using System.Text;
using SabreTools.Library.Data; using SabreTools.Library.Data;
@@ -31,7 +30,8 @@ namespace SabreTools.Library.DatFiles
/// <param name="filename">Name of the file to be parsed</param> /// <param name="filename">Name of the file to be parsed</param>
/// <param name="indexId">Index ID for the DAT</param> /// <param name="indexId">Index ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
protected override void ParseFile(string filename, int indexId, bool keep) /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
{ {
// Prepare all intenral variables // Prepare all intenral variables
IniReader ir = filename.GetIniReader(false); IniReader ir = filename.GetIniReader(false);
@@ -85,8 +85,7 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}"); Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}");
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
} }
ir.Dispose(); ir.Dispose();
@@ -367,8 +366,9 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="outfile">Name of the file to write to</param> /// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param> /// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns> /// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false) public override bool WriteToFile(string outfile, bool ignoreblanks = false, bool throwOnError = false)
{ {
try try
{ {
@@ -422,9 +422,7 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Error(ex.ToString()); Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
return false; return false;
} }
@@ -435,40 +433,26 @@ namespace SabreTools.Library.DatFiles
/// Write out DAT header using the supplied StreamWriter /// Write out DAT header using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="iw">IniWriter to output to</param> /// <param name="iw">IniWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteHeader(IniWriter iw)
private bool WriteHeader(IniWriter iw)
{ {
try iw.WriteSection("CREDITS");
{ iw.WriteKeyValuePair("author", Header.Author);
iw.WriteSection("CREDITS"); iw.WriteKeyValuePair("version", Header.Version);
iw.WriteKeyValuePair("author", Header.Author); iw.WriteKeyValuePair("comment", Header.Comment);
iw.WriteKeyValuePair("version", Header.Version);
iw.WriteKeyValuePair("comment", Header.Comment);
iw.WriteSection("DAT"); iw.WriteSection("DAT");
iw.WriteKeyValuePair("version", Header.RomCenterVersion ?? "2.50"); iw.WriteKeyValuePair("version", Header.RomCenterVersion ?? "2.50");
iw.WriteKeyValuePair("plugin", Header.System); iw.WriteKeyValuePair("plugin", Header.System);
iw.WriteKeyValuePair("split", Header.ForceMerging == MergingFlag.Split ? "1" : "0"); iw.WriteKeyValuePair("split", Header.ForceMerging == MergingFlag.Split ? "1" : "0");
iw.WriteKeyValuePair("merge", Header.ForceMerging == MergingFlag.Full || Header.ForceMerging == MergingFlag.Merged ? "1" : "0"); iw.WriteKeyValuePair("merge", Header.ForceMerging == MergingFlag.Full || Header.ForceMerging == MergingFlag.Merged ? "1" : "0");
iw.WriteSection("EMULATOR"); iw.WriteSection("EMULATOR");
iw.WriteKeyValuePair("refname", Header.Name); iw.WriteKeyValuePair("refname", Header.Name);
iw.WriteKeyValuePair("version", Header.Description); iw.WriteKeyValuePair("version", Header.Description);
iw.WriteSection("GAMES"); iw.WriteSection("GAMES");
iw.Flush(); iw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
@@ -476,8 +460,7 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="iw">IniWriter to output to</param> /// <param name="iw">IniWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> private void WriteDatItem(IniWriter iw, DatItem datItem)
private bool WriteDatItem(IniWriter iw, DatItem datItem)
{ {
/* /*
The rominfo order is as follows: The rominfo order is as follows:
@@ -492,47 +475,34 @@ namespace SabreTools.Library.DatFiles
9 - merge name 9 - merge name
*/ */
try // Pre-process the item name
ProcessItemName(datItem, true);
// Build the state
switch (datItem.ItemType)
{ {
// Pre-process the item name case ItemType.Rom:
ProcessItemName(datItem, true); var rom = datItem as Rom;
// Build the state iw.WriteString($"¬{rom.Machine.CloneOf ?? string.Empty}");
switch (datItem.ItemType) iw.WriteString($"¬{rom.Machine.CloneOf ?? string.Empty}");
{ iw.WriteString($"¬{rom.Machine.Name ?? string.Empty}");
case ItemType.Rom: if (string.IsNullOrWhiteSpace(rom.Machine.Description ?? string.Empty))
var rom = datItem as Rom;
iw.WriteString($"¬{rom.Machine.CloneOf ?? string.Empty}");
iw.WriteString($"¬{rom.Machine.CloneOf ?? string.Empty}");
iw.WriteString($"¬{rom.Machine.Name ?? string.Empty}"); iw.WriteString($"¬{rom.Machine.Name ?? string.Empty}");
if (string.IsNullOrWhiteSpace(rom.Machine.Description ?? string.Empty)) else
iw.WriteString($"¬{rom.Machine.Name ?? string.Empty}"); iw.WriteString($"¬{rom.Machine.Description ?? string.Empty}");
else iw.WriteString($"¬{rom.Name ?? string.Empty}");
iw.WriteString($"¬{rom.Machine.Description ?? string.Empty}"); iw.WriteString($"¬{rom.CRC ?? string.Empty}");
iw.WriteString($"¬{rom.Name ?? string.Empty}"); iw.WriteString($"¬{rom.Size?.ToString() ?? string.Empty}");
iw.WriteString($"¬{rom.CRC ?? string.Empty}"); iw.WriteString($"¬{rom.Machine.RomOf ?? string.Empty}");
iw.WriteString($"¬{rom.Size?.ToString() ?? string.Empty}"); iw.WriteString($"¬{rom.MergeTag ?? string.Empty}");
iw.WriteString(${rom.Machine.RomOf ?? string.Empty}"); iw.WriteString("¬");
iw.WriteString($"¬{rom.MergeTag ?? string.Empty}"); iw.WriteLine();
iw.WriteString("¬");
iw.WriteLine();
break; break;
}
iw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
} }
return true; iw.Flush();
} }
} }
} }

View File

@@ -32,7 +32,8 @@ namespace SabreTools.Library.DatFiles
/// <param name="filename">Name of the file to be parsed</param> /// <param name="filename">Name of the file to be parsed</param>
/// <param name="indexId">Index ID for the DAT</param> /// <param name="indexId">Index ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
protected override void ParseFile(string filename, int indexId, bool keep) /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
{ {
// Prepare all internal variables // Prepare all internal variables
StreamReader sr = new StreamReader(FileExtensions.TryOpenRead(filename), new UTF8Encoding(false)); StreamReader sr = new StreamReader(FileExtensions.TryOpenRead(filename), new UTF8Encoding(false));
@@ -78,8 +79,7 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}"); Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}");
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
} }
jtr.Close(); jtr.Close();
@@ -336,8 +336,9 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="outfile">Name of the file to write to</param> /// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param> /// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns> /// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false) public override bool WriteToFile(string outfile, bool ignoreblanks = false, bool throwOnError = false)
{ {
try try
{ {
@@ -407,9 +408,7 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Error(ex.ToString()); Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
return false; return false;
} }
@@ -420,33 +419,19 @@ namespace SabreTools.Library.DatFiles
/// Write out DAT header using the supplied JsonTextWriter /// Write out DAT header using the supplied JsonTextWriter
/// </summary> /// </summary>
/// <param name="jtw">JsonTextWriter to output to</param> /// <param name="jtw">JsonTextWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteHeader(JsonTextWriter jtw)
private bool WriteHeader(JsonTextWriter jtw)
{ {
try jtw.WriteStartObject();
{
jtw.WriteStartObject();
// Write the DatHeader // Write the DatHeader
jtw.WritePropertyName("header"); jtw.WritePropertyName("header");
JsonSerializer js = new JsonSerializer() { Formatting = Formatting.Indented }; JsonSerializer js = new JsonSerializer() { Formatting = Formatting.Indented };
js.Serialize(jtw, Header); js.Serialize(jtw, Header);
jtw.WritePropertyName("machines"); jtw.WritePropertyName("machines");
jtw.WriteStartArray(); jtw.WriteStartArray();
jtw.Flush(); jtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
@@ -454,66 +439,38 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="jtw">JsonTextWriter to output to</param> /// <param name="jtw">JsonTextWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> private void WriteStartGame(JsonTextWriter jtw, DatItem datItem)
private bool WriteStartGame(JsonTextWriter jtw, DatItem datItem)
{ {
try // No game should start with a path separator
{ datItem.Machine.Name = datItem.Machine.Name.TrimStart(Path.DirectorySeparatorChar) ?? string.Empty;
// No game should start with a path separator
datItem.Machine.Name = datItem.Machine.Name.TrimStart(Path.DirectorySeparatorChar) ?? string.Empty;
// Build the state // Build the state
jtw.WriteStartObject(); jtw.WriteStartObject();
// Write the Machine // Write the Machine
jtw.WritePropertyName("machine"); jtw.WritePropertyName("machine");
JsonSerializer js = new JsonSerializer() { Formatting = Formatting.Indented }; JsonSerializer js = new JsonSerializer() { Formatting = Formatting.Indented };
js.Serialize(jtw, datItem.Machine); js.Serialize(jtw, datItem.Machine);
jtw.WritePropertyName("items"); jtw.WritePropertyName("items");
jtw.WriteStartArray(); jtw.WriteStartArray();
jtw.Flush(); jtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
/// Write out Game end using the supplied JsonTextWriter /// Write out Game end using the supplied JsonTextWriter
/// </summary> /// </summary>
/// <param name="jtw">JsonTextWriter to output to</param> /// <param name="jtw">JsonTextWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteEndGame(JsonTextWriter jtw)
private bool WriteEndGame(JsonTextWriter jtw)
{ {
try // End items
{ jtw.WriteEndArray();
// End items
jtw.WriteEndArray();
// End machine // End machine
jtw.WriteEndObject(); jtw.WriteEndObject();
jtw.Flush(); jtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
@@ -521,72 +478,44 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="jtw">JsonTextWriter to output to</param> /// <param name="jtw">JsonTextWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> private void WriteDatItem(JsonTextWriter jtw, DatItem datItem)
private bool WriteDatItem(JsonTextWriter jtw, DatItem datItem)
{ {
try // Pre-process the item name
{ ProcessItemName(datItem, true);
// Pre-process the item name
ProcessItemName(datItem, true);
// Build the state // Build the state
jtw.WriteStartObject(); jtw.WriteStartObject();
// Write the DatItem // Write the DatItem
jtw.WritePropertyName("datitem"); jtw.WritePropertyName("datitem");
JsonSerializer js = new JsonSerializer() { ContractResolver = new BaseFirstContractResolver(), Formatting = Formatting.Indented }; JsonSerializer js = new JsonSerializer() { ContractResolver = new BaseFirstContractResolver(), Formatting = Formatting.Indented };
js.Serialize(jtw, datItem); js.Serialize(jtw, datItem);
// End item // End item
jtw.WriteEndObject(); jtw.WriteEndObject();
jtw.Flush(); jtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
/// Write out DAT footer using the supplied JsonTextWriter /// Write out DAT footer using the supplied JsonTextWriter
/// </summary> /// </summary>
/// <param name="jtw">JsonTextWriter to output to</param> /// <param name="jtw">JsonTextWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteFooter(JsonTextWriter jtw)
private bool WriteFooter(JsonTextWriter jtw)
{ {
try // End items
{ jtw.WriteEndArray();
// End items
jtw.WriteEndArray();
// End machine // End machine
jtw.WriteEndObject(); jtw.WriteEndObject();
// End machines // End machines
jtw.WriteEndArray(); jtw.WriteEndArray();
// End file // End file
jtw.WriteEndObject(); jtw.WriteEndObject();
jtw.Flush(); jtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
} }
} }

View File

@@ -31,7 +31,8 @@ namespace SabreTools.Library.DatFiles
/// <param name="filename">Name of the file to be parsed</param> /// <param name="filename">Name of the file to be parsed</param>
/// <param name="indexId">Index ID for the DAT</param> /// <param name="indexId">Index ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
protected override void ParseFile(string filename, int indexId, bool keep) /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
{ {
// Prepare all internal variables // Prepare all internal variables
XmlReader xtr = filename.GetXmlTextReader(); XmlReader xtr = filename.GetXmlTextReader();
@@ -77,9 +78,8 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}"); Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}");
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
// For XML errors, just skip the affected node // For XML errors, just skip the affected node
xtr?.Read(); xtr?.Read();
} }
@@ -103,46 +103,34 @@ namespace SabreTools.Library.DatFiles
Machine machine = null; Machine machine = null;
// Otherwise, read the directory // Otherwise, read the directory
try xtr.MoveToContent();
while (!xtr.EOF)
{ {
xtr.MoveToContent(); // We only want elements
while (!xtr.EOF) if (xtr.NodeType != XmlNodeType.Element)
{ {
// We only want elements xtr.Read();
if (xtr.NodeType != XmlNodeType.Element) continue;
{
xtr.Read();
continue;
}
switch (xtr.Name)
{
case "machine":
XmlSerializer xs = new XmlSerializer(typeof(Machine));
machine = xs.Deserialize(xtr.ReadSubtree()) as Machine;
xtr.Skip();
break;
case "files":
ReadFiles(xtr.ReadSubtree(), machine, filename, indexId);
// Skip the directory node now that we've processed it
xtr.Read();
break;
default:
xtr.Read();
break;
}
} }
}
catch (Exception ex)
{
Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}");
if (Globals.ThrowOnError)
throw ex;
// For XML errors, just skip the affected node switch (xtr.Name)
xtr?.Read(); {
case "machine":
XmlSerializer xs = new XmlSerializer(typeof(Machine));
machine = xs.Deserialize(xtr.ReadSubtree()) as Machine;
xtr.Skip();
break;
case "files":
ReadFiles(xtr.ReadSubtree(), machine, filename, indexId);
// Skip the directory node now that we've processed it
xtr.Read();
break;
default:
xtr.Read();
break;
}
} }
} }
@@ -160,42 +148,30 @@ namespace SabreTools.Library.DatFiles
return; return;
// Otherwise, read the items // Otherwise, read the items
try xtr.MoveToContent();
while (!xtr.EOF)
{ {
xtr.MoveToContent(); // We only want elements
while (!xtr.EOF) if (xtr.NodeType != XmlNodeType.Element)
{ {
// We only want elements xtr.Read();
if (xtr.NodeType != XmlNodeType.Element) continue;
{
xtr.Read();
continue;
}
switch (xtr.Name)
{
case "datitem":
XmlSerializer xs = new XmlSerializer(typeof(DatItem));
DatItem item = xs.Deserialize(xtr.ReadSubtree()) as DatItem;
item.CopyMachineInformation(machine);
item.Source = new Source { Name = filename, Index = indexId };
ParseAddHelper(item);
xtr.Skip();
break;
default:
xtr.Read();
break;
}
} }
}
catch (Exception ex)
{
Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}");
if (Globals.ThrowOnError)
throw ex;
// For XML errors, just skip the affected node switch (xtr.Name)
xtr?.Read(); {
case "datitem":
XmlSerializer xs = new XmlSerializer(typeof(DatItem));
DatItem item = xs.Deserialize(xtr.ReadSubtree()) as DatItem;
item.CopyMachineInformation(machine);
item.Source = new Source { Name = filename, Index = indexId };
ParseAddHelper(item);
xtr.Skip();
break;
default:
xtr.Read();
break;
}
} }
} }
@@ -204,9 +180,9 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="outfile">Name of the file to write to</param> /// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param> /// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns> /// <returns>True if the DAT was written correctly, false otherwise</returns>
/// TODO: Fix writing out files that have a path in the name public override bool WriteToFile(string outfile, bool ignoreblanks = false, bool throwOnError = false)
public override bool WriteToFile(string outfile, bool ignoreblanks = false)
{ {
try try
{ {
@@ -275,9 +251,7 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Error(ex.ToString()); Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
return false; return false;
} }
@@ -288,34 +262,20 @@ namespace SabreTools.Library.DatFiles
/// Write out DAT header using the supplied StreamWriter /// Write out DAT header using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteHeader(XmlTextWriter xtw)
private bool WriteHeader(XmlTextWriter xtw)
{ {
try xtw.WriteStartDocument();
{
xtw.WriteStartDocument();
xtw.WriteStartElement("datafile"); xtw.WriteStartElement("datafile");
XmlSerializer xs = new XmlSerializer(typeof(DatHeader)); XmlSerializer xs = new XmlSerializer(typeof(DatHeader));
XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", ""); ns.Add("", "");
xs.Serialize(xtw, Header, ns); xs.Serialize(xtw, Header, ns);
xtw.WriteStartElement("data"); xtw.WriteStartElement("data");
xtw.Flush(); xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
@@ -323,63 +283,36 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> private void WriteStartGame(XmlTextWriter xtw, DatItem datItem)
private bool WriteStartGame(XmlTextWriter xtw, DatItem datItem)
{ {
try // No game should start with a path separator
{ datItem.Machine.Name = datItem.Machine.Name?.TrimStart(Path.DirectorySeparatorChar) ?? string.Empty;
// No game should start with a path separator
datItem.Machine.Name = datItem.Machine.Name?.TrimStart(Path.DirectorySeparatorChar) ?? string.Empty;
// Write the machine // Write the machine
xtw.WriteStartElement("directory"); xtw.WriteStartElement("directory");
XmlSerializer xs = new XmlSerializer(typeof(Machine)); XmlSerializer xs = new XmlSerializer(typeof(Machine));
XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", ""); ns.Add("", "");
xs.Serialize(xtw, datItem.Machine, ns); xs.Serialize(xtw, datItem.Machine, ns);
xtw.WriteStartElement("files"); xtw.WriteStartElement("files");
xtw.Flush(); xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
/// Write out Game start using the supplied StreamWriter /// Write out Game start using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
private bool WriteEndGame(XmlTextWriter xtw) private void WriteEndGame(XmlTextWriter xtw)
{ {
try // End files
{ xtw.WriteEndElement();
// End files
xtw.WriteEndElement();
// End directory // End directory
xtw.WriteEndElement(); xtw.WriteEndElement();
xtw.Flush(); xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
@@ -387,67 +320,39 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> private void WriteDatItem(XmlTextWriter xtw, DatItem datItem)
private bool WriteDatItem(XmlTextWriter xtw, DatItem datItem)
{ {
try // Pre-process the item name
{ ProcessItemName(datItem, true);
// Pre-process the item name
ProcessItemName(datItem, true);
// Write the DatItem // Write the DatItem
XmlSerializer xs = new XmlSerializer(typeof(DatItem)); XmlSerializer xs = new XmlSerializer(typeof(DatItem));
XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", ""); ns.Add("", "");
xs.Serialize(xtw, datItem, ns); xs.Serialize(xtw, datItem, ns);
xtw.Flush(); xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
/// Write out DAT footer using the supplied StreamWriter /// Write out DAT footer using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteFooter(XmlTextWriter xtw)
private bool WriteFooter(XmlTextWriter xtw)
{ {
try // End files
{ xtw.WriteEndElement();
// End files
xtw.WriteEndElement();
// End directory // End directory
xtw.WriteEndElement(); xtw.WriteEndElement();
// End data // End data
xtw.WriteEndElement(); xtw.WriteEndElement();
// End datafile // End datafile
xtw.WriteEndElement(); xtw.WriteEndElement();
xtw.Flush(); xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
} }
} }

View File

@@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Text; using System.Text;
using SabreTools.Library.Data; using SabreTools.Library.Data;
@@ -36,7 +35,8 @@ namespace SabreTools.Library.DatFiles
/// <param name="filename">Name of the file to be parsed</param> /// <param name="filename">Name of the file to be parsed</param>
/// <param name="indexId">Index ID for the DAT</param> /// <param name="indexId">Index ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
protected override void ParseFile(string filename, int indexId, bool keep) /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
{ {
// Open a file reader // Open a file reader
Encoding enc = FileExtensions.GetEncoding(filename); Encoding enc = FileExtensions.GetEncoding(filename);
@@ -106,8 +106,9 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="outfile">Name of the file to write to</param> /// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param> /// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns> /// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false) public override bool WriteToFile(string outfile, bool ignoreblanks = false, bool throwOnError = false)
{ {
try try
{ {
@@ -159,9 +160,7 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Error(ex.ToString()); Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
return false; return false;
} }
@@ -172,13 +171,10 @@ namespace SabreTools.Library.DatFiles
/// Write out DAT header using the supplied StreamWriter /// Write out DAT header using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="svw">SeparatedValueWriter to output to</param> /// <param name="svw">SeparatedValueWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteHeader(SeparatedValueWriter svw)
private bool WriteHeader(SeparatedValueWriter svw)
{ {
try string[] headers = new string[]
{ {
string[] headers = new string[]
{
"File Name", "File Name",
"Internal Name", "Internal Name",
"Description", "Description",
@@ -197,22 +193,11 @@ namespace SabreTools.Library.DatFiles
//"SHA512", //"SHA512",
//"SpamSum", //"SpamSum",
"Nodump", "Nodump",
}; };
svw.WriteHeader(headers); svw.WriteHeader(headers);
svw.Flush(); svw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
@@ -220,95 +205,81 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="svw">SeparatedValueWriter to output to</param> /// <param name="svw">SeparatedValueWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> private void WriteDatItem(SeparatedValueWriter svw, DatItem datItem)
private bool WriteDatItem(SeparatedValueWriter svw, DatItem datItem)
{ {
try // Separated values should only output Rom and Disk
if (datItem.ItemType != ItemType.Disk && datItem.ItemType != ItemType.Rom)
return;
// Build the state
// TODO: Can we have some way of saying what fields to write out? Support for read extends to all fields now
string[] fields = new string[14]; // 18;
fields[0] = Header.FileName;
fields[1] = Header.Name;
fields[2] = Header.Description;
fields[3] = datItem.Machine.Name;
fields[4] = datItem.Machine.Description;
switch (datItem.ItemType)
{ {
// Separated values should only output Rom and Disk case ItemType.Disk:
if (datItem.ItemType != ItemType.Disk && datItem.ItemType != ItemType.Rom) var disk = datItem as Disk;
return true; fields[5] = "disk";
fields[6] = string.Empty;
fields[7] = disk.Name;
fields[8] = string.Empty;
fields[9] = string.Empty;
fields[10] = disk.MD5?.ToLowerInvariant();
//fields[11] = string.Empty;
fields[11] = disk.SHA1?.ToLowerInvariant();
fields[12] = string.Empty;
//fields[13] = string.Empty;
//fields[14] = string.Empty;
//fields[15] = string.Empty;
fields[13] = disk.ItemStatus.ToString();
break;
// Build the state case ItemType.Media:
// TODO: Can we have some way of saying what fields to write out? Support for read extends to all fields now var media = datItem as Media;
string[] fields = new string[14]; // 18; fields[5] = "media";
fields[0] = Header.FileName; fields[6] = string.Empty;
fields[1] = Header.Name; fields[7] = media.Name;
fields[2] = Header.Description; fields[8] = string.Empty;
fields[3] = datItem.Machine.Name; fields[9] = string.Empty;
fields[4] = datItem.Machine.Description; fields[10] = media.MD5?.ToLowerInvariant();
//fields[11] = string.Empty;
fields[11] = media.SHA1?.ToLowerInvariant();
fields[12] = media.SHA256?.ToLowerInvariant();
//fields[13] = string.Empty;
//fields[14] = string.Empty;
//fields[15] = media.SpamSum?.ToLowerInvariant();
fields[13] = string.Empty;
break;
switch (datItem.ItemType) case ItemType.Rom:
{ var rom = datItem as Rom;
case ItemType.Disk: fields[5] = "rom";
var disk = datItem as Disk; fields[6] = rom.Name;
fields[5] = "disk"; fields[7] = string.Empty;
fields[6] = string.Empty; fields[8] = rom.Size?.ToString();
fields[7] = disk.Name; fields[9] = rom.CRC?.ToLowerInvariant();
fields[8] = string.Empty; fields[10] = rom.MD5?.ToLowerInvariant();
fields[9] = string.Empty; //fields[11] = rom.RIPEMD160?.ToLowerInvariant();
fields[10] = disk.MD5?.ToLowerInvariant(); fields[11] = rom.SHA1?.ToLowerInvariant();
//fields[11] = string.Empty; fields[12] = rom.SHA256?.ToLowerInvariant();
fields[11] = disk.SHA1?.ToLowerInvariant(); //fields[13] = rom.SHA384?.ToLowerInvariant();
fields[12] = string.Empty; //fields[14] = rom.SHA512?.ToLowerInvariant();
//fields[13] = string.Empty; //fields[15] = rom.SpamSum?.ToLowerInvariant();
//fields[14] = string.Empty; fields[13] = rom.ItemStatus.ToString();
//fields[15] = string.Empty; break;
fields[13] = disk.ItemStatus.ToString();
break;
case ItemType.Media:
var media = datItem as Media;
fields[5] = "media";
fields[6] = string.Empty;
fields[7] = media.Name;
fields[8] = string.Empty;
fields[9] = string.Empty;
fields[10] = media.MD5?.ToLowerInvariant();
//fields[11] = string.Empty;
fields[11] = media.SHA1?.ToLowerInvariant();
fields[12] = media.SHA256?.ToLowerInvariant();
//fields[13] = string.Empty;
//fields[14] = string.Empty;
//fields[15] = media.SpamSum?.ToLowerInvariant();
fields[13] = string.Empty;
break;
case ItemType.Rom:
var rom = datItem as Rom;
fields[5] = "rom";
fields[6] = rom.Name;
fields[7] = string.Empty;
fields[8] = rom.Size?.ToString();
fields[9] = rom.CRC?.ToLowerInvariant();
fields[10] = rom.MD5?.ToLowerInvariant();
//fields[11] = rom.RIPEMD160?.ToLowerInvariant();
fields[11] = rom.SHA1?.ToLowerInvariant();
fields[12] = rom.SHA256?.ToLowerInvariant();
//fields[13] = rom.SHA384?.ToLowerInvariant();
//fields[14] = rom.SHA512?.ToLowerInvariant();
//fields[15] = rom.SpamSum?.ToLowerInvariant();
fields[13] = rom.ItemStatus.ToString();
break;
}
svw.WriteString(CreatePrefixPostfix(datItem, true));
svw.WriteValues(fields, false);
svw.WriteString(CreatePrefixPostfix(datItem, false));
svw.WriteLine();
svw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
} }
return true; svw.WriteString(CreatePrefixPostfix(datItem, true));
svw.WriteValues(fields, false);
svw.WriteString(CreatePrefixPostfix(datItem, false));
svw.WriteLine();
svw.Flush();
} }
} }
} }

View File

@@ -33,7 +33,8 @@ namespace SabreTools.Library.DatFiles
/// <param name="filename">Name of the file to be parsed</param> /// <param name="filename">Name of the file to be parsed</param>
/// <param name="indexId">Index ID for the DAT</param> /// <param name="indexId">Index ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
protected override void ParseFile(string filename, int indexId, bool keep) /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
{ {
// Prepare all internal variables // Prepare all internal variables
XmlReader xtr = filename.GetXmlTextReader(); XmlReader xtr = filename.GetXmlTextReader();
@@ -81,8 +82,7 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}"); Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}");
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
// For XML errors, just skip the affected node // For XML errors, just skip the affected node
xtr?.Read(); xtr?.Read();
@@ -505,8 +505,9 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="outfile">Name of the file to write to</param> /// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param> /// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns> /// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false) public override bool WriteToFile(string outfile, bool ignoreblanks = false, bool throwOnError = false)
{ {
try try
{ {
@@ -575,9 +576,7 @@ namespace SabreTools.Library.DatFiles
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Error(ex.ToString()); Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError) if (throwOnError) throw ex;
throw ex;
return false; return false;
} }
@@ -588,30 +587,16 @@ namespace SabreTools.Library.DatFiles
/// Write out DAT header using the supplied StreamWriter /// Write out DAT header using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteHeader(XmlTextWriter xtw)
private bool WriteHeader(XmlTextWriter xtw)
{ {
try xtw.WriteStartDocument();
{ xtw.WriteDocType("softwarelist", null, "softwarelist.dtd", null);
xtw.WriteStartDocument();
xtw.WriteDocType("softwarelist", null, "softwarelist.dtd", null);
xtw.WriteStartElement("softwarelist"); xtw.WriteStartElement("softwarelist");
xtw.WriteRequiredAttributeString("name", Header.Name); xtw.WriteRequiredAttributeString("name", Header.Name);
xtw.WriteRequiredAttributeString("description", Header.Description); xtw.WriteRequiredAttributeString("description", Header.Description);
xtw.Flush(); xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
@@ -619,63 +604,35 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> private void WriteStartGame(XmlTextWriter xtw, DatItem datItem)
private bool WriteStartGame(XmlTextWriter xtw, DatItem datItem)
{ {
try // No game should start with a path separator
{ datItem.Machine.Name = datItem.Machine.Name.TrimStart(Path.DirectorySeparatorChar);
// No game should start with a path separator
datItem.Machine.Name = datItem.Machine.Name.TrimStart(Path.DirectorySeparatorChar);
// Build the state // Build the state
xtw.WriteStartElement("software"); xtw.WriteStartElement("software");
xtw.WriteRequiredAttributeString("name", datItem.Machine.Name); xtw.WriteRequiredAttributeString("name", datItem.Machine.Name);
if (!string.Equals(datItem.Machine.Name, datItem.Machine.CloneOf, StringComparison.OrdinalIgnoreCase)) if (!string.Equals(datItem.Machine.Name, datItem.Machine.CloneOf, StringComparison.OrdinalIgnoreCase))
xtw.WriteOptionalAttributeString("cloneof", datItem.Machine.CloneOf); xtw.WriteOptionalAttributeString("cloneof", datItem.Machine.CloneOf);
xtw.WriteOptionalAttributeString("supported", datItem.Machine.Supported.FromSupported(false)); xtw.WriteOptionalAttributeString("supported", datItem.Machine.Supported.FromSupported(false));
xtw.WriteOptionalElementString("description", datItem.Machine.Description); xtw.WriteOptionalElementString("description", datItem.Machine.Description);
xtw.WriteOptionalElementString("year", datItem.Machine.Year); xtw.WriteOptionalElementString("year", datItem.Machine.Year);
xtw.WriteOptionalElementString("publisher", datItem.Machine.Publisher); xtw.WriteOptionalElementString("publisher", datItem.Machine.Publisher);
xtw.Flush(); xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
/// Write out Game start using the supplied StreamWriter /// Write out Game start using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteEndGame(XmlTextWriter xtw)
private bool WriteEndGame(XmlTextWriter xtw)
{ {
try // End software
{ xtw.WriteEndElement();
// End software
xtw.WriteEndElement();
xtw.Flush(); xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
/// <summary> /// <summary>
@@ -683,186 +640,158 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <param name="datItem">DatItem object to be output</param> /// <param name="datItem">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns> private void WriteDatItem(XmlTextWriter xtw, DatItem datItem)
private bool WriteDatItem(XmlTextWriter xtw, DatItem datItem)
{ {
try // Pre-process the item name
ProcessItemName(datItem, true);
// Build the state
switch (datItem.ItemType)
{ {
// Pre-process the item name case ItemType.DipSwitch:
ProcessItemName(datItem, true); var dipSwitch = datItem as DipSwitch;
xtw.WriteStartElement("dipswitch");
// Build the state xtw.WriteRequiredAttributeString("name", dipSwitch.Name);
switch (datItem.ItemType) xtw.WriteRequiredAttributeString("tag", dipSwitch.Tag);
{ xtw.WriteRequiredAttributeString("mask", dipSwitch.Mask);
case ItemType.DipSwitch: if (dipSwitch.Values != null)
var dipSwitch = datItem as DipSwitch; {
xtw.WriteStartElement("dipswitch"); foreach (Setting dipValue in dipSwitch.Values)
xtw.WriteRequiredAttributeString("name", dipSwitch.Name);
xtw.WriteRequiredAttributeString("tag", dipSwitch.Tag);
xtw.WriteRequiredAttributeString("mask", dipSwitch.Mask);
if (dipSwitch.Values != null)
{ {
foreach (Setting dipValue in dipSwitch.Values) xtw.WriteStartElement("dipvalue");
{ xtw.WriteRequiredAttributeString("name", dipValue.Name);
xtw.WriteStartElement("dipvalue"); xtw.WriteOptionalAttributeString("value", dipValue.Value);
xtw.WriteRequiredAttributeString("name", dipValue.Name); xtw.WriteOptionalAttributeString("default", dipValue.Default.FromYesNo());
xtw.WriteOptionalAttributeString("value", dipValue.Value); xtw.WriteEndElement();
xtw.WriteOptionalAttributeString("default", dipValue.Default.FromYesNo());
xtw.WriteEndElement();
}
} }
xtw.WriteEndElement(); }
break; xtw.WriteEndElement();
break;
case ItemType.Disk: case ItemType.Disk:
var disk = datItem as Disk; var disk = datItem as Disk;
string diskAreaName = disk.DiskArea?.Name; string diskAreaName = disk.DiskArea?.Name;
if (string.IsNullOrWhiteSpace(diskAreaName)) if (string.IsNullOrWhiteSpace(diskAreaName))
diskAreaName = "cdrom"; diskAreaName = "cdrom";
xtw.WriteStartElement("part"); xtw.WriteStartElement("part");
xtw.WriteRequiredAttributeString("name", disk.Part?.Name); xtw.WriteRequiredAttributeString("name", disk.Part?.Name);
xtw.WriteRequiredAttributeString("interface", disk.Part?.Interface); xtw.WriteRequiredAttributeString("interface", disk.Part?.Interface);
if (disk.Part?.Features != null && disk.Part?.Features.Count > 0) if (disk.Part?.Features != null && disk.Part?.Features.Count > 0)
{
foreach (PartFeature partFeature in disk.Part.Features)
{ {
foreach (PartFeature partFeature in disk.Part.Features) xtw.WriteStartElement("feature");
{ xtw.WriteRequiredAttributeString("name", partFeature.Name);
xtw.WriteStartElement("feature"); xtw.WriteRequiredAttributeString("value", partFeature.Value);
xtw.WriteRequiredAttributeString("name", partFeature.Name); xtw.WriteEndElement();
xtw.WriteRequiredAttributeString("value", partFeature.Value);
xtw.WriteEndElement();
}
} }
}
xtw.WriteStartElement("diskarea"); xtw.WriteStartElement("diskarea");
xtw.WriteRequiredAttributeString("name", diskAreaName); xtw.WriteRequiredAttributeString("name", diskAreaName);
xtw.WriteStartElement("disk"); xtw.WriteStartElement("disk");
xtw.WriteRequiredAttributeString("name", disk.Name); xtw.WriteRequiredAttributeString("name", disk.Name);
xtw.WriteOptionalAttributeString("md5", disk.MD5?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("md5", disk.MD5?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha1", disk.SHA1?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("sha1", disk.SHA1?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("status", disk.ItemStatus.FromItemStatus(false)); xtw.WriteOptionalAttributeString("status", disk.ItemStatus.FromItemStatus(false));
xtw.WriteOptionalAttributeString("writable", disk.Writable.FromYesNo()); xtw.WriteOptionalAttributeString("writable", disk.Writable.FromYesNo());
xtw.WriteEndElement(); xtw.WriteEndElement();
// End diskarea // End diskarea
xtw.WriteEndElement(); xtw.WriteEndElement();
// End part // End part
xtw.WriteEndElement(); xtw.WriteEndElement();
break; break;
case ItemType.Info: case ItemType.Info:
var info = datItem as Info; var info = datItem as Info;
xtw.WriteStartElement("info"); xtw.WriteStartElement("info");
xtw.WriteRequiredAttributeString("name", info.Name); xtw.WriteRequiredAttributeString("name", info.Name);
xtw.WriteRequiredAttributeString("value", info.Value); xtw.WriteRequiredAttributeString("value", info.Value);
xtw.WriteEndElement(); xtw.WriteEndElement();
break; break;
case ItemType.Rom: case ItemType.Rom:
var rom = datItem as Rom; var rom = datItem as Rom;
string dataAreaName = rom.DataArea?.Name; string dataAreaName = rom.DataArea?.Name;
if (string.IsNullOrWhiteSpace(dataAreaName)) if (string.IsNullOrWhiteSpace(dataAreaName))
dataAreaName = "rom"; dataAreaName = "rom";
xtw.WriteStartElement("part"); xtw.WriteStartElement("part");
xtw.WriteRequiredAttributeString("name", rom.Part?.Name); xtw.WriteRequiredAttributeString("name", rom.Part?.Name);
xtw.WriteRequiredAttributeString("interface", rom.Part?.Interface); xtw.WriteRequiredAttributeString("interface", rom.Part?.Interface);
if (rom.Part?.Features != null && rom.Part?.Features.Count > 0) if (rom.Part?.Features != null && rom.Part?.Features.Count > 0)
{
foreach (PartFeature kvp in rom.Part.Features)
{ {
foreach (PartFeature kvp in rom.Part.Features) xtw.WriteStartElement("feature");
{ xtw.WriteRequiredAttributeString("name", kvp.Name);
xtw.WriteStartElement("feature"); xtw.WriteRequiredAttributeString("value", kvp.Value);
xtw.WriteRequiredAttributeString("name", kvp.Name); xtw.WriteEndElement();
xtw.WriteRequiredAttributeString("value", kvp.Value);
xtw.WriteEndElement();
}
} }
}
xtw.WriteStartElement("dataarea"); xtw.WriteStartElement("dataarea");
xtw.WriteRequiredAttributeString("name", dataAreaName); xtw.WriteRequiredAttributeString("name", dataAreaName);
xtw.WriteOptionalAttributeString("size", rom.DataArea?.Size.ToString()); xtw.WriteOptionalAttributeString("size", rom.DataArea?.Size.ToString());
xtw.WriteOptionalAttributeString("width", rom.DataArea?.Width?.ToString()); xtw.WriteOptionalAttributeString("width", rom.DataArea?.Width?.ToString());
xtw.WriteOptionalAttributeString("endianness", rom.DataArea?.Endianness.FromEndianness()); xtw.WriteOptionalAttributeString("endianness", rom.DataArea?.Endianness.FromEndianness());
xtw.WriteStartElement("rom"); xtw.WriteStartElement("rom");
xtw.WriteRequiredAttributeString("name", rom.Name); xtw.WriteRequiredAttributeString("name", rom.Name);
xtw.WriteOptionalAttributeString("size", rom.Size?.ToString()); xtw.WriteOptionalAttributeString("size", rom.Size?.ToString());
xtw.WriteOptionalAttributeString("crc", rom.CRC?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("crc", rom.CRC?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("md5", rom.MD5?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("md5", rom.MD5?.ToLowerInvariant());
#if NET_FRAMEWORK #if NET_FRAMEWORK
xtw.WriteOptionalAttributeString("ripemd160", rom.RIPEMD160?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("ripemd160", rom.RIPEMD160?.ToLowerInvariant());
#endif #endif
xtw.WriteOptionalAttributeString("sha1", rom.SHA1?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("sha1", rom.SHA1?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha256", rom.SHA256?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("sha256", rom.SHA256?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha384", rom.SHA384?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("sha384", rom.SHA384?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha512", rom.SHA512?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("sha512", rom.SHA512?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("offset", rom.Offset); xtw.WriteOptionalAttributeString("offset", rom.Offset);
xtw.WriteOptionalAttributeString("value", rom.Value); xtw.WriteOptionalAttributeString("value", rom.Value);
xtw.WriteOptionalAttributeString("status", rom.ItemStatus.FromItemStatus(false)); xtw.WriteOptionalAttributeString("status", rom.ItemStatus.FromItemStatus(false));
xtw.WriteOptionalAttributeString("loadflag", rom.LoadFlag.FromLoadFlag()); xtw.WriteOptionalAttributeString("loadflag", rom.LoadFlag.FromLoadFlag());
xtw.WriteEndElement(); xtw.WriteEndElement();
// End dataarea // End dataarea
xtw.WriteEndElement(); xtw.WriteEndElement();
// End part // End part
xtw.WriteEndElement(); xtw.WriteEndElement();
break; break;
case ItemType.SharedFeature: case ItemType.SharedFeature:
var sharedFeature = datItem as SharedFeature; var sharedFeature = datItem as SharedFeature;
xtw.WriteStartElement("sharedfeat"); xtw.WriteStartElement("sharedfeat");
xtw.WriteRequiredAttributeString("name", sharedFeature.Name); xtw.WriteRequiredAttributeString("name", sharedFeature.Name);
xtw.WriteRequiredAttributeString("value", sharedFeature.Value); xtw.WriteRequiredAttributeString("value", sharedFeature.Value);
xtw.WriteEndElement(); xtw.WriteEndElement();
break; break;
}
xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
} }
return true; xtw.Flush();
} }
/// <summary> /// <summary>
/// Write out DAT footer using the supplied StreamWriter /// Write out DAT footer using the supplied StreamWriter
/// </summary> /// </summary>
/// <param name="xtw">XmlTextWriter to output to</param> /// <param name="xtw">XmlTextWriter to output to</param>
/// <returns>True if the data was written, false on error</returns> private void WriteFooter(XmlTextWriter xtw)
private bool WriteFooter(XmlTextWriter xtw)
{ {
try // End software
{ xtw.WriteEndElement();
// End software
xtw.WriteEndElement();
// End softwarelist // End softwarelist
xtw.WriteEndElement(); xtw.WriteEndElement();
xtw.Flush(); xtw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
if (Globals.ThrowOnError)
throw ex;
return false;
}
return true;
} }
} }
} }

View File

@@ -168,24 +168,8 @@ namespace SabreTools.Library.IO
} }
else else
{ {
// Special case for non-quoted names (old DATs only)
if (key == "name" && !linegc[i + 1].Contains("\""))
{
while (++i < linegc.Length
&& linegc[i] != "size"
&& linegc[i] != "crc"
&& linegc[i] != "md5"
&& linegc[i] != "sha1"
&& linegc[i] != "status")
{
value += $" {linegc[i]}";
}
value = value.Trim();
i--;
}
// Special cases for standalone statuses // Special cases for standalone statuses
else if (key == "baddump" || key == "good" || key == "nodump" || key == "verified") if (key == "baddump" || key == "good" || key == "nodump" || key == "verified")
{ {
value = key; value = key;
key = "status"; key = "status";

View File

@@ -422,9 +422,6 @@ Reset the internal state: reset();";
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Error($"There was an exception processing {path}: {ex}"); Globals.Logger.Error($"There was an exception processing {path}: {ex}");
if (Globals.ThrowOnError)
throw ex;
continue; continue;
} }
} }