mirror of
https://github.com/claunia/SabreTools.git
synced 2025-12-16 19:14:27 +00:00
Use CMPReader in CMP and DC
This commit is contained in:
@@ -2,13 +2,13 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
using SabreTools.Library.Data;
|
using SabreTools.Library.Data;
|
||||||
using SabreTools.Library.DatItems;
|
using SabreTools.Library.DatItems;
|
||||||
using SabreTools.Library.Tools;
|
using SabreTools.Library.Tools;
|
||||||
using SabreTools.Library.Writers;
|
using SabreTools.Library.Writers;
|
||||||
using NaturalSort;
|
using NaturalSort;
|
||||||
|
using SabreTools.Library.Readers;
|
||||||
|
|
||||||
namespace SabreTools.Library.DatFiles
|
namespace SabreTools.Library.DatFiles
|
||||||
{
|
{
|
||||||
@@ -48,144 +48,148 @@ namespace SabreTools.Library.DatFiles
|
|||||||
{
|
{
|
||||||
// Open a file reader
|
// Open a file reader
|
||||||
Encoding enc = Utilities.GetEncoding(filename);
|
Encoding enc = Utilities.GetEncoding(filename);
|
||||||
StreamReader sr = new StreamReader(Utilities.TryOpenRead(filename), enc);
|
ClrMameProReader cmpr = new ClrMameProReader(Utilities.TryOpenRead(filename), enc);
|
||||||
|
cmpr.DosCenter = false;
|
||||||
|
|
||||||
while (!sr.EndOfStream)
|
while (!cmpr.EndOfStream)
|
||||||
{
|
{
|
||||||
string line = sr.ReadLine();
|
cmpr.ReadNextLine();
|
||||||
|
|
||||||
// Comments in CMP DATs start with a #
|
// Ignore everything not top-level
|
||||||
if (line.Trim().StartsWith("#"))
|
if (cmpr.RowType != CmpRowType.TopLevel)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// If the line is the header or a game
|
// Switch on the top-level name
|
||||||
if (Regex.IsMatch(line, Constants.HeaderPatternCMP))
|
switch (cmpr.TopLevel.ToLowerInvariant())
|
||||||
{
|
{
|
||||||
GroupCollection gc = Regex.Match(line, Constants.HeaderPatternCMP).Groups;
|
// Header values
|
||||||
string normalizedValue = gc[1].Value.ToLowerInvariant();
|
case "clrmamepro":
|
||||||
|
case "romvault":
|
||||||
|
ReadHeader(cmpr, keep);
|
||||||
|
break;
|
||||||
|
|
||||||
// If we have a known header
|
// Sets
|
||||||
if (normalizedValue == "clrmamepro" || normalizedValue == "romvault")
|
case "set": // Used by the most ancient DATs
|
||||||
{
|
case "game": // Used by most CMP DATs
|
||||||
ReadHeader(sr, keep);
|
case "machine": // Possibly used by MAME CMP DATs
|
||||||
}
|
ReadSet(cmpr, false, filename, sysid, srcid, clean, remUnicode);
|
||||||
// If we have a known set type
|
break;
|
||||||
else if (normalizedValue == "set" // Used by the most ancient DATs
|
case "resource": // Used by some other DATs to denote a BIOS set
|
||||||
|| normalizedValue == "game" // Used by most CMP DATs
|
ReadSet(cmpr, true, filename, sysid, srcid, clean, remUnicode);
|
||||||
|| normalizedValue == "machine") // Possibly used by MAME CMP DATs
|
break;
|
||||||
{
|
|
||||||
ReadSet(sr, false, filename, sysid, srcid, clean, remUnicode);
|
default:
|
||||||
}
|
break;
|
||||||
else if (normalizedValue == "resource") // Used by some other DATs to denote a BIOS set
|
|
||||||
{
|
|
||||||
ReadSet(sr, true, filename, sysid, srcid, clean, remUnicode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sr.Dispose();
|
cmpr.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Read header information
|
/// Read header information
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="reader">StreamReader to use to parse the header</param>
|
/// <param name="cmpr">ClrMameProReader to use to parse the header</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>
|
||||||
private void ReadHeader(StreamReader reader, bool keep)
|
private void ReadHeader(ClrMameProReader cmpr, bool keep)
|
||||||
{
|
{
|
||||||
bool superdat = false;
|
bool superdat = false;
|
||||||
|
|
||||||
// If there's no subtree to the header, skip it
|
// If there's no subtree to the header, skip it
|
||||||
if (reader == null || reader.EndOfStream)
|
if (cmpr == null || cmpr.EndOfStream)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Otherwise, add what is possible
|
// While we don't hit an end element or end of stream
|
||||||
string line = reader.ReadLine();
|
while (!cmpr.EndOfStream)
|
||||||
while (!Regex.IsMatch(line, Constants.EndPatternCMP))
|
|
||||||
{
|
{
|
||||||
// We only want elements
|
cmpr.ReadNextLine();
|
||||||
if (line.Trim().StartsWith("#"))
|
|
||||||
{
|
// Ignore comments, internal items, and nothingness
|
||||||
line = reader.ReadLine();
|
if (cmpr.RowType == CmpRowType.None || cmpr.RowType == CmpRowType.Comment || cmpr.RowType == CmpRowType.Internal)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
// Get all header items (ONLY OVERWRITE IF THERE'S NO DATA)
|
// If we reached the end of a section, break
|
||||||
GroupCollection gc = Regex.Match(line, Constants.ItemPatternCMP).Groups;
|
if (cmpr.RowType == CmpRowType.EndTopLevel)
|
||||||
string itemval = gc[2].Value.Replace("\"", string.Empty);
|
break;
|
||||||
|
|
||||||
switch (gc[1].Value)
|
// If the standalone value is null, we skip
|
||||||
|
if (cmpr.Standalone == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
string itemKey = cmpr.Standalone?.Key.ToLowerInvariant();
|
||||||
|
string itemVal = cmpr.Standalone?.Value;
|
||||||
|
|
||||||
|
// For all other cases
|
||||||
|
switch (itemKey)
|
||||||
{
|
{
|
||||||
case "name":
|
case "name":
|
||||||
Name = (string.IsNullOrWhiteSpace(Name) ? itemval : Name);
|
Name = (string.IsNullOrWhiteSpace(Name) ? itemVal : Name);
|
||||||
superdat = superdat || itemval.Contains(" - SuperDAT");
|
superdat = superdat || itemVal.Contains(" - SuperDAT");
|
||||||
|
|
||||||
if (keep && superdat)
|
if (keep && superdat)
|
||||||
Type = (string.IsNullOrWhiteSpace(Type) ? "SuperDAT" : Type);
|
Type = (string.IsNullOrWhiteSpace(Type) ? "SuperDAT" : Type);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "description":
|
case "description":
|
||||||
Description = (string.IsNullOrWhiteSpace(Description) ? itemval : Description);
|
Description = (string.IsNullOrWhiteSpace(Description) ? itemVal : Description);
|
||||||
break;
|
break;
|
||||||
case "rootdir":
|
case "rootdir":
|
||||||
RootDir = (string.IsNullOrWhiteSpace(RootDir) ? itemval : RootDir);
|
RootDir = (string.IsNullOrWhiteSpace(RootDir) ? itemVal : RootDir);
|
||||||
break;
|
break;
|
||||||
case "category":
|
case "category":
|
||||||
Category = (string.IsNullOrWhiteSpace(Category) ? itemval : Category);
|
Category = (string.IsNullOrWhiteSpace(Category) ? itemVal : Category);
|
||||||
break;
|
break;
|
||||||
case "version":
|
case "version":
|
||||||
Version = (string.IsNullOrWhiteSpace(Version) ? itemval : Version);
|
Version = (string.IsNullOrWhiteSpace(Version) ? itemVal : Version);
|
||||||
break;
|
break;
|
||||||
case "date":
|
case "date":
|
||||||
Date = (string.IsNullOrWhiteSpace(Date) ? itemval : Date);
|
Date = (string.IsNullOrWhiteSpace(Date) ? itemVal : Date);
|
||||||
break;
|
break;
|
||||||
case "author":
|
case "author":
|
||||||
Author = (string.IsNullOrWhiteSpace(Author) ? itemval : Author);
|
Author = (string.IsNullOrWhiteSpace(Author) ? itemVal : Author);
|
||||||
break;
|
break;
|
||||||
case "email":
|
case "email":
|
||||||
Email = (string.IsNullOrWhiteSpace(Email) ? itemval : Email);
|
Email = (string.IsNullOrWhiteSpace(Email) ? itemVal : Email);
|
||||||
break;
|
break;
|
||||||
case "homepage":
|
case "homepage":
|
||||||
Homepage = (string.IsNullOrWhiteSpace(Homepage) ? itemval : Homepage);
|
Homepage = (string.IsNullOrWhiteSpace(Homepage) ? itemVal : Homepage);
|
||||||
break;
|
break;
|
||||||
case "url":
|
case "url":
|
||||||
Url = (string.IsNullOrWhiteSpace(Url) ? itemval : Url);
|
Url = (string.IsNullOrWhiteSpace(Url) ? itemVal : Url);
|
||||||
break;
|
break;
|
||||||
case "comment":
|
case "comment":
|
||||||
Comment = (string.IsNullOrWhiteSpace(Comment) ? itemval : Comment);
|
Comment = (string.IsNullOrWhiteSpace(Comment) ? itemVal : Comment);
|
||||||
break;
|
break;
|
||||||
case "header":
|
case "header":
|
||||||
Header = (string.IsNullOrWhiteSpace(Header) ? itemval : Header);
|
Header = (string.IsNullOrWhiteSpace(Header) ? itemVal : Header);
|
||||||
break;
|
break;
|
||||||
case "type":
|
case "type":
|
||||||
Type = (string.IsNullOrWhiteSpace(Type) ? itemval : Type);
|
Type = (string.IsNullOrWhiteSpace(Type) ? itemVal : Type);
|
||||||
superdat = superdat || itemval.Contains("SuperDAT");
|
superdat = superdat || itemVal.Contains("SuperDAT");
|
||||||
break;
|
break;
|
||||||
case "forcemerging":
|
case "forcemerging":
|
||||||
if (ForceMerging == ForceMerging.None)
|
if (ForceMerging == ForceMerging.None)
|
||||||
ForceMerging = Utilities.GetForceMerging(itemval);
|
ForceMerging = Utilities.GetForceMerging(itemVal);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "forcezipping":
|
case "forcezipping":
|
||||||
if (ForcePacking == ForcePacking.None)
|
if (ForcePacking == ForcePacking.None)
|
||||||
ForcePacking = Utilities.GetForcePacking(itemval);
|
ForcePacking = Utilities.GetForcePacking(itemVal);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "forcepacking":
|
case "forcepacking":
|
||||||
if (ForcePacking == ForcePacking.None)
|
if (ForcePacking == ForcePacking.None)
|
||||||
ForcePacking = Utilities.GetForcePacking(itemval);
|
ForcePacking = Utilities.GetForcePacking(itemVal);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
line = reader.ReadLine();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Read set information
|
/// Read set information
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="reader">StreamReader to use to parse the header</param>
|
/// <param name="cmpr">ClrMameProReader to use to parse the header</param>
|
||||||
/// <param name="resource">True if the item is a resource (bios), false otherwise</param>
|
/// <param name="resource">True if the item is a resource (bios), false otherwise</param>
|
||||||
/// <param name="filename">Name of the file to be parsed</param>
|
/// <param name="filename">Name of the file to be parsed</param>
|
||||||
/// <param name="sysid">System ID for the DAT</param>
|
/// <param name="sysid">System ID for the DAT</param>
|
||||||
@@ -193,7 +197,7 @@ namespace SabreTools.Library.DatFiles
|
|||||||
/// <param name="clean">True if game names are sanitized, false otherwise (default)</param>
|
/// <param name="clean">True if game names are sanitized, false otherwise (default)</param>
|
||||||
/// <param name="remUnicode">True if we should remove non-ASCII characters from output, false otherwise (default)</param>
|
/// <param name="remUnicode">True if we should remove non-ASCII characters from output, false otherwise (default)</param>
|
||||||
private void ReadSet(
|
private void ReadSet(
|
||||||
StreamReader reader,
|
ClrMameProReader cmpr,
|
||||||
bool resource,
|
bool resource,
|
||||||
|
|
||||||
// Standard Dat parsing
|
// Standard Dat parsing
|
||||||
@@ -213,40 +217,87 @@ namespace SabreTools.Library.DatFiles
|
|||||||
};
|
};
|
||||||
|
|
||||||
// If there's no subtree to the header, skip it
|
// If there's no subtree to the header, skip it
|
||||||
if (reader == null || reader.EndOfStream)
|
if (cmpr == null || cmpr.EndOfStream)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Otherwise, add what is possible
|
// While we don't hit an end element or end of stream
|
||||||
string line = reader.ReadLine();
|
while (!cmpr.EndOfStream)
|
||||||
while (!Regex.IsMatch(line, Constants.EndPatternCMP))
|
|
||||||
{
|
{
|
||||||
// We only want elements
|
cmpr.ReadNextLine();
|
||||||
if (line.Trim().StartsWith("#"))
|
|
||||||
{
|
// Ignore comments and nothingness
|
||||||
line = reader.ReadLine();
|
if (cmpr.RowType == CmpRowType.None || cmpr.RowType == CmpRowType.Comment)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// If we reached the end of a section, break
|
||||||
|
if (cmpr.RowType == CmpRowType.EndTopLevel)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Handle any standalone items
|
||||||
|
if (cmpr.RowType == CmpRowType.Standalone && cmpr.Standalone != null)
|
||||||
|
{
|
||||||
|
string itemKey = cmpr.Standalone?.Key.ToLowerInvariant();
|
||||||
|
string itemVal = cmpr.Standalone?.Value;
|
||||||
|
|
||||||
|
switch (itemKey)
|
||||||
|
{
|
||||||
|
case "name":
|
||||||
|
machine.Name = itemVal;
|
||||||
|
break;
|
||||||
|
case "description":
|
||||||
|
machine.Description = itemVal;
|
||||||
|
break;
|
||||||
|
case "year":
|
||||||
|
machine.Year = itemVal;
|
||||||
|
break;
|
||||||
|
case "manufacturer":
|
||||||
|
machine.Manufacturer = itemVal;
|
||||||
|
break;
|
||||||
|
case "cloneof":
|
||||||
|
machine.CloneOf = itemVal;
|
||||||
|
break;
|
||||||
|
case "romof":
|
||||||
|
machine.RomOf = itemVal;
|
||||||
|
break;
|
||||||
|
case "sampleof":
|
||||||
|
machine.SampleOf = itemVal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Item-specific lines have a known pattern
|
// Handle any internal items
|
||||||
string trimmedline = line.Trim();
|
else if (cmpr.RowType == CmpRowType.Internal
|
||||||
if (trimmedline.StartsWith("archive (")
|
&& !string.IsNullOrWhiteSpace(cmpr.InternalName)
|
||||||
|| trimmedline.StartsWith("biosset (")
|
&& cmpr.Internal != null)
|
||||||
|| trimmedline.StartsWith("disk (")
|
|
||||||
|| trimmedline.StartsWith("release (")
|
|
||||||
|| trimmedline.StartsWith("rom (")
|
|
||||||
|| (trimmedline.StartsWith("sample") && !trimmedline.StartsWith("sampleof")))
|
|
||||||
{
|
{
|
||||||
containsItems = true;
|
containsItems = true;
|
||||||
ItemType temptype = ItemType.Rom;
|
string itemKey = cmpr.InternalName;
|
||||||
if (trimmedline.StartsWith("rom ("))
|
|
||||||
temptype = ItemType.Rom;
|
ItemType itemType = ItemType.Rom;
|
||||||
else if (trimmedline.StartsWith("disk ("))
|
switch (itemKey)
|
||||||
temptype = ItemType.Disk;
|
{
|
||||||
else if (trimmedline.StartsWith("sample"))
|
case "archive":
|
||||||
temptype = ItemType.Sample;
|
itemType = ItemType.Archive;
|
||||||
|
break;
|
||||||
|
case "biosset":
|
||||||
|
itemType = ItemType.BiosSet;
|
||||||
|
break;
|
||||||
|
case "disk":
|
||||||
|
itemType = ItemType.Disk;
|
||||||
|
break;
|
||||||
|
case "release":
|
||||||
|
itemType = ItemType.Release;
|
||||||
|
break;
|
||||||
|
case "rom":
|
||||||
|
itemType = ItemType.Rom;
|
||||||
|
break;
|
||||||
|
case "sample":
|
||||||
|
itemType = ItemType.Sample;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Create the proper DatItem based on the type
|
// Create the proper DatItem based on the type
|
||||||
DatItem item = Utilities.GetDatItem(temptype);
|
DatItem item = Utilities.GetDatItem(itemType);
|
||||||
|
|
||||||
// Then populate it with information
|
// Then populate it with information
|
||||||
item.CopyMachineInformation(machine);
|
item.CopyMachineInformation(machine);
|
||||||
@@ -255,55 +306,27 @@ namespace SabreTools.Library.DatFiles
|
|||||||
item.System = filename;
|
item.System = filename;
|
||||||
item.SourceID = srcid;
|
item.SourceID = srcid;
|
||||||
|
|
||||||
// If we have a sample, treat it special
|
// Loop through all of the attributes
|
||||||
if (temptype == ItemType.Sample)
|
foreach (var kvp in cmpr.Internal)
|
||||||
{
|
{
|
||||||
line = line.Trim().Remove(0, 6).Trim().Replace("\"", string.Empty); // Remove "sample" from the input string
|
string attrKey = kvp.Key;
|
||||||
item.Name = line;
|
string attrVal = kvp.Value;
|
||||||
|
|
||||||
// Now process and add the sample
|
switch (attrKey)
|
||||||
ParseAddHelper(item, clean, remUnicode);
|
|
||||||
line = reader.ReadLine();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the line split by spaces and quotes
|
|
||||||
string[] linegc = Utilities.SplitLineAsCMP(line);
|
|
||||||
|
|
||||||
// Loop over all attributes normally and add them if possible
|
|
||||||
for (int i = 0; i < linegc.Length; i++)
|
|
||||||
{
|
|
||||||
// Look at the current item and use it if possible
|
|
||||||
string quoteless = linegc[i].Replace("\"", string.Empty);
|
|
||||||
switch (quoteless)
|
|
||||||
{
|
{
|
||||||
//If the item is empty, we automatically skip it because it's a fluke
|
//If the item is empty, we automatically skip it because it's a fluke
|
||||||
case "":
|
case "":
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Special cases for standalone item statuses
|
|
||||||
case "baddump":
|
|
||||||
case "good":
|
|
||||||
case "nodump":
|
|
||||||
case "verified":
|
|
||||||
ItemStatus tempStandaloneStatus = Utilities.GetItemStatus(quoteless);
|
|
||||||
if (item.ItemType == ItemType.Rom)
|
|
||||||
((Rom)item).ItemStatus = tempStandaloneStatus;
|
|
||||||
else if (item.ItemType == ItemType.Disk)
|
|
||||||
((Disk)item).ItemStatus = tempStandaloneStatus;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Regular attributes
|
// Regular attributes
|
||||||
case "name":
|
case "name":
|
||||||
quoteless = linegc[++i].Replace("\"", string.Empty);
|
item.Name = attrVal;
|
||||||
item.Name = quoteless;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "size":
|
case "size":
|
||||||
if (item.ItemType == ItemType.Rom)
|
if (item.ItemType == ItemType.Rom)
|
||||||
{
|
{
|
||||||
quoteless = linegc[++i].Replace("\"", string.Empty);
|
if (Int64.TryParse(attrVal, out long size))
|
||||||
if (Int64.TryParse(quoteless, out long size))
|
|
||||||
((Rom)item).Size = size;
|
((Rom)item).Size = size;
|
||||||
else
|
else
|
||||||
((Rom)item).Size = -1;
|
((Rom)item).Size = -1;
|
||||||
@@ -312,95 +335,53 @@ namespace SabreTools.Library.DatFiles
|
|||||||
break;
|
break;
|
||||||
case "crc":
|
case "crc":
|
||||||
if (item.ItemType == ItemType.Rom)
|
if (item.ItemType == ItemType.Rom)
|
||||||
{
|
(item as Rom).CRC = Utilities.CleanHashData(attrVal, Constants.CRCLength);
|
||||||
quoteless = linegc[++i].Replace("\"", string.Empty);
|
|
||||||
((Rom)item).CRC = Utilities.CleanHashData(quoteless, Constants.CRCLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "md5":
|
case "md5":
|
||||||
if (item.ItemType == ItemType.Rom)
|
if (item.ItemType == ItemType.Rom)
|
||||||
{
|
(item as Rom).MD5 = Utilities.CleanHashData(attrVal, Constants.MD5Length);
|
||||||
quoteless = linegc[++i].Replace("\"", string.Empty);
|
|
||||||
((Rom)item).MD5 = Utilities.CleanHashData(quoteless, Constants.MD5Length);
|
|
||||||
}
|
|
||||||
else if (item.ItemType == ItemType.Disk)
|
else if (item.ItemType == ItemType.Disk)
|
||||||
{
|
((Disk)item).MD5 = Utilities.CleanHashData(attrVal, Constants.MD5Length);
|
||||||
i++;
|
|
||||||
quoteless = linegc[i].Replace("\"", string.Empty);
|
|
||||||
((Disk)item).MD5 = Utilities.CleanHashData(quoteless, Constants.MD5Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "ripemd160":
|
case "ripemd160":
|
||||||
if (item.ItemType == ItemType.Rom)
|
if (item.ItemType == ItemType.Rom)
|
||||||
{
|
(item as Rom).RIPEMD160 = Utilities.CleanHashData(attrVal, Constants.RIPEMD160Length);
|
||||||
quoteless = linegc[++i].Replace("\"", string.Empty);
|
|
||||||
((Rom)item).RIPEMD160 = Utilities.CleanHashData(quoteless, Constants.RIPEMD160Length);
|
|
||||||
}
|
|
||||||
else if (item.ItemType == ItemType.Disk)
|
else if (item.ItemType == ItemType.Disk)
|
||||||
{
|
((Disk)item).RIPEMD160 = Utilities.CleanHashData(attrVal, Constants.RIPEMD160Length);
|
||||||
quoteless = linegc[++i].Replace("\"", string.Empty);
|
|
||||||
((Disk)item).RIPEMD160 = Utilities.CleanHashData(quoteless, Constants.RIPEMD160Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "sha1":
|
case "sha1":
|
||||||
if (item.ItemType == ItemType.Rom)
|
if (item.ItemType == ItemType.Rom)
|
||||||
{
|
(item as Rom).SHA1 = Utilities.CleanHashData(attrVal, Constants.SHA1Length);
|
||||||
quoteless = linegc[++i].Replace("\"", string.Empty);
|
|
||||||
((Rom)item).SHA1 = Utilities.CleanHashData(quoteless, Constants.SHA1Length);
|
|
||||||
}
|
|
||||||
else if (item.ItemType == ItemType.Disk)
|
else if (item.ItemType == ItemType.Disk)
|
||||||
{
|
((Disk)item).SHA1 = Utilities.CleanHashData(attrVal, Constants.SHA1Length);
|
||||||
quoteless = linegc[++i].Replace("\"", string.Empty);
|
|
||||||
((Disk)item).SHA1 = Utilities.CleanHashData(quoteless, Constants.SHA1Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "sha256":
|
case "sha256":
|
||||||
if (item.ItemType == ItemType.Rom)
|
if (item.ItemType == ItemType.Rom)
|
||||||
{
|
((Rom)item).SHA256 = Utilities.CleanHashData(attrVal, Constants.SHA256Length);
|
||||||
quoteless = linegc[++i].Replace("\"", string.Empty);
|
|
||||||
((Rom)item).SHA256 = Utilities.CleanHashData(quoteless, Constants.SHA256Length);
|
|
||||||
}
|
|
||||||
else if (item.ItemType == ItemType.Disk)
|
else if (item.ItemType == ItemType.Disk)
|
||||||
{
|
((Disk)item).SHA256 = Utilities.CleanHashData(attrVal, Constants.SHA256Length);
|
||||||
quoteless = linegc[++i].Replace("\"", string.Empty);
|
|
||||||
((Disk)item).SHA256 = Utilities.CleanHashData(quoteless, Constants.SHA256Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "sha384":
|
case "sha384":
|
||||||
if (item.ItemType == ItemType.Rom)
|
if (item.ItemType == ItemType.Rom)
|
||||||
{
|
((Rom)item).SHA384 = Utilities.CleanHashData(attrVal, Constants.SHA384Length);
|
||||||
quoteless = linegc[++i].Replace("\"", string.Empty);
|
|
||||||
((Rom)item).SHA384 = Utilities.CleanHashData(quoteless, Constants.SHA384Length);
|
|
||||||
}
|
|
||||||
else if (item.ItemType == ItemType.Disk)
|
else if (item.ItemType == ItemType.Disk)
|
||||||
{
|
((Disk)item).SHA384 = Utilities.CleanHashData(attrVal, Constants.SHA384Length);
|
||||||
quoteless = linegc[++i].Replace("\"", string.Empty);
|
|
||||||
((Disk)item).SHA384 = Utilities.CleanHashData(quoteless, Constants.SHA384Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "sha512":
|
case "sha512":
|
||||||
if (item.ItemType == ItemType.Rom)
|
if (item.ItemType == ItemType.Rom)
|
||||||
{
|
((Rom)item).SHA512 = Utilities.CleanHashData(attrVal, Constants.SHA512Length);
|
||||||
quoteless = linegc[++i].Replace("\"", string.Empty);
|
|
||||||
((Rom)item).SHA512 = Utilities.CleanHashData(quoteless, Constants.SHA512Length);
|
|
||||||
}
|
|
||||||
else if (item.ItemType == ItemType.Disk)
|
else if (item.ItemType == ItemType.Disk)
|
||||||
{
|
((Disk)item).SHA512 = Utilities.CleanHashData(attrVal, Constants.SHA512Length);
|
||||||
quoteless = linegc[++i].Replace("\"", string.Empty);
|
|
||||||
((Disk)item).SHA512 = Utilities.CleanHashData(quoteless, Constants.SHA512Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "status":
|
case "status":
|
||||||
case "flags":
|
ItemStatus tempFlagStatus = Utilities.GetItemStatus(attrVal);
|
||||||
quoteless = linegc[++i].Replace("\"", string.Empty);
|
|
||||||
ItemStatus tempFlagStatus = Utilities.GetItemStatus(quoteless);
|
|
||||||
if (item.ItemType == ItemType.Rom)
|
if (item.ItemType == ItemType.Rom)
|
||||||
((Rom)item).ItemStatus = tempFlagStatus;
|
((Rom)item).ItemStatus = tempFlagStatus;
|
||||||
else if (item.ItemType == ItemType.Disk)
|
else if (item.ItemType == ItemType.Disk)
|
||||||
@@ -409,66 +390,31 @@ namespace SabreTools.Library.DatFiles
|
|||||||
break;
|
break;
|
||||||
case "date":
|
case "date":
|
||||||
if (item.ItemType == ItemType.Rom)
|
if (item.ItemType == ItemType.Rom)
|
||||||
{
|
((Rom)item).Date = attrVal;
|
||||||
// If we have quotes in the next item, assume only one item
|
|
||||||
if (linegc[i + 1].Contains("\""))
|
|
||||||
quoteless = linegc[++i].Replace("\"", string.Empty);
|
|
||||||
|
|
||||||
// Otherwise, we assume we need to read the next two items
|
|
||||||
else
|
|
||||||
quoteless = $"{linegc[++i].Replace("\"", string.Empty)} {linegc[++i].Replace("\"", string.Empty)}";
|
|
||||||
|
|
||||||
((Rom)item).Date = quoteless;
|
|
||||||
}
|
|
||||||
else if (item.ItemType == ItemType.Release)
|
else if (item.ItemType == ItemType.Release)
|
||||||
{
|
((Release)item).Date = attrVal;
|
||||||
// If we have quotes in the next item, assume only one item
|
|
||||||
if (linegc[i + 1].Contains("\""))
|
|
||||||
quoteless = linegc[++i].Replace("\"", string.Empty);
|
|
||||||
|
|
||||||
// Otherwise, we assume we need to read the next two items
|
|
||||||
else
|
|
||||||
quoteless = $"{linegc[++i].Replace("\"", string.Empty)} {linegc[++i].Replace("\"", string.Empty)}";
|
|
||||||
|
|
||||||
((Release)item).Date = quoteless;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "default":
|
case "default":
|
||||||
if (item.ItemType == ItemType.BiosSet)
|
if (item.ItemType == ItemType.BiosSet)
|
||||||
{
|
((BiosSet)item).Default = Utilities.GetYesNo(attrVal.ToLowerInvariant());
|
||||||
quoteless = linegc[++i].Replace("\"", string.Empty);
|
|
||||||
((BiosSet)item).Default = Utilities.GetYesNo(quoteless.ToLowerInvariant());
|
|
||||||
}
|
|
||||||
else if (item.ItemType == ItemType.Release)
|
else if (item.ItemType == ItemType.Release)
|
||||||
{
|
((Release)item).Default = Utilities.GetYesNo(attrVal.ToLowerInvariant());
|
||||||
quoteless = linegc[++i].Replace("\"", string.Empty);
|
|
||||||
((Release)item).Default = Utilities.GetYesNo(quoteless.ToLowerInvariant());
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "description":
|
case "description":
|
||||||
if (item.ItemType == ItemType.BiosSet)
|
if (item.ItemType == ItemType.BiosSet)
|
||||||
{
|
((BiosSet)item).Description = attrVal.ToLowerInvariant();
|
||||||
quoteless = linegc[++i].Replace("\"", string.Empty);
|
|
||||||
((BiosSet)item).Description = quoteless.ToLowerInvariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "region":
|
case "region":
|
||||||
if (item.ItemType == ItemType.Release)
|
if (item.ItemType == ItemType.Release)
|
||||||
{
|
((Release)item).Region = attrVal.ToLowerInvariant();
|
||||||
quoteless = linegc[++i].Replace("\"", string.Empty);
|
|
||||||
((Release)item).Region = quoteless.ToLowerInvariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "language":
|
case "language":
|
||||||
if (item.ItemType == ItemType.Release)
|
if (item.ItemType == ItemType.Release)
|
||||||
{
|
((Release)item).Language = attrVal.ToLowerInvariant();
|
||||||
quoteless = linegc[++i].Replace("\"", string.Empty);
|
|
||||||
((Release)item).Language = quoteless.ToLowerInvariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -476,42 +422,7 @@ namespace SabreTools.Library.DatFiles
|
|||||||
|
|
||||||
// Now process and add the rom
|
// Now process and add the rom
|
||||||
ParseAddHelper(item, clean, remUnicode);
|
ParseAddHelper(item, clean, remUnicode);
|
||||||
|
|
||||||
line = reader.ReadLine();
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set-specific lines have a known pattern
|
|
||||||
GroupCollection setgc = Regex.Match(line, Constants.ItemPatternCMP).Groups;
|
|
||||||
string itemval = setgc[2].Value.Replace("\"", string.Empty);
|
|
||||||
|
|
||||||
switch (setgc[1].Value)
|
|
||||||
{
|
|
||||||
case "name":
|
|
||||||
machine.Name = (itemval.ToLowerInvariant().EndsWith(".zip") ? itemval.Remove(itemval.Length - 4) : itemval);
|
|
||||||
machine.Description = (itemval.ToLowerInvariant().EndsWith(".zip") ? itemval.Remove(itemval.Length - 4) : itemval);
|
|
||||||
break;
|
|
||||||
case "description":
|
|
||||||
machine.Description = itemval;
|
|
||||||
break;
|
|
||||||
case "year":
|
|
||||||
machine.Year = itemval;
|
|
||||||
break;
|
|
||||||
case "manufacturer":
|
|
||||||
machine.Manufacturer = itemval;
|
|
||||||
break;
|
|
||||||
case "cloneof":
|
|
||||||
machine.CloneOf = itemval;
|
|
||||||
break;
|
|
||||||
case "romof":
|
|
||||||
machine.RomOf = itemval;
|
|
||||||
break;
|
|
||||||
case "sampleof":
|
|
||||||
machine.SampleOf = itemval;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
line = reader.ReadLine();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no items were found for this machine, add a Blank placeholder
|
// If no items were found for this machine, add a Blank placeholder
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using System.Text.RegularExpressions;
|
|||||||
|
|
||||||
using SabreTools.Library.Data;
|
using SabreTools.Library.Data;
|
||||||
using SabreTools.Library.DatItems;
|
using SabreTools.Library.DatItems;
|
||||||
|
using SabreTools.Library.Readers;
|
||||||
using SabreTools.Library.Tools;
|
using SabreTools.Library.Tools;
|
||||||
using SabreTools.Library.Writers;
|
using SabreTools.Library.Writers;
|
||||||
using NaturalSort;
|
using NaturalSort;
|
||||||
@@ -49,98 +50,107 @@ namespace SabreTools.Library.DatFiles
|
|||||||
{
|
{
|
||||||
// Open a file reader
|
// Open a file reader
|
||||||
Encoding enc = Utilities.GetEncoding(filename);
|
Encoding enc = Utilities.GetEncoding(filename);
|
||||||
StreamReader sr = new StreamReader(Utilities.TryOpenRead(filename), enc);
|
ClrMameProReader cmpr = new ClrMameProReader(Utilities.TryOpenRead(filename), enc);
|
||||||
|
cmpr.DosCenter = true;
|
||||||
|
|
||||||
while (!sr.EndOfStream)
|
while (!cmpr.EndOfStream)
|
||||||
{
|
{
|
||||||
string line = sr.ReadLine();
|
cmpr.ReadNextLine();
|
||||||
|
|
||||||
// If the line is the header or a game
|
// Ignore everything not top-level
|
||||||
if (Regex.IsMatch(line, Constants.HeaderPatternCMP))
|
if (cmpr.RowType != CmpRowType.TopLevel)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Switch on the top-level name
|
||||||
|
switch (cmpr.TopLevel.ToLowerInvariant())
|
||||||
{
|
{
|
||||||
GroupCollection gc = Regex.Match(line, Constants.HeaderPatternCMP).Groups;
|
// Header values
|
||||||
string normalizedValue = gc[1].Value.ToLowerInvariant();
|
case "doscenter":
|
||||||
|
ReadHeader(cmpr);
|
||||||
|
break;
|
||||||
|
|
||||||
// If we have a known header
|
// Sets
|
||||||
if (normalizedValue == "doscenter")
|
case "game":
|
||||||
ReadHeader(sr, keep);
|
ReadGame(cmpr, filename, sysid, srcid, clean, remUnicode);
|
||||||
|
break;
|
||||||
|
|
||||||
// If we have a game
|
default:
|
||||||
else if (normalizedValue == "game" )
|
break;
|
||||||
ReadGame(sr, filename, sysid, srcid, clean, remUnicode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sr.Dispose();
|
cmpr.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Read header information
|
/// Read header information
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="reader">StreamReader to use to parse the header</param>
|
/// <param name="cmpr">ClrMameProReader to use to parse the header</param>
|
||||||
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
|
private void ReadHeader(ClrMameProReader cmpr)
|
||||||
private void ReadHeader(StreamReader reader, bool keep)
|
|
||||||
{
|
{
|
||||||
// If there's no subtree to the header, skip it
|
// If there's no subtree to the header, skip it
|
||||||
if (reader == null || reader.EndOfStream)
|
if (cmpr == null || cmpr.EndOfStream)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Otherwise, add what is possible
|
// While we don't hit an end element or end of stream
|
||||||
string line = reader.ReadLine();
|
while (!cmpr.EndOfStream)
|
||||||
while (!Regex.IsMatch(line, Constants.EndPatternCMP))
|
|
||||||
{
|
{
|
||||||
// Get all header items (ONLY OVERWRITE IF THERE'S NO DATA)
|
cmpr.ReadNextLine();
|
||||||
GroupCollection gc = Regex.Match(line, Constants.ItemPatternCMP).Groups;
|
|
||||||
string itemval = gc[2].Value.Replace("\"", string.Empty);
|
|
||||||
|
|
||||||
// Some dats don't have the space between "Name:" and the dat name
|
// Ignore comments, internal items, and nothingness
|
||||||
if (line.Trim().StartsWith("Name:"))
|
if (cmpr.RowType == CmpRowType.None || cmpr.RowType == CmpRowType.Comment || cmpr.RowType == CmpRowType.Internal)
|
||||||
{
|
|
||||||
Name = (string.IsNullOrWhiteSpace(Name) ? line.Substring("Name:".Length).Trim() : Name);
|
|
||||||
line = reader.ReadLine();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
switch (gc[1].Value)
|
// If we reached the end of a section, break
|
||||||
|
if (cmpr.RowType == CmpRowType.EndTopLevel)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// If the standalone value is null, we skip
|
||||||
|
if (cmpr.Standalone == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
string itemKey = cmpr.Standalone?.Key.ToLowerInvariant().TrimEnd(':');
|
||||||
|
string itemVal = cmpr.Standalone?.Value;
|
||||||
|
|
||||||
|
// For all other cases
|
||||||
|
switch (itemKey)
|
||||||
{
|
{
|
||||||
case "Name:":
|
case "name":
|
||||||
Name = (string.IsNullOrWhiteSpace(Name) ? itemval : Name);
|
Name = (string.IsNullOrWhiteSpace(Name) ? itemVal : Name);
|
||||||
break;
|
break;
|
||||||
case "Description:":
|
case "description":
|
||||||
Description = (string.IsNullOrWhiteSpace(Description) ? itemval : Description);
|
Description = (string.IsNullOrWhiteSpace(Description) ? itemVal : Description);
|
||||||
break;
|
break;
|
||||||
case "Version:":
|
case "dersion":
|
||||||
Version = (string.IsNullOrWhiteSpace(Version) ? itemval : Version);
|
Version = (string.IsNullOrWhiteSpace(Version) ? itemVal : Version);
|
||||||
break;
|
break;
|
||||||
case "Date:":
|
case "date":
|
||||||
Date = (string.IsNullOrWhiteSpace(Date) ? itemval : Date);
|
Date = (string.IsNullOrWhiteSpace(Date) ? itemVal : Date);
|
||||||
break;
|
break;
|
||||||
case "Author:":
|
case "author":
|
||||||
Author = (string.IsNullOrWhiteSpace(Author) ? itemval : Author);
|
Author = (string.IsNullOrWhiteSpace(Author) ? itemVal : Author);
|
||||||
break;
|
break;
|
||||||
case "Homepage:":
|
case "homepage":
|
||||||
Homepage = (string.IsNullOrWhiteSpace(Homepage) ? itemval : Homepage);
|
Homepage = (string.IsNullOrWhiteSpace(Homepage) ? itemVal : Homepage);
|
||||||
break;
|
break;
|
||||||
case "Comment:":
|
case "comment":
|
||||||
Comment = (string.IsNullOrWhiteSpace(Comment) ? itemval : Comment);
|
Comment = (string.IsNullOrWhiteSpace(Comment) ? itemVal : Comment);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
line = reader.ReadLine();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Read set information
|
/// Read set information
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="reader">StreamReader to use to parse the header</param>
|
/// <param name="cmpr">ClrMameProReader to use to parse the header</param>
|
||||||
/// <param name="filename">Name of the file to be parsed</param>
|
/// <param name="filename">Name of the file to be parsed</param>
|
||||||
/// <param name="sysid">System ID for the DAT</param>
|
/// <param name="sysid">System ID for the DAT</param>
|
||||||
/// <param name="srcid">Source ID for the DAT</param>
|
/// <param name="srcid">Source ID for the DAT</param>
|
||||||
/// <param name="clean">True if game names are sanitized, false otherwise (default)</param>
|
/// <param name="clean">True if game names are sanitized, false otherwise (default)</param>
|
||||||
/// <param name="remUnicode">True if we should remove non-ASCII characters from output, false otherwise (default)</param>
|
/// <param name="remUnicode">True if we should remove non-ASCII characters from output, false otherwise (default)</param>
|
||||||
private void ReadGame(
|
private void ReadGame(
|
||||||
StreamReader reader,
|
ClrMameProReader cmpr,
|
||||||
|
|
||||||
// Standard Dat parsing
|
// Standard Dat parsing
|
||||||
string filename,
|
string filename,
|
||||||
@@ -159,22 +169,46 @@ namespace SabreTools.Library.DatFiles
|
|||||||
};
|
};
|
||||||
|
|
||||||
// If there's no subtree to the header, skip it
|
// If there's no subtree to the header, skip it
|
||||||
if (reader == null || reader.EndOfStream)
|
if (cmpr == null || cmpr.EndOfStream)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Otherwise, add what is possible
|
// While we don't hit an end element or end of stream
|
||||||
string line = reader.ReadLine();
|
while (!cmpr.EndOfStream)
|
||||||
while (!Regex.IsMatch(line, Constants.EndPatternCMP))
|
|
||||||
{
|
{
|
||||||
// Item-specific lines have a known pattern
|
cmpr.ReadNextLine();
|
||||||
string trimmedline = line.Trim();
|
|
||||||
if (trimmedline.StartsWith("file ("))
|
// Ignore comments and nothingness
|
||||||
|
if (cmpr.RowType == CmpRowType.None || cmpr.RowType == CmpRowType.Comment)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// If we reached the end of a section, break
|
||||||
|
if (cmpr.RowType == CmpRowType.EndTopLevel)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Handle any standalone items
|
||||||
|
if (cmpr.RowType == CmpRowType.Standalone && cmpr.Standalone != null)
|
||||||
|
{
|
||||||
|
string itemKey = cmpr.Standalone?.Key.ToLowerInvariant();
|
||||||
|
string itemVal = cmpr.Standalone?.Value;
|
||||||
|
|
||||||
|
switch (itemKey)
|
||||||
|
{
|
||||||
|
case "name":
|
||||||
|
machine.Name = (itemVal.ToLowerInvariant().EndsWith(".zip") ? itemVal.Remove(itemVal.Length - 4) : itemVal);
|
||||||
|
machine.Description = (itemVal.ToLowerInvariant().EndsWith(".zip") ? itemVal.Remove(itemVal.Length - 4) : itemVal);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle any internal items
|
||||||
|
else if (cmpr.RowType == CmpRowType.Internal
|
||||||
|
&& string.Equals(cmpr.InternalName, "file", StringComparison.OrdinalIgnoreCase)
|
||||||
|
&& cmpr.Internal != null)
|
||||||
{
|
{
|
||||||
containsItems = true;
|
containsItems = true;
|
||||||
ItemType temptype = ItemType.Rom;
|
|
||||||
|
|
||||||
// Create the proper DatItem based on the type
|
// Create the proper DatItem based on the type
|
||||||
DatItem item = Utilities.GetDatItem(temptype);
|
Rom item = Utilities.GetDatItem(ItemType.Rom) as Rom;
|
||||||
|
|
||||||
// Then populate it with information
|
// Then populate it with information
|
||||||
item.CopyMachineInformation(machine);
|
item.CopyMachineInformation(machine);
|
||||||
@@ -183,71 +217,43 @@ namespace SabreTools.Library.DatFiles
|
|||||||
item.System = filename;
|
item.System = filename;
|
||||||
item.SourceID = srcid;
|
item.SourceID = srcid;
|
||||||
|
|
||||||
// Get the line split by spaces and quotes
|
// Loop through all of the attributes
|
||||||
string[] linegc = Utilities.SplitLineAsCMP(line);
|
foreach (var kvp in cmpr.Internal)
|
||||||
|
|
||||||
// Loop over the specifics
|
|
||||||
for (int i = 0; i < linegc.Length; i++)
|
|
||||||
{
|
{
|
||||||
// Names are not quoted, for some stupid reason
|
string attrKey = kvp.Key;
|
||||||
if (linegc[i] == "name")
|
string attrVal = kvp.Value;
|
||||||
|
|
||||||
|
switch (attrKey)
|
||||||
{
|
{
|
||||||
// Get the name in order until we find the next flag
|
//If the item is empty, we automatically skip it because it's a fluke
|
||||||
while (++i < linegc.Length
|
case "":
|
||||||
&& linegc[i] != "size"
|
continue;
|
||||||
&& linegc[i] != "date"
|
|
||||||
&& linegc[i] != "crc")
|
|
||||||
{
|
|
||||||
item.Name += $"{linegc[i]}";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform correction
|
// Regular attributes
|
||||||
item.Name = item.Name.TrimStart();
|
case "name":
|
||||||
i--;
|
item.Name = attrVal;
|
||||||
}
|
break;
|
||||||
|
|
||||||
// Get the size from the next part
|
case "size":
|
||||||
else if (linegc[i] == "size")
|
if (Int64.TryParse(attrVal, out long size))
|
||||||
{
|
item.Size = size;
|
||||||
if (!Int64.TryParse(linegc[++i], out long tempsize))
|
else
|
||||||
tempsize = 0;
|
item.Size = -1;
|
||||||
|
|
||||||
((Rom)item).Size = tempsize;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
// Get the date from the next part
|
case "crc":
|
||||||
else if (linegc[i] == "date")
|
item.CRC = Utilities.CleanHashData(attrVal, Constants.CRCLength);
|
||||||
{
|
break;
|
||||||
((Rom)item).Date = $"{linegc[++i].Replace("\"", string.Empty)} {linegc[++i].Replace("\"", string.Empty)}";
|
case "date":
|
||||||
}
|
item.Date = attrVal;
|
||||||
|
break;
|
||||||
// Get the CRC from the next part
|
|
||||||
else if (linegc[i] == "crc")
|
|
||||||
{
|
|
||||||
((Rom)item).CRC = linegc[++i].Replace("\"", string.Empty).ToLowerInvariant();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now process and add the rom
|
// Now process and add the rom
|
||||||
ParseAddHelper(item, clean, remUnicode);
|
ParseAddHelper(item, clean, remUnicode);
|
||||||
|
|
||||||
line = reader.ReadLine();
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Game-specific lines have a known pattern
|
|
||||||
GroupCollection setgc = Regex.Match(line, Constants.ItemPatternCMP).Groups;
|
|
||||||
string itemval = setgc[2].Value.Replace("\"", string.Empty);
|
|
||||||
|
|
||||||
switch (setgc[1].Value)
|
|
||||||
{
|
|
||||||
case "name":
|
|
||||||
machine.Name = (itemval.ToLowerInvariant().EndsWith(".zip") ? itemval.Remove(itemval.Length - 4) : itemval);
|
|
||||||
machine.Description = (itemval.ToLowerInvariant().EndsWith(".zip") ? itemval.Remove(itemval.Length - 4) : itemval);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
line = reader.ReadLine();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no items were found for this machine, add a Blank placeholder
|
// If no items were found for this machine, add a Blank placeholder
|
||||||
|
|||||||
@@ -450,6 +450,7 @@
|
|||||||
Standalone,
|
Standalone,
|
||||||
Internal,
|
Internal,
|
||||||
Comment,
|
Comment,
|
||||||
|
EndTopLevel,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -158,6 +158,11 @@ namespace SabreTools.Library.Readers
|
|||||||
{
|
{
|
||||||
value = $"{linegc[++i].Replace("\"", string.Empty)} {linegc[++i].Replace("\"", string.Empty)}";
|
value = $"{linegc[++i].Replace("\"", string.Empty)} {linegc[++i].Replace("\"", string.Empty)}";
|
||||||
}
|
}
|
||||||
|
// Default case
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = linegc[++i].Replace("\"", string.Empty);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -167,6 +172,13 @@ namespace SabreTools.Library.Readers
|
|||||||
value = key;
|
value = key;
|
||||||
key = "status";
|
key = "status";
|
||||||
}
|
}
|
||||||
|
// Special case for standalone sample
|
||||||
|
else if (normalizedValue == "sample")
|
||||||
|
{
|
||||||
|
value = key;
|
||||||
|
key = "name";
|
||||||
|
}
|
||||||
|
// Default case
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
value = linegc[++i].Replace("\"", string.Empty);
|
value = linegc[++i].Replace("\"", string.Empty);
|
||||||
@@ -198,7 +210,7 @@ namespace SabreTools.Library.Readers
|
|||||||
{
|
{
|
||||||
Internal = null;
|
Internal = null;
|
||||||
InternalName = null;
|
InternalName = null;
|
||||||
RowType = CmpRowType.None;
|
RowType = CmpRowType.EndTopLevel;
|
||||||
Standalone = null;
|
Standalone = null;
|
||||||
TopLevel = null;
|
TopLevel = null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user