using System;
using System.Collections.Generic;
using Mono.Data.Sqlite;
using System.IO;
using System.Text;
using System.Web;
namespace SabreTools.Helper
{
public class Output
{
///
/// Create and open an output file for writing
///
/// Internal name of the DAT
/// Description and external name of the DAT
/// Version or iteration of the DAT
/// Usually the DAT creation date
/// Category of the DAT
/// DAT author
/// Force all sets to be unzipped
/// Set output mode to old-style DAT
/// Set the output directory
/// List of RomData objects representing the games to be written out
/// Logger object for console and/or file output
/// Tru if the DAT was written correctly, false otherwise
public static bool WriteToDat(string name, string description, string version, string date, string category, string author,
bool forceunpack, bool old, string outDir, List roms, Logger logger)
{
// If it's empty, use the current folder
if (outDir.Trim() == "")
{
outDir = Environment.CurrentDirectory;
}
// Double check the outdir for the end delim
if (!outDir.EndsWith(Path.DirectorySeparatorChar.ToString()))
{
outDir += Path.DirectorySeparatorChar;
}
// (currently uses current time, change to "last updated time")
logger.Log("Opening file for writing: " + outDir + description + (old ? ".dat" : ".xml"));
try
{
FileStream fs = File.Create(outDir + description + (old ? ".dat" : ".xml"));
StreamWriter sw = new StreamWriter(fs, Encoding.UTF8);
string header_old = "clrmamepro (\n" +
"\tname \"" + HttpUtility.HtmlEncode(name) + "\"\n" +
"\tdescription \"" + HttpUtility.HtmlEncode(description) + "\"\n" +
"\tcategory \"" + HttpUtility.HtmlEncode(category) + "\"\n" +
"\tversion \"" + HttpUtility.HtmlEncode(version) + "\"\n" +
"\tdate \"" + HttpUtility.HtmlEncode(date) + "\"\n" +
"\tauthor \"" + HttpUtility.HtmlEncode(author) + "\"\n" +
(forceunpack ? "\tforcezipping no\n" : "") +
")\n";
string header = "\n" +
"\n\n" +
"\t\n" +
"\t\t\n" +
"\t\t\t" + HttpUtility.HtmlEncode(name) + "\n" +
"\t\t\t" + HttpUtility.HtmlEncode(description) + "\n" +
"\t\t\t" + HttpUtility.HtmlEncode(category) + "\n" +
"\t\t\t" + HttpUtility.HtmlEncode(version) + "\n" +
"\t\t\t" + HttpUtility.HtmlEncode(date) + "\n" +
"\t\t\t" + HttpUtility.HtmlEncode(author) + "\n" +
(forceunpack ? "\t\t\t\n" : "") +
"\t\t\n";
// Write the header out
sw.Write((old ? header_old : header));
// Write out each of the machines and roms
string lastgame = "";
foreach (RomData rom in roms)
{
string state = "";
if (lastgame != "" && lastgame != rom.Game)
{
state += (old ? ")\n" : "\t\n");
}
if (lastgame != rom.Game)
{
state += (old ? "game (\n\tname \"" + rom.Game + "\"\n" +
"\tdescription \"" + rom.Game + "\"\n" :
"\t\n" +
"\t\t" + HttpUtility.HtmlEncode(rom.Game) + "\n");
}
if (old)
{
state += "\t" + rom.Type + " ( name \"" + rom.Name + "\"" +
(rom.Size != 0 ? " size " + rom.Size : "") +
(rom.CRC != "" ? " crc " + rom.CRC.ToLowerInvariant() : "") +
(rom.MD5 != "" ? " md5 " + rom.MD5.ToLowerInvariant() : "") +
(rom.SHA1 != "" ? " sha1 " + rom.SHA1.ToLowerInvariant() : "") +
" )\n";
}
else
{
state += "\t\t<" + rom.Type + " name=\"" + HttpUtility.HtmlEncode(rom.Name) + "\"" +
(rom.Size != -1 ? " size=\"" + rom.Size + "\"" : "") +
(rom.CRC != "" ? " crc=\"" + rom.CRC.ToLowerInvariant() + "\"" : "") +
(rom.MD5 != "" ? " md5=\"" + rom.MD5.ToLowerInvariant() + "\"" : "") +
(rom.SHA1 != "" ? " sha1=\"" + rom.SHA1.ToLowerInvariant() + "\"" : "") +
"/>\n";
}
lastgame = rom.Game;
sw.Write(state);
}
sw.Write((old ? ")" : "\t\n"));
logger.Log("File written!" + Environment.NewLine);
sw.Close();
fs.Close();
}
catch (Exception ex)
{
logger.Error(ex.ToString());
return false;
}
return true;
}
///
/// Create and open an output file for writing
///
/// Internal name of the DAT
/// Description and external name of the DAT
/// Version or iteration of the DAT
/// Usually the DAT creation date
/// Category of the DAT
/// DAT author
/// Force all sets to be unzipped
/// Set output mode to old-style DAT
/// Only output files that don't have dupes
/// Enable output of files just in each DAT and also just duped. Best if combined with diff=true.
/// Set the output directory
/// Database connection representing the roms to be written
/// Logger object for console and/or file output
/// Tru if the DAT was written correctly, false otherwise
public static bool WriteToDat2(string name, string description, string version, string date, string category, string author,
bool forceunpack, bool old, bool diff, bool ab, string outDir, SqliteConnection dbc, Logger logger)
{
// If it's empty, use the current folder
if (outDir.Trim() == "")
{
outDir = Environment.CurrentDirectory;
}
// Double check the outdir for the end delim
if (!outDir.EndsWith(Path.DirectorySeparatorChar.ToString()))
{
outDir += Path.DirectorySeparatorChar;
}
// Get all query strings to use
List inputs = new List();
inputs.Add("");
if (diff)
{
inputs.Add("WHERE dupe<>'true'");
}
if (ab)
{
using (SqliteDataReader sldr = (new SqliteCommand("SELECT DISTINCT dupe FROM roms", dbc).ExecuteReader()))
{
if (sldr.HasRows)
{
while (sldr.Read())
{
inputs.Add("WHERE dupe='" + inputs + "'");
}
}
}
}
int i = 0;
foreach (string input in inputs)
{
string tempname = name;
string tempdesc = description;
// If we have special outputs, append the right things
if (i != 0)
{
tempname += " (" + i + ")";
tempdesc += " (" + i + ")";
}
// (currently uses current time, change to "last updated time")
logger.Log("Opening file for writing: " + outDir + tempdesc + (old ? ".dat" : ".xml"));
try
{
FileStream fs = File.Create(outDir + tempdesc + (old ? ".dat" : ".xml"));
StreamWriter sw = new StreamWriter(fs, Encoding.UTF8);
string header_old = "clrmamepro (\n" +
"\tname \"" + HttpUtility.HtmlEncode(tempname) + "\"\n" +
"\tdescription \"" + HttpUtility.HtmlEncode(tempdesc) + "\"\n" +
"\tcategory \"" + HttpUtility.HtmlEncode(category) + "\"\n" +
"\tversion \"" + HttpUtility.HtmlEncode(version) + "\"\n" +
"\tdate \"" + HttpUtility.HtmlEncode(date) + "\"\n" +
"\tauthor \"" + HttpUtility.HtmlEncode(author) + "\"\n" +
(forceunpack ? "\tforcezipping no\n" : "") +
")\n";
string header = "\n" +
"\n\n" +
"\t\n" +
"\t\t\n" +
"\t\t\t" + HttpUtility.HtmlEncode(tempname) + "\n" +
"\t\t\t" + HttpUtility.HtmlEncode(tempdesc) + "\n" +
"\t\t\t" + HttpUtility.HtmlEncode(category) + "\n" +
"\t\t\t" + HttpUtility.HtmlEncode(version) + "\n" +
"\t\t\t" + HttpUtility.HtmlEncode(date) + "\n" +
"\t\t\t" + HttpUtility.HtmlEncode(author) + "\n" +
(forceunpack ? "\t\t\t\n" : "") +
"\t\t\n";
// Write the header out
sw.Write((old ? header_old : header));
// Write out each of the machines and roms
string lastgame = "";
string query = "SELECT * FROM roms " + input + " ORDER BY game, name";
using (SqliteDataReader sldr = (new SqliteCommand(query, dbc).ExecuteReader()))
{
while (sldr.Read())
{
string state = "";
if (lastgame != "" && lastgame != sldr.GetString(1))
{
state += (old ? ")\n" : "\t\n");
}
if (lastgame != sldr.GetString(1))
{
state += (old ? "game (\n\tname \"" + sldr.GetString(1) + "\"\n" +
"\tdescription \"" + sldr.GetString(1) + "\"\n" :
"\t\n" +
"\t\t" + HttpUtility.HtmlEncode(sldr.GetString(1)) + "\n");
}
if (old)
{
state += "\t" + sldr.GetString(3) + " ( name \"" + sldr.GetString(2) + "\"" +
(sldr.GetInt64(6) != 0 ? " size " + sldr.GetInt64(6) : "") +
(sldr.GetString(7) != "" ? " crc " + sldr.GetString(7).ToLowerInvariant() : "") +
(sldr.GetString(8) != "" ? " md5 " + sldr.GetString(8).ToLowerInvariant() : "") +
(sldr.GetString(9) != "" ? " sha1 " + sldr.GetString(9).ToLowerInvariant() : "") +
" )\n";
}
else
{
state += "\t\t<" + sldr.GetString(3) + " name=\"" + HttpUtility.HtmlEncode(sldr.GetString(2)) + "\"" +
(sldr.GetInt64(6) != -1 ? " size=\"" + sldr.GetInt64(6) + "\"" : "") +
(sldr.GetString(7) != "" ? " crc=\"" + sldr.GetString(7).ToLowerInvariant() + "\"" : "") +
(sldr.GetString(8) != "" ? " md5=\"" + sldr.GetString(8).ToLowerInvariant() + "\"" : "") +
(sldr.GetString(9) != "" ? " sha1=\"" + sldr.GetString(9).ToLowerInvariant() + "\"" : "") +
"/>\n";
}
lastgame = sldr.GetString(1);
sw.Write(state);
}
}
sw.Write((old ? ")" : "\t\n"));
logger.Log("File written!" + Environment.NewLine);
sw.Close();
fs.Close();
}
catch (Exception ex)
{
logger.Error(ex.ToString());
return false;
}
i++;
}
return true;
}
///
/// Output a list of roms as a text file with an arbitrary prefix and postfix
///
/// Name of the output file
/// Output directory for the miss file
/// List of RomData objects representing the roms to be output
/// Logger object for console and/or file output
/// True if only games are written to text file (default), false for files only
/// Arbitrary string to prefix each line
/// Arbitrary string to postfix each line
/// True if quotes should be put around the item, false otherwise (default)
/// Arbitrary extension added to the end of each item
/// Arbitrary extension to replace all extensions in the item
/// True if the game name is appended (only when !usegame), false otherwise
/// True if the file was written, false otherwise
public static bool WriteToText(string textfile, string outdir, List roms, Logger logger, bool useGame = true, string prefix = "",
string postfix = "", string addext = "", string repext = "", bool quotes = false, bool gamename = false)
{
// Normalize the output directory
if (outdir == "")
{
outdir = Environment.CurrentDirectory;
}
if (!outdir.EndsWith(Path.DirectorySeparatorChar.ToString()))
{
outdir += Path.DirectorySeparatorChar;
}
// Make the output directory if it doesn't exist
if (!Directory.Exists(outdir))
{
Directory.CreateDirectory(outdir);
}
// Normalize the extensions
addext = (addext == "" || addext.StartsWith(".") ? addext : "." + addext);
repext = (repext == "" || repext.StartsWith(".") ? repext : "." + repext);
logger.Log("Opening file for writing: " + outdir + textfile);
try
{
FileStream fs = File.Create(outdir + textfile);
StreamWriter sw = new StreamWriter(fs, Encoding.UTF8);
string lastgame = "";
foreach (RomData rom in roms)
{
string pre = prefix + (quotes ? "\"" : "");
string post = (quotes ? "\"" : "") + postfix;
string name = (useGame ? rom.Game : rom.Name);
if (repext != "")
{
string dir = Path.GetDirectoryName(name);
dir = (dir.EndsWith(Path.DirectorySeparatorChar.ToString()) ? dir : dir + Path.DirectorySeparatorChar);
dir = (dir.StartsWith(Path.DirectorySeparatorChar.ToString()) ? dir.Remove(0, 1) : dir);
name = dir + Path.GetFileNameWithoutExtension(name) + repext;
}
if (addext != "")
{
name += addext;
}
if (!useGame && gamename)
{
name = (rom.Game.EndsWith(Path.DirectorySeparatorChar.ToString()) ? rom.Game : rom.Game + Path.DirectorySeparatorChar) + name;
}
if (useGame && rom.Game != lastgame)
{
sw.WriteLine(pre + name + post);
lastgame = rom.Game;
}
else if (!useGame)
{
sw.WriteLine(pre + name + post);
}
}
logger.Log("File written!" + Environment.NewLine);
sw.Close();
fs.Close();
}
catch (Exception ex)
{
logger.Error(ex.ToString());
return false;
}
return true;
}
///
/// Convert a List of RomData objects to a List of tab-deliminated strings
///
/// List of RomData objects representing the roms to be parsed
/// List of Strings representing the roms
public static List RomDataToString(List roms)
{
List outlist = new List();
foreach (RomData rom in roms)
{
outlist.Add(rom.Manufacturer + "\t" +
rom.System + "\t" +
rom.SystemID + "\t" +
rom.Source + "\t" +
rom.URL + "\t" +
rom.SourceID + "\t" +
rom.Game + "\t" +
rom.Name + "\t" +
rom.Type + "\t" +
rom.Size + "\t" +
rom.CRC + "\t" +
rom.MD5 + "\t" +
rom.SHA1);
}
return outlist;
}
///
/// Convert a List of RomData objects' hash information to a List of tab-deliminated strings
///
/// List of RomData objects representing the roms to be parsed
/// List of Strings representing the rom hashes
public static List HashDataToString(List roms)
{
List outlist = new List();
foreach (RomData rom in roms)
{
outlist.Add(rom.Size + "\t" +
rom.CRC + "\t" +
rom.MD5 + "\t" +
rom.SHA1);
}
return outlist;
}
///
/// Convert a List of tab-deliminated strings objects to a List of RomData objects
///
/// List of Strings representing the roms to be parsed
/// List of RomData objects representing the roms
public static List StringToRomData(List roms)
{
List outlist = new List();
foreach (String rom in roms)
{
string[] temp = rom.Split('\t');
try
{
outlist.Add(new RomData
{
Manufacturer = temp[0],
System = temp[1],
SystemID = Int32.Parse(temp[2]),
Source = temp[3],
URL = temp[4],
SourceID = Int32.Parse(temp[5]),
Game = temp[6],
Name = temp[7],
Type = temp[8],
Size = Int64.Parse(temp[9]),
CRC = temp[10],
MD5 = temp[11],
SHA1 = temp[12],
});
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
return outlist;
}
}
}