diff --git a/SabreHelper/RomManipulation.cs b/SabreHelper/RomManipulation.cs
index 73df6452..e5aefc9c 100644
--- a/SabreHelper/RomManipulation.cs
+++ b/SabreHelper/RomManipulation.cs
@@ -215,360 +215,134 @@ namespace SabreTools.Helper
/// Logger object for console and/or file output
/// List of RomData objects representing the found data
public static List Parse(string filename, int sysid, int srcid, Logger logger)
- {
- List roms = new List();
-
- bool superdat = false;
- XmlDocument doc = GetXmlDocument(filename, logger);
-
- // If the returned document is null, return the empty list
- if (doc == null)
- {
- return roms;
- }
-
- // Experimental looping using only XML parsing
- XmlNode node = doc.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;
- }
-
- // Skip the header if it exists
- if (node != null && node.Name == "header")
- {
- // Check for SuperDAT mode
- if (node.SelectSingleNode("name").InnerText.Contains(" - SuperDAT"))
- {
- superdat = true;
- }
-
- // Skip over anything that's not an element
- while (node.NodeType != XmlNodeType.Element)
- {
- node = node.NextSibling;
- }
- }
-
- // Loop over the document until the end
- while (node != null)
- {
- if (node.NodeType == XmlNodeType.Element && (node.Name == "machine" || node.Name == "game" || node.Name == "software"))
- {
- string tempname = "";
- if (node.Name == "software")
- {
- tempname = node.SelectSingleNode("description").InnerText;
- }
- else
- {
- // There are rare cases where a malformed XML will not have the required attributes. We can only skip them.
- if (node.Attributes.Count == 0)
- {
- logger.Error("No attributes were found");
- node = node.NextSibling;
- continue;
- }
- tempname = node.Attributes["name"].Value;
- }
-
- if (superdat)
- {
- tempname = Regex.Match(tempname, @".*?\\(.*)").Groups[1].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 (child.NodeType == XmlNodeType.Element && (child.Name == "rom" || child.Name == "disk"))
- {
- // Take care of hex-sized files
- long size = -1;
- if (child.Attributes["size"] != null && child.Attributes["size"].Value.Contains("0x"))
- {
- size = Convert.ToInt64(child.Attributes["size"].Value, 16);
- }
- else if (child.Attributes["size"] != null)
- {
- Int64.TryParse(child.Attributes["size"].Value, out size);
- }
-
- roms.Add(new RomData
- {
- Game = tempname,
- Name = child.Attributes["name"].Value,
- Type = child.Name,
- SystemID = sysid,
- SourceID = srcid,
- Size = size,
- CRC = (child.Attributes["crc"] != null ? child.Attributes["crc"].Value.ToLowerInvariant().Trim() : ""),
- MD5 = (child.Attributes["md5"] != null ? child.Attributes["md5"].Value.ToLowerInvariant().Trim() : ""),
- SHA1 = (child.Attributes["sha1"] != null ? 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)
- {
- // Take care of hex-sized files
- long size = -1;
- if (data.Attributes["size"] != null && data.Attributes["size"].Value.Contains("0x"))
- {
- size = Convert.ToInt64(data.Attributes["size"].Value, 16);
- }
- else if (data.Attributes["size"] != null)
- {
- Int64.TryParse(data.Attributes["size"].Value, out size);
- }
-
- roms.Add(new RomData
- {
- Game = tempname,
- Name = data.Attributes["name"].Value,
- Type = data.Name,
- SystemID = sysid,
- SourceID = srcid,
- Size = size,
- CRC = (data.Attributes["crc"] != null ? data.Attributes["crc"].Value.ToLowerInvariant().Trim() : ""),
- MD5 = (data.Attributes["md5"] != null ? data.Attributes["md5"].Value.ToLowerInvariant().Trim() : ""),
- SHA1 = (data.Attributes["sha1"] != null ? data.Attributes["sha1"].Value.ToLowerInvariant().Trim() : ""),
- });
- }
- }
- }
- }
- }
- }
- }
- }
- node = node.NextSibling;
- }
-
- return roms;
- }
-
- ///
- /// Parse a DAT and return all found games and roms within
- ///
- /// Name of the file to be parsed
- /// System ID for the DAT
- /// Source ID for the DAT
- /// Logger object for console and/or file output
- /// List of RomData objects representing the found data
- public static List Parse2(string filename, int sysid, int srcid, Logger logger)
{
List roms = new List();
XmlTextReader xtr = GetXmlTextReader(filename, logger);
xtr.WhitespaceHandling = WhitespaceHandling.None;
- bool superdat = false;
+ bool superdat = false, shouldbreak = false;
string parent = "";
if (xtr != null)
{
xtr.MoveToContent();
- while (true)
+ while (xtr.NodeType != XmlNodeType.None)
{
- // If we're at the end element, break
- if (xtr.NodeType == XmlNodeType.EndElement && xtr.Name == parent)
- {
- break;
- }
-
// We only want elements
- if (xtr.NodeType != XmlNodeType.Element && xtr.NodeType != XmlNodeType.Text)
+ if (xtr.NodeType != XmlNodeType.Element)
{
xtr.Read();
continue;
}
- Console.WriteLine(xtr.Name + " " + xtr.NodeType);
-
- if (xtr.Name == "datafile" || xtr.Name == "softwarelist")
+ switch (xtr.Name)
{
- parent = xtr.Name;
- xtr.Read();
- }
- else if (xtr.Name == "header")
- {
- xtr.ReadToDescendant("name");
- superdat = (xtr.ReadElementContentAsString() != null ? xtr.ReadElementContentAsString().Contains(" - SuperDAT") : false);
- }
- else if (xtr.Name == "machine" || xtr.Name == "game" || xtr.Name == "software")
- {
- string temptype = xtr.Name;
- string tempname = "";
- if (temptype == "software")
- {
- xtr.ReadToDescendant("description");
- tempname = xtr.ReadElementContentAsString();
- }
- else
- {
- // There are rare cases where a malformed XML will not have the required attributes. We can only skip them.
- if (xtr.AttributeCount == 0)
+ case "datafile":
+ case "softwarelist":
+ parent = xtr.Name;
+ xtr.Read();
+ break;
+ case "header":
+ xtr.ReadToDescendant("name");
+ superdat = (xtr.ReadElementContentAsString() != null ? xtr.ReadElementContentAsString().Contains(" - SuperDAT") : false);
+ while (xtr.Name != "header")
{
- logger.Error("No attributes were found");
- xtr.ReadToNextSibling(xtr.Name);
- continue;
+ xtr.Read();
}
- tempname = xtr.GetAttribute("name");
- }
+ xtr.Read();
+ break;
+ case "machine":
+ case "game":
+ case "software":
+ string temptype = xtr.Name;
+ string tempname = "";
- if (superdat)
- {
- tempname = Regex.Match(tempname, @".*?\\(.*)").Groups[1].Value;
- }
+ // We want to process the entire subtree of the game
+ XmlReader subreader = xtr.ReadSubtree();
- // Get the roms from the machine
- if (xtr.ReadInnerXml() != null && xtr.ReadInnerXml() != "")
- {
- while (!(xtr.Name == temptype && xtr.NodeType == XmlNodeType.EndElement))
+ if (subreader != null)
{
- // If we find a rom or disk, add it
- if (xtr.Name == "rom" || xtr.Name == "disk")
+ if (temptype == "software" && subreader.ReadToFollowing("description"))
{
- // Take care of hex-sized files
- long size = -1;
- if (xtr.GetAttribute("size") != null && xtr.GetAttribute("size").Contains("0x"))
- {
- size = Convert.ToInt64(xtr.GetAttribute("size"), 16);
- }
- else if (xtr.GetAttribute("size") != null)
- {
- Int64.TryParse(xtr.GetAttribute("size"), out size);
- }
-
- roms.Add(new RomData
- {
- Game = tempname,
- Name = xtr.GetAttribute("name"),
- Type = xtr.Name,
- SystemID = sysid,
- SourceID = srcid,
- Size = size,
- CRC = (xtr.GetAttribute("crc") != null ? xtr.GetAttribute("crc").ToLowerInvariant().Trim() : ""),
- MD5 = (xtr.GetAttribute("md5") != null ? xtr.GetAttribute("md5").ToLowerInvariant().Trim() : ""),
- SHA1 = (xtr.GetAttribute("sha1") != null ? xtr.GetAttribute("sha1").ToLowerInvariant().Trim() : ""),
- });
-
- xtr.Read();
-
- // If we hit end of file, break
- if (xtr.EOF)
- {
- break;
- }
- }
- // If we find the signs of a software list, traverse the children
- else if (xtr.NodeType == XmlNodeType.Element && xtr.Name == "part" && xtr.ReadInnerXml() != null && xtr.ReadInnerXml() != "")
- {
- while (!(xtr.Name == "part" && xtr.NodeType == XmlNodeType.EndElement))
- {
- // If we find a dataarea, traverse the children
- if (xtr.NodeType == XmlNodeType.Element && xtr.Name == "dataarea")
- {
- while (!(xtr.Name == "dataarea" && xtr.NodeType == XmlNodeType.EndElement))
- {
- // If we find a rom or disk, add it
- if ((xtr.Name == "rom" || xtr.Name == "disk") && xtr.GetAttribute("name") != null)
- {
- // Take care of hex-sized files
- long size = -1;
- if (xtr.GetAttribute("size") != null && xtr.GetAttribute("size").Contains("0x"))
- {
- size = Convert.ToInt64(xtr.GetAttribute("size"), 16);
- }
- else if (xtr.GetAttribute("size") != null)
- {
- Int64.TryParse(xtr.GetAttribute("size"), out size);
- }
-
- roms.Add(new RomData
- {
- Game = tempname,
- Name = xtr.GetAttribute("name"),
- Type = xtr.Name,
- SystemID = sysid,
- SourceID = srcid,
- Size = size,
- CRC = (xtr.GetAttribute("crc") != null ? xtr.GetAttribute("crc").ToLowerInvariant().Trim() : ""),
- MD5 = (xtr.GetAttribute("md5") != null ? xtr.GetAttribute("md5").ToLowerInvariant().Trim() : ""),
- SHA1 = (xtr.GetAttribute("sha1") != null ? xtr.GetAttribute("sha1").ToLowerInvariant().Trim() : ""),
- });
- }
-
- xtr.Read();
-
- // If we hit end of file, break
- if (xtr.EOF)
- {
- break;
- }
- }
- }
-
- xtr.Read();
-
- // If we hit end of file, break
- if (xtr.EOF)
- {
- break;
- }
- }
+ tempname = subreader.ReadElementContentAsString();
}
else
{
- xtr.Read();
+ // There are rare cases where a malformed XML will not have the required attributes. We can only skip them.
+ if (xtr.AttributeCount == 0)
+ {
+ logger.Error("No attributes were found");
+ xtr.ReadToNextSibling(xtr.Name);
+ continue;
+ }
+ tempname = xtr.GetAttribute("name");
+ }
+
+ if (superdat)
+ {
+ tempname = Regex.Match(tempname, @".*?\\(.*)").Groups[1].Value;
+ }
+
+ while (subreader.Read())
+ {
+ // We only want elements
+ if (subreader.NodeType != XmlNodeType.Element)
+ {
+ continue;
+ }
+
+ // Get the roms from the machine
+ switch (subreader.Name)
+ {
+ case "rom":
+ case "disk":
+ // Take care of hex-sized files
+ long size = -1;
+ if (xtr.GetAttribute("size") != null && xtr.GetAttribute("size").Contains("0x"))
+ {
+ size = Convert.ToInt64(xtr.GetAttribute("size"), 16);
+ }
+ else if (xtr.GetAttribute("size") != null)
+ {
+ Int64.TryParse(xtr.GetAttribute("size"), out size);
+ }
+
+ roms.Add(new RomData
+ {
+ Game = tempname,
+ Name = xtr.GetAttribute("name"),
+ Type = xtr.Name,
+ SystemID = sysid,
+ SourceID = srcid,
+ Size = size,
+ CRC = (xtr.GetAttribute("crc") != null ? xtr.GetAttribute("crc").ToLowerInvariant().Trim() : ""),
+ MD5 = (xtr.GetAttribute("md5") != null ? xtr.GetAttribute("md5").ToLowerInvariant().Trim() : ""),
+ SHA1 = (xtr.GetAttribute("sha1") != null ? xtr.GetAttribute("sha1").ToLowerInvariant().Trim() : ""),
+ });
+ break;
+ }
}
}
- }
- xtr.ReadToNextSibling(temptype);
- }
- else
- {
- xtr.Read();
+
+ // Read to next game
+ if (!xtr.ReadToNextSibling(temptype))
+ {
+ shouldbreak = true;
+ }
+ break;
+ default:
+ xtr.Read();
+ break;
}
- // If we hit end of file, break
- if (xtr.EOF)
- {
- break;
- }
- // If we're at the end element, break
- if (xtr.NodeType == XmlNodeType.EndElement && xtr.Name == parent)
+ // If we hit an endpoint, break out of the loop early
+ if (shouldbreak)
{
break;
}
}
}
- logger.Log("Outputting roms");
-
return roms;
}
- }
///
/// Merge an arbitrary set of ROMs based on the supplied information