Add support for old CMP dats (partial library-only)

This commit is contained in:
Matt Nadareski
2020-09-20 21:12:57 -07:00
parent 195aaba308
commit 9510d9efe6
4 changed files with 60 additions and 10 deletions

View File

@@ -15,13 +15,24 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
internal class ClrMamePro : DatFile internal class ClrMamePro : DatFile
{ {
#region Fields
/// <summary>
/// Get whether to assume quote usage on read and write or not
/// </summary>
public bool Quotes { get; set; } = true;
#endregion
/// <summary> /// <summary>
/// Constructor designed for casting a base DatFile /// Constructor designed for casting a base DatFile
/// </summary> /// </summary>
/// <param name="datFile">Parent DatFile to copy from</param> /// <param name="datFile">Parent DatFile to copy from</param>
public ClrMamePro(DatFile datFile) /// <param name="quotes">Enable quotes on read and write, false otherwise</param>
public ClrMamePro(DatFile datFile, bool quotes)
: base(datFile) : base(datFile)
{ {
Quotes = quotes;
} }
/// <summary> /// <summary>
@@ -37,7 +48,8 @@ namespace SabreTools.Library.DatFiles
Encoding enc = FileExtensions.GetEncoding(filename); Encoding enc = FileExtensions.GetEncoding(filename);
ClrMameProReader cmpr = new ClrMameProReader(FileExtensions.TryOpenRead(filename), enc) ClrMameProReader cmpr = new ClrMameProReader(FileExtensions.TryOpenRead(filename), enc)
{ {
DosCenter = false DosCenter = false,
Quotes = Quotes,
}; };
while (!cmpr.EndOfStream) while (!cmpr.EndOfStream)
@@ -445,7 +457,7 @@ namespace SabreTools.Library.DatFiles
ClrMameProWriter cmpw = new ClrMameProWriter(fs, new UTF8Encoding(false)) ClrMameProWriter cmpw = new ClrMameProWriter(fs, new UTF8Encoding(false))
{ {
Quotes = true Quotes = Quotes
}; };
// Write out the header // Write out the header

View File

@@ -65,8 +65,9 @@ namespace SabreTools.Library.DatFiles
/// </summary> /// </summary>
/// <param name="datFormat">Format of the DAT to be created</param> /// <param name="datFormat">Format of the DAT to be created</param>
/// <param name="baseDat">DatFile containing the information to use in specific operations</param> /// <param name="baseDat">DatFile containing the information to use in specific operations</param>
/// <param name="quotes">For relevant types, assume the usage of quotes</param>
/// <returns>DatFile of the specific internal type that corresponds to the inputs</returns> /// <returns>DatFile of the specific internal type that corresponds to the inputs</returns>
public static DatFile Create(DatFormat? datFormat = null, DatFile baseDat = null) public static DatFile Create(DatFormat? datFormat = null, DatFile baseDat = null, bool quotes = true)
{ {
switch (datFormat) switch (datFormat)
{ {
@@ -74,7 +75,7 @@ namespace SabreTools.Library.DatFiles
return new AttractMode(baseDat); return new AttractMode(baseDat);
case DatFormat.ClrMamePro: case DatFormat.ClrMamePro:
return new ClrMamePro(baseDat); return new ClrMamePro(baseDat, quotes);
case DatFormat.CSV: case DatFormat.CSV:
return new SeparatedValue(baseDat, ','); return new SeparatedValue(baseDat, ',');
@@ -1819,16 +1820,18 @@ namespace SabreTools.Library.DatFiles
/// <param name="indexId">Index ID for the DAT</param> /// <param name="indexId">Index ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
/// <param name="keepext">True if original extension should be kept, false otherwise (default)</param> /// <param name="keepext">True if original extension should be kept, false otherwise (default)</param>
/// <param name="quotes">True if quotes are assumed in supported types (default), false otherwise</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param> /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
public void Parse( public void Parse(
string filename, string filename,
int indexId = 0, int indexId = 0,
bool keep = false, bool keep = false,
bool keepext = false, bool keepext = false,
bool quotes = true,
bool throwOnError = false) bool throwOnError = false)
{ {
ParentablePath path = new ParentablePath(filename.Trim('"')); ParentablePath path = new ParentablePath(filename.Trim('"'));
Parse(path, indexId, keep, keepext, throwOnError); Parse(path, indexId, keep, keepext, quotes, throwOnError);
} }
/// <summary> /// <summary>
@@ -1838,12 +1841,14 @@ namespace SabreTools.Library.DatFiles
/// <param name="indexId">Index ID for the DAT</param> /// <param name="indexId">Index ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
/// <param name="keepext">True if original extension should be kept, false otherwise (default)</param> /// <param name="keepext">True if original extension should be kept, false otherwise (default)</param>
/// <param name="quotes">True if quotes are assumed in supported types (default), false otherwise</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param> /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
public void Parse( public void Parse(
ParentablePath filename, ParentablePath filename,
int indexId = 0, int indexId = 0,
bool keep = false, bool keep = false,
bool keepext = false, bool keepext = false,
bool quotes = true,
bool throwOnError = false) bool throwOnError = false)
{ {
// Get the current path from the filename // Get the current path from the filename
@@ -1863,7 +1868,7 @@ namespace SabreTools.Library.DatFiles
// Now parse the correct type of DAT // Now parse the correct type of DAT
try try
{ {
Create(currentPath.GetDatFormat(), this)?.ParseFile(currentPath, indexId, keep, throwOnError); Create(currentPath.GetDatFormat(), this, quotes)?.ParseFile(currentPath, indexId, keep, throwOnError);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -3484,9 +3489,15 @@ namespace SabreTools.Library.DatFiles
/// <param name="outDir">Set the output directory (current directory on null)</param> /// <param name="outDir">Set the output directory (current directory on null)</param>
/// <param name="overwrite">True if files should be overwritten (default), false if they should be renamed instead</param> /// <param name="overwrite">True if files should be overwritten (default), false if they should be renamed instead</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param> /// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <param name="quotes">True if quotes are assumed in supported types (default), false otherwise</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param> /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns> /// <returns>True if the DAT was written correctly, false otherwise</returns>
public bool Write(string outDir, bool overwrite = true, bool ignoreblanks = false, bool throwOnError = false) public bool Write(
string outDir,
bool overwrite = true,
bool ignoreblanks = false,
bool quotes = true,
bool throwOnError = false)
{ {
// If we have nothing writable, abort // If we have nothing writable, abort
if (!HasWritable()) if (!HasWritable())
@@ -3525,7 +3536,7 @@ namespace SabreTools.Library.DatFiles
string outfile = outfiles[datFormat]; string outfile = outfiles[datFormat];
try try
{ {
Create(datFormat, this)?.WriteToFile(outfile, ignoreblanks, throwOnError); Create(datFormat, this, quotes)?.WriteToFile(outfile, ignoreblanks, throwOnError);
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@@ -526,7 +526,7 @@ namespace SabreTools.Library.Data
public const string XmlPattern = @"<(.*?)>(.*?)</(.*?)>"; public const string XmlPattern = @"<(.*?)>(.*?)</(.*?)>";
public const string HeaderPatternCMP = @"(^.*?) \($"; public const string HeaderPatternCMP = @"(^.*?) \($";
public const string InternalPatternCMP = @"(^.*?) (\(.+\))$"; public const string InternalPatternCMP = @"(^\S*?) (\(.+\))$";
public const string InternalPatternAttributesCMP = @"[^\s""]+|""[^""]*"""; public const string InternalPatternAttributesCMP = @"[^\s""]+|""[^""]*""";
//public const string InternalPatternAttributesCMP = @"([^\s]*""[^""]+""[^\s]*)|[^""]?\w+[^""]?"; //public const string InternalPatternAttributesCMP = @"([^\s]*""[^""]+""[^\s]*)|[^""]?\w+[^""]?";
public const string ItemPatternCMP = @"^\s*(\S*?) (.*)"; public const string ItemPatternCMP = @"^\s*(\S*?) (.*)";

View File

@@ -42,6 +42,17 @@ namespace SabreTools.Library.IO
/// </summary> /// </summary>
public bool DosCenter { get; set; } = false; public bool DosCenter { get; set; } = false;
/// <summary>
/// Get if quotes should surround attribute values
/// </summary>
/// <remarks>
/// If this is disabled, then a special bit of code will be
/// invoked to deal with unquoted, multi-part names. This can
/// backfire in a lot of circumstances, so don't disable this
/// unless you know what you're doing
/// </remarks>
public bool Quotes { get; set; } = true;
/// <summary> /// <summary>
/// Current row type /// Current row type
/// </summary> /// </summary>
@@ -166,6 +177,22 @@ namespace SabreTools.Library.IO
value = linegc[++i].Replace("\"", string.Empty); value = linegc[++i].Replace("\"", string.Empty);
} }
} }
// Special case for assumed unquoted values (only affects `name`)
else if (!Quotes && key == "name")
{
while (++i < linegc.Length
&& linegc[i] != "merge"
&& linegc[i] != "size"
&& linegc[i] != "crc"
&& linegc[i] != "md5"
&& linegc[i] != "sha1")
{
value += $" {linegc[i]}";
}
value = value.Trim();
i--;
}
else else
{ {
// Special cases for standalone statuses // Special cases for standalone statuses