diff --git a/SabreTools.Helper/Objects/Dat/DatFile.cs b/SabreTools.Helper/Objects/Dat/DatFile.cs
index 031f9c3e..869234c5 100644
--- a/SabreTools.Helper/Objects/Dat/DatFile.cs
+++ b/SabreTools.Helper/Objects/Dat/DatFile.cs
@@ -1221,7 +1221,6 @@ namespace SabreTools.Helper
case OutputFormat.OfflineList:
case OutputFormat.SabreDat:
case OutputFormat.SoftwareList:
- case OutputFormat.Xml:
ParseXML(filename, sysid, srcid, gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, itemStatus, trim, single, root, logger, keep, clean, softlist);
break;
case OutputFormat.RedumpMD5:
@@ -1236,6 +1235,9 @@ namespace SabreTools.Helper
case OutputFormat.RomCenter:
ParseRC(filename, sysid, srcid, gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, itemStatus, trim, single, root, logger, clean);
break;
+ case OutputFormat.Xml:
+ ParseXMLString(filename, sysid, srcid, gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, itemStatus, trim, single, root, logger, keep, clean, softlist);
+ break;
default:
return;
}
@@ -3085,851 +3087,6 @@ namespace SabreTools.Helper
xtr.Dispose();
}
- ///
- /// Parse an XML DAT (Logiqx, OfflineList, SabreDAT, and Software List) 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
- /// Name of the game to match (can use asterisk-partials)
- /// Name of the rom to match (can use asterisk-partials)
- /// Type of the rom to match
- /// Find roms greater than or equal to this size
- /// Find roms less than or equal to this size
- /// Find roms equal to this size
- /// CRC of the rom to match (can use asterisk-partials)
- /// MD5 of the rom to match (can use asterisk-partials)
- /// SHA-1 of the rom to match (can use asterisk-partials)
- /// Select roms with the given status
- /// True if we are supposed to trim names to NTFS length, false otherwise
- /// True if all games should be replaced by '!', false otherwise
- /// String representing root directory to compare against for length calculation
- /// Logger object for console and/or file output
- /// True if full pathnames are to be kept, false otherwise (default)
- /// True if game names are sanitized, false otherwise (default)
- /// True if SL XML names should be kept, false otherwise (default)
- private void ParseXMLLinq(
- // Standard Dat parsing
- string filename,
- int sysid,
- int srcid,
-
- // Rom filtering
- string gamename,
- string romname,
- string romtype,
- long sgt,
- long slt,
- long seq,
- string crc,
- string md5,
- string sha1,
- ItemStatus itemStatus,
-
- // Rom renaming
- bool trim,
- bool single,
- string root,
-
- // Miscellaneous
- Logger logger,
- bool keep,
- bool clean,
- bool softlist)
-
- {
- // Prepare all internal variables
- bool superdat = false, empty = true;
- string key = "", date = "";
- long size = -1;
- ItemStatus its = ItemStatus.None;
- List parent = new List();
-
- Encoding enc = Style.GetEncoding(filename);
- XElement xtr = XElement.Load(FileTools.GetXmlTextReader(filename, logger), LoadOptions.None);
-
- // If we got a null reader, just return
- if (xtr == null)
- {
- return;
- }
-
- // Otherwise, read the file to the end
- foreach (XElement node in xtr.Nodes())
- {
- // If we're ending a folder or game, take care of possibly empty games and removing from the parent
- if (node.NodeType == XmlNodeType.EndElement && (node.Name == "directory" || node.Name == "dir"))
- {
- // If we didn't find any items in the folder, make sure to add the blank rom
- if (empty)
- {
- string tempgame = String.Join("\\", parent);
- Rom rom = new Rom("null", tempgame);
-
- // Now process and add the rom
- ParseAddHelper(rom, gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, itemStatus, trim, single, root, clean, logger, out key);
- }
-
- // Regardless, end the current folder
- int parentcount = parent.Count;
- if (parentcount == 0)
- {
- logger.Verbose("Empty parent: " + String.Join("\\", parent));
- empty = true;
- }
-
- // If we have an end folder element, remove one item from the parent, if possible
- if (parentcount > 0)
- {
- parent.RemoveAt(parent.Count - 1);
- if (keep && parentcount > 1)
- {
- Type = (String.IsNullOrEmpty(Type) ? "SuperDAT" : Type);
- superdat = true;
- }
- }
- }
-
- // We only want elements
- if (node.NodeType != XmlNodeType.Element)
- {
- continue;
- }
-
- switch (node.Name.ToString())
- {
- // Handle MAME listxml since they're halfway between a SL and a Logiqx XML
- case "mame":
- if (node.Attribute("build") != null)
- {
- Name = (String.IsNullOrEmpty(Name) ? node.Attribute("build").ToString() : Name);
- Description = (String.IsNullOrEmpty(Description) ? Name : Name);
- }
- break;
- // New software lists have this behavior
- case "softwarelist":
- if (node.Attribute("name") != null)
- {
- Name = (String.IsNullOrEmpty(Name) ? node.Attribute("name").ToString() : Name);
- }
- if (node.Attribute("description") != null)
- {
- Description = (String.IsNullOrEmpty(Description) ? node.Attribute("description").ToString() : Description);
- }
- if (node.Attribute("forcemerging") != null)
- {
- switch (node.Attribute("forcemerging").ToString())
- {
- case "split":
- ForceMerging = ForceMerging.Split;
- break;
- case "none":
- ForceMerging = ForceMerging.None;
- break;
- case "full":
- ForceMerging = ForceMerging.Full;
- break;
- }
- }
- if (node.Attribute("forceitemStatus") != null)
- {
- switch (node.Attribute("forceitemStatus").ToString())
- {
- case "obsolete":
- ForceNodump = ForceNodump.Obsolete;
- break;
- case "required":
- ForceNodump = ForceNodump.Required;
- break;
- case "ignore":
- ForceNodump = ForceNodump.Ignore;
- break;
- }
- }
- if (node.Attribute("forcepacking") != null)
- {
- switch (node.Attribute("forcepacking").ToString())
- {
- case "zip":
- ForcePacking = ForcePacking.Zip;
- break;
- case "unzip":
- ForcePacking = ForcePacking.Unzip;
- break;
- }
- }
- break;
- // Handle M1 DATs since they're 99% the same as a SL DAT
- case "m1":
- Name = (String.IsNullOrEmpty(Name) ? "M1" : Name);
- Description = (String.IsNullOrEmpty(Description) ? "M1" : Description);
- if (node.Attribute("version") != null)
- {
- Version = (String.IsNullOrEmpty(Version) ? node.Attribute("version").ToString() : Version);
- }
- break;
- // OfflineList has a different header format
- case "configuration":
- // If there's no subtree to the header, skip it
- if (!node.HasElements)
- {
- continue;
- }
-
- // Otherwise, read what we can from the header
- foreach (XElement headnode in node.Elements())
- {
- // We only want elements
- if (headnode.NodeType != XmlNodeType.Element || headnode.Name == "configuration")
- {
- continue;
- }
-
- // Get all header items (ONLY OVERWRITE IF THERE'S NO DATA)
- string content = "";
- switch (headnode.Name.ToString().ToLowerInvariant())
- {
- case "datname":
- content = headnode.Value;
- Name = (String.IsNullOrEmpty(Name) ? content : Name);
- superdat = superdat || content.Contains(" - SuperDAT");
- if (keep && superdat)
- {
- Type = (String.IsNullOrEmpty(Type) ? "SuperDAT" : Type);
- }
- break;
- case "datversionurl":
- content = headnode.Value;
- Url = (String.IsNullOrEmpty(Name) ? content : Url);
- break;
- default:
- break;
- }
- }
-
- break;
- // We want to process the entire subtree of the header
- case "header":
- // If there's no subtree to the header, skip it
- if (!node.HasElements)
- {
- continue;
- }
-
- // Otherwise, read what we can from the header
- foreach (XElement headnode in node.Elements())
- {
- // We only want elements
- if (headnode.NodeType != XmlNodeType.Element || headnode.Name == "header")
- {
- continue;
- }
-
- // Get all header items (ONLY OVERWRITE IF THERE'S NO DATA)
- string content = "";
- switch (headnode.Name.ToString())
- {
- case "name":
- content = headnode.Value;
- Name = (String.IsNullOrEmpty(Name) ? content : Name);
- superdat = superdat || content.Contains(" - SuperDAT");
- if (keep && superdat)
- {
- Type = (String.IsNullOrEmpty(Type) ? "SuperDAT" : Type);
- }
- break;
- case "description":
- content = headnode.Value;
- Description = (String.IsNullOrEmpty(Description) ? content : Description);
- break;
- case "rootdir":
- content = headnode.Value;
- RootDir = (String.IsNullOrEmpty(RootDir) ? content : RootDir);
- break;
- case "category":
- content = headnode.Value;
- Category = (String.IsNullOrEmpty(Category) ? content : Category);
- break;
- case "version":
- content = headnode.Value;
- Version = (String.IsNullOrEmpty(Version) ? content : Version);
- break;
- case "date":
- content = headnode.Value;
- Date = (String.IsNullOrEmpty(Date) ? content.Replace(".", "/") : Date);
- break;
- case "author":
- content = headnode.Value;
- Author = (String.IsNullOrEmpty(Author) ? content : Author);
-
- // Special cases for SabreDAT
- Email = (String.IsNullOrEmpty(Email) && headnode.Attribute("email") != null ?
- headnode.Attribute("email").ToString() : Email);
- Homepage = (String.IsNullOrEmpty(Homepage) && headnode.Attribute("homepage") != null ?
- headnode.Attribute("homepage").ToString() : Email);
- Url = (String.IsNullOrEmpty(Url) && headnode.Attribute("url") != null ?
- headnode.Attribute("url").ToString() : Email);
- break;
- case "email":
- content = headnode.Value;
- Email = (String.IsNullOrEmpty(Email) ? content : Email);
- break;
- case "homepage":
- content = headnode.Value;
- Homepage = (String.IsNullOrEmpty(Homepage) ? content : Homepage);
- break;
- case "url":
- content = headnode.Value;
- Url = (String.IsNullOrEmpty(Url) ? content : Url);
- break;
- case "comment":
- content = headnode.Value;
- Comment = (String.IsNullOrEmpty(Comment) ? content : Comment);
- break;
- case "type":
- content = headnode.Value;
- Type = (String.IsNullOrEmpty(Type) ? content : Type);
- superdat = superdat || content.Contains("SuperDAT");
- break;
- case "clrmamepro":
- case "romcenter":
- if (headnode.Attribute("header") != null)
- {
- Header = (String.IsNullOrEmpty(Header) ? headnode.Attribute("header").ToString() : Header);
- }
- if (headnode.Attribute("plugin") != null)
- {
- Header = (String.IsNullOrEmpty(Header) ? headnode.Attribute("plugin").ToString() : Header);
- }
- if (headnode.Attribute("forcemerging") != null)
- {
- switch (headnode.Attribute("forcemerging").ToString())
- {
- case "split":
- ForceMerging = ForceMerging.Split;
- break;
- case "none":
- ForceMerging = ForceMerging.None;
- break;
- case "full":
- ForceMerging = ForceMerging.Full;
- break;
- }
- }
- if (headnode.Attribute("forceitemStatus") != null)
- {
- switch (headnode.Attribute("forceitemStatus").ToString())
- {
- case "obsolete":
- ForceNodump = ForceNodump.Obsolete;
- break;
- case "required":
- ForceNodump = ForceNodump.Required;
- break;
- case "ignore":
- ForceNodump = ForceNodump.Ignore;
- break;
- }
- }
- if (headnode.Attribute("forcepacking") != null)
- {
- switch (headnode.Attribute("forcepacking").ToString())
- {
- case "zip":
- ForcePacking = ForcePacking.Zip;
- break;
- case "unzip":
- ForcePacking = ForcePacking.Unzip;
- break;
- }
- }
- break;
- case "flags":
- // If there's no subtree to the flags, skip it
- if (!headnode.HasElements)
- {
- continue;
- }
-
- // Otherwise, read what we can from the flags
- foreach (XElement flagnode in node.Elements())
- {
- // We only want elements
- if (flagnode.NodeType != XmlNodeType.Element || flagnode.Name == "flags")
- {
- continue;
- }
-
- switch (flagnode.Name.ToString())
- {
- case "flag":
- if (flagnode.Attribute("name") != null && flagnode.Attribute("value") != null)
- {
- content = flagnode.Attribute("value").ToString();
- switch (flagnode.Attribute("name").ToString())
- {
- case "type":
- Type = (String.IsNullOrEmpty(Type) ? content : Type);
- superdat = superdat || content.Contains("SuperDAT");
- break;
- case "forcemerging":
- switch (content)
- {
- case "split":
- ForceMerging = ForceMerging.Split;
- break;
- case "none":
- ForceMerging = ForceMerging.None;
- break;
- case "full":
- ForceMerging = ForceMerging.Full;
- break;
- }
- break;
- case "forceitemStatus":
- switch (content)
- {
- case "obsolete":
- ForceNodump = ForceNodump.Obsolete;
- break;
- case "required":
- ForceNodump = ForceNodump.Required;
- break;
- case "ignore":
- ForceNodump = ForceNodump.Ignore;
- break;
- }
- break;
- case "forcepacking":
- switch (content)
- {
- case "zip":
- ForcePacking = ForcePacking.Zip;
- break;
- case "unzip":
- ForcePacking = ForcePacking.Unzip;
- break;
- }
- break;
- }
- }
- break;
- default:
- break;
- }
- }
- break;
- default:
- break;
- }
- }
- break;
- case "machine":
- case "game":
- case "software":
- string temptype = node.Name.ToString();
- string tempname = "", gamedesc = "", romof = "",
- cloneof = "", sampleof = "", year = "", manufacturer = "";
-
- // If there's no subtree to the header, skip it
- if (!node.HasElements)
- {
- continue;
- }
-
- // Otherwise, add what is possible
- if (!softlist && temptype == "software" && node.Element("description") != null)
- {
- tempname = node.Element("description").Value;
- gamedesc = tempname;
- tempname = tempname.Replace('/', '_').Replace("\"", "''");
- }
- else
- {
- tempname = node.Attribute("name").ToString();
- romof = (node.Attribute("romof") != null ? node.Attribute("romof").ToString() : "");
- cloneof = (node.Attribute("cloneof") != null ? node.Attribute("cloneof").ToString() : "");
- sampleof = (node.Attribute("sampleof") != null ? node.Attribute("sampleof").ToString() : "");
- }
-
- if (superdat && !keep)
- {
- string tempout = Regex.Match(tempname, @".*?\\(.*)").Groups[1].Value;
- if (tempout != "")
- {
- tempname = tempout;
- }
- }
- // Get the name of the game from the parent
- else if (superdat && keep && parent.Count > 0)
- {
- tempname = String.Join("\\", parent) + "\\" + tempname;
- }
-
- // Special offline list parts
- string ext = "";
- string releaseNumber = "";
-
- // Now loop through the rest of the child nodes
- foreach (XElement gamenode in node.Elements())
- {
- // We only want elements
- if (gamenode.NodeType != XmlNodeType.Element)
- {
- continue;
- }
-
- // Get the roms from the machine
- switch (gamenode.Name.ToString())
- {
- // For offline lists only
- case "title":
- tempname = gamenode.Value;
- break;
- case "releaseNumber":
- releaseNumber = gamenode.Value;
- break;
- case "romSize":
- if (!Int64.TryParse(gamenode.Value, out size))
- {
- size = -1;
- }
- break;
- case "romCRC":
- empty = false;
-
- ext = (gamenode.Attribute("extension") != null ? gamenode.Attribute("extension").ToString() : "");
-
- DatItem olrom = new Rom(releaseNumber + " - " + tempname + ext, size, gamenode.Value, null, null, ItemStatus.None,
- null, tempname, null, tempname, null, null, null, null, null, null, false, null, null, sysid, null, srcid, "");
-
- // Now process and add the rom
- ParseAddHelper(olrom, gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, itemStatus, trim, single, root, clean, logger, out key);
- break;
-
- // For Logiqx, SabreDAT, and Software List
- case "description":
- gamedesc = gamenode.Value;
- break;
- case "year":
- year = gamenode.Value;
- break;
- case "manufacturer":
- manufacturer = gamenode.Value;
- break;
- case "release":
- empty = false;
-
- bool? defaultrel = null;
- if (gamenode.Attribute("default") != null)
- {
- if (gamenode.Attribute("default").ToString() == "yes")
- {
- defaultrel = true;
- }
- else if (gamenode.Attribute("default").ToString() == "no")
- {
- defaultrel = false;
- }
- }
-
- DatItem relrom = new Release(gamenode.Attribute("name").ToString(),
- gamenode.Attribute("region").ToString(), gamenode.Attribute("language").ToString(), date, defaultrel);
-
- // Now process and add the rom
- ParseAddHelper(relrom, gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, itemStatus, trim, single, root, clean, logger, out key);
- break;
- case "biosset":
- empty = false;
-
- bool? defaultbios = null;
- if (gamenode.Attribute("default") != null)
- {
- if (gamenode.Attribute("default").ToString() == "yes")
- {
- defaultbios = true;
- }
- else if (gamenode.Attribute("default").ToString() == "no")
- {
- defaultbios = false;
- }
- }
-
- DatItem biosrom = new BiosSet(gamenode.Attribute("name").ToString(), gamenode.Attribute("description").ToString(), defaultbios,
- tempname, null, gamedesc, null, null, romof, cloneof, sampleof, null, false, null, null, sysid, filename, srcid, null);
-
- // Now process and add the rom
- ParseAddHelper(biosrom, gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, itemStatus, trim, single, root, clean, logger, out key);
- break;
- case "archive":
- empty = false;
-
- DatItem archiverom = new Archive(gamenode.Attribute("name").ToString(), tempname, null, gamedesc, null, null,
- romof, cloneof, sampleof, null, false, null, null, sysid, filename, srcid, null);
-
- // Now process and add the rom
- ParseAddHelper(archiverom, gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, itemStatus, trim, single, root, clean, logger, out key);
- break;
- case "sample":
- empty = false;
-
- DatItem samplerom = new Sample(gamenode.Attribute("name").ToString(), tempname, null, gamedesc, null, null,
- romof, cloneof, sampleof, null, false, null, null, sysid, filename, srcid, null);
-
- // Now process and add the rom
- ParseAddHelper(samplerom, gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, itemStatus, trim, single, root, clean, logger, out key);
- break;
- case "rom":
- case "disk":
- empty = false;
-
- // If the rom has a status, flag it
- its = ItemStatus.None;
- if (gamenode.Attribute("flags").ToString() == "good" || gamenode.Attribute("status").ToString() == "good")
- {
- its = ItemStatus.Good;
- }
- if (gamenode.Attribute("flags").ToString() == "baddump" || gamenode.Attribute("status").ToString() == "baddump")
- {
- logger.Verbose("Bad dump detected: " +
- (gamenode.Attribute("name") != null ? "\"" + node.Attribute("name") + "\"" : "ROM NAME NOT FOUND"));
- its = ItemStatus.BadDump;
- }
- if (gamenode.Attribute("flags").ToString() == "itemStatus" || gamenode.Attribute("status").ToString() == "itemStatus")
- {
- logger.Verbose("Nodump detected: " +
- (gamenode.Attribute("name") != null ? "\"" + node.Attribute("name") + "\"" : "ROM NAME NOT FOUND"));
- its = ItemStatus.Nodump;
- }
- if (gamenode.Attribute("flags").ToString() == "verified" || gamenode.Attribute("status").ToString() == "verified")
- {
- its = ItemStatus.Verified;
- }
-
- // If the rom has a Date attached, read it in and then sanitize it
- date = "";
- if (gamenode.Attribute("date") != null)
- {
- DateTime dateTime = DateTime.Now;
- if (DateTime.TryParse(gamenode.Attribute("date").ToString(), out dateTime))
- {
- date = dateTime.ToString();
- }
- else
- {
- date = gamenode.Attribute("date").ToString();
- }
- }
-
- // Take care of hex-sized files
- size = -1;
- if (gamenode.Attribute("size") != null && gamenode.Attribute("size").ToString().Contains("0x"))
- {
- size = Convert.ToInt64(gamenode.Attribute("size").ToString(), 16);
- }
- else if (gamenode.Attribute("size") != null)
- {
- Int64.TryParse(gamenode.Attribute("size").ToString(), out size);
- }
-
- // If the rom is continue or ignore, add the size to the previous rom
- if (gamenode.Attribute("loadflag").ToString() == "continue" || gamenode.Attribute("loadflag").ToString() == "ignore")
- {
- int index = Files[key].Count() - 1;
- DatItem lastrom = Files[key][index];
- if (lastrom.Type == ItemType.Rom)
- {
- ((Rom)lastrom).Size += size;
- }
- Files[key].RemoveAt(index);
- Files[key].Add(lastrom);
- continue;
- }
-
- // If we're in clean mode, sanitize the game name
- if (clean)
- {
- tempname = Style.CleanGameName(tempname.Split(Path.DirectorySeparatorChar));
- }
-
- DatItem inrom;
- switch (gamenode.Name.ToString().ToLowerInvariant())
- {
- case "disk":
- inrom = new Disk(gamenode.Attribute("name").ToString(), gamenode.Attribute("md5").ToString(), gamenode.Attribute("sha1").ToString(),
- its, tempname, null, gamedesc, null, null, romof, cloneof, sampleof, null, false, null, null, sysid,
- filename, srcid, null);
- break;
- case "rom":
- default:
- inrom = new Rom(gamenode.Attribute("name").ToString(), size, gamenode.Attribute("crc").ToString(), gamenode.Attribute("md5").ToString(),
- gamenode.Attribute("sha1").ToString(), its, date, tempname, null, gamedesc, null, null, romof, cloneof, sampleof,
- null, false, null, null, sysid, filename, srcid, null);
- break;
- }
-
- // Now process and add the rom
- ParseAddHelper(inrom, gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, itemStatus, trim, single, root, clean, logger, out key);
- break;
- default:
- break;
- }
- }
-
- // If we didn't find any items in the folder, make sure to add the blank rom
- if (empty)
- {
- tempname = (parent.Count > 0 ? String.Join("\\", parent) + Path.DirectorySeparatorChar : "") + tempname;
-
- Rom inrom = new Rom("null", tempname);
-
- // Now process and add the rom
- ParseAddHelper(inrom, gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, itemStatus, trim, single, root, clean, logger, out key);
-
- // Regardless, end the current folder
- if (parent.Count == 0)
- {
- empty = true;
- }
- }
- break;
- case "dir":
- case "directory":
- // Set SuperDAT flag for all SabreDAT inputs, regardless of depth
- superdat = true;
- if (keep)
- {
- Type = (Type == "" ? "SuperDAT" : Type);
- }
-
- string foldername = (node.Attribute("name") == null ? "" : node.Attribute("name").ToString());
- if (foldername != "")
- {
- parent.Add(foldername);
- }
- break;
- case "file":
- empty = false;
-
- // If the rom is itemStatus, flag it
- its = ItemStatus.None;
- // If there's no subtree to the flags, skip it
- if (!node.HasElements)
- {
- continue;
- }
-
- // Otherwise, read what we can from the flags
- foreach (XElement flagnode in node.Elements())
- {
- // We only want elements
- if (flagnode.NodeType != XmlNodeType.Element || flagnode.Name == "flags")
- {
- continue;
- }
-
- switch (flagnode.Name.ToString())
- {
- case "flag":
- case "status":
- if (flagnode.Attribute("name") != null && flagnode.Attribute("value") != null)
- {
- string content = flagnode.Attribute("value").ToString();
- switch (flagnode.Attribute("name").ToString())
- {
- case "good":
- its = ItemStatus.Good;
- break;
- case "baddump":
- logger.Verbose("Bad dump detected: " + (node.Attribute("name") != null ?
- "\"" + node.Attribute("name") + "\"" : "ROM NAME NOT FOUND"));
- its = ItemStatus.BadDump;
- break;
- case "itemStatus":
- logger.Verbose("Nodump detected: " + (node.Attribute("name") != null ?
- "\"" + node.Attribute("name") + "\"" : "ROM NAME NOT FOUND"));
- its = ItemStatus.Nodump;
- break;
- case "verified":
- its = ItemStatus.Verified;
- break;
- }
- }
- break;
- }
- }
-
- // If the rom has a Date attached, read it in and then sanitize it
- date = "";
- if (node.Attribute("date") != null)
- {
- date = DateTime.Parse(node.Attribute("date").ToString()).ToString();
- }
-
- // Take care of hex-sized files
- size = -1;
- if (node.Attribute("size") != null && node.Attribute("size").ToString().Contains("0x"))
- {
- size = Convert.ToInt64(node.Attribute("size").ToString(), 16);
- }
- else if (node.Attribute("size") != null)
- {
- Int64.TryParse(node.Attribute("size").ToString(), out size);
- }
-
- // If the rom is continue or ignore, add the size to the previous rom
- if (node.Attribute("loadflag").ToString() == "continue" || node.Attribute("loadflag").ToString() == "ignore")
- {
- int index = Files[key].Count() - 1;
- DatItem lastrom = Files[key][index];
- if (lastrom.Type == ItemType.Rom)
- {
- ((Rom)lastrom).Size += size;
- }
- Files[key].RemoveAt(index);
- Files[key].Add(lastrom);
- continue;
- }
-
- // Get the name of the game from the parent
- tempname = String.Join("\\", parent);
-
- // If we aren't keeping names, trim out the path
- if (!keep || !superdat)
- {
- string tempout = Regex.Match(tempname, @".*?\\(.*)").Groups[1].Value;
- if (tempout != "")
- {
- tempname = tempout;
- }
- }
-
- DatItem rom;
- switch (node.Attribute("type").ToString().ToLowerInvariant())
- {
- case "disk":
- rom = new Disk(node.Attribute("name").ToString(), node.Attribute("md5")?.ToString().ToLowerInvariant(),
- node.Attribute("sha1")?.ToString().ToLowerInvariant(), its, tempname, null, tempname, null, null,
- null, null, null, null, false, null, null, sysid, filename, srcid, null);
- break;
- case "rom":
- default:
- rom = new Rom(node.Attribute("name").ToString(), size, node.Attribute("crc")?.ToString().ToLowerInvariant(),
- node.Attribute("md5")?.ToString().ToLowerInvariant(), node.Attribute("sha1")?.ToString().ToLowerInvariant(), its,
- date, tempname, null, tempname, null, null, null, null, null, null, false, null, null, sysid, filename,
- srcid, null);
- break;
- }
-
- // Now process and add the rom
- ParseAddHelper(rom, gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, itemStatus, trim, single, root, clean, logger, out key);
- break;
- default:
- break;
- }
- }
- }
-
///
/// Parse an XML DAT (Logiqx, OfflineList, SabreDAT, and Software List) and return all found games and roms within
///
@@ -4099,18 +3256,18 @@ namespace SabreTools.Helper
matched = Regex.Match(line, Constants.XmlPattern).Groups;
// Get all header items (ONLY OVERWRITE IF THERE'S NO DATA)
- if (matched[0].Value.ToLowerInvariant().StartsWith("datname"))
+ if (matched[1].Value.ToLowerInvariant().StartsWith("datname"))
{
- Name = (String.IsNullOrEmpty(Name) ? matched[1].Value : Name);
+ Name = (String.IsNullOrEmpty(Name) ? matched[2].Value : Name);
superdat = superdat || Name.Contains(" - SuperDAT");
if (keep && superdat)
{
Type = (String.IsNullOrEmpty(Type) ? "SuperDAT" : Type);
}
}
- else if (matched[0].Value.ToLowerInvariant().StartsWith("datversionurl"))
+ else if (matched[1].Value.ToLowerInvariant().StartsWith("datversionurl"))
{
- Url = (String.IsNullOrEmpty(Name) ? matched[1].Value : Url);
+ Url = (String.IsNullOrEmpty(Name) ? matched[2].Value : Url);
break;
}
}
@@ -4127,41 +3284,41 @@ namespace SabreTools.Helper
matched = Regex.Match(line, Constants.XmlPattern).Groups;
// Now check for all of the header items
- if (matched[0].Value.StartsWith("name"))
+ if (matched[1].Value.StartsWith("name"))
{
- Name = (String.IsNullOrEmpty(Name) ? matched[1].Value : Name);
+ Name = (String.IsNullOrEmpty(Name) ? matched[2].Value : Name);
superdat = superdat || Name.Contains(" - SuperDAT");
if (keep && superdat)
{
Type = (String.IsNullOrEmpty(Type) ? "SuperDAT" : Type);
}
}
- else if (matched[0].Value.StartsWith("description"))
+ else if (matched[1].Value.StartsWith("description"))
{
- Description = (String.IsNullOrEmpty(Description) ? matched[1].Value : Description);
+ Description = (String.IsNullOrEmpty(Description) ? matched[2].Value : Description);
}
- else if (matched[0].Value.StartsWith("rootdir"))
+ else if (matched[1].Value.StartsWith("rootdir"))
{
- RootDir = (String.IsNullOrEmpty(RootDir) ? matched[1].Value : RootDir);
+ RootDir = (String.IsNullOrEmpty(RootDir) ? matched[2].Value : RootDir);
}
- else if (matched[0].Value.StartsWith("category"))
+ else if (matched[1].Value.StartsWith("category"))
{
- Category = (String.IsNullOrEmpty(Category) ? matched[1].Value : Category);
+ Category = (String.IsNullOrEmpty(Category) ? matched[2].Value : Category);
}
- else if (matched[0].Value.StartsWith("version"))
+ else if (matched[1].Value.StartsWith("version"))
{
- Version = (String.IsNullOrEmpty(Version) ? matched[1].Value : Version);
+ Version = (String.IsNullOrEmpty(Version) ? matched[2].Value : Version);
}
- else if (matched[0].Value.StartsWith("date"))
+ else if (matched[1].Value.StartsWith("date"))
{
- Date = (String.IsNullOrEmpty(Date) ? matched[1].Value : Date);
+ Date = (String.IsNullOrEmpty(Date) ? matched[2].Value : Date);
}
- else if (matched[0].Value.StartsWith("author"))
+ else if (matched[1].Value.StartsWith("author"))
{
- Author = (String.IsNullOrEmpty(Author) ? matched[1].Value : Author);
+ Author = (String.IsNullOrEmpty(Author) ? matched[2].Value : Author);
// Special cases for SabreDAT
- Dictionary attribs = GetAttributes(matched[0].Value);
+ Dictionary attribs = GetAttributes(matched[1].Value);
if (attribs.ContainsKey("email"))
{
Email = (String.IsNullOrEmpty(Email) ? attribs["email"] : Email);
@@ -4175,31 +3332,31 @@ namespace SabreTools.Helper
Url = (String.IsNullOrEmpty(Url) ? attribs["url"] : Url);
}
}
- else if (matched[0].Value.StartsWith("email"))
+ else if (matched[1].Value.StartsWith("email"))
{
- Email = (String.IsNullOrEmpty(Date) ? matched[1].Value : Email);
+ Email = (String.IsNullOrEmpty(Date) ? matched[2].Value : Email);
}
- else if (matched[0].Value.StartsWith("homepage"))
+ else if (matched[1].Value.StartsWith("homepage"))
{
- Homepage = (String.IsNullOrEmpty(Homepage) ? matched[1].Value : Homepage);
+ Homepage = (String.IsNullOrEmpty(Homepage) ? matched[2].Value : Homepage);
}
- else if (matched[0].Value.StartsWith("url"))
+ else if (matched[1].Value.StartsWith("url"))
{
- Url = (String.IsNullOrEmpty(Url) ? matched[1].Value : Url);
+ Url = (String.IsNullOrEmpty(Url) ? matched[2].Value : Url);
}
- else if (matched[0].Value.StartsWith("comment"))
+ else if (matched[1].Value.StartsWith("comment"))
{
- Comment = (String.IsNullOrEmpty(Comment) ? matched[1].Value : Comment);
+ Comment = (String.IsNullOrEmpty(Comment) ? matched[2].Value : Comment);
}
- else if (matched[0].Value.StartsWith("type"))
+ else if (matched[1].Value.StartsWith("type"))
{
- Type = (String.IsNullOrEmpty(Type) ? matched[1].Value : Type);
- superdat = superdat || matched[1].Value.Contains("SuperDAT");
+ Type = (String.IsNullOrEmpty(Type) ? matched[2].Value : Type);
+ superdat = superdat || matched[2].Value.Contains("SuperDAT");
break;
}
- else if (matched[0].Value.StartsWith("clrmamepro") || matched[0].Value.StartsWith("romcenter"))
+ else if (matched[1].Value.StartsWith("clrmamepro") || matched[1].Value.StartsWith("romcenter"))
{
- Dictionary attribs = GetAttributes(matched[0].Value);
+ Dictionary attribs = GetAttributes(matched[1].Value);
if (attribs.ContainsKey("header"))
{
Header = (String.IsNullOrEmpty(Header) ? attribs["header"].ToString() : Header);
@@ -4267,7 +3424,7 @@ namespace SabreTools.Helper
{
case "type":
Type = (String.IsNullOrEmpty(Type) ? attribs["value"] : Type);
- superdat = superdat || matched[1].Value.Contains("SuperDAT");
+ superdat = superdat || matched[2].Value.Contains("SuperDAT");
break;
case "forcemerging":
switch (attribs["value"])
@@ -4317,13 +3474,13 @@ namespace SabreTools.Helper
}
// If the line is a game/machine
- if (matched[0].Value.StartsWith("game") || matched[0].Value.StartsWith("machine") || matched[0].Value.StartsWith("software"))
+ if (line.StartsWith(" gameattribs = GetAttributes(matched[0].Value);
+ Dictionary gameattribs = GetAttributes(line.Substring(1, line.Length - 3));
string tempname = (gameattribs.ContainsKey("name") ? gameattribs["name"] : "");
string sourcefile = (gameattribs.ContainsKey("sourcefile") ? gameattribs["sourcefile"] : "");
@@ -4353,21 +3510,21 @@ namespace SabreTools.Helper
matched = Regex.Match(line, Constants.XmlPattern).Groups;
// Standalone game values
- if (matched[0].Value.StartsWith("comment"))
+ if (matched[1].Value.StartsWith("comment"))
{
- comment = matched[1].Value;
+ comment = matched[2].Value;
}
- else if (matched[0].Value.StartsWith("description"))
+ else if (matched[1].Value.StartsWith("description"))
{
- gamedesc = matched[1].Value;
+ gamedesc = matched[2].Value;
}
- else if (matched[0].Value.StartsWith("year"))
+ else if (matched[1].Value.StartsWith("year"))
{
- year = matched[1].Value;
+ year = matched[2].Value;
}
- else if (matched[0].Value.StartsWith("manufacturer"))
+ else if (matched[1].Value.StartsWith("manufacturer"))
{
- manufacturer = matched[1].Value;
+ manufacturer = matched[2].Value;
}
// Now for the different file types
@@ -4729,6 +3886,17 @@ namespace SabreTools.Helper
}
}
}
+
+ // For directories, we handle them specially
+ else if (line.StartsWith("
+ /// Clean a rom name from invalid characters
+ ///
+ /// Name of the item to be cleaned
+ /// The cleaned name
+ public static string CleanRomName(string name)
+ {
+ return new string(name.Where(c => !char.IsControl(c)).ToArray());
+ }
+
///
/// Clean a game (or rom) name to the WoD standard
///