Use superior DAT creation tools instead of direct DAT conversion.

This change includes a few changes meant to keep the information from each DAT and have it retained in a single object which can then be written out in any format or added to other DATs with very little issue. This new system is much more versitile since all it needs is a way to convert each DAT to XML and then use the built-in output to output from the XML to the target format. This also gives the ability to clean a DAT by "converting" a DAT to the same format, removing any improper tagging or the such.
This commit is contained in:
Matt Nadareski
2016-05-16 15:17:11 -07:00
parent d2e96a8f24
commit d90826b7a4
5 changed files with 75 additions and 172 deletions

View File

@@ -1251,22 +1251,29 @@ Make a selection:
if (File.Exists(filename))
{
logger.User("Converting " + filename);
XmlDocument doc = new XmlDocument();
try
DatData datdata = new DatData
{
doc.LoadXml(File.ReadAllText(filename));
string conv = Converters.XMLToClrMamePro(doc);
FileStream fs = File.OpenWrite(Path.GetFileNameWithoutExtension(filename) + ".new.dat");
StreamWriter sw = new StreamWriter(fs);
sw.Write(conv);
sw.Close();
fs.Close();
logger.User("Converted file: " + Path.GetFileNameWithoutExtension(filename) + ".new.dat");
}
catch (XmlException)
{
logger.Warning("The file " + filename + " could not be parsed as an XML file");
}
Name = "",
Description = "",
Category = "",
Version = "",
Date = "",
Author = "",
Email = "",
Homepage = "",
Url = "",
Comment = "",
OutputFormat = OutputFormat.ClrMamePro,
Roms = new Dictionary<string, List<RomData>>(),
MergeRoms = false,
};
datdata = RomManipulation.ParseDict(filename, 0, 0, datdata, logger);
logger.User("datdata.Description: " + datdata.Description);
datdata.Description += ".new";
Output.WriteToDatFromDict(datdata, Path.GetDirectoryName(filename), logger);
}
else
{
@@ -1284,19 +1291,33 @@ Make a selection:
if (File.Exists(filename))
{
logger.User("Converting " + filename);
XElement conv = Converters.ClrMameProToXML(File.ReadAllLines(filename));
FileStream fs = File.OpenWrite(Path.GetFileNameWithoutExtension(filename) + ".new.xml");
StreamWriter sw = new StreamWriter(fs);
sw.Write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<!DOCTYPE datafile PUBLIC \"-//Logiqx//DTD ROM Management Datafile//EN\" \"http://www.logiqx.com/Dats/datafile.dtd\">\n\n");
sw.Write(conv);
sw.Close();
fs.Close();
logger.User("Converted file: " + Path.GetFileNameWithoutExtension(filename) + ".new.xml");
DatData datdata = new DatData
{
Name = "",
Description = "",
Category = "",
Version = "",
Date = "",
Author = "",
Email = "",
Homepage = "",
Url = "",
Comment = "",
OutputFormat = OutputFormat.Xml,
Roms = new Dictionary<string, List<RomData>>(),
MergeRoms = false,
};
datdata = RomManipulation.ParseDict(filename, 0, 0, datdata, logger);
logger.User("datdata.Description: " + datdata.Description);
datdata.Description += ".new";
Output.WriteToDatFromDict(datdata, Path.GetDirectoryName(filename), logger);
}
else
{
logger.Error("I'm sorry but " + filename + "doesn't exist!");
logger.Error("I'm sorry but " + filename + " doesn't exist!");
}
return;
}

View File

@@ -87,7 +87,7 @@ Options:
-system= System name (system only)
-source= Source name (source only)
-url= URL (source only)
-cc, --convert-cmp Convert an XML DAT to CMP
-cc, --convert-cmp Convert any DAT to CMP
-out= Output directory
-cm, --convert-miss Convert from DAT to miss
-r, --roms Output roms to miss instead of sets
@@ -97,7 +97,7 @@ Options:
-q, --quotes Put double-quotes around each item
-ae=, --add-ext= Add an extension to each item
-re=, --rep-ext= Replace all extensions with specified
-cx, --convert-xml Convert a CMP DAT to XML
-cx, --convert-xml Convert any DAT to XML
-out= Output directory
-es, --ext-split Split a DAT by two file extensions
-exta= First extension to split by

View File

@@ -10,14 +10,7 @@ namespace SabreTools.Helper
/// Provide DAT conversion functionality
///
/// The following features have been requested:
/// - Implement converting from/to DOSCenter format
/// - Implement converting to RomCenter format
///
/// Internal notes:
/// - Can the XMLToDATFORMAT functions be replaced by Output.WriteToDatFromDict?
/// - ParseDict should then return a DatData with the current DAT information as well as the parsed roms
/// - This in turn would make converting a lot easier since all we have to do is know how to read from every
/// DAT type and write in every DAT type without needing a middle ground
/// - Implement converting from DOSCenter format
/// </summary>
public class Converters
{
@@ -316,128 +309,5 @@ namespace SabreTools.Helper
return elem;
}
/// <summary>
/// Convert an XML derived DAT to a ClrMamePro style DAT
/// </summary>
/// <param name="root">XElement representing the file</param>
/// <returns>String representing the output ClrMamePro DAT file</returns>
public static String XMLToClrMamePro(XmlDocument root)
{
string output = "";
// Experimental looping using only XML parsing
XmlNode node = root.FirstChild;
if (node != null && node.Name == "xml")
{
// Skip over everything that's not an element
while (node.NodeType != XmlNodeType.Element)
{
node = node.NextSibling;
}
}
// Once we find the main body, enter it
if (node != null && (node.Name == "datafile" || node.Name == "softwarelist"))
{
node = node.FirstChild;
}
// Read the header if it exists
if (node != null && node.Name == "header")
{
output += "clrmamepro (";
XmlNode child = node.FirstChild;
while (child != null)
{
output += "\n\t" + child.Name + " \"" + child.InnerText + "\"";
child = child.NextSibling;
}
output += "\n)";
// Skip over anything that's not an element
while (node.NodeType != XmlNodeType.Element)
{
node = node.NextSibling;
}
}
while (node != null)
{
if (node.NodeType == XmlNodeType.Element && (node.Name == "machine" || node.Name == "game" || node.Name == "software"))
{
// There are rare cases where a malformed XML will not have the required attributes. We can only skip them.
if (node.Attributes.Count == 0)
{
node = node.NextSibling;
continue;
}
output += "\ngame (\n\tname \"" + node.Attributes["name"].Value;
// Get the roms from the machine
if (node.HasChildNodes)
{
// If this node has children, traverse the children
foreach (XmlNode child in node.ChildNodes)
{
// If we find a rom or disk, add it
if (node.NodeType == XmlNodeType.Element && (child.Name == "rom" || child.Name == "disk"))
{
output += "\n\t" + child.Name + " ( name \"" + child.Attributes["name"].Value + "\"" +
(child.Attributes["size"] != null ? " size " + Int32.Parse(child.Attributes["size"].Value) : "") +
(child.Attributes["crc"] != null ? " crc " + child.Attributes["crc"].Value.ToLowerInvariant().Trim() : "") +
(child.Attributes["md5"] != null ? " md5 " + child.Attributes["md5"].Value.ToLowerInvariant().Trim() : "") +
(child.Attributes["sha1"] != null ? " sha1 " + child.Attributes["sha1"].Value.ToLowerInvariant().Trim() : "") + " )";
}
// If we find the signs of a software list, traverse the children
else if (child.NodeType == XmlNodeType.Element && child.Name == "part" && child.HasChildNodes)
{
foreach (XmlNode part in child.ChildNodes)
{
// If we find a dataarea, traverse the children
if (part.NodeType == XmlNodeType.Element && part.Name == "dataarea")
{
foreach (XmlNode data in part.ChildNodes)
{
// If we find a rom or disk, add it
if (data.NodeType == XmlNodeType.Element && (data.Name == "rom" || data.Name == "disk") && data.Attributes["name"] != null)
{
output += "\n\t" + data.Name + " ( name \"" + data.Attributes["name"].Value +
(data.Attributes["size"] != null ? " size " + Int32.Parse(data.Attributes["size"].Value) : "") +
(data.Attributes["crc"] != null ? " crc " + data.Attributes["crc"].Value.ToLowerInvariant().Trim() : "") +
(data.Attributes["md5"] != null ? " md5 " + data.Attributes["md5"].Value.ToLowerInvariant().Trim() : "") +
(data.Attributes["sha1"] != null ? " sha1 " + data.Attributes["sha1"].Value.ToLowerInvariant().Trim() : "") + " )";
}
}
}
}
}
else
{
output += "\n\t" + child.Name + " \"" + child.InnerText + "\"";
}
}
}
output += "\n)";
}
node = node.NextSibling;
}
return output;
}
/// <summary>
/// Convert an XML derived DAT to a RomCenter style DAT
/// </summary>
/// <param name="root">XElement representing the file</param>
/// <returns>String representing the output RomCenter DAT file</returns>
public static String XMLToRomCenter(XmlDocument root)
{
string output = "";
return output;
}
}
}

View File

@@ -268,7 +268,7 @@ namespace SabreTools.Helper
state += ")\n";
break;
case OutputFormat.Xml:
state += "\t </ machine >\n";
state += "\t</machine>\n";
break;
}
}

View File

@@ -404,48 +404,59 @@ namespace SabreTools.Helper
if (headreader != null)
{
while (headreader.Read())
while (!headreader.EOF)
{
// We only want elements
if (headreader.NodeType != XmlNodeType.Element)
if (headreader.NodeType != XmlNodeType.Element || headreader.Name == "header")
{
headreader.Read();
continue;
}
// Get all header items (ONLY OVERWRITE IF THERE'S NO DATA)
switch (xtr.Name)
string content = "";
switch (headreader.Name)
{
case "name":
string readname = headreader.ReadElementContentAsString();
string readname = headreader.ReadElementContentAsString(); ;
datdata.Name = (datdata.Name == "" ? readname : "");
superdat = superdat || readname.Contains(" - SuperDAT");
break;
case "description":
datdata.Description = (datdata.Description == "" ? headreader.ReadElementContentAsString() : datdata.Description);
content = headreader.ReadElementContentAsString();
datdata.Description = (datdata.Description == "" ? content : datdata.Description);
break;
case "category":
datdata.Category = (datdata.Category == "" ? headreader.ReadElementContentAsString() : datdata.Category);
content = headreader.ReadElementContentAsString();
datdata.Category = (datdata.Category == "" ? content : datdata.Category);
break;
case "version":
datdata.Version = (datdata.Version == "" ? headreader.ReadElementContentAsString() : datdata.Version);
content = headreader.ReadElementContentAsString();
datdata.Version = (datdata.Version == "" ? content : datdata.Version);
break;
case "date":
datdata.Date = (datdata.Date == "" ? headreader.ReadElementContentAsString() : datdata.Date);
content = headreader.ReadElementContentAsString();
datdata.Date = (datdata.Date == "" ? content : datdata.Date);
break;
case "author":
datdata.Author = (datdata.Author == "" ? headreader.ReadElementContentAsString() : datdata.Author);
content = headreader.ReadElementContentAsString();
datdata.Author = (datdata.Author == "" ? content : datdata.Author);
break;
case "email":
datdata.Email = (datdata.Email == "" ? headreader.ReadElementContentAsString() : datdata.Email);
content = headreader.ReadElementContentAsString();
datdata.Email = (datdata.Email == "" ? content : datdata.Email);
break;
case "homepage":
datdata.Homepage = (datdata.Homepage == "" ? headreader.ReadElementContentAsString() : datdata.Homepage);
content = headreader.ReadElementContentAsString();
datdata.Homepage = (datdata.Homepage == "" ? content : datdata.Homepage);
break;
case "url":
datdata.Url = (datdata.Url == "" ? headreader.ReadElementContentAsString() : datdata.Url);
content = headreader.ReadElementContentAsString();
datdata.Url = (datdata.Url == "" ? content : datdata.Url);
break;
case "comment":
datdata.Comment = (datdata.Comment == "" ? headreader.ReadElementContentAsString() : datdata.Comment);
content = headreader.ReadElementContentAsString();
datdata.Comment = (datdata.Comment == "" ? content : datdata.Comment);
break;
case "clrmamepro":
if (headreader.GetAttribute("forcemerging") != null)
@@ -490,6 +501,7 @@ namespace SabreTools.Helper
break;
}
}
headreader.Read();
break;
}
}