[DatFiles/] Whitespace and cleanup

This commit is contained in:
Matt Nadareski
2019-01-11 13:43:15 -08:00
parent 621ae2f230
commit 51e92c4472
14 changed files with 8457 additions and 8474 deletions

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;
using SabreTools.Library.Data;
using SabreTools.Library.DatItems;
using SabreTools.Library.Tools;
@@ -19,248 +18,248 @@ using NaturalSort;
namespace SabreTools.Library.DatFiles
{
/// <summary>
/// Represents parsing and writing of an AttractMode DAT
/// </summary>
internal class AttractMode : DatFile
{
/// <summary>
/// Constructor designed for casting a base DatFile
/// </summary>
/// <param name="datFile">Parent DatFile to copy from</param>
public AttractMode(DatFile datFile)
: base(datFile, cloneHeader: false)
{
}
/// <summary>
/// Represents parsing and writing of an AttractMode DAT
/// </summary>
internal class AttractMode : DatFile
{
/// <summary>
/// Constructor designed for casting a base DatFile
/// </summary>
/// <param name="datFile">Parent DatFile to copy from</param>
public AttractMode(DatFile datFile)
: base(datFile, cloneHeader: false)
{
}
/// <summary>
/// Parse an AttractMode DAT and return all found games within
/// </summary>
/// <param name="filename">Name of the file to be parsed</param>
/// <param name="sysid">System ID for the DAT</param>
/// <param name="srcid">Source ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, 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>
public override void ParseFile(
// Standard Dat parsing
string filename,
int sysid,
int srcid,
/// <summary>
/// Parse an AttractMode DAT and return all found games within
/// </summary>
/// <param name="filename">Name of the file to be parsed</param>
/// <param name="sysid">System ID for the DAT</param>
/// <param name="srcid">Source ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, 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>
public override void ParseFile(
// Standard Dat parsing
string filename,
int sysid,
int srcid,
// Miscellaneous
bool keep,
bool clean,
bool remUnicode)
{
// Open a file reader
Encoding enc = Utilities.GetEncoding(filename);
StreamReader sr = new StreamReader(Utilities.TryOpenRead(filename), enc);
// Miscellaneous
bool keep,
bool clean,
bool remUnicode)
{
// Open a file reader
Encoding enc = Utilities.GetEncoding(filename);
StreamReader sr = new StreamReader(Utilities.TryOpenRead(filename), enc);
sr.ReadLine(); // Skip the first line since it's the header
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
sr.ReadLine(); // Skip the first line since it's the header
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
/*
The gameinfo order is as follows
0 - game name
1 - game description
2 - emulator name (filename)
3 - cloneof
4 - year
5 - manufacturer
6 - category
7 - players
8 - rotation
9 - control
10 - status
11 - displaycount
12 - displaytype
13 - alt romname
14 - alt title
15 - extra
16 - buttons
*/
/*
The gameinfo order is as follows
0 - game name
1 - game description
2 - emulator name (filename)
3 - cloneof
4 - year
5 - manufacturer
6 - category
7 - players
8 - rotation
9 - control
10 - status
11 - displaycount
12 - displaytype
13 - alt romname
14 - alt title
15 - extra
16 - buttons
*/
string[] gameinfo = line.Split(';');
string[] gameinfo = line.Split(';');
Rom rom = new Rom
{
Name = "-",
Size = Constants.SizeZero,
CRC = Constants.CRCZero,
MD5 = Constants.MD5Zero,
SHA1 = Constants.SHA1Zero,
ItemStatus = ItemStatus.None,
Rom rom = new Rom
{
Name = "-",
Size = Constants.SizeZero,
CRC = Constants.CRCZero,
MD5 = Constants.MD5Zero,
SHA1 = Constants.SHA1Zero,
ItemStatus = ItemStatus.None,
MachineName = gameinfo[0],
MachineDescription = gameinfo[1],
CloneOf = gameinfo[3],
Year = gameinfo[4],
Manufacturer = gameinfo[5],
Comment = gameinfo[15],
};
MachineName = gameinfo[0],
MachineDescription = gameinfo[1],
CloneOf = gameinfo[3],
Year = gameinfo[4],
Manufacturer = gameinfo[5],
Comment = gameinfo[15],
};
// Now process and add the rom
ParseAddHelper(rom, clean, remUnicode);
}
// Now process and add the rom
ParseAddHelper(rom, clean, remUnicode);
}
sr.Dispose();
}
sr.Dispose();
}
/// <summary>
/// Create and open an output file for writing direct from a dictionary
/// </summary>
/// <param name="outfile">Name of the file to write to</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns>
public bool WriteToFile(string outfile)
{
try
{
Globals.Logger.User("Opening file for writing: {0}", outfile);
FileStream fs = Utilities.TryCreate(outfile);
/// <summary>
/// Create and open an output file for writing direct from a dictionary
/// </summary>
/// <param name="outfile">Name of the file to write to</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns>
public bool WriteToFile(string outfile)
{
try
{
Globals.Logger.User("Opening file for writing: {0}", outfile);
FileStream fs = Utilities.TryCreate(outfile);
// If we get back null for some reason, just log and return
if (fs == null)
{
Globals.Logger.Warning("File '{0}' could not be created for writing! Please check to see if the file is writable", outfile);
return false;
}
// If we get back null for some reason, just log and return
if (fs == null)
{
Globals.Logger.Warning("File '{0}' could not be created for writing! Please check to see if the file is writable", outfile);
return false;
}
StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(false));
StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(false));
// Write out the header
WriteHeader(sw);
// Write out the header
WriteHeader(sw);
// Write out each of the machines and roms
string lastgame = null;
// Write out each of the machines and roms
string lastgame = null;
// Get a properly sorted set of keys
List<string> keys = Keys;
keys.Sort(new NaturalComparer());
// Get a properly sorted set of keys
List<string> keys = Keys;
keys.Sort(new NaturalComparer());
foreach (string key in keys)
{
List<DatItem> roms = this[key];
foreach (string key in keys)
{
List<DatItem> roms = this[key];
// Resolve the names in the block
roms = DatItem.ResolveNames(roms);
// Resolve the names in the block
roms = DatItem.ResolveNames(roms);
for (int index = 0; index < roms.Count; index++)
{
DatItem item = roms[index];
for (int index = 0; index < roms.Count; index++)
{
DatItem item = roms[index];
// There are apparently times when a null rom can skip by, skip them
if (item.Name == null || item.MachineName == null)
{
Globals.Logger.Warning("Null rom found!");
continue;
}
// There are apparently times when a null rom can skip by, skip them
if (item.Name == null || item.MachineName == null)
{
Globals.Logger.Warning("Null rom found!");
continue;
}
// If we have a new game, output the beginning of the new item
if (lastgame == null || lastgame.ToLowerInvariant() != item.MachineName.ToLowerInvariant())
{
WriteStartGame(sw, item);
}
// If we have a new game, output the beginning of the new item
if (lastgame == null || lastgame.ToLowerInvariant() != item.MachineName.ToLowerInvariant())
{
WriteStartGame(sw, item);
}
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (item.ItemType == ItemType.Rom
&& ((Rom)item).Size == -1
&& ((Rom)item).CRC == "null")
{
Globals.Logger.Verbose("Empty folder found: {0}", item.MachineName);
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (item.ItemType == ItemType.Rom
&& ((Rom)item).Size == -1
&& ((Rom)item).CRC == "null")
{
Globals.Logger.Verbose("Empty folder found: {0}", item.MachineName);
item.Name = (item.Name == "null" ? "-" : item.Name);
((Rom)item).Size = Constants.SizeZero;
}
item.Name = (item.Name == "null" ? "-" : item.Name);
((Rom)item).Size = Constants.SizeZero;
}
// Set the new data to compare against
lastgame = item.MachineName;
}
}
// Set the new data to compare against
lastgame = item.MachineName;
}
}
Globals.Logger.Verbose("File written!" + Environment.NewLine);
sw.Dispose();
fs.Dispose();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
Globals.Logger.Verbose("File written!" + Environment.NewLine);
sw.Dispose();
fs.Dispose();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
return true;
}
/// <summary>
/// Write out DAT header using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteHeader(StreamWriter sw)
{
try
{
string header = "#Title;Name;Emulator;CloneOf;Year;Manufacturer;Category;Players;Rotation;Control;Status;DisplayCount;DisplayType;AltRomname;AltTitle;Extra;Buttons\n";
/// <summary>
/// Write out DAT header using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteHeader(StreamWriter sw)
{
try
{
string header = "#Title;Name;Emulator;CloneOf;Year;Manufacturer;Category;Players;Rotation;Control;Status;DisplayCount;DisplayType;AltRomname;AltTitle;Extra;Buttons\n";
// Write the header out
sw.Write(header);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
// Write the header out
sw.Write(header);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
return true;
}
/// <summary>
/// Write out Game start using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <param name="rom">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteStartGame(StreamWriter sw, DatItem rom)
{
try
{
// No game should start with a path separator
if (rom.MachineName.StartsWith(Path.DirectorySeparatorChar.ToString()))
{
rom.MachineName = rom.MachineName.Substring(1);
}
/// <summary>
/// Write out Game start using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <param name="rom">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteStartGame(StreamWriter sw, DatItem rom)
{
try
{
// No game should start with a path separator
if (rom.MachineName.StartsWith(Path.DirectorySeparatorChar.ToString()))
{
rom.MachineName = rom.MachineName.Substring(1);
}
string state = (!ExcludeFields[(int)Field.MachineName] ? rom.MachineName : "") + ";"
+ (!ExcludeFields[(int)Field.Description] ? rom.MachineDescription : "") + ";"
+ FileName + ";"
+ (!ExcludeFields[(int)Field.CloneOf] ? rom.CloneOf : "") + ";"
+ (!ExcludeFields[(int)Field.Year] ? rom.Year : "") + ";"
+ (!ExcludeFields[(int)Field.Manufacturer] ? rom.Manufacturer : "") + ";"
/* + rom.Category */ + ";"
/* + rom.Players */ + ";"
/* + rom.Rotation */ + ";"
/* + rom.Control */ + ";"
/* + rom.Status */ + ";"
/* + rom.DisplayCount */ + ";"
/* + rom.DisplayType */ + ";"
/* + rom.AltRomname */ + ";"
/* + rom.AltTitle */ + ";"
+ (!ExcludeFields[(int)Field.Comment] ? rom.Comment : "") + ";"
/* + rom.Buttons */ + "\n";
string state = (!ExcludeFields[(int)Field.MachineName] ? rom.MachineName : "") + ";"
+ (!ExcludeFields[(int)Field.Description] ? rom.MachineDescription : "") + ";"
+ FileName + ";"
+ (!ExcludeFields[(int)Field.CloneOf] ? rom.CloneOf : "") + ";"
+ (!ExcludeFields[(int)Field.Year] ? rom.Year : "") + ";"
+ (!ExcludeFields[(int)Field.Manufacturer] ? rom.Manufacturer : "") + ";"
/* + rom.Category */ + ";"
/* + rom.Players */ + ";"
/* + rom.Rotation */ + ";"
/* + rom.Control */ + ";"
/* + rom.Status */ + ";"
/* + rom.DisplayCount */ + ";"
/* + rom.DisplayType */ + ";"
/* + rom.AltRomname */ + ";"
/* + rom.AltTitle */ + ";"
+ (!ExcludeFields[(int)Field.Comment] ? rom.Comment : "") + ";"
/* + rom.Buttons */ + "\n";
sw.Write(state);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
sw.Write(state);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
}
return true;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SabreTools.Library.Data;
using SabreTools.Library.DatItems;
using SabreTools.Library.Tools;
@@ -19,313 +18,313 @@ using NaturalSort;
namespace SabreTools.Library.DatFiles
{
/// <summary>
/// Represents parsing and writing of a DosCenter DAT
/// </summary>
internal class DosCenter : DatFile
{
/// <summary>
/// Constructor designed for casting a base DatFile
/// </summary>
/// <param name="datFile">Parent DatFile to copy from</param>
public DosCenter(DatFile datFile)
: base(datFile, cloneHeader: false)
{
}
/// <summary>
/// Represents parsing and writing of a DosCenter DAT
/// </summary>
internal class DosCenter : DatFile
{
/// <summary>
/// Constructor designed for casting a base DatFile
/// </summary>
/// <param name="datFile">Parent DatFile to copy from</param>
public DosCenter(DatFile datFile)
: base(datFile, cloneHeader: false)
{
}
/// <summary>
/// Parse a DosCenter DAT and return all found games and roms within
/// </summary>
/// <param name="filename">Name of the file to be parsed</param>
/// <param name="sysid">System ID for the DAT</param>
/// <param name="srcid">Source ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, 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>
/// TODO: Pull parsing into this file instead of relying on CMP
public override void ParseFile(
// Standard Dat parsing
string filename,
int sysid,
int srcid,
/// <summary>
/// Parse a DosCenter DAT and return all found games and roms within
/// </summary>
/// <param name="filename">Name of the file to be parsed</param>
/// <param name="sysid">System ID for the DAT</param>
/// <param name="srcid">Source ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, 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>
/// TODO: Pull parsing into this file instead of relying on CMP
public override void ParseFile(
// Standard Dat parsing
string filename,
int sysid,
int srcid,
// Miscellaneous
bool keep,
bool clean,
bool remUnicode)
{
// ClrMamePro and DosCenter parsing are identical so it just calls one implementation
new ClrMamePro(this).ParseFile(filename, sysid, srcid, keep, clean, remUnicode);
}
// Miscellaneous
bool keep,
bool clean,
bool remUnicode)
{
// ClrMamePro and DosCenter parsing are identical so it just calls one implementation
new ClrMamePro(this).ParseFile(filename, sysid, srcid, keep, clean, remUnicode);
}
/// <summary>
/// Create and open an output file for writing direct from a dictionary
/// </summary>
/// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false)
{
try
{
Globals.Logger.User("Opening file for writing: {0}", outfile);
FileStream fs = Utilities.TryCreate(outfile);
/// <summary>
/// Create and open an output file for writing direct from a dictionary
/// </summary>
/// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false)
{
try
{
Globals.Logger.User("Opening file for writing: {0}", outfile);
FileStream fs = Utilities.TryCreate(outfile);
// If we get back null for some reason, just log and return
if (fs == null)
{
Globals.Logger.Warning("File '{0}' could not be created for writing! Please check to see if the file is writable", outfile);
return false;
}
// If we get back null for some reason, just log and return
if (fs == null)
{
Globals.Logger.Warning("File '{0}' could not be created for writing! Please check to see if the file is writable", outfile);
return false;
}
StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(false));
StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(false));
// Write out the header
WriteHeader(sw);
// Write out the header
WriteHeader(sw);
// Write out each of the machines and roms
string lastgame = null;
// Write out each of the machines and roms
string lastgame = null;
// Get a properly sorted set of keys
List<string> keys = Keys;
keys.Sort(new NaturalComparer());
// Get a properly sorted set of keys
List<string> keys = Keys;
keys.Sort(new NaturalComparer());
foreach (string key in keys)
{
List<DatItem> roms = this[key];
foreach (string key in keys)
{
List<DatItem> roms = this[key];
// Resolve the names in the block
roms = DatItem.ResolveNames(roms);
// Resolve the names in the block
roms = DatItem.ResolveNames(roms);
for (int index = 0; index < roms.Count; index++)
{
DatItem rom = roms[index];
for (int index = 0; index < roms.Count; index++)
{
DatItem rom = roms[index];
// There are apparently times when a null rom can skip by, skip them
if (rom.Name == null || rom.MachineName == null)
{
Globals.Logger.Warning("Null rom found!");
continue;
}
// There are apparently times when a null rom can skip by, skip them
if (rom.Name == null || rom.MachineName == null)
{
Globals.Logger.Warning("Null rom found!");
continue;
}
List<string> newsplit = rom.MachineName.Split('\\').ToList();
List<string> newsplit = rom.MachineName.Split('\\').ToList();
// If we have a different game and we're not at the start of the list, output the end of last item
if (lastgame != null && lastgame.ToLowerInvariant() != rom.MachineName.ToLowerInvariant())
{
WriteEndGame(sw, rom);
}
// If we have a different game and we're not at the start of the list, output the end of last item
if (lastgame != null && lastgame.ToLowerInvariant() != rom.MachineName.ToLowerInvariant())
{
WriteEndGame(sw, rom);
}
// If we have a new game, output the beginning of the new item
if (lastgame == null || lastgame.ToLowerInvariant() != rom.MachineName.ToLowerInvariant())
{
WriteStartGame(sw, rom);
}
// If we have a new game, output the beginning of the new item
if (lastgame == null || lastgame.ToLowerInvariant() != rom.MachineName.ToLowerInvariant())
{
WriteStartGame(sw, rom);
}
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
{
Globals.Logger.Verbose("Empty folder found: {0}", rom.MachineName);
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
{
Globals.Logger.Verbose("Empty folder found: {0}", rom.MachineName);
rom.Name = (rom.Name == "null" ? "-" : rom.Name);
((Rom)rom).Size = Constants.SizeZero;
((Rom)rom).CRC = ((Rom)rom).CRC == "null" ? Constants.CRCZero : null;
((Rom)rom).MD5 = ((Rom)rom).MD5 == "null" ? Constants.MD5Zero : null;
((Rom)rom).SHA1 = ((Rom)rom).SHA1 == "null" ? Constants.SHA1Zero : null;
((Rom)rom).SHA256 = ((Rom)rom).SHA256 == "null" ? Constants.SHA256Zero : null;
((Rom)rom).SHA384 = ((Rom)rom).SHA384 == "null" ? Constants.SHA384Zero : null;
((Rom)rom).SHA512 = ((Rom)rom).SHA512 == "null" ? Constants.SHA512Zero : null;
}
rom.Name = (rom.Name == "null" ? "-" : rom.Name);
((Rom)rom).Size = Constants.SizeZero;
((Rom)rom).CRC = ((Rom)rom).CRC == "null" ? Constants.CRCZero : null;
((Rom)rom).MD5 = ((Rom)rom).MD5 == "null" ? Constants.MD5Zero : null;
((Rom)rom).SHA1 = ((Rom)rom).SHA1 == "null" ? Constants.SHA1Zero : null;
((Rom)rom).SHA256 = ((Rom)rom).SHA256 == "null" ? Constants.SHA256Zero : null;
((Rom)rom).SHA384 = ((Rom)rom).SHA384 == "null" ? Constants.SHA384Zero : null;
((Rom)rom).SHA512 = ((Rom)rom).SHA512 == "null" ? Constants.SHA512Zero : null;
}
// Now, output the rom data
WriteDatItem(sw, rom, ignoreblanks);
// Now, output the rom data
WriteDatItem(sw, rom, ignoreblanks);
// Set the new data to compare against
lastgame = rom.MachineName;
}
}
// Set the new data to compare against
lastgame = rom.MachineName;
}
}
// Write the file footer out
WriteFooter(sw);
// Write the file footer out
WriteFooter(sw);
Globals.Logger.Verbose("File written!" + Environment.NewLine);
sw.Dispose();
fs.Dispose();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
Globals.Logger.Verbose("File written!" + Environment.NewLine);
sw.Dispose();
fs.Dispose();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
return true;
}
/// <summary>
/// Write out DAT header using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteHeader(StreamWriter sw)
{
try
{
string header = "DOSCenter (\n" +
"\tName: " + Name + "\n" +
"\tDescription: " + Description + "\n" +
"\tVersion: " + Version + "\n" +
"\tDate: " + Date + "\n" +
"\tAuthor: " + Author + "\n" +
"\tHomepage: " + Homepage + "\n" +
"\tComment: " + Comment + "\n" +
")\n";
/// <summary>
/// Write out DAT header using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteHeader(StreamWriter sw)
{
try
{
string header = "DOSCenter (\n" +
"\tName: " + Name + "\n" +
"\tDescription: " + Description + "\n" +
"\tVersion: " + Version + "\n" +
"\tDate: " + Date + "\n" +
"\tAuthor: " + Author + "\n" +
"\tHomepage: " + Homepage + "\n" +
"\tComment: " + Comment + "\n" +
")\n";
// Write the header out
sw.Write(header);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
// Write the header out
sw.Write(header);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
return true;
}
/// <summary>
/// Write out Game start using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <param name="rom">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteStartGame(StreamWriter sw, DatItem rom)
{
try
{
// No game should start with a path separator
if (rom.MachineName.StartsWith(Path.DirectorySeparatorChar.ToString()))
{
rom.MachineName = rom.MachineName.Substring(1);
}
/// <summary>
/// Write out Game start using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <param name="rom">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteStartGame(StreamWriter sw, DatItem rom)
{
try
{
// No game should start with a path separator
if (rom.MachineName.StartsWith(Path.DirectorySeparatorChar.ToString()))
{
rom.MachineName = rom.MachineName.Substring(1);
}
string state = "game (\n\tname \"" + (!ExcludeFields[(int)Field.MachineName] ? rom.MachineName + ".zip" : "") + "\"\n";
string state = "game (\n\tname \"" + (!ExcludeFields[(int)Field.MachineName] ? rom.MachineName + ".zip" : "") + "\"\n";
sw.Write(state);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
sw.Write(state);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
return true;
}
/// <summary>
/// Write out Game end using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <param name="rom">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteEndGame(StreamWriter sw, DatItem rom)
{
try
{
string state = (!ExcludeFields[(int)Field.SampleOf] && String.IsNullOrWhiteSpace(rom.SampleOf) ? "" : "\tsampleof \"" + rom.SampleOf + "\"\n") + ")\n";
/// <summary>
/// Write out Game end using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <param name="rom">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteEndGame(StreamWriter sw, DatItem rom)
{
try
{
string state = (!ExcludeFields[(int)Field.SampleOf] && String.IsNullOrWhiteSpace(rom.SampleOf) ? "" : "\tsampleof \"" + rom.SampleOf + "\"\n") + ")\n";
sw.Write(state);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
sw.Write(state);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
return true;
}
/// <summary>
/// Write out DatItem using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <param name="rom">DatItem object to be output</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteDatItem(StreamWriter sw, DatItem rom, bool ignoreblanks = false)
{
// If we are in ignore blanks mode AND we have a blank (0-size) rom, skip
if (ignoreblanks
&& (rom.ItemType == ItemType.Rom
&& (((Rom)rom).Size == 0 || ((Rom)rom).Size == -1)))
{
return true;
}
/// <summary>
/// Write out DatItem using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <param name="rom">DatItem object to be output</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteDatItem(StreamWriter sw, DatItem rom, bool ignoreblanks = false)
{
// If we are in ignore blanks mode AND we have a blank (0-size) rom, skip
if (ignoreblanks
&& (rom.ItemType == ItemType.Rom
&& (((Rom)rom).Size == 0 || ((Rom)rom).Size == -1)))
{
return true;
}
try
{
string state = "";
try
{
string state = "";
// Pre-process the item name
ProcessItemName(rom, true);
// Pre-process the item name
ProcessItemName(rom, true);
switch (rom.ItemType)
{
case ItemType.Archive:
case ItemType.BiosSet:
case ItemType.Disk:
case ItemType.Release:
case ItemType.Sample:
// We don't output these at all for DosCenter
break;
case ItemType.Rom:
state += "\tfile ( name " + (!ExcludeFields[(int)Field.Name] ? ((Rom)rom).Name : "")
+ (!ExcludeFields[(int)Field.Size] && ((Rom)rom).Size != -1 ? " size " + ((Rom)rom).Size : "")
+ (!ExcludeFields[(int)Field.Date] && !String.IsNullOrWhiteSpace(((Rom)rom).Date) ? " date " + ((Rom)rom).Date : "")
+ (!ExcludeFields[(int)Field.CRC] && !String.IsNullOrWhiteSpace(((Rom)rom).CRC) ? " crc " + ((Rom)rom).CRC.ToLowerInvariant() : "")
+ " )\n";
break;
}
switch (rom.ItemType)
{
case ItemType.Archive:
case ItemType.BiosSet:
case ItemType.Disk:
case ItemType.Release:
case ItemType.Sample:
// We don't output these at all for DosCenter
break;
case ItemType.Rom:
state += "\tfile ( name " + (!ExcludeFields[(int)Field.Name] ? ((Rom)rom).Name : "")
+ (!ExcludeFields[(int)Field.Size] && ((Rom)rom).Size != -1 ? " size " + ((Rom)rom).Size : "")
+ (!ExcludeFields[(int)Field.Date] && !String.IsNullOrWhiteSpace(((Rom)rom).Date) ? " date " + ((Rom)rom).Date : "")
+ (!ExcludeFields[(int)Field.CRC] && !String.IsNullOrWhiteSpace(((Rom)rom).CRC) ? " crc " + ((Rom)rom).CRC.ToLowerInvariant() : "")
+ " )\n";
break;
}
sw.Write(state);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
sw.Write(state);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
return true;
}
/// <summary>
/// Write out DAT footer using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteFooter(StreamWriter sw)
{
try
{
string footer = ")\n";
/// <summary>
/// Write out DAT footer using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteFooter(StreamWriter sw)
{
try
{
string footer = ")\n";
// Write the footer out
sw.Write(footer);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
// Write the footer out
sw.Write(footer);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
}
return true;
}
}
}

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;
using SabreTools.Library.Data;
using SabreTools.Library.DatItems;
using SabreTools.Library.Tools;
@@ -19,282 +18,282 @@ using NaturalSort;
namespace SabreTools.Library.DatFiles
{
/// <summary>
/// Represents parsing and writing of a hashfile such as an SFV, MD5, or SHA-1 file
/// </summary>
internal class Hashfile : DatFile
{
// Private instance variables specific to Hashfile DATs
Hash _hash;
/// <summary>
/// Represents parsing and writing of a hashfile such as an SFV, MD5, or SHA-1 file
/// </summary>
internal class Hashfile : DatFile
{
// Private instance variables specific to Hashfile DATs
Hash _hash;
/// <summary>
/// Constructor designed for casting a base DatFile
/// </summary>
/// <param name="datFile">Parent DatFile to copy from</param>
/// <param name="hash">Type of hash that is associated with this DAT</param>
public Hashfile(DatFile datFile, Hash hash)
: base(datFile, cloneHeader: false)
{
_hash = hash;
}
/// <summary>
/// Constructor designed for casting a base DatFile
/// </summary>
/// <param name="datFile">Parent DatFile to copy from</param>
/// <param name="hash">Type of hash that is associated with this DAT</param>
public Hashfile(DatFile datFile, Hash hash)
: base(datFile, cloneHeader: false)
{
_hash = hash;
}
/// <summary>
/// Parse a hashfile or SFV and return all found games and roms within
/// </summary>
/// <param name="filename">Name of the file to be parsed</param>
/// <param name="sysid">System ID for the DAT</param>
/// <param name="srcid">Source ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, 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>
public override void ParseFile(
// Standard Dat parsing
string filename,
int sysid,
int srcid,
/// <summary>
/// Parse a hashfile or SFV and return all found games and roms within
/// </summary>
/// <param name="filename">Name of the file to be parsed</param>
/// <param name="sysid">System ID for the DAT</param>
/// <param name="srcid">Source ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, 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>
public override void ParseFile(
// Standard Dat parsing
string filename,
int sysid,
int srcid,
// Miscellaneous
bool keep,
bool clean,
bool remUnicode)
{
// Open a file reader
Encoding enc = Utilities.GetEncoding(filename);
StreamReader sr = new StreamReader(Utilities.TryOpenRead(filename), enc);
// Miscellaneous
bool keep,
bool clean,
bool remUnicode)
{
// Open a file reader
Encoding enc = Utilities.GetEncoding(filename);
StreamReader sr = new StreamReader(Utilities.TryOpenRead(filename), enc);
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
// Split the line and get the name and hash
string[] split = line.Split(' ');
string name = "";
string hash = "";
// Split the line and get the name and hash
string[] split = line.Split(' ');
string name = "";
string hash = "";
// If we have CRC, then it's an SFV file and the name is first are
if ((_hash & Hash.CRC) != 0)
{
name = split[0].Replace("*", String.Empty);
hash = split[1];
}
// Otherwise, the name is second
else
{
name = split[1].Replace("*", String.Empty);
hash = split[0];
}
// If we have CRC, then it's an SFV file and the name is first are
if ((_hash & Hash.CRC) != 0)
{
name = split[0].Replace("*", String.Empty);
hash = split[1];
}
// Otherwise, the name is second
else
{
name = split[1].Replace("*", String.Empty);
hash = split[0];
}
Rom rom = new Rom
{
Name = name,
Size = -1,
CRC = ((_hash & Hash.CRC) != 0 ? Utilities.CleanHashData(hash, Constants.CRCLength) : null),
MD5 = ((_hash & Hash.MD5) != 0 ? Utilities.CleanHashData(hash, Constants.MD5Length) : null),
SHA1 = ((_hash & Hash.SHA1) != 0 ? Utilities.CleanHashData(hash, Constants.SHA1Length) : null),
SHA256 = ((_hash & Hash.SHA256) != 0 ? Utilities.CleanHashData(hash, Constants.SHA256Length) : null),
SHA384 = ((_hash & Hash.SHA384) != 0 ? Utilities.CleanHashData(hash, Constants.SHA384Length) : null),
SHA512 = ((_hash & Hash.SHA512) != 0 ? Utilities.CleanHashData(hash, Constants.SHA512Length) : null),
ItemStatus = ItemStatus.None,
Rom rom = new Rom
{
Name = name,
Size = -1,
CRC = ((_hash & Hash.CRC) != 0 ? Utilities.CleanHashData(hash, Constants.CRCLength) : null),
MD5 = ((_hash & Hash.MD5) != 0 ? Utilities.CleanHashData(hash, Constants.MD5Length) : null),
SHA1 = ((_hash & Hash.SHA1) != 0 ? Utilities.CleanHashData(hash, Constants.SHA1Length) : null),
SHA256 = ((_hash & Hash.SHA256) != 0 ? Utilities.CleanHashData(hash, Constants.SHA256Length) : null),
SHA384 = ((_hash & Hash.SHA384) != 0 ? Utilities.CleanHashData(hash, Constants.SHA384Length) : null),
SHA512 = ((_hash & Hash.SHA512) != 0 ? Utilities.CleanHashData(hash, Constants.SHA512Length) : null),
ItemStatus = ItemStatus.None,
MachineName = Path.GetFileNameWithoutExtension(filename),
MachineName = Path.GetFileNameWithoutExtension(filename),
SystemID = sysid,
SourceID = srcid,
};
SystemID = sysid,
SourceID = srcid,
};
// Now process and add the rom
ParseAddHelper(rom, clean, remUnicode);
}
// Now process and add the rom
ParseAddHelper(rom, clean, remUnicode);
}
sr.Dispose();
}
sr.Dispose();
}
/// <summary>
/// Create and open an output file for writing direct from a dictionary
/// </summary>
/// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false)
{
try
{
Globals.Logger.User("Opening file for writing: {0}", outfile);
FileStream fs = Utilities.TryCreate(outfile);
/// <summary>
/// Create and open an output file for writing direct from a dictionary
/// </summary>
/// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false)
{
try
{
Globals.Logger.User("Opening file for writing: {0}", outfile);
FileStream fs = Utilities.TryCreate(outfile);
// If we get back null for some reason, just log and return
if (fs == null)
{
Globals.Logger.Warning("File '{0}' could not be created for writing! Please check to see if the file is writable", outfile);
return false;
}
// If we get back null for some reason, just log and return
if (fs == null)
{
Globals.Logger.Warning("File '{0}' could not be created for writing! Please check to see if the file is writable", outfile);
return false;
}
StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(false));
StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(false));
// Get a properly sorted set of keys
List<string> keys = Keys;
keys.Sort(new NaturalComparer());
// Get a properly sorted set of keys
List<string> keys = Keys;
keys.Sort(new NaturalComparer());
foreach (string key in keys)
{
List<DatItem> roms = this[key];
foreach (string key in keys)
{
List<DatItem> roms = this[key];
// Resolve the names in the block
roms = DatItem.ResolveNames(roms);
// Resolve the names in the block
roms = DatItem.ResolveNames(roms);
for (int index = 0; index < roms.Count; index++)
{
DatItem rom = roms[index];
for (int index = 0; index < roms.Count; index++)
{
DatItem rom = roms[index];
// There are apparently times when a null rom can skip by, skip them
if (rom.Name == null || rom.MachineName == null)
{
Globals.Logger.Warning("Null rom found!");
continue;
}
// There are apparently times when a null rom can skip by, skip them
if (rom.Name == null || rom.MachineName == null)
{
Globals.Logger.Warning("Null rom found!");
continue;
}
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
{
Globals.Logger.Verbose("Empty folder found: {0}", rom.MachineName);
}
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
{
Globals.Logger.Verbose("Empty folder found: {0}", rom.MachineName);
}
// Now, output the rom data
WriteDatItem(sw, rom, ignoreblanks);
}
}
// Now, output the rom data
WriteDatItem(sw, rom, ignoreblanks);
}
}
Globals.Logger.Verbose("File written!" + Environment.NewLine);
sw.Dispose();
fs.Dispose();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
Globals.Logger.Verbose("File written!" + Environment.NewLine);
sw.Dispose();
fs.Dispose();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
return true;
}
/// <summary>
/// Write out DatItem using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <param name="rom">DatItem object to be output</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteDatItem(StreamWriter sw, DatItem rom, bool ignoreblanks = false)
{
// If we are in ignore blanks mode AND we have a blank (0-size) rom, skip
if (ignoreblanks
&& (rom.ItemType == ItemType.Rom
&& (((Rom)rom).Size == 0 || ((Rom)rom).Size == -1)))
{
return true;
}
/// <summary>
/// Write out DatItem using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <param name="rom">DatItem object to be output</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteDatItem(StreamWriter sw, DatItem rom, bool ignoreblanks = false)
{
// If we are in ignore blanks mode AND we have a blank (0-size) rom, skip
if (ignoreblanks
&& (rom.ItemType == ItemType.Rom
&& (((Rom)rom).Size == 0 || ((Rom)rom).Size == -1)))
{
return true;
}
try
{
string state = "";
try
{
string state = "";
// Pre-process the item name
ProcessItemName(rom, true);
// Pre-process the item name
ProcessItemName(rom, true);
switch (_hash)
{
case Hash.MD5:
if (rom.ItemType == ItemType.Rom)
{
state += (!ExcludeFields[(int)Field.MD5] ? ((Rom)rom).MD5 : "")
+ " *" + (!ExcludeFields[(int)Field.MachineName] && GameName ? rom.MachineName + Path.DirectorySeparatorChar : "")
+ (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
else if (rom.ItemType == ItemType.Disk)
{
state += (!ExcludeFields[(int)Field.MD5] ? ((Disk)rom).MD5 : "")
+ " *" + (!ExcludeFields[(int)Field.MachineName] && GameName ? rom.MachineName + Path.DirectorySeparatorChar : "")
+ (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
break;
case Hash.CRC:
if (rom.ItemType == ItemType.Rom)
{
state += (!ExcludeFields[(int)Field.MachineName] && GameName ? rom.MachineName + Path.DirectorySeparatorChar : "")
+ (!ExcludeFields[(int)Field.Name] ? rom.Name : "")
+ " " + (!ExcludeFields[(int)Field.CRC] ? ((Rom)rom).CRC : "") + "\n";
}
break;
case Hash.SHA1:
if (rom.ItemType == ItemType.Rom)
{
state += (!ExcludeFields[(int)Field.SHA1] ? ((Rom)rom).SHA1 : "")
+ " *" + (!ExcludeFields[(int)Field.MachineName] && GameName ? rom.MachineName + Path.DirectorySeparatorChar : "")
+ (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
else if (rom.ItemType == ItemType.Disk)
{
state += (!ExcludeFields[(int)Field.SHA1] ? ((Disk)rom).SHA1 : "")
+ " *" + (!ExcludeFields[(int)Field.MachineName] && GameName ? rom.MachineName + Path.DirectorySeparatorChar : "")
+ (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
break;
case Hash.SHA256:
if (rom.ItemType == ItemType.Rom)
{
state += (!ExcludeFields[(int)Field.SHA256] ? ((Rom)rom).SHA256 : "")
+ " *" + (!ExcludeFields[(int)Field.MachineName] && GameName ? rom.MachineName + Path.DirectorySeparatorChar : "")
+ (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
else if (rom.ItemType == ItemType.Disk)
{
state += (!ExcludeFields[(int)Field.SHA256] ? ((Disk)rom).SHA256 : "")
+ " *" + (!ExcludeFields[(int)Field.MachineName] && GameName ? rom.MachineName + Path.DirectorySeparatorChar : "")
+ (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
break;
case Hash.SHA384:
if (rom.ItemType == ItemType.Rom)
{
state += (!ExcludeFields[(int)Field.SHA384] ? ((Rom)rom).SHA384 : "")
+ " *" + (!ExcludeFields[(int)Field.MachineName] && GameName ? rom.MachineName + Path.DirectorySeparatorChar : "")
+ (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
else if (rom.ItemType == ItemType.Disk)
{
state += (!ExcludeFields[(int)Field.SHA384] ? ((Disk)rom).SHA384 : "")
+ " *" + (!ExcludeFields[(int)Field.MachineName] && GameName ? rom.MachineName + Path.DirectorySeparatorChar : "")
+ (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
break;
case Hash.SHA512:
if (rom.ItemType == ItemType.Rom)
{
state += (!ExcludeFields[(int)Field.SHA512] ? ((Rom)rom).SHA512 : "")
+ " *" + (!ExcludeFields[(int)Field.MachineName] && GameName ? rom.MachineName + Path.DirectorySeparatorChar : "")
+ (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
else if (rom.ItemType == ItemType.Disk)
{
state += (!ExcludeFields[(int)Field.SHA512] ? ((Disk)rom).SHA512 : "")
+ " *" + (!ExcludeFields[(int)Field.MachineName] && GameName ? rom.MachineName + Path.DirectorySeparatorChar : "")
+ (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
break;
}
switch (_hash)
{
case Hash.MD5:
if (rom.ItemType == ItemType.Rom)
{
state += (!ExcludeFields[(int)Field.MD5] ? ((Rom)rom).MD5 : "")
+ " *" + (!ExcludeFields[(int)Field.MachineName] && GameName ? rom.MachineName + Path.DirectorySeparatorChar : "")
+ (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
else if (rom.ItemType == ItemType.Disk)
{
state += (!ExcludeFields[(int)Field.MD5] ? ((Disk)rom).MD5 : "")
+ " *" + (!ExcludeFields[(int)Field.MachineName] && GameName ? rom.MachineName + Path.DirectorySeparatorChar : "")
+ (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
break;
case Hash.CRC:
if (rom.ItemType == ItemType.Rom)
{
state += (!ExcludeFields[(int)Field.MachineName] && GameName ? rom.MachineName + Path.DirectorySeparatorChar : "")
+ (!ExcludeFields[(int)Field.Name] ? rom.Name : "")
+ " " + (!ExcludeFields[(int)Field.CRC] ? ((Rom)rom).CRC : "") + "\n";
}
break;
case Hash.SHA1:
if (rom.ItemType == ItemType.Rom)
{
state += (!ExcludeFields[(int)Field.SHA1] ? ((Rom)rom).SHA1 : "")
+ " *" + (!ExcludeFields[(int)Field.MachineName] && GameName ? rom.MachineName + Path.DirectorySeparatorChar : "")
+ (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
else if (rom.ItemType == ItemType.Disk)
{
state += (!ExcludeFields[(int)Field.SHA1] ? ((Disk)rom).SHA1 : "")
+ " *" + (!ExcludeFields[(int)Field.MachineName] && GameName ? rom.MachineName + Path.DirectorySeparatorChar : "")
+ (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
break;
case Hash.SHA256:
if (rom.ItemType == ItemType.Rom)
{
state += (!ExcludeFields[(int)Field.SHA256] ? ((Rom)rom).SHA256 : "")
+ " *" + (!ExcludeFields[(int)Field.MachineName] && GameName ? rom.MachineName + Path.DirectorySeparatorChar : "")
+ (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
else if (rom.ItemType == ItemType.Disk)
{
state += (!ExcludeFields[(int)Field.SHA256] ? ((Disk)rom).SHA256 : "")
+ " *" + (!ExcludeFields[(int)Field.MachineName] && GameName ? rom.MachineName + Path.DirectorySeparatorChar : "")
+ (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
break;
case Hash.SHA384:
if (rom.ItemType == ItemType.Rom)
{
state += (!ExcludeFields[(int)Field.SHA384] ? ((Rom)rom).SHA384 : "")
+ " *" + (!ExcludeFields[(int)Field.MachineName] && GameName ? rom.MachineName + Path.DirectorySeparatorChar : "")
+ (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
else if (rom.ItemType == ItemType.Disk)
{
state += (!ExcludeFields[(int)Field.SHA384] ? ((Disk)rom).SHA384 : "")
+ " *" + (!ExcludeFields[(int)Field.MachineName] && GameName ? rom.MachineName + Path.DirectorySeparatorChar : "")
+ (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
break;
case Hash.SHA512:
if (rom.ItemType == ItemType.Rom)
{
state += (!ExcludeFields[(int)Field.SHA512] ? ((Rom)rom).SHA512 : "")
+ " *" + (!ExcludeFields[(int)Field.MachineName] && GameName ? rom.MachineName + Path.DirectorySeparatorChar : "")
+ (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
else if (rom.ItemType == ItemType.Disk)
{
state += (!ExcludeFields[(int)Field.SHA512] ? ((Disk)rom).SHA512 : "")
+ " *" + (!ExcludeFields[(int)Field.MachineName] && GameName ? rom.MachineName + Path.DirectorySeparatorChar : "")
+ (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
break;
}
sw.Write(state);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
sw.Write(state);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
}
return true;
}
}
}

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using SabreTools.Library.Data;
using SabreTools.Library.DatItems;
using SabreTools.Library.Tools;
@@ -20,497 +19,497 @@ using NaturalSort;
namespace SabreTools.Library.DatFiles
{
/// <summary>
/// Represents parsing and writing of a MAME Listrom DAT
/// </summary>
internal class Listrom : DatFile
{
/// <summary>
/// Constructor designed for casting a base DatFile
/// </summary>
/// <param name="datFile">Parent DatFile to copy from</param>
public Listrom(DatFile datFile)
: base(datFile, cloneHeader: false)
{
}
/// <summary>
/// Parse a MAME Listrom DAT and return all found games and roms within
/// </summary>
/// <param name="filename">Name of the file to be parsed</param>
/// <param name="sysid">System ID for the DAT</param>
/// <param name="srcid">Source ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, 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>
/// <remarks>
/// In a new style MAME listrom DAT, each game has the following format:
///
/// ROMs required for driver "005".
/// Name Size Checksum
/// 1346b.cpu-u25 2048 CRC(8e68533e) SHA1(a257c556d31691068ed5c991f1fb2b51da4826db)
/// 6331.sound-u8 32 BAD CRC(1d298cb0) SHA1(bb0bb62365402543e3154b9a77be9c75010e6abc) BAD_DUMP
/// 16v8h-blue.u24 279 NO GOOD DUMP KNOWN
/// </remarks>
public override void ParseFile(
// Standard Dat parsing
string filename,
int sysid,
int srcid,
// Miscellaneous
bool keep,
bool clean,
bool remUnicode)
{
// Open a file reader
Encoding enc = Utilities.GetEncoding(filename);
StreamReader sr = new StreamReader(Utilities.TryOpenRead(filename), enc);
string gamename = "";
while (!sr.EndOfStream)
{
string line = sr.ReadLine().Trim();
// If we have a blank line, we just skip it
if (String.IsNullOrWhiteSpace(line))
{
continue;
}
// If we have the descriptor line, ignore it
else if (line == "Name Size Checksum")
{
continue;
}
// If we have the beginning of a game, set the name of the game
else if (line.StartsWith("ROMs required for"))
{
gamename = Regex.Match(line, @"^ROMs required for \S*? ""(.*?)""\.").Groups[1].Value;
}
// If we have a machine with no required roms (usually internal devices), skip it
else if (line.StartsWith("No ROMs required for"))
{
continue;
}
// Otherwise, we assume we have a rom that we need to add
else
{
// First, we preprocess the line so that the rom name is consistently correct
string romname = "";
string[] split = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
// If the line doesn't have the 4 spaces of padding, check for 3
if (split.Length == 1)
{
split = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
}
// If the split is still unsuccessful, log it and skip
if (split.Length == 1)
{
Globals.Logger.Warning("Possibly malformed line: '{0}'", line);
}
romname = split[0];
line = line.Substring(romname.Length);
// Next we separate the ROM into pieces
split = line.Split(new char[0], StringSplitOptions.RemoveEmptyEntries);
// Standard Disks have 2 pieces (name, sha1)
if (split.Length == 1)
{
Disk disk = new Disk()
{
Name = romname,
SHA1 = Utilities.CleanListromHashData(split[0]),
MachineName = gamename,
};
ParseAddHelper(disk, clean, remUnicode);
}
// Baddump Disks have 4 pieces (name, BAD, sha1, BAD_DUMP)
else if (split.Length == 3 && line.EndsWith("BAD_DUMP"))
{
Disk disk = new Disk()
{
Name = romname,
SHA1 = Utilities.CleanListromHashData(split[1]),
ItemStatus = ItemStatus.BadDump,
MachineName = gamename,
};
ParseAddHelper(disk, clean, remUnicode);
}
// Standard ROMs have 4 pieces (name, size, crc, sha1)
else if (split.Length == 3)
{
if (!Int64.TryParse(split[0], out long size))
{
size = 0;
}
Rom rom = new Rom()
{
Name = romname,
Size = size,
CRC = Utilities.CleanListromHashData(split[1]),
SHA1 = Utilities.CleanListromHashData(split[2]),
MachineName = gamename,
};
ParseAddHelper(rom, clean, remUnicode);
}
// Nodump Disks have 5 pieces (name, NO, GOOD, DUMP, KNOWN)
else if (split.Length == 4 && line.EndsWith("NO GOOD DUMP KNOWN"))
{
Disk disk = new Disk()
{
Name = romname,
ItemStatus = ItemStatus.Nodump,
MachineName = gamename,
};
ParseAddHelper(disk, clean, remUnicode);
}
// Baddump ROMs have 6 pieces (name, size, BAD, crc, sha1, BAD_DUMP)
else if (split.Length == 5 && line.EndsWith("BAD_DUMP"))
{
if (!Int64.TryParse(split[0], out long size))
{
size = 0;
}
Rom rom = new Rom()
{
Name = romname,
Size = size,
CRC = Utilities.CleanListromHashData(split[2]),
SHA1 = Utilities.CleanListromHashData(split[3]),
ItemStatus = ItemStatus.BadDump,
MachineName = gamename,
};
ParseAddHelper(rom, clean, remUnicode);
}
// Nodump ROMs have 6 pieces (name, size, NO, GOOD, DUMP, KNOWN)
else if (split.Length == 5 && line.EndsWith("NO GOOD DUMP KNOWN"))
{
if (!Int64.TryParse(split[0], out long size))
{
size = 0;
}
Rom rom = new Rom()
{
Name = romname,
Size = size,
ItemStatus = ItemStatus.Nodump,
MachineName = gamename,
};
ParseAddHelper(rom, clean, remUnicode);
}
// If we have something else, it's invalid
else
{
Globals.Logger.Warning("Invalid line detected: '{0} {1}'", romname, line);
}
}
}
}
/// <summary>
/// Create and open an output file for writing direct from a dictionary
/// </summary>
/// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false)
{
try
{
Globals.Logger.User("Opening file for writing: {0}", outfile);
FileStream fs = Utilities.TryCreate(outfile);
// If we get back null for some reason, just log and return
if (fs == null)
{
Globals.Logger.Warning("File '{0}' could not be created for writing! Please check to see if the file is writable", outfile);
return false;
}
StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(false));
// Write out each of the machines and roms
string lastgame = null;
// Get a properly sorted set of keys
List<string> keys = Keys;
keys.Sort(new NaturalComparer());
foreach (string key in keys)
{
List<DatItem> roms = this[key];
// Resolve the names in the block
roms = DatItem.ResolveNames(roms);
for (int index = 0; index < roms.Count; index++)
{
DatItem rom = roms[index];
// There are apparently times when a null rom can skip by, skip them
if (rom.Name == null || rom.MachineName == null)
{
Globals.Logger.Warning("Null rom found!");
continue;
}
// If we have a different game and we're not at the start of the list, output the end of last item
if (lastgame != null && lastgame.ToLowerInvariant() != rom.MachineName.ToLowerInvariant())
{
WriteEndGame(sw);
}
// If we have a new game, output the beginning of the new item
if (lastgame == null || lastgame.ToLowerInvariant() != rom.MachineName.ToLowerInvariant())
{
WriteStartGame(sw, rom);
}
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
{
Globals.Logger.Verbose("Empty folder found: {0}", rom.MachineName);
rom.Name = (rom.Name == "null" ? "-" : rom.Name);
((Rom)rom).Size = Constants.SizeZero;
((Rom)rom).CRC = ((Rom)rom).CRC == "null" ? Constants.CRCZero : null;
((Rom)rom).MD5 = ((Rom)rom).MD5 == "null" ? Constants.MD5Zero : null;
((Rom)rom).SHA1 = ((Rom)rom).SHA1 == "null" ? Constants.SHA1Zero : null;
((Rom)rom).SHA256 = ((Rom)rom).SHA256 == "null" ? Constants.SHA256Zero : null;
((Rom)rom).SHA384 = ((Rom)rom).SHA384 == "null" ? Constants.SHA384Zero : null;
((Rom)rom).SHA512 = ((Rom)rom).SHA512 == "null" ? Constants.SHA512Zero : null;
}
// Now, output the rom data
WriteDatItem(sw, rom, ignoreblanks);
// Set the new data to compare against
lastgame = rom.MachineName;
}
}
Globals.Logger.Verbose("File written!" + Environment.NewLine);
sw.Dispose();
fs.Dispose();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
/// <summary>
/// Write out Game start using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <param name="rom">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteStartGame(StreamWriter sw, DatItem rom)
{
try
{
// No game should start with a path separator
if (rom.MachineName.StartsWith(Path.DirectorySeparatorChar.ToString()))
{
rom.MachineName = rom.MachineName.Substring(1);
}
string state = "ROMs required for driver \"" + (!ExcludeFields[(int)Field.MachineName] ? rom.MachineName : "") + "\".\n" +
"Name Size Checksum\n";
sw.Write(state);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
/// <summary>
/// Write out Game end using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteEndGame(StreamWriter sw)
{
try
{
string state = "\n";
sw.Write(state);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
/// <summary>
/// Write out DatItem using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <param name="rom">DatItem object to be output</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteDatItem(StreamWriter sw, DatItem rom, bool ignoreblanks = false)
{
// If we are in ignore blanks mode AND we have a blank (0-size) rom, skip
if (ignoreblanks
&& (rom.ItemType == ItemType.Rom
&& (((Rom)rom).Size == 0 || ((Rom)rom).Size == -1)))
{
return true;
}
try
{
string state = "";
// Pre-process the item name
ProcessItemName(rom, true);
switch (rom.ItemType)
{
case ItemType.Archive:
case ItemType.BiosSet:
case ItemType.Release:
case ItemType.Sample:
// We don't output these at all
break;
case ItemType.Disk:
// The name is padded out to a particular length
if (rom.Name.Length < 43)
{
state += rom.Name.PadRight(43, ' ');
}
else
{
state += rom.Name + " ";
}
// If we have a baddump, put the first indicator
if (!ExcludeFields[(int)Field.Status] && ((Disk)rom).ItemStatus == ItemStatus.BadDump)
{
state += " BAD";
}
// If we have a nodump, write out the indicator
if (!ExcludeFields[(int)Field.Status] && ((Disk)rom).ItemStatus == ItemStatus.Nodump)
{
state += " NO GOOD DUMP KNOWN";
}
// Otherwise, write out the SHA-1 hash
else if (!ExcludeFields[(int)Field.SHA1])
{
state += " SHA1(" + ((Disk)rom).SHA1 + ")";
}
// If we have a baddump, put the second indicator
if (!ExcludeFields[(int)Field.Status] && ((Disk)rom).ItemStatus == ItemStatus.BadDump)
{
state += " BAD_DUMP";
}
state += "\n";
break;
case ItemType.Rom:
// The name is padded out to a particular length
if (rom.Name.Length < 40)
{
state += rom.Name.PadRight(43 - (((Rom)rom).Size.ToString().Length), ' ');
}
else
{
state += rom.Name + " ";
}
// If we don't have a nodump, write out the size
if (((Rom)rom).ItemStatus != ItemStatus.Nodump)
{
state += ((Rom)rom).Size;
}
// If we have a baddump, put the first indicator
if (!ExcludeFields[(int)Field.Status] && ((Rom)rom).ItemStatus == ItemStatus.BadDump)
{
state += " BAD";
}
// If we have a nodump, write out the indicator
if (!ExcludeFields[(int)Field.Status] && ((Rom)rom).ItemStatus == ItemStatus.Nodump)
{
state += " NO GOOD DUMP KNOWN";
}
// Otherwise, write out the CRC and SHA-1 hashes
else
{
state += (!ExcludeFields[(int)Field.CRC] ? " CRC(" + ((Rom)rom).CRC + ")" : "");
state += (!ExcludeFields[(int)Field.SHA1] ? " SHA1(" + ((Rom)rom).SHA1 + ")" : "");
}
// If we have a baddump, put the second indicator
if (!ExcludeFields[(int)Field.Status] && ((Rom)rom).ItemStatus == ItemStatus.BadDump)
{
state += " BAD_DUMP";
}
state += "\n";
break;
}
sw.Write(state);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
}
/// <summary>
/// Represents parsing and writing of a MAME Listrom DAT
/// </summary>
internal class Listrom : DatFile
{
/// <summary>
/// Constructor designed for casting a base DatFile
/// </summary>
/// <param name="datFile">Parent DatFile to copy from</param>
public Listrom(DatFile datFile)
: base(datFile, cloneHeader: false)
{
}
/// <summary>
/// Parse a MAME Listrom DAT and return all found games and roms within
/// </summary>
/// <param name="filename">Name of the file to be parsed</param>
/// <param name="sysid">System ID for the DAT</param>
/// <param name="srcid">Source ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, 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>
/// <remarks>
/// In a new style MAME listrom DAT, each game has the following format:
///
/// ROMs required for driver "005".
/// Name Size Checksum
/// 1346b.cpu-u25 2048 CRC(8e68533e) SHA1(a257c556d31691068ed5c991f1fb2b51da4826db)
/// 6331.sound-u8 32 BAD CRC(1d298cb0) SHA1(bb0bb62365402543e3154b9a77be9c75010e6abc) BAD_DUMP
/// 16v8h-blue.u24 279 NO GOOD DUMP KNOWN
/// </remarks>
public override void ParseFile(
// Standard Dat parsing
string filename,
int sysid,
int srcid,
// Miscellaneous
bool keep,
bool clean,
bool remUnicode)
{
// Open a file reader
Encoding enc = Utilities.GetEncoding(filename);
StreamReader sr = new StreamReader(Utilities.TryOpenRead(filename), enc);
string gamename = "";
while (!sr.EndOfStream)
{
string line = sr.ReadLine().Trim();
// If we have a blank line, we just skip it
if (String.IsNullOrWhiteSpace(line))
{
continue;
}
// If we have the descriptor line, ignore it
else if (line == "Name Size Checksum")
{
continue;
}
// If we have the beginning of a game, set the name of the game
else if (line.StartsWith("ROMs required for"))
{
gamename = Regex.Match(line, @"^ROMs required for \S*? ""(.*?)""\.").Groups[1].Value;
}
// If we have a machine with no required roms (usually internal devices), skip it
else if (line.StartsWith("No ROMs required for"))
{
continue;
}
// Otherwise, we assume we have a rom that we need to add
else
{
// First, we preprocess the line so that the rom name is consistently correct
string romname = "";
string[] split = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
// If the line doesn't have the 4 spaces of padding, check for 3
if (split.Length == 1)
{
split = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
}
// If the split is still unsuccessful, log it and skip
if (split.Length == 1)
{
Globals.Logger.Warning("Possibly malformed line: '{0}'", line);
}
romname = split[0];
line = line.Substring(romname.Length);
// Next we separate the ROM into pieces
split = line.Split(new char[0], StringSplitOptions.RemoveEmptyEntries);
// Standard Disks have 2 pieces (name, sha1)
if (split.Length == 1)
{
Disk disk = new Disk()
{
Name = romname,
SHA1 = Utilities.CleanListromHashData(split[0]),
MachineName = gamename,
};
ParseAddHelper(disk, clean, remUnicode);
}
// Baddump Disks have 4 pieces (name, BAD, sha1, BAD_DUMP)
else if (split.Length == 3 && line.EndsWith("BAD_DUMP"))
{
Disk disk = new Disk()
{
Name = romname,
SHA1 = Utilities.CleanListromHashData(split[1]),
ItemStatus = ItemStatus.BadDump,
MachineName = gamename,
};
ParseAddHelper(disk, clean, remUnicode);
}
// Standard ROMs have 4 pieces (name, size, crc, sha1)
else if (split.Length == 3)
{
if (!Int64.TryParse(split[0], out long size))
{
size = 0;
}
Rom rom = new Rom()
{
Name = romname,
Size = size,
CRC = Utilities.CleanListromHashData(split[1]),
SHA1 = Utilities.CleanListromHashData(split[2]),
MachineName = gamename,
};
ParseAddHelper(rom, clean, remUnicode);
}
// Nodump Disks have 5 pieces (name, NO, GOOD, DUMP, KNOWN)
else if (split.Length == 4 && line.EndsWith("NO GOOD DUMP KNOWN"))
{
Disk disk = new Disk()
{
Name = romname,
ItemStatus = ItemStatus.Nodump,
MachineName = gamename,
};
ParseAddHelper(disk, clean, remUnicode);
}
// Baddump ROMs have 6 pieces (name, size, BAD, crc, sha1, BAD_DUMP)
else if (split.Length == 5 && line.EndsWith("BAD_DUMP"))
{
if (!Int64.TryParse(split[0], out long size))
{
size = 0;
}
Rom rom = new Rom()
{
Name = romname,
Size = size,
CRC = Utilities.CleanListromHashData(split[2]),
SHA1 = Utilities.CleanListromHashData(split[3]),
ItemStatus = ItemStatus.BadDump,
MachineName = gamename,
};
ParseAddHelper(rom, clean, remUnicode);
}
// Nodump ROMs have 6 pieces (name, size, NO, GOOD, DUMP, KNOWN)
else if (split.Length == 5 && line.EndsWith("NO GOOD DUMP KNOWN"))
{
if (!Int64.TryParse(split[0], out long size))
{
size = 0;
}
Rom rom = new Rom()
{
Name = romname,
Size = size,
ItemStatus = ItemStatus.Nodump,
MachineName = gamename,
};
ParseAddHelper(rom, clean, remUnicode);
}
// If we have something else, it's invalid
else
{
Globals.Logger.Warning("Invalid line detected: '{0} {1}'", romname, line);
}
}
}
}
/// <summary>
/// Create and open an output file for writing direct from a dictionary
/// </summary>
/// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false)
{
try
{
Globals.Logger.User("Opening file for writing: {0}", outfile);
FileStream fs = Utilities.TryCreate(outfile);
// If we get back null for some reason, just log and return
if (fs == null)
{
Globals.Logger.Warning("File '{0}' could not be created for writing! Please check to see if the file is writable", outfile);
return false;
}
StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(false));
// Write out each of the machines and roms
string lastgame = null;
// Get a properly sorted set of keys
List<string> keys = Keys;
keys.Sort(new NaturalComparer());
foreach (string key in keys)
{
List<DatItem> roms = this[key];
// Resolve the names in the block
roms = DatItem.ResolveNames(roms);
for (int index = 0; index < roms.Count; index++)
{
DatItem rom = roms[index];
// There are apparently times when a null rom can skip by, skip them
if (rom.Name == null || rom.MachineName == null)
{
Globals.Logger.Warning("Null rom found!");
continue;
}
// If we have a different game and we're not at the start of the list, output the end of last item
if (lastgame != null && lastgame.ToLowerInvariant() != rom.MachineName.ToLowerInvariant())
{
WriteEndGame(sw);
}
// If we have a new game, output the beginning of the new item
if (lastgame == null || lastgame.ToLowerInvariant() != rom.MachineName.ToLowerInvariant())
{
WriteStartGame(sw, rom);
}
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
{
Globals.Logger.Verbose("Empty folder found: {0}", rom.MachineName);
rom.Name = (rom.Name == "null" ? "-" : rom.Name);
((Rom)rom).Size = Constants.SizeZero;
((Rom)rom).CRC = ((Rom)rom).CRC == "null" ? Constants.CRCZero : null;
((Rom)rom).MD5 = ((Rom)rom).MD5 == "null" ? Constants.MD5Zero : null;
((Rom)rom).SHA1 = ((Rom)rom).SHA1 == "null" ? Constants.SHA1Zero : null;
((Rom)rom).SHA256 = ((Rom)rom).SHA256 == "null" ? Constants.SHA256Zero : null;
((Rom)rom).SHA384 = ((Rom)rom).SHA384 == "null" ? Constants.SHA384Zero : null;
((Rom)rom).SHA512 = ((Rom)rom).SHA512 == "null" ? Constants.SHA512Zero : null;
}
// Now, output the rom data
WriteDatItem(sw, rom, ignoreblanks);
// Set the new data to compare against
lastgame = rom.MachineName;
}
}
Globals.Logger.Verbose("File written!" + Environment.NewLine);
sw.Dispose();
fs.Dispose();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
/// <summary>
/// Write out Game start using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <param name="rom">DatItem object to be output</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteStartGame(StreamWriter sw, DatItem rom)
{
try
{
// No game should start with a path separator
if (rom.MachineName.StartsWith(Path.DirectorySeparatorChar.ToString()))
{
rom.MachineName = rom.MachineName.Substring(1);
}
string state = "ROMs required for driver \"" + (!ExcludeFields[(int)Field.MachineName] ? rom.MachineName : "") + "\".\n" +
"Name Size Checksum\n";
sw.Write(state);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
/// <summary>
/// Write out Game end using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteEndGame(StreamWriter sw)
{
try
{
string state = "\n";
sw.Write(state);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
/// <summary>
/// Write out DatItem using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <param name="rom">DatItem object to be output</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteDatItem(StreamWriter sw, DatItem rom, bool ignoreblanks = false)
{
// If we are in ignore blanks mode AND we have a blank (0-size) rom, skip
if (ignoreblanks
&& (rom.ItemType == ItemType.Rom
&& (((Rom)rom).Size == 0 || ((Rom)rom).Size == -1)))
{
return true;
}
try
{
string state = "";
// Pre-process the item name
ProcessItemName(rom, true);
switch (rom.ItemType)
{
case ItemType.Archive:
case ItemType.BiosSet:
case ItemType.Release:
case ItemType.Sample:
// We don't output these at all
break;
case ItemType.Disk:
// The name is padded out to a particular length
if (rom.Name.Length < 43)
{
state += rom.Name.PadRight(43, ' ');
}
else
{
state += rom.Name + " ";
}
// If we have a baddump, put the first indicator
if (!ExcludeFields[(int)Field.Status] && ((Disk)rom).ItemStatus == ItemStatus.BadDump)
{
state += " BAD";
}
// If we have a nodump, write out the indicator
if (!ExcludeFields[(int)Field.Status] && ((Disk)rom).ItemStatus == ItemStatus.Nodump)
{
state += " NO GOOD DUMP KNOWN";
}
// Otherwise, write out the SHA-1 hash
else if (!ExcludeFields[(int)Field.SHA1])
{
state += " SHA1(" + ((Disk)rom).SHA1 + ")";
}
// If we have a baddump, put the second indicator
if (!ExcludeFields[(int)Field.Status] && ((Disk)rom).ItemStatus == ItemStatus.BadDump)
{
state += " BAD_DUMP";
}
state += "\n";
break;
case ItemType.Rom:
// The name is padded out to a particular length
if (rom.Name.Length < 40)
{
state += rom.Name.PadRight(43 - (((Rom)rom).Size.ToString().Length), ' ');
}
else
{
state += rom.Name + " ";
}
// If we don't have a nodump, write out the size
if (((Rom)rom).ItemStatus != ItemStatus.Nodump)
{
state += ((Rom)rom).Size;
}
// If we have a baddump, put the first indicator
if (!ExcludeFields[(int)Field.Status] && ((Rom)rom).ItemStatus == ItemStatus.BadDump)
{
state += " BAD";
}
// If we have a nodump, write out the indicator
if (!ExcludeFields[(int)Field.Status] && ((Rom)rom).ItemStatus == ItemStatus.Nodump)
{
state += " NO GOOD DUMP KNOWN";
}
// Otherwise, write out the CRC and SHA-1 hashes
else
{
state += (!ExcludeFields[(int)Field.CRC] ? " CRC(" + ((Rom)rom).CRC + ")" : "");
state += (!ExcludeFields[(int)Field.SHA1] ? " SHA1(" + ((Rom)rom).SHA1 + ")" : "");
}
// If we have a baddump, put the second indicator
if (!ExcludeFields[(int)Field.Status] && ((Rom)rom).ItemStatus == ItemStatus.BadDump)
{
state += " BAD_DUMP";
}
state += "\n";
break;
}
sw.Write(state);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;
using SabreTools.Library.Data;
using SabreTools.Library.DatItems;
using SabreTools.Library.Tools;
@@ -18,176 +17,176 @@ using NaturalSort;
namespace SabreTools.Library.DatFiles
{
/// <summary>
/// Represents parsing and writing of a Missfile
/// </summary>
internal class Missfile : DatFile
{
/// <summary>
/// Constructor designed for casting a base DatFile
/// </summary>
/// <param name="datFile">Parent DatFile to copy from</param>
public Missfile(DatFile datFile)
: base(datFile, cloneHeader: false)
{
}
/// <summary>
/// Represents parsing and writing of a Missfile
/// </summary>
internal class Missfile : DatFile
{
/// <summary>
/// Constructor designed for casting a base DatFile
/// </summary>
/// <param name="datFile">Parent DatFile to copy from</param>
public Missfile(DatFile datFile)
: base(datFile, cloneHeader: false)
{
}
/// <summary>
/// Parse a Missfile and return all found games and roms within
/// </summary>
/// <param name="filename">Name of the file to be parsed</param>
/// <param name="sysid">System ID for the DAT</param>
/// <param name="srcid">Source ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, 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>
public override void ParseFile(
// Standard Dat parsing
string filename,
int sysid,
int srcid,
/// <summary>
/// Parse a Missfile and return all found games and roms within
/// </summary>
/// <param name="filename">Name of the file to be parsed</param>
/// <param name="sysid">System ID for the DAT</param>
/// <param name="srcid">Source ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, 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>
public override void ParseFile(
// Standard Dat parsing
string filename,
int sysid,
int srcid,
// Miscellaneous
bool keep,
bool clean,
bool remUnicode)
{
// There is no consistent way to parse a missfile...
throw new NotImplementedException();
}
// Miscellaneous
bool keep,
bool clean,
bool remUnicode)
{
// There is no consistent way to parse a missfile...
throw new NotImplementedException();
}
/// <summary>
/// Create and open an output file for writing direct from a dictionary
/// </summary>
/// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false)
{
try
{
Globals.Logger.User("Opening file for writing: {0}", outfile);
FileStream fs = Utilities.TryCreate(outfile);
/// <summary>
/// Create and open an output file for writing direct from a dictionary
/// </summary>
/// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false)
{
try
{
Globals.Logger.User("Opening file for writing: {0}", outfile);
FileStream fs = Utilities.TryCreate(outfile);
// If we get back null for some reason, just log and return
if (fs == null)
{
Globals.Logger.Warning("File '{0}' could not be created for writing! Please check to see if the file is writable", outfile);
return false;
}
// If we get back null for some reason, just log and return
if (fs == null)
{
Globals.Logger.Warning("File '{0}' could not be created for writing! Please check to see if the file is writable", outfile);
return false;
}
StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(false));
StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(false));
// Write out each of the machines and roms
string lastgame = null;
// Write out each of the machines and roms
string lastgame = null;
// Get a properly sorted set of keys
List<string> keys = Keys;
keys.Sort(new NaturalComparer());
// Get a properly sorted set of keys
List<string> keys = Keys;
keys.Sort(new NaturalComparer());
foreach (string key in keys)
{
List<DatItem> roms = this[key];
foreach (string key in keys)
{
List<DatItem> roms = this[key];
// Resolve the names in the block
roms = DatItem.ResolveNames(roms);
// Resolve the names in the block
roms = DatItem.ResolveNames(roms);
for (int index = 0; index < roms.Count; index++)
{
DatItem rom = roms[index];
for (int index = 0; index < roms.Count; index++)
{
DatItem rom = roms[index];
// There are apparently times when a null rom can skip by, skip them
if (rom.Name == null || rom.MachineName == null)
{
Globals.Logger.Warning("Null rom found!");
continue;
}
// There are apparently times when a null rom can skip by, skip them
if (rom.Name == null || rom.MachineName == null)
{
Globals.Logger.Warning("Null rom found!");
continue;
}
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
{
Globals.Logger.Verbose("Empty folder found: {0}", rom.MachineName);
lastgame = rom.MachineName;
continue;
}
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
{
Globals.Logger.Verbose("Empty folder found: {0}", rom.MachineName);
lastgame = rom.MachineName;
continue;
}
// Now, output the rom data
WriteDatItem(sw, rom, lastgame, ignoreblanks);
// Now, output the rom data
WriteDatItem(sw, rom, lastgame, ignoreblanks);
// Set the new data to compare against
lastgame = rom.MachineName;
}
}
// Set the new data to compare against
lastgame = rom.MachineName;
}
}
Globals.Logger.Verbose("File written!" + Environment.NewLine);
sw.Dispose();
fs.Dispose();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
Globals.Logger.Verbose("File written!" + Environment.NewLine);
sw.Dispose();
fs.Dispose();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
return true;
}
/// <summary>
/// Write out DatItem using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <param name="rom">DatItem object to be output</param>
/// <param name="lastgame">The name of the last game to be output</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteDatItem(StreamWriter sw, DatItem rom, string lastgame, bool ignoreblanks = false)
{
// If we are in ignore blanks mode AND we have a blank (0-size) rom, skip
if (ignoreblanks
&& (rom.ItemType == ItemType.Rom
&& (((Rom)rom).Size == 0 || ((Rom)rom).Size == -1)))
{
return true;
}
/// <summary>
/// Write out DatItem using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <param name="rom">DatItem object to be output</param>
/// <param name="lastgame">The name of the last game to be output</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteDatItem(StreamWriter sw, DatItem rom, string lastgame, bool ignoreblanks = false)
{
// If we are in ignore blanks mode AND we have a blank (0-size) rom, skip
if (ignoreblanks
&& (rom.ItemType == ItemType.Rom
&& (((Rom)rom).Size == 0 || ((Rom)rom).Size == -1)))
{
return true;
}
try
{
string state = "";
try
{
string state = "";
// Process the item name
ProcessItemName(rom, false, forceRomName: false);
// Process the item name
ProcessItemName(rom, false, forceRomName: false);
// If we're in Romba mode, the state is consistent
if (Romba)
{
state += (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
// Otherwise, use any flags
else
{
if (!UseRomName && rom.MachineName != lastgame)
{
state += (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
lastgame = rom.MachineName;
}
else if (UseRomName)
{
state += (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
}
// If we're in Romba mode, the state is consistent
if (Romba)
{
state += (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
// Otherwise, use any flags
else
{
if (!UseRomName && rom.MachineName != lastgame)
{
state += (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
lastgame = rom.MachineName;
}
else if (UseRomName)
{
state += (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\n";
}
}
sw.Write(state);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
sw.Write(state);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
}
return true;
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Text;
using System.Web;
using SabreTools.Library.Data;
using SabreTools.Library.DatItems;
using SabreTools.Library.Tools;
@@ -20,359 +19,359 @@ using NaturalSort;
namespace SabreTools.Library.DatFiles
{
/// <summary>
/// Represents parsing and writing of a RomCenter DAT
/// </summary>
internal class RomCenter : DatFile
{
/// <summary>
/// Constructor designed for casting a base DatFile
/// </summary>
/// <param name="datFile">Parent DatFile to copy from</param>
public RomCenter(DatFile datFile)
: base(datFile, cloneHeader: false)
{
}
/// <summary>
/// Represents parsing and writing of a RomCenter DAT
/// </summary>
internal class RomCenter : DatFile
{
/// <summary>
/// Constructor designed for casting a base DatFile
/// </summary>
/// <param name="datFile">Parent DatFile to copy from</param>
public RomCenter(DatFile datFile)
: base(datFile, cloneHeader: false)
{
}
/// <summary>
/// Parse a RomCenter DAT and return all found games and roms within
/// </summary>
/// <param name="filename">Name of the file to be parsed</param>
/// <param name="sysid">System ID for the DAT</param>
/// <param name="srcid">Source ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, 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>
public override void ParseFile(
// Standard Dat parsing
string filename,
int sysid,
int srcid,
/// <summary>
/// Parse a RomCenter DAT and return all found games and roms within
/// </summary>
/// <param name="filename">Name of the file to be parsed</param>
/// <param name="sysid">System ID for the DAT</param>
/// <param name="srcid">Source ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, 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>
public override void ParseFile(
// Standard Dat parsing
string filename,
int sysid,
int srcid,
// Miscellaneous
bool keep,
bool clean,
bool remUnicode)
{
// Open a file reader
Encoding enc = Utilities.GetEncoding(filename);
StreamReader sr = new StreamReader(Utilities.TryOpenRead(filename), enc);
// Miscellaneous
bool keep,
bool clean,
bool remUnicode)
{
// Open a file reader
Encoding enc = Utilities.GetEncoding(filename);
StreamReader sr = new StreamReader(Utilities.TryOpenRead(filename), enc);
string blocktype = "";
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
string blocktype = "";
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
// If the line is the start of the credits section
if (line.ToLowerInvariant().StartsWith("[credits]"))
{
blocktype = "credits";
}
// If the line is the start of the dat section
else if (line.ToLowerInvariant().StartsWith("[dat]"))
{
blocktype = "dat";
}
// If the line is the start of the emulator section
else if (line.ToLowerInvariant().StartsWith("[emulator]"))
{
blocktype = "emulator";
}
// If the line is the start of the game section
else if (line.ToLowerInvariant().StartsWith("[games]"))
{
blocktype = "games";
}
// Otherwise, it's not a section and it's data, so get out all data
else
{
// If we have an author
if (line.ToLowerInvariant().StartsWith("author="))
{
Author = (String.IsNullOrWhiteSpace(Author) ? line.Split('=')[1] : Author);
}
// If we have one of the three version tags
else if (line.ToLowerInvariant().StartsWith("version="))
{
switch (blocktype)
{
case "credits":
Version = (String.IsNullOrWhiteSpace(Version) ? line.Split('=')[1] : Version);
break;
case "emulator":
Description = (String.IsNullOrWhiteSpace(Description) ? line.Split('=')[1] : Description);
break;
}
}
// If we have a URL
else if (line.ToLowerInvariant().StartsWith("url="))
{
Url = (String.IsNullOrWhiteSpace(Url) ? line.Split('=')[1] : Url);
}
// If we have a comment
else if (line.ToLowerInvariant().StartsWith("comment="))
{
Comment = (String.IsNullOrWhiteSpace(Comment) ? line.Split('=')[1] : Comment);
}
// If we have the split flag
else if (line.ToLowerInvariant().StartsWith("split="))
{
if (Int32.TryParse(line.Split('=')[1], out int split))
{
if (split == 1 && ForceMerging == ForceMerging.None)
{
ForceMerging = ForceMerging.Split;
}
}
}
// If we have the merge tag
else if (line.ToLowerInvariant().StartsWith("merge="))
{
if (Int32.TryParse(line.Split('=')[1], out int merge))
{
if (merge == 1 && ForceMerging == ForceMerging.None)
{
ForceMerging = ForceMerging.Full;
}
}
}
// If we have the refname tag
else if (line.ToLowerInvariant().StartsWith("refname="))
{
Name = (String.IsNullOrWhiteSpace(Name) ? line.Split('=')[1] : Name);
}
// If we have a rom
else if (line.StartsWith("¬"))
{
// Some old RC DATs have this behavior
if (line.Contains("¬N¬O"))
{
line = line.Replace("¬N¬O", "") + "¬¬";
}
// If the line is the start of the credits section
if (line.ToLowerInvariant().StartsWith("[credits]"))
{
blocktype = "credits";
}
// If the line is the start of the dat section
else if (line.ToLowerInvariant().StartsWith("[dat]"))
{
blocktype = "dat";
}
// If the line is the start of the emulator section
else if (line.ToLowerInvariant().StartsWith("[emulator]"))
{
blocktype = "emulator";
}
// If the line is the start of the game section
else if (line.ToLowerInvariant().StartsWith("[games]"))
{
blocktype = "games";
}
// Otherwise, it's not a section and it's data, so get out all data
else
{
// If we have an author
if (line.ToLowerInvariant().StartsWith("author="))
{
Author = (String.IsNullOrWhiteSpace(Author) ? line.Split('=')[1] : Author);
}
// If we have one of the three version tags
else if (line.ToLowerInvariant().StartsWith("version="))
{
switch (blocktype)
{
case "credits":
Version = (String.IsNullOrWhiteSpace(Version) ? line.Split('=')[1] : Version);
break;
case "emulator":
Description = (String.IsNullOrWhiteSpace(Description) ? line.Split('=')[1] : Description);
break;
}
}
// If we have a URL
else if (line.ToLowerInvariant().StartsWith("url="))
{
Url = (String.IsNullOrWhiteSpace(Url) ? line.Split('=')[1] : Url);
}
// If we have a comment
else if (line.ToLowerInvariant().StartsWith("comment="))
{
Comment = (String.IsNullOrWhiteSpace(Comment) ? line.Split('=')[1] : Comment);
}
// If we have the split flag
else if (line.ToLowerInvariant().StartsWith("split="))
{
if (Int32.TryParse(line.Split('=')[1], out int split))
{
if (split == 1 && ForceMerging == ForceMerging.None)
{
ForceMerging = ForceMerging.Split;
}
}
}
// If we have the merge tag
else if (line.ToLowerInvariant().StartsWith("merge="))
{
if (Int32.TryParse(line.Split('=')[1], out int merge))
{
if (merge == 1 && ForceMerging == ForceMerging.None)
{
ForceMerging = ForceMerging.Full;
}
}
}
// If we have the refname tag
else if (line.ToLowerInvariant().StartsWith("refname="))
{
Name = (String.IsNullOrWhiteSpace(Name) ? line.Split('=')[1] : Name);
}
// If we have a rom
else if (line.StartsWith("¬"))
{
// Some old RC DATs have this behavior
if (line.Contains("¬N¬O"))
{
line = line.Replace("¬N¬O", "") + "¬¬";
}
/*
The rominfo order is as follows:
1 - parent name
2 - parent description
3 - game name
4 - game description
5 - rom name
6 - rom crc
7 - rom size
8 - romof name
9 - merge name
*/
string[] rominfo = line.Split('¬');
/*
The rominfo order is as follows:
1 - parent name
2 - parent description
3 - game name
4 - game description
5 - rom name
6 - rom crc
7 - rom size
8 - romof name
9 - merge name
*/
string[] rominfo = line.Split('¬');
// Try getting the size separately
if (!Int64.TryParse(rominfo[7], out long size))
{
size = 0;
}
// Try getting the size separately
if (!Int64.TryParse(rominfo[7], out long size))
{
size = 0;
}
Rom rom = new Rom
{
Name = rominfo[5],
Size = size,
CRC = Utilities.CleanHashData(rominfo[6], Constants.CRCLength),
ItemStatus = ItemStatus.None,
Rom rom = new Rom
{
Name = rominfo[5],
Size = size,
CRC = Utilities.CleanHashData(rominfo[6], Constants.CRCLength),
ItemStatus = ItemStatus.None,
MachineName = rominfo[3],
MachineDescription = rominfo[4],
CloneOf = rominfo[1],
RomOf = rominfo[8],
MachineName = rominfo[3],
MachineDescription = rominfo[4],
CloneOf = rominfo[1],
RomOf = rominfo[8],
SystemID = sysid,
SourceID = srcid,
};
SystemID = sysid,
SourceID = srcid,
};
// Now process and add the rom
ParseAddHelper(rom, clean, remUnicode);
}
}
}
// Now process and add the rom
ParseAddHelper(rom, clean, remUnicode);
}
}
}
sr.Dispose();
}
sr.Dispose();
}
/// <summary>
/// Create and open an output file for writing direct from a dictionary
/// </summary>
/// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false)
{
try
{
Globals.Logger.User("Opening file for writing: {0}", outfile);
FileStream fs = Utilities.TryCreate(outfile);
/// <summary>
/// Create and open an output file for writing direct from a dictionary
/// </summary>
/// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false)
{
try
{
Globals.Logger.User("Opening file for writing: {0}", outfile);
FileStream fs = Utilities.TryCreate(outfile);
// If we get back null for some reason, just log and return
if (fs == null)
{
Globals.Logger.Warning("File '{0}' could not be created for writing! Please check to see if the file is writable", outfile);
return false;
}
// If we get back null for some reason, just log and return
if (fs == null)
{
Globals.Logger.Warning("File '{0}' could not be created for writing! Please check to see if the file is writable", outfile);
return false;
}
StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(false));
StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(false));
// Write out the header
WriteHeader(sw);
// Write out the header
WriteHeader(sw);
// Write out each of the machines and roms
string lastgame = null;
List<string> splitpath = new List<string>();
// Write out each of the machines and roms
string lastgame = null;
List<string> splitpath = new List<string>();
// Get a properly sorted set of keys
List<string> keys = Keys;
keys.Sort(new NaturalComparer());
// Get a properly sorted set of keys
List<string> keys = Keys;
keys.Sort(new NaturalComparer());
foreach (string key in keys)
{
List<DatItem> roms = this[key];
foreach (string key in keys)
{
List<DatItem> roms = this[key];
// Resolve the names in the block
roms = DatItem.ResolveNames(roms);
// Resolve the names in the block
roms = DatItem.ResolveNames(roms);
for (int index = 0; index < roms.Count; index++)
{
DatItem rom = roms[index];
for (int index = 0; index < roms.Count; index++)
{
DatItem rom = roms[index];
// There are apparently times when a null rom can skip by, skip them
if (rom.Name == null || rom.MachineName == null)
{
Globals.Logger.Warning("Null rom found!");
continue;
}
// There are apparently times when a null rom can skip by, skip them
if (rom.Name == null || rom.MachineName == null)
{
Globals.Logger.Warning("Null rom found!");
continue;
}
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
{
Globals.Logger.Verbose("Empty folder found: {0}", rom.MachineName);
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
{
Globals.Logger.Verbose("Empty folder found: {0}", rom.MachineName);
rom.Name = (rom.Name == "null" ? "-" : rom.Name);
((Rom)rom).Size = Constants.SizeZero;
((Rom)rom).CRC = ((Rom)rom).CRC == "null" ? Constants.CRCZero : null;
((Rom)rom).MD5 = ((Rom)rom).MD5 == "null" ? Constants.MD5Zero : null;
((Rom)rom).SHA1 = ((Rom)rom).SHA1 == "null" ? Constants.SHA1Zero : null;
((Rom)rom).SHA256 = ((Rom)rom).SHA256 == "null" ? Constants.SHA256Zero : null;
((Rom)rom).SHA384 = ((Rom)rom).SHA384 == "null" ? Constants.SHA384Zero : null;
((Rom)rom).SHA512 = ((Rom)rom).SHA512 == "null" ? Constants.SHA512Zero : null;
}
rom.Name = (rom.Name == "null" ? "-" : rom.Name);
((Rom)rom).Size = Constants.SizeZero;
((Rom)rom).CRC = ((Rom)rom).CRC == "null" ? Constants.CRCZero : null;
((Rom)rom).MD5 = ((Rom)rom).MD5 == "null" ? Constants.MD5Zero : null;
((Rom)rom).SHA1 = ((Rom)rom).SHA1 == "null" ? Constants.SHA1Zero : null;
((Rom)rom).SHA256 = ((Rom)rom).SHA256 == "null" ? Constants.SHA256Zero : null;
((Rom)rom).SHA384 = ((Rom)rom).SHA384 == "null" ? Constants.SHA384Zero : null;
((Rom)rom).SHA512 = ((Rom)rom).SHA512 == "null" ? Constants.SHA512Zero : null;
}
// Now, output the rom data
WriteDatItem(sw, rom, ignoreblanks);
// Now, output the rom data
WriteDatItem(sw, rom, ignoreblanks);
// Set the new data to compare against
lastgame = rom.MachineName;
}
}
// Set the new data to compare against
lastgame = rom.MachineName;
}
}
Globals.Logger.Verbose("File written!" + Environment.NewLine);
sw.Dispose();
fs.Dispose();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
Globals.Logger.Verbose("File written!" + Environment.NewLine);
sw.Dispose();
fs.Dispose();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
return true;
}
/// <summary>
/// Write out DAT header using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteHeader(StreamWriter sw)
{
try
{
string header = header = "[CREDITS]\n" +
"author=" + Author + "\n" +
"version=" + Version + "\n" +
"comment=" + Comment + "\n" +
"[DAT]\n" +
"version=2.50\n" +
"split=" + (ForceMerging == ForceMerging.Split ? "1" : "0") + "\n" +
"merge=" + (ForceMerging == ForceMerging.Full || ForceMerging == ForceMerging.Merged ? "1" : "0") + "\n" +
"[EMULATOR]\n" +
"refname=" + Name + "\n" +
"version=" + Description + "\n" +
"[GAMES]\n";
/// <summary>
/// Write out DAT header using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteHeader(StreamWriter sw)
{
try
{
string header = header = "[CREDITS]\n" +
"author=" + Author + "\n" +
"version=" + Version + "\n" +
"comment=" + Comment + "\n" +
"[DAT]\n" +
"version=2.50\n" +
"split=" + (ForceMerging == ForceMerging.Split ? "1" : "0") + "\n" +
"merge=" + (ForceMerging == ForceMerging.Full || ForceMerging == ForceMerging.Merged ? "1" : "0") + "\n" +
"[EMULATOR]\n" +
"refname=" + Name + "\n" +
"version=" + Description + "\n" +
"[GAMES]\n";
// Write the header out
sw.Write(header);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
// Write the header out
sw.Write(header);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
return true;
}
/// <summary>
/// Write out DatItem using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <param name="rom">DatItem object to be output</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteDatItem(StreamWriter sw, DatItem rom, bool ignoreblanks = false)
{
// If we are in ignore blanks mode AND we have a blank (0-size) rom, skip
if (ignoreblanks
&& (rom.ItemType == ItemType.Rom
&& (((Rom)rom).Size == 0 || ((Rom)rom).Size == -1)))
{
return true;
}
/// <summary>
/// Write out DatItem using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <param name="rom">DatItem object to be output</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteDatItem(StreamWriter sw, DatItem rom, bool ignoreblanks = false)
{
// If we are in ignore blanks mode AND we have a blank (0-size) rom, skip
if (ignoreblanks
&& (rom.ItemType == ItemType.Rom
&& (((Rom)rom).Size == 0 || ((Rom)rom).Size == -1)))
{
return true;
}
try
{
string state = "";
try
{
string state = "";
// Pre-process the item name
ProcessItemName(rom, true);
// Pre-process the item name
ProcessItemName(rom, true);
if (rom.ItemType == ItemType.Rom)
{
state += "¬" + (!ExcludeFields[(int)Field.CloneOf] && String.IsNullOrWhiteSpace(rom.CloneOf) ? HttpUtility.HtmlEncode(rom.CloneOf) : "") +
"¬" + (!ExcludeFields[(int)Field.CloneOf] && String.IsNullOrWhiteSpace(rom.CloneOf) ? HttpUtility.HtmlEncode(rom.CloneOf) : "") +
"¬" + (!ExcludeFields[(int)Field.MachineName] ? HttpUtility.HtmlEncode(rom.MachineName) : "") +
"¬" + (!ExcludeFields[(int)Field.Description] ? HttpUtility.HtmlEncode((String.IsNullOrWhiteSpace(rom.MachineDescription) ? rom.MachineName : rom.MachineDescription)) : "") +
"¬" + (!ExcludeFields[(int)Field.Name] ? HttpUtility.HtmlEncode(rom.Name) : "") +
"¬" + (!ExcludeFields[(int)Field.CRC] ? ((Rom)rom).CRC.ToLowerInvariant() : "") +
"¬" + (!ExcludeFields[(int)Field.Size] && ((Rom)rom).Size != -1 ? ((Rom)rom).Size.ToString() : "") + "¬¬¬\n";
}
else if (rom.ItemType == ItemType.Disk)
{
state += "¬" + (!ExcludeFields[(int)Field.CloneOf] && String.IsNullOrWhiteSpace(rom.CloneOf) ? HttpUtility.HtmlEncode(rom.CloneOf) : "") +
"¬" + (!ExcludeFields[(int)Field.CloneOf] && String.IsNullOrWhiteSpace(rom.CloneOf) ? HttpUtility.HtmlEncode(rom.CloneOf) : "") +
"¬" + (!ExcludeFields[(int)Field.MachineName] ? HttpUtility.HtmlEncode(rom.MachineName) : "") +
"¬" + (!ExcludeFields[(int)Field.Description] ? HttpUtility.HtmlEncode((String.IsNullOrWhiteSpace(rom.MachineDescription) ? rom.MachineName : rom.MachineDescription)) : "") +
"¬" + (!ExcludeFields[(int)Field.Name] ? HttpUtility.HtmlEncode(rom.Name) : "") +
"¬¬¬¬¬\n";
}
if (rom.ItemType == ItemType.Rom)
{
state += "¬" + (!ExcludeFields[(int)Field.CloneOf] && String.IsNullOrWhiteSpace(rom.CloneOf) ? HttpUtility.HtmlEncode(rom.CloneOf) : "") +
"¬" + (!ExcludeFields[(int)Field.CloneOf] && String.IsNullOrWhiteSpace(rom.CloneOf) ? HttpUtility.HtmlEncode(rom.CloneOf) : "") +
"¬" + (!ExcludeFields[(int)Field.MachineName] ? HttpUtility.HtmlEncode(rom.MachineName) : "") +
"¬" + (!ExcludeFields[(int)Field.Description] ? HttpUtility.HtmlEncode((String.IsNullOrWhiteSpace(rom.MachineDescription) ? rom.MachineName : rom.MachineDescription)) : "") +
"¬" + (!ExcludeFields[(int)Field.Name] ? HttpUtility.HtmlEncode(rom.Name) : "") +
"¬" + (!ExcludeFields[(int)Field.CRC] ? ((Rom)rom).CRC.ToLowerInvariant() : "") +
"¬" + (!ExcludeFields[(int)Field.Size] && ((Rom)rom).Size != -1 ? ((Rom)rom).Size.ToString() : "") + "¬¬¬\n";
}
else if (rom.ItemType == ItemType.Disk)
{
state += "¬" + (!ExcludeFields[(int)Field.CloneOf] && String.IsNullOrWhiteSpace(rom.CloneOf) ? HttpUtility.HtmlEncode(rom.CloneOf) : "") +
"¬" + (!ExcludeFields[(int)Field.CloneOf] && String.IsNullOrWhiteSpace(rom.CloneOf) ? HttpUtility.HtmlEncode(rom.CloneOf) : "") +
"¬" + (!ExcludeFields[(int)Field.MachineName] ? HttpUtility.HtmlEncode(rom.MachineName) : "") +
"¬" + (!ExcludeFields[(int)Field.Description] ? HttpUtility.HtmlEncode((String.IsNullOrWhiteSpace(rom.MachineDescription) ? rom.MachineName : rom.MachineDescription)) : "") +
"¬" + (!ExcludeFields[(int)Field.Name] ? HttpUtility.HtmlEncode(rom.Name) : "") +
"¬¬¬¬¬\n";
}
sw.Write(state);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
sw.Write(state);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
}
return true;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SabreTools.Library.Data;
using SabreTools.Library.DatItems;
using SabreTools.Library.Tools;
@@ -18,515 +16,515 @@ using NaturalSort;
namespace SabreTools.Library.DatFiles
{
/// <summary>
/// Represents parsing and writing of a value-separated DAT
/// </summary>
internal class SeparatedValue : DatFile
{
// Private instance variables specific to Separated Value DATs
char _delim;
/// <summary>
/// Represents parsing and writing of a value-separated DAT
/// </summary>
internal class SeparatedValue : DatFile
{
// Private instance variables specific to Separated Value DATs
char _delim;
/// <summary>
/// Constructor designed for casting a base DatFile
/// </summary>
/// <param name="datFile">Parent DatFile to copy from</param>
/// <param name="delim">Delimiter for parsing individual lines</param>
public SeparatedValue(DatFile datFile, char delim)
: base(datFile, cloneHeader: false)
{
_delim = delim;
}
/// <summary>
/// Constructor designed for casting a base DatFile
/// </summary>
/// <param name="datFile">Parent DatFile to copy from</param>
/// <param name="delim">Delimiter for parsing individual lines</param>
public SeparatedValue(DatFile datFile, char delim)
: base(datFile, cloneHeader: false)
{
_delim = delim;
}
/// <summary>
/// Parse a character-separated value DAT and return all found games and roms within
/// </summary>
/// <param name="filename">Name of the file to be parsed</param>
/// <param name="sysid">System ID for the DAT</param>
/// <param name="srcid">Source ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, 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>
public override void ParseFile(
// Standard Dat parsing
string filename,
int sysid,
int srcid,
/// <summary>
/// Parse a character-separated value DAT and return all found games and roms within
/// </summary>
/// <param name="filename">Name of the file to be parsed</param>
/// <param name="sysid">System ID for the DAT</param>
/// <param name="srcid">Source ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, 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>
public override void ParseFile(
// Standard Dat parsing
string filename,
int sysid,
int srcid,
// Miscellaneous
bool keep,
bool clean,
bool remUnicode)
{
// Open a file reader
Encoding enc = Utilities.GetEncoding(filename);
StreamReader sr = new StreamReader(Utilities.TryOpenRead(filename), enc);
// Miscellaneous
bool keep,
bool clean,
bool remUnicode)
{
// Open a file reader
Encoding enc = Utilities.GetEncoding(filename);
StreamReader sr = new StreamReader(Utilities.TryOpenRead(filename), enc);
// Create an empty list of columns to parse though
List<string> columns = new List<string>();
// Create an empty list of columns to parse though
List<string> columns = new List<string>();
long linenum = -1;
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
linenum++;
long linenum = -1;
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
linenum++;
// Parse the first line, getting types from the column names
if (linenum == 0)
{
string[] parsedColumns = line.Split(_delim);
foreach (string parsed in parsedColumns)
{
switch (parsed.ToLowerInvariant().Trim('"'))
{
case "file":
case "filename":
case "file name":
columns.Add("DatFile.FileName");
break;
case "internal name":
columns.Add("DatFile.Name");
break;
case "description":
case "dat description":
columns.Add("DatFile.Description");
break;
case "game name":
case "game":
case "machine":
columns.Add("Machine.Name");
break;
case "game description":
columns.Add("Description");
break;
case "type":
columns.Add("DatItem.Type");
break;
case "rom":
case "romname":
case "rom name":
case "name":
columns.Add("Rom.Name");
break;
case "disk":
case "diskname":
case "disk name":
columns.Add("Disk.Name");
break;
case "size":
columns.Add("DatItem.Size");
break;
case "crc":
case "crc hash":
columns.Add("DatItem.CRC");
break;
case "md5":
case "md5 hash":
columns.Add("DatItem.MD5");
break;
case "sha1":
case "sha-1":
case "sha1 hash":
case "sha-1 hash":
columns.Add("DatItem.SHA1");
break;
case "sha256":
case "sha-256":
case "sha256 hash":
case "sha-256 hash":
columns.Add("DatItem.SHA256");
break;
case "sha384":
case "sha-384":
case "sha384 hash":
case "sha-384 hash":
columns.Add("DatItem.SHA384");
break;
case "sha512":
case "sha-512":
case "sha512 hash":
case "sha-512 hash":
columns.Add("DatItem.SHA512");
break;
case "nodump":
case "no dump":
case "status":
case "item status":
columns.Add("DatItem.Nodump");
break;
case "date":
columns.Add("DatItem.Date");
break;
default:
columns.Add("INVALID");
break;
}
}
// Parse the first line, getting types from the column names
if (linenum == 0)
{
string[] parsedColumns = line.Split(_delim);
foreach (string parsed in parsedColumns)
{
switch (parsed.ToLowerInvariant().Trim('"'))
{
case "file":
case "filename":
case "file name":
columns.Add("DatFile.FileName");
break;
case "internal name":
columns.Add("DatFile.Name");
break;
case "description":
case "dat description":
columns.Add("DatFile.Description");
break;
case "game name":
case "game":
case "machine":
columns.Add("Machine.Name");
break;
case "game description":
columns.Add("Description");
break;
case "type":
columns.Add("DatItem.Type");
break;
case "rom":
case "romname":
case "rom name":
case "name":
columns.Add("Rom.Name");
break;
case "disk":
case "diskname":
case "disk name":
columns.Add("Disk.Name");
break;
case "size":
columns.Add("DatItem.Size");
break;
case "crc":
case "crc hash":
columns.Add("DatItem.CRC");
break;
case "md5":
case "md5 hash":
columns.Add("DatItem.MD5");
break;
case "sha1":
case "sha-1":
case "sha1 hash":
case "sha-1 hash":
columns.Add("DatItem.SHA1");
break;
case "sha256":
case "sha-256":
case "sha256 hash":
case "sha-256 hash":
columns.Add("DatItem.SHA256");
break;
case "sha384":
case "sha-384":
case "sha384 hash":
case "sha-384 hash":
columns.Add("DatItem.SHA384");
break;
case "sha512":
case "sha-512":
case "sha512 hash":
case "sha-512 hash":
columns.Add("DatItem.SHA512");
break;
case "nodump":
case "no dump":
case "status":
case "item status":
columns.Add("DatItem.Nodump");
break;
case "date":
columns.Add("DatItem.Date");
break;
default:
columns.Add("INVALID");
break;
}
}
continue;
}
continue;
}
// Otherwise, we want to split the line and parse
string[] parsedLine = line.Split(_delim);
// Otherwise, we want to split the line and parse
string[] parsedLine = line.Split(_delim);
// If the line doesn't have the correct number of columns, we log and skip
if (parsedLine.Length != columns.Count)
{
Globals.Logger.Warning("Malformed line found in '{0}' at line {1}", filename, linenum);
continue;
}
// If the line doesn't have the correct number of columns, we log and skip
if (parsedLine.Length != columns.Count)
{
Globals.Logger.Warning("Malformed line found in '{0}' at line {1}", filename, linenum);
continue;
}
// Set the output item information
string machineName = null, machineDesc = null, name = null, crc = null, md5 = null, sha1 = null,
sha256 = null, sha384 = null, sha512 = null, date = null;
long size = -1;
ItemType itemType = ItemType.Rom;
ItemStatus status = ItemStatus.None;
// Set the output item information
string machineName = null, machineDesc = null, name = null, crc = null, md5 = null, sha1 = null,
sha256 = null, sha384 = null, sha512 = null, date = null;
long size = -1;
ItemType itemType = ItemType.Rom;
ItemStatus status = ItemStatus.None;
// Now we loop through and get values for everything
for (int i = 0; i < columns.Count; i++)
{
string value = parsedLine[i].Trim('"');
switch (columns[i])
{
case "DatFile.FileName":
FileName = (String.IsNullOrWhiteSpace(FileName) ? value : FileName);
break;
case "DatFile.Name":
Name = (String.IsNullOrWhiteSpace(Name) ? value : Name);
break;
case "DatFile.Description":
Description = (String.IsNullOrWhiteSpace(Description) ? value : Description);
break;
case "Machine.Name":
machineName = value;
break;
case "Description":
machineDesc = value;
break;
case "DatItem.Type":
itemType = Utilities.GetItemType(value) ?? ItemType.Rom;
break;
case "Rom.Name":
case "Disk.Name":
name = String.IsNullOrWhiteSpace(value) ? name : value;
break;
case "DatItem.Size":
if (!Int64.TryParse(value, out size))
{
size = -1;
}
break;
case "DatItem.CRC":
crc = Utilities.CleanHashData(value, Constants.CRCLength);
break;
case "DatItem.MD5":
md5 = Utilities.CleanHashData(value, Constants.MD5Length);
break;
case "DatItem.SHA1":
sha1 = Utilities.CleanHashData(value, Constants.SHA1Length);
break;
case "DatItem.SHA256":
sha256 = Utilities.CleanHashData(value, Constants.SHA256Length);
break;
case "DatItem.SHA384":
sha384 = Utilities.CleanHashData(value, Constants.SHA384Length);
break;
case "DatItem.SHA512":
sha512 = Utilities.CleanHashData(value, Constants.SHA512Length);
break;
case "DatItem.Nodump":
status = Utilities.GetItemStatus(value);
break;
case "DatItem.Date":
date = value;
break;
}
}
// Now we loop through and get values for everything
for (int i = 0; i < columns.Count; i++)
{
string value = parsedLine[i].Trim('"');
switch (columns[i])
{
case "DatFile.FileName":
FileName = (String.IsNullOrWhiteSpace(FileName) ? value : FileName);
break;
case "DatFile.Name":
Name = (String.IsNullOrWhiteSpace(Name) ? value : Name);
break;
case "DatFile.Description":
Description = (String.IsNullOrWhiteSpace(Description) ? value : Description);
break;
case "Machine.Name":
machineName = value;
break;
case "Description":
machineDesc = value;
break;
case "DatItem.Type":
itemType = Utilities.GetItemType(value) ?? ItemType.Rom;
break;
case "Rom.Name":
case "Disk.Name":
name = String.IsNullOrWhiteSpace(value) ? name : value;
break;
case "DatItem.Size":
if (!Int64.TryParse(value, out size))
{
size = -1;
}
break;
case "DatItem.CRC":
crc = Utilities.CleanHashData(value, Constants.CRCLength);
break;
case "DatItem.MD5":
md5 = Utilities.CleanHashData(value, Constants.MD5Length);
break;
case "DatItem.SHA1":
sha1 = Utilities.CleanHashData(value, Constants.SHA1Length);
break;
case "DatItem.SHA256":
sha256 = Utilities.CleanHashData(value, Constants.SHA256Length);
break;
case "DatItem.SHA384":
sha384 = Utilities.CleanHashData(value, Constants.SHA384Length);
break;
case "DatItem.SHA512":
sha512 = Utilities.CleanHashData(value, Constants.SHA512Length);
break;
case "DatItem.Nodump":
status = Utilities.GetItemStatus(value);
break;
case "DatItem.Date":
date = value;
break;
}
}
// And now we populate and add the new item
switch (itemType)
{
case ItemType.Archive:
Archive archive = new Archive()
{
Name = name,
// And now we populate and add the new item
switch (itemType)
{
case ItemType.Archive:
Archive archive = new Archive()
{
Name = name,
MachineName = machineName,
MachineDescription = machineDesc,
};
MachineName = machineName,
MachineDescription = machineDesc,
};
ParseAddHelper(archive, clean, remUnicode);
break;
case ItemType.BiosSet:
BiosSet biosset = new BiosSet()
{
Name = name,
ParseAddHelper(archive, clean, remUnicode);
break;
case ItemType.BiosSet:
BiosSet biosset = new BiosSet()
{
Name = name,
MachineName = machineName,
Description = machineDesc,
};
MachineName = machineName,
Description = machineDesc,
};
ParseAddHelper(biosset, clean, remUnicode);
break;
case ItemType.Disk:
Disk disk = new Disk()
{
Name = name,
MD5 = md5,
SHA1 = sha1,
SHA256 = sha256,
SHA384 = sha384,
SHA512 = sha512,
ParseAddHelper(biosset, clean, remUnicode);
break;
case ItemType.Disk:
Disk disk = new Disk()
{
Name = name,
MD5 = md5,
SHA1 = sha1,
SHA256 = sha256,
SHA384 = sha384,
SHA512 = sha512,
MachineName = machineName,
MachineDescription = machineDesc,
MachineName = machineName,
MachineDescription = machineDesc,
ItemStatus = status,
};
ItemStatus = status,
};
ParseAddHelper(disk, clean, remUnicode);
break;
case ItemType.Release:
Release release = new Release()
{
Name = name,
ParseAddHelper(disk, clean, remUnicode);
break;
case ItemType.Release:
Release release = new Release()
{
Name = name,
MachineName = machineName,
MachineDescription = machineDesc,
};
MachineName = machineName,
MachineDescription = machineDesc,
};
ParseAddHelper(release, clean, remUnicode);
break;
case ItemType.Rom:
Rom rom = new Rom()
{
Name = name,
Size = size,
CRC = crc,
MD5 = md5,
SHA1 = sha1,
SHA256 = sha256,
SHA384 = sha384,
SHA512 = sha512,
Date = date,
ParseAddHelper(release, clean, remUnicode);
break;
case ItemType.Rom:
Rom rom = new Rom()
{
Name = name,
Size = size,
CRC = crc,
MD5 = md5,
SHA1 = sha1,
SHA256 = sha256,
SHA384 = sha384,
SHA512 = sha512,
Date = date,
MachineName = machineName,
MachineDescription = machineDesc,
MachineName = machineName,
MachineDescription = machineDesc,
ItemStatus = status,
};
ItemStatus = status,
};
ParseAddHelper(rom, clean, remUnicode);
break;
case ItemType.Sample:
Sample sample = new Sample()
{
Name = name,
ParseAddHelper(rom, clean, remUnicode);
break;
case ItemType.Sample:
Sample sample = new Sample()
{
Name = name,
MachineName = machineName,
MachineDescription = machineDesc,
};
MachineName = machineName,
MachineDescription = machineDesc,
};
ParseAddHelper(sample, clean, remUnicode);
break;
}
}
}
ParseAddHelper(sample, clean, remUnicode);
break;
}
}
}
/// <summary>
/// Create and open an output file for writing direct from a dictionary
/// </summary>
/// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false)
{
try
{
Globals.Logger.User("Opening file for writing: {0}", outfile);
FileStream fs = Utilities.TryCreate(outfile);
/// <summary>
/// Create and open an output file for writing direct from a dictionary
/// </summary>
/// <param name="outfile">Name of the file to write to</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the DAT was written correctly, false otherwise</returns>
public override bool WriteToFile(string outfile, bool ignoreblanks = false)
{
try
{
Globals.Logger.User("Opening file for writing: {0}", outfile);
FileStream fs = Utilities.TryCreate(outfile);
// If we get back null for some reason, just log and return
if (fs == null)
{
Globals.Logger.Warning("File '{0}' could not be created for writing! Please check to see if the file is writable", outfile);
return false;
}
// If we get back null for some reason, just log and return
if (fs == null)
{
Globals.Logger.Warning("File '{0}' could not be created for writing! Please check to see if the file is writable", outfile);
return false;
}
StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(false));
StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(false));
// Write out the header
WriteHeader(sw);
// Write out the header
WriteHeader(sw);
// Get a properly sorted set of keys
List<string> keys = Keys;
keys.Sort(new NaturalComparer());
// Get a properly sorted set of keys
List<string> keys = Keys;
keys.Sort(new NaturalComparer());
foreach (string key in keys)
{
List<DatItem> roms = this[key];
foreach (string key in keys)
{
List<DatItem> roms = this[key];
// Resolve the names in the block
roms = DatItem.ResolveNames(roms);
// Resolve the names in the block
roms = DatItem.ResolveNames(roms);
for (int index = 0; index < roms.Count; index++)
{
DatItem rom = roms[index];
for (int index = 0; index < roms.Count; index++)
{
DatItem rom = roms[index];
// There are apparently times when a null rom can skip by, skip them
if (rom.Name == null || rom.MachineName == null)
{
Globals.Logger.Warning("Null rom found!");
continue;
}
// There are apparently times when a null rom can skip by, skip them
if (rom.Name == null || rom.MachineName == null)
{
Globals.Logger.Warning("Null rom found!");
continue;
}
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
{
Globals.Logger.Verbose("Empty folder found: {0}", rom.MachineName);
}
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
{
Globals.Logger.Verbose("Empty folder found: {0}", rom.MachineName);
}
// Now, output the rom data
WriteDatItem(sw, rom, ignoreblanks);
}
}
// Now, output the rom data
WriteDatItem(sw, rom, ignoreblanks);
}
}
Globals.Logger.Verbose("File written!" + Environment.NewLine);
sw.Dispose();
fs.Dispose();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
Globals.Logger.Verbose("File written!" + Environment.NewLine);
sw.Dispose();
fs.Dispose();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
return true;
}
/// <summary>
/// Write out DAT header using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteHeader(StreamWriter sw)
{
try
{
string header = string.Format("\"File Name\"{0}\"Internal Name\"{0}\"Description\"{0}\"Game Name\"{0}\"Game Description\"{0}\"Type\"{0}\"" +
"Rom Name\"{0}\"Disk Name\"{0}\"Size\"{0}\"CRC\"{0}\"MD5\"{0}\"SHA1\"{0}\"SHA256\"{0}\"Nodump\"\n", _delim);
/// <summary>
/// Write out DAT header using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteHeader(StreamWriter sw)
{
try
{
string header = string.Format("\"File Name\"{0}\"Internal Name\"{0}\"Description\"{0}\"Game Name\"{0}\"Game Description\"{0}\"Type\"{0}\"" +
"Rom Name\"{0}\"Disk Name\"{0}\"Size\"{0}\"CRC\"{0}\"MD5\"{0}\"SHA1\"{0}\"SHA256\"{0}\"Nodump\"\n", _delim);
// Write the header out
sw.Write(header);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
// Write the header out
sw.Write(header);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
return true;
}
/// <summary>
/// Write out DatItem using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <param name="rom">DatItem object to be output</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteDatItem(StreamWriter sw, DatItem rom, bool ignoreblanks = false)
{
// If we are in ignore blanks mode AND we have a blank (0-size) rom, skip
if (ignoreblanks
&& (rom.ItemType == ItemType.Rom
&& (((Rom)rom).Size == 0 || ((Rom)rom).Size == -1)))
{
return true;
}
/// <summary>
/// Write out DatItem using the supplied StreamWriter
/// </summary>
/// <param name="sw">StreamWriter to output to</param>
/// <param name="rom">DatItem object to be output</param>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
/// <returns>True if the data was written, false on error</returns>
private bool WriteDatItem(StreamWriter sw, DatItem rom, bool ignoreblanks = false)
{
// If we are in ignore blanks mode AND we have a blank (0-size) rom, skip
if (ignoreblanks
&& (rom.ItemType == ItemType.Rom
&& (((Rom)rom).Size == 0 || ((Rom)rom).Size == -1)))
{
return true;
}
try
{
// Initialize all strings
string state = "",
pre = "",
post = "",
type = "",
romname = "",
diskname = "",
size = "",
crc = "",
md5 = "",
sha1 = "",
sha256 = "",
sha384 = "",
sha512 = "",
status = "";
try
{
// Initialize all strings
string state = "",
pre = "",
post = "",
type = "",
romname = "",
diskname = "",
size = "",
crc = "",
md5 = "",
sha1 = "",
sha256 = "",
sha384 = "",
sha512 = "",
status = "";
// Separated values should only output Rom and Disk
if (rom.ItemType != ItemType.Disk && rom.ItemType != ItemType.Rom)
{
return true;
}
// Separated values should only output Rom and Disk
if (rom.ItemType != ItemType.Disk && rom.ItemType != ItemType.Rom)
{
return true;
}
if (rom.ItemType == ItemType.Rom)
{
type = "rom";
romname = rom.Name;
size = ((Rom)rom).Size.ToString();
crc = ((Rom)rom).CRC;
md5 = ((Rom)rom).MD5;
sha1 = ((Rom)rom).SHA1;
sha256 = ((Rom)rom).SHA256;
sha384 = ((Rom)rom).SHA384;
sha512 = ((Rom)rom).SHA512;
status = (((Rom)rom).ItemStatus != ItemStatus.None ? "\"" + ((Rom)rom).ItemStatus.ToString() + "\"" : "\"\"");
}
else if (rom.ItemType == ItemType.Disk)
{
type = "disk";
diskname = rom.Name;
md5 = ((Disk)rom).MD5;
sha1 = ((Disk)rom).SHA1;
sha256 = ((Disk)rom).SHA256;
sha384 = ((Disk)rom).SHA384;
sha512 = ((Disk)rom).SHA512;
status = (((Disk)rom).ItemStatus != ItemStatus.None ? "\"" + ((Disk)rom).ItemStatus.ToString() + "\"" : "\"\"");
}
if (rom.ItemType == ItemType.Rom)
{
type = "rom";
romname = rom.Name;
size = ((Rom)rom).Size.ToString();
crc = ((Rom)rom).CRC;
md5 = ((Rom)rom).MD5;
sha1 = ((Rom)rom).SHA1;
sha256 = ((Rom)rom).SHA256;
sha384 = ((Rom)rom).SHA384;
sha512 = ((Rom)rom).SHA512;
status = (((Rom)rom).ItemStatus != ItemStatus.None ? "\"" + ((Rom)rom).ItemStatus.ToString() + "\"" : "\"\"");
}
else if (rom.ItemType == ItemType.Disk)
{
type = "disk";
diskname = rom.Name;
md5 = ((Disk)rom).MD5;
sha1 = ((Disk)rom).SHA1;
sha256 = ((Disk)rom).SHA256;
sha384 = ((Disk)rom).SHA384;
sha512 = ((Disk)rom).SHA512;
status = (((Disk)rom).ItemStatus != ItemStatus.None ? "\"" + ((Disk)rom).ItemStatus.ToString() + "\"" : "\"\"");
}
pre = CreatePrefixPostfix(rom, true);
post = CreatePrefixPostfix(rom, false);
string inline = string.Format("\"" + FileName + "\""
+ "{0}\"" + Name + "\""
+ "{0}\"" + Description + "\""
+ "{0}\"" + (!ExcludeFields[(int)Field.MachineName] ? rom.MachineName : "") + "\""
+ "{0}\"" + (!ExcludeFields[(int)Field.Description] ? rom.MachineDescription : "") + "\""
+ "{0}\"" + type + "\""
+ "{0}\"" + (!ExcludeFields[(int)Field.Name] ? romname : "") + "\""
+ "{0}\"" + (!ExcludeFields[(int)Field.Name] ? diskname : "") + "\""
+ "{0}\"" + (!ExcludeFields[(int)Field.Size] ? size : "") + "\""
+ "{0}\"" + (!ExcludeFields[(int)Field.CRC] ? crc : "") + "\""
+ "{0}\"" + (!ExcludeFields[(int)Field.MD5] ? md5 : "") + "\""
+ "{0}\"" + (!ExcludeFields[(int)Field.SHA1] ? sha1 : "") + "\""
+ "{0}\"" + (!ExcludeFields[(int)Field.SHA256] ? sha256 : "") + "\""
// + "{0}\"" + (!ExcludeFields[(int)Field.SHA384] ? sha384 : "") + "\""
// + "{0}\"" + (!ExcludeFields[(int)Field.SHA512] ? sha512 : "") + "\""
+ "{0}" + status, _delim);
state += pre + inline + post + "\n";
pre = CreatePrefixPostfix(rom, true);
post = CreatePrefixPostfix(rom, false);
string inline = string.Format("\"" + FileName + "\""
+ "{0}\"" + Name + "\""
+ "{0}\"" + Description + "\""
+ "{0}\"" + (!ExcludeFields[(int)Field.MachineName] ? rom.MachineName : "") + "\""
+ "{0}\"" + (!ExcludeFields[(int)Field.Description] ? rom.MachineDescription : "") + "\""
+ "{0}\"" + type + "\""
+ "{0}\"" + (!ExcludeFields[(int)Field.Name] ? romname : "") + "\""
+ "{0}\"" + (!ExcludeFields[(int)Field.Name] ? diskname : "") + "\""
+ "{0}\"" + (!ExcludeFields[(int)Field.Size] ? size : "") + "\""
+ "{0}\"" + (!ExcludeFields[(int)Field.CRC] ? crc : "") + "\""
+ "{0}\"" + (!ExcludeFields[(int)Field.MD5] ? md5 : "") + "\""
+ "{0}\"" + (!ExcludeFields[(int)Field.SHA1] ? sha1 : "") + "\""
+ "{0}\"" + (!ExcludeFields[(int)Field.SHA256] ? sha256 : "") + "\""
// + "{0}\"" + (!ExcludeFields[(int)Field.SHA384] ? sha384 : "") + "\""
// + "{0}\"" + (!ExcludeFields[(int)Field.SHA512] ? sha512 : "") + "\""
+ "{0}" + status, _delim);
state += pre + inline + post + "\n";
sw.Write(state);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
sw.Write(state);
sw.Flush();
}
catch (Exception ex)
{
Globals.Logger.Error(ex.ToString());
return false;
}
return true;
}
}
return true;
}
}
}

File diff suppressed because it is too large Load Diff