mirror of
https://github.com/claunia/SabreTools.git
synced 2025-12-16 19:14:27 +00:00
Migrate to Serialization package
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.1.0" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.1.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
try
|
||||
{
|
||||
// Deserialize the input file
|
||||
var files = Serialization.ArchiveDotOrg.Deserialize(filename);
|
||||
var files = new Serialization.Files.ArchiveDotOrg().Deserialize(filename);
|
||||
|
||||
// Convert the files data to the internal format
|
||||
ConvertFiles(files?.File, filename, indexId, statsOnly);
|
||||
@@ -69,7 +69,11 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// <param name="filename">Name of the file to be parsed</param>
|
||||
/// <param name="indexId">Index ID for the DAT</param>
|
||||
/// <param name="statsOnly">True to only add item statistics while parsing, false otherwise</param>
|
||||
#if NET48
|
||||
private void ConvertFiles(Models.ArchiveDotOrg.File[]? files, string filename, int indexId, bool statsOnly)
|
||||
#else
|
||||
private void ConvertFiles(Models.ArchiveDotOrg.File?[]? files, string filename, int indexId, bool statsOnly)
|
||||
#endif
|
||||
{
|
||||
// If the files array is missing, we can't do anything
|
||||
if (files == null || !files.Any())
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
logger.User($"Writing to '{outfile}'...");
|
||||
|
||||
var files = CreateFiles(ignoreblanks);
|
||||
if (!Serialization.ArchiveDotOrg.SerializeToFile(files, outfile))
|
||||
if (!(new Serialization.Files.ArchiveDotOrg().Serialize(files, outfile)))
|
||||
{
|
||||
logger.Warning($"File '{outfile}' could not be written! See the log for more details.");
|
||||
return false;
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
try
|
||||
{
|
||||
// Deserialize the input file
|
||||
var metadataFile = Serialization.AttractMode.Deserialize(filename);
|
||||
var metadataFile = new Serialization.Files.AttractMode().Deserialize(filename);
|
||||
|
||||
// Convert the row data to the internal format
|
||||
ConvertRows(metadataFile?.Row, filename, indexId, statsOnly);
|
||||
@@ -38,7 +38,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// <param name="filename">Name of the file to be parsed</param>
|
||||
/// <param name="indexId">Index ID for the DAT</param>
|
||||
/// <param name="statsOnly">True to only add item statistics while parsing, false otherwise</param>
|
||||
private void ConvertRows(Models.AttractMode.Row[]? rows, string filename, int indexId, bool statsOnly)
|
||||
private void ConvertRows(Models.AttractMode.Row?[]? rows, string filename, int indexId, bool statsOnly)
|
||||
{
|
||||
// If the rows array is missing, we can't do anything
|
||||
if (rows == null || !rows.Any())
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
logger.User($"Writing to '{outfile}'...");
|
||||
|
||||
var metadataFile = CreateMetadataFile(ignoreblanks);
|
||||
if (!Serialization.AttractMode.SerializeToFile(metadataFile, outfile))
|
||||
if (!(new Serialization.Files.AttractMode().Serialize(metadataFile, outfile)))
|
||||
{
|
||||
logger.Warning($"File '{outfile}' could not be written! See the log for more details.");
|
||||
return false;
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
try
|
||||
{
|
||||
// Deserialize the input file
|
||||
var metadataFile = Serialization.ClrMamePro.Deserialize(filename, this.Quotes);
|
||||
var metadataFile = new Serialization.Files.ClrMamePro().Deserialize(filename, this.Quotes);
|
||||
|
||||
// Convert the header to the internal format
|
||||
ConvertHeader(metadataFile?.ClrMamePro, keep);
|
||||
|
||||
@@ -141,7 +141,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
logger.User($"Writing to '{outfile}'...");
|
||||
|
||||
var metadataFile = CreateMetadataFile(ignoreblanks);
|
||||
if (!Serialization.ClrMamePro.SerializeToFile(metadataFile, outfile, Quotes))
|
||||
if (!(new Serialization.Files.ClrMamePro().Serialize(metadataFile, outfile, Quotes)))
|
||||
{
|
||||
logger.Warning($"File '{outfile}' could not be written! See the log for more details.");
|
||||
return false;
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
try
|
||||
{
|
||||
// Deserialize the input file
|
||||
var metadataFile = Serialization.DosCenter.Deserialize(filename);
|
||||
var metadataFile = new Serialization.Files.DosCenter().Deserialize(filename);
|
||||
|
||||
// Convert the header to the internal format
|
||||
ConvertHeader(metadataFile?.DosCenter, keep);
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
logger.User($"Writing to '{outfile}'...");
|
||||
|
||||
var metadataFile = CreateMetadataFile(ignoreblanks);
|
||||
if (!Serialization.DosCenter.SerializeToFile(metadataFile, outfile))
|
||||
if (!(new Serialization.Files.DosCenter().Serialize(metadataFile, outfile)))
|
||||
{
|
||||
logger.Warning($"File '{outfile}' could not be written! See the log for more details.");
|
||||
return false;
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
try
|
||||
{
|
||||
// Deserialize the input file
|
||||
var metadataFile = Serialization.EverdriveSMDB.Deserialize(filename);
|
||||
var metadataFile = new Serialization.Files.EverdriveSMDB().Deserialize(filename);
|
||||
|
||||
// Convert the row data to the internal format
|
||||
ConvertRows(metadataFile?.Row, filename, indexId, statsOnly);
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
logger.User($"Writing to '{outfile}'...");
|
||||
|
||||
var metadataFile = CreateMetadataFile(ignoreblanks);
|
||||
if (!Serialization.EverdriveSMDB.SerializeToFile(metadataFile, outfile))
|
||||
if (!(new Serialization.Files.EverdriveSMDB().Serialize(metadataFile, outfile)))
|
||||
{
|
||||
logger.Warning($"File '{outfile}' could not be written! See the log for more details.");
|
||||
return false;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
try
|
||||
{
|
||||
// Deserialize the input file
|
||||
var hashfile = Serialization.Hashfile.Deserialize(filename, _hash);
|
||||
var hashfile = new Serialization.Files.Hashfile().Deserialize(filename, _hash);
|
||||
|
||||
// Convert items
|
||||
switch (_hash)
|
||||
|
||||
@@ -157,7 +157,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
logger.User($"Writing to '{outfile}'...");
|
||||
|
||||
var hashfile = CreateHashFile(ignoreblanks);
|
||||
if (!Serialization.Hashfile.SerializeToFile(hashfile, outfile, _hash))
|
||||
if (!(new Serialization.Files.Hashfile().Serialize(hashfile, outfile, _hash)))
|
||||
{
|
||||
logger.Warning($"File '{outfile}' could not be written! See the log for more details.");
|
||||
return false;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
try
|
||||
{
|
||||
// Deserialize the input file
|
||||
var metadataFile = Serialization.Listrom.Deserialize(filename);
|
||||
var metadataFile = new Serialization.Files.Listrom().Deserialize(filename);
|
||||
|
||||
// Convert the set data to the internal format
|
||||
ConvertSets(metadataFile?.Set, filename, indexId, statsOnly);
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
logger.User($"Writing to '{outfile}'...");
|
||||
|
||||
var metadataFile = CreateMetadataFile(ignoreblanks);
|
||||
if (!Serialization.Listrom.SerializeToFile(metadataFile, outfile))
|
||||
if (!(new Serialization.Files.Listrom().Serialize(metadataFile, outfile)))
|
||||
{
|
||||
logger.Warning($"File '{outfile}' could not be written! See the log for more details.");
|
||||
return false;
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
{
|
||||
// Deserialize the input file
|
||||
// TODO: Support M1 DATs again
|
||||
var mame = Serialization.Listxml.Deserialize(filename);
|
||||
var mame = new Serialization.Files.Listxml().Deserialize(filename);
|
||||
|
||||
// Convert the header to the internal format
|
||||
ConvertHeader(mame, keep);
|
||||
|
||||
@@ -186,7 +186,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
logger.User($"Writing to '{outfile}'...");
|
||||
|
||||
var mame = CreateMame(ignoreblanks);
|
||||
if (!Serialization.Listxml.SerializeToFile(mame, outfile))
|
||||
if (!(new Serialization.Files.Listxml().Serialize(mame, outfile)))
|
||||
{
|
||||
logger.Warning($"File '{outfile}' could not be written! See the log for more details.");
|
||||
return false;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
try
|
||||
{
|
||||
// Deserialize the input file
|
||||
var metadataFile = Serialization.Logiqx.Deserialize(filename);
|
||||
var metadataFile = new Serialization.Files.Logiqx().Deserialize(filename);
|
||||
|
||||
// Convert the header to the internal format
|
||||
ConvertHeader(metadataFile, keep);
|
||||
|
||||
@@ -138,9 +138,9 @@ namespace SabreTools.DatFiles.Formats
|
||||
// Only write the doctype if we don't have No-Intro data
|
||||
bool success;
|
||||
if (string.IsNullOrWhiteSpace(Header.NoIntroID))
|
||||
success = Serialization.Logiqx.SerializeToFileWithDocType(datafile, outfile);
|
||||
success = new Serialization.Files.Logiqx().SerializeToFileWithDocType(datafile, outfile);
|
||||
else
|
||||
success = Serialization.Logiqx.SerializeToFile(datafile, outfile);
|
||||
success = new Serialization.Files.Logiqx().Serialize(datafile, outfile);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
try
|
||||
{
|
||||
// Deserialize the input file
|
||||
var dat = Serialization.OfflineList.Deserialize(filename);
|
||||
var dat = new Serialization.Files.OfflineList().Deserialize(filename);
|
||||
|
||||
// Convert the header to the internal format
|
||||
ConvertHeader(dat);
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
logger.User($"Writing to '{outfile}'...");
|
||||
|
||||
var datafile = CreateDat(ignoreblanks);
|
||||
if (!Serialization.OfflineList.SerializeToFile(datafile, outfile))
|
||||
if (!(new Serialization.Files.OfflineList().Serialize(datafile, outfile)))
|
||||
{
|
||||
logger.Warning($"File '{outfile}' could not be written! See the log for more details.");
|
||||
return false;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
try
|
||||
{
|
||||
// Deserialize the input file
|
||||
var softwareDb = Serialization.OpenMSX.Deserialize(filename);
|
||||
var softwareDb = new Serialization.Files.OpenMSX().Deserialize(filename);
|
||||
|
||||
// Convert the header to the internal format
|
||||
ConvertHeader(softwareDb);
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
|
||||
// TODO: Write out comment prefix somehow
|
||||
var softwaredb = CreateSoftwareDb(ignoreblanks);
|
||||
if (!Serialization.OpenMSX.SerializeToFileWithDocType(softwaredb, outfile))
|
||||
if (!(new Serialization.Files.OpenMSX().SerializeToFileWithDocType(softwaredb, outfile)))
|
||||
{
|
||||
logger.Warning($"File '{outfile}' could not be written! See the log for more details.");
|
||||
return false;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
try
|
||||
{
|
||||
// Deserialize the input file
|
||||
var metadataFile = Serialization.RomCenter.Deserialize(filename);
|
||||
var metadataFile = new Serialization.Files.RomCenter().Deserialize(filename);
|
||||
|
||||
// Convert the credits data to the internal format
|
||||
ConvertCredits(metadataFile?.Credits);
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
logger.User($"Writing to '{outfile}'...");
|
||||
|
||||
var metadataFile = CreateMetadataFile(ignoreblanks);
|
||||
if (!Serialization.RomCenter.SerializeToFile(metadataFile, outfile))
|
||||
if (!(new Serialization.Files.RomCenter().Serialize(metadataFile, outfile)))
|
||||
{
|
||||
logger.Warning($"File '{outfile}' could not be written! See the log for more details.");
|
||||
return false;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
try
|
||||
{
|
||||
// Deserialize the input file
|
||||
var metadataFile = Serialization.SeparatedValue.Deserialize(filename, _delim);
|
||||
var metadataFile = new Serialization.Files.SeparatedValue().Deserialize(filename, _delim);
|
||||
|
||||
// Convert the row data to the internal format
|
||||
ConvertRows(metadataFile?.Row, filename, indexId, statsOnly);
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
logger.User($"Writing to '{outfile}'...");
|
||||
|
||||
var metadataFile = CreateMetadataFile(ignoreblanks);
|
||||
if (!Serialization.SeparatedValue.SerializeToFile(metadataFile, outfile, _delim))
|
||||
if (!(new Serialization.Files.SeparatedValue().Serialize(metadataFile, outfile, _delim)))
|
||||
{
|
||||
logger.Warning($"File '{outfile}' could not be written! See the log for more details.");
|
||||
return false;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
try
|
||||
{
|
||||
// Deserialize the input file
|
||||
var softwarelist = Serialization.SoftawreList.Deserialize(filename);
|
||||
var softwarelist = new Serialization.Files.SoftwareList().Deserialize(filename);
|
||||
|
||||
// Convert the header to the internal format
|
||||
ConvertHeader(softwarelist, keep);
|
||||
|
||||
@@ -140,7 +140,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
logger.User($"Writing to '{outfile}'...");
|
||||
|
||||
var softwarelist = CreateSoftwareList(ignoreblanks);
|
||||
if (!Serialization.SoftawreList.SerializeToFileWithDocType(softwarelist, outfile))
|
||||
if (!(new Serialization.Files.SoftwareList().SerializeToFileWithDocType(softwarelist, outfile)))
|
||||
{
|
||||
logger.Warning($"File '{outfile}' could not be written! See the log for more details.");
|
||||
return false;
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
<ProjectReference Include="..\SabreTools.Core\SabreTools.Core.csproj" />
|
||||
<ProjectReference Include="..\SabreTools.DatItems\SabreTools.DatItems.csproj" />
|
||||
<ProjectReference Include="..\SabreTools.Logging\SabreTools.Logging.csproj" />
|
||||
<ProjectReference Include="..\SabreTools.Serialization\SabreTools.Serialization.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.10" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="SabreTools.IO" Version="1.1.1" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.1.0" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.1.1" />
|
||||
<PackageReference Include="SabreTools.Serialization" Version="1.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.1.0" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.1.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SabreTools.Models" Version="1.1.0" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.1.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using SabreTools.Models.ArchiveDotOrg;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// XML deserializer for archive.org metadata files
|
||||
/// </summary>
|
||||
public partial class ArchiveDotOrg : XmlSerializer<Files>
|
||||
{
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.MetadataFile"/> to an array of <cref="Models.ArchiveDotOrg.Files"/>
|
||||
/// </summary>
|
||||
public static Files? ConvertFromInternalModel(Models.Metadata.MetadataFile? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var files = new Files();
|
||||
|
||||
var machines = item.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
|
||||
if (machines != null && machines.Any())
|
||||
{
|
||||
files.File = machines
|
||||
.Where(m => m != null)
|
||||
.SelectMany(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Machine"/> to an array of <cref="Models.ArchiveDotOrg.File"/>
|
||||
/// </summary>
|
||||
private static File[] ConvertFromInternalModel(Models.Metadata.Machine item)
|
||||
{
|
||||
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
|
||||
if (roms == null)
|
||||
return Array.Empty<File>();
|
||||
|
||||
return roms
|
||||
.Where(r => r != null)
|
||||
.Select(ConvertFromInternalModel).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.ArchiveDotOrg.File"/>
|
||||
/// </summary>
|
||||
private static File ConvertFromInternalModel(Models.Metadata.Rom item)
|
||||
{
|
||||
var file = new File
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Rom.NameKey),
|
||||
Source = item.ReadString(Models.Metadata.Rom.SourceKey),
|
||||
BitTorrentMagnetHash = item.ReadString(Models.Metadata.Rom.BitTorrentMagnetHashKey),
|
||||
LastModifiedTime = item.ReadString(Models.Metadata.Rom.LastModifiedTimeKey),
|
||||
Size = item.ReadString(Models.Metadata.Rom.SizeKey),
|
||||
MD5 = item.ReadString(Models.Metadata.Rom.MD5Key),
|
||||
CRC32 = item.ReadString(Models.Metadata.Rom.CRCKey),
|
||||
SHA1 = item.ReadString(Models.Metadata.Rom.SHA1Key),
|
||||
FileCount = item.ReadString(Models.Metadata.Rom.FileCountKey),
|
||||
Format = item.ReadString(Models.Metadata.Rom.FormatKey),
|
||||
Original = item.ReadString(Models.Metadata.Rom.OriginalKey),
|
||||
Summation = item.ReadString(Models.Metadata.Rom.SummationKey),
|
||||
MatrixNumber = item.ReadString(Models.Metadata.Rom.MatrixNumberKey),
|
||||
CollectionCatalogNumber = item.ReadString(Models.Metadata.Rom.CollectionCatalogNumberKey),
|
||||
Comment = item.ReadString(Models.Metadata.Rom.CommentKey),
|
||||
|
||||
ASRDetectedLang = item.ReadString(Models.Metadata.Rom.ASRDetectedLangKey),
|
||||
ASRDetectedLangConf = item.ReadString(Models.Metadata.Rom.ASRDetectedLangConfKey),
|
||||
ASRTranscribedLang = item.ReadString(Models.Metadata.Rom.ASRTranscribedLangKey),
|
||||
WhisperASRModuleVersion = item.ReadString(Models.Metadata.Rom.WhisperASRModuleVersionKey),
|
||||
WhisperModelHash = item.ReadString(Models.Metadata.Rom.WhisperModelHashKey),
|
||||
WhisperModelName = item.ReadString(Models.Metadata.Rom.WhisperModelNameKey),
|
||||
WhisperVersion = item.ReadString(Models.Metadata.Rom.WhisperVersionKey),
|
||||
|
||||
ClothCoverDetectionModuleVersion = item.ReadString(Models.Metadata.Rom.ClothCoverDetectionModuleVersionKey),
|
||||
hOCRCharToWordhOCRVersion = item.ReadString(Models.Metadata.Rom.hOCRCharToWordhOCRVersionKey),
|
||||
hOCRCharToWordModuleVersion = item.ReadString(Models.Metadata.Rom.hOCRCharToWordModuleVersionKey),
|
||||
hOCRFtsTexthOCRVersion = item.ReadString(Models.Metadata.Rom.hOCRFtsTexthOCRVersionKey),
|
||||
hOCRFtsTextModuleVersion = item.ReadString(Models.Metadata.Rom.hOCRFtsTextModuleVersionKey),
|
||||
hOCRPageIndexhOCRVersion = item.ReadString(Models.Metadata.Rom.hOCRPageIndexhOCRVersionKey),
|
||||
hOCRPageIndexModuleVersion = item.ReadString(Models.Metadata.Rom.hOCRPageIndexModuleVersionKey),
|
||||
TesseractOCR = item.ReadString(Models.Metadata.Rom.TesseractOCRKey),
|
||||
TesseractOCRConverted = item.ReadString(Models.Metadata.Rom.TesseractOCRConvertedKey),
|
||||
TesseractOCRDetectedLang = item.ReadString(Models.Metadata.Rom.TesseractOCRDetectedLangKey),
|
||||
TesseractOCRDetectedLangConf = item.ReadString(Models.Metadata.Rom.TesseractOCRDetectedLangConfKey),
|
||||
TesseractOCRDetectedScript = item.ReadString(Models.Metadata.Rom.TesseractOCRDetectedScriptKey),
|
||||
TesseractOCRDetectedScriptConf = item.ReadString(Models.Metadata.Rom.TesseractOCRDetectedScriptConfKey),
|
||||
TesseractOCRModuleVersion = item.ReadString(Models.Metadata.Rom.TesseractOCRModuleVersionKey),
|
||||
TesseractOCRParameters = item.ReadString(Models.Metadata.Rom.TesseractOCRParametersKey),
|
||||
PDFModuleVersion = item.ReadString(Models.Metadata.Rom.PDFModuleVersionKey),
|
||||
WordConfidenceInterval0To10 = item.ReadString(Models.Metadata.Rom.WordConfidenceInterval0To10Key),
|
||||
WordConfidenceInterval11To20 = item.ReadString(Models.Metadata.Rom.WordConfidenceInterval11To20Key),
|
||||
WordConfidenceInterval21To30 = item.ReadString(Models.Metadata.Rom.WordConfidenceInterval21To30Key),
|
||||
WordConfidenceInterval31To40 = item.ReadString(Models.Metadata.Rom.WordConfidenceInterval31To40Key),
|
||||
WordConfidenceInterval41To50 = item.ReadString(Models.Metadata.Rom.WordConfidenceInterval41To50Key),
|
||||
WordConfidenceInterval51To60 = item.ReadString(Models.Metadata.Rom.WordConfidenceInterval51To60Key),
|
||||
WordConfidenceInterval61To70 = item.ReadString(Models.Metadata.Rom.WordConfidenceInterval61To70Key),
|
||||
WordConfidenceInterval71To80 = item.ReadString(Models.Metadata.Rom.WordConfidenceInterval71To80Key),
|
||||
WordConfidenceInterval81To90 = item.ReadString(Models.Metadata.Rom.WordConfidenceInterval81To90Key),
|
||||
WordConfidenceInterval91To100 = item.ReadString(Models.Metadata.Rom.WordConfidenceInterval91To100Key),
|
||||
|
||||
Album = item.ReadString(Models.Metadata.Rom.AlbumKey),
|
||||
Artist = item.ReadString(Models.Metadata.Rom.ArtistKey),
|
||||
Bitrate = item.ReadString(Models.Metadata.Rom.BitrateKey),
|
||||
Creator = item.ReadString(Models.Metadata.Rom.CreatorKey),
|
||||
Height = item.ReadString(Models.Metadata.Rom.HeightKey),
|
||||
Length = item.ReadString(Models.Metadata.Rom.LengthKey),
|
||||
PreviewImage = item.ReadString(Models.Metadata.Rom.PreviewImageKey),
|
||||
Rotation = item.ReadString(Models.Metadata.Rom.RotationKey),
|
||||
Title = item.ReadString(Models.Metadata.Rom.TitleKey),
|
||||
Track = item.ReadString(Models.Metadata.Rom.TrackKey),
|
||||
Width = item.ReadString(Models.Metadata.Rom.WidthKey),
|
||||
};
|
||||
return file;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
using System.Linq;
|
||||
using SabreTools.Models.ArchiveDotOrg;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// XML serializer for archive.org metadata files
|
||||
/// </summary>
|
||||
public partial class ArchiveDotOrg : XmlSerializer<Files>
|
||||
{
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.ArchiveDotOrg.Files"/> to <cref="Models.Metadata.MetadataFile"/>
|
||||
/// </summary>
|
||||
public static Models.Metadata.MetadataFile? ConvertToInternalModel(Files? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var metadataFile = new Models.Metadata.MetadataFile
|
||||
{
|
||||
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
|
||||
};
|
||||
|
||||
if (item?.File != null && item.File.Any())
|
||||
{
|
||||
metadataFile[Models.Metadata.MetadataFile.MachineKey] = item.File
|
||||
.Where(f => f != null)
|
||||
.Select(ConvertMachineToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.ArchiveDotOrg.Files"/> to <cref="Models.Metadata.Header"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Header ConvertHeaderToInternalModel(Files item)
|
||||
{
|
||||
var header = new Models.Metadata.Header
|
||||
{
|
||||
[Models.Metadata.Header.NameKey] = "archive.org",
|
||||
};
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.ArchiveDotOrg.File"/> to <cref="Models.Metadata.Machine"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Machine ConvertMachineToInternalModel(File item)
|
||||
{
|
||||
var machine = new Models.Metadata.Machine
|
||||
{
|
||||
[Models.Metadata.Machine.RomKey] = ConvertToInternalModel(item),
|
||||
};
|
||||
return machine;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.ArchiveDotOrg.File"/> to <cref="Models.Metadata.Rom"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Rom ConvertToInternalModel(File item)
|
||||
{
|
||||
var rom = new Models.Metadata.Rom
|
||||
{
|
||||
[Models.Metadata.Rom.NameKey] = item.Name,
|
||||
[Models.Metadata.Rom.SourceKey] = item.Source,
|
||||
[Models.Metadata.Rom.BitTorrentMagnetHashKey] = item.BitTorrentMagnetHash,
|
||||
[Models.Metadata.Rom.LastModifiedTimeKey] = item.LastModifiedTime,
|
||||
[Models.Metadata.Rom.SizeKey] = item.Size,
|
||||
[Models.Metadata.Rom.MD5Key] = item.MD5,
|
||||
[Models.Metadata.Rom.CRCKey] = item.CRC32,
|
||||
[Models.Metadata.Rom.SHA1Key] = item.SHA1,
|
||||
[Models.Metadata.Rom.FileCountKey] = item.FileCount,
|
||||
[Models.Metadata.Rom.FormatKey] = item.Format,
|
||||
[Models.Metadata.Rom.OriginalKey] = item.Original,
|
||||
[Models.Metadata.Rom.SummationKey] = item.Summation,
|
||||
[Models.Metadata.Rom.MatrixNumberKey] = item.MatrixNumber,
|
||||
[Models.Metadata.Rom.CollectionCatalogNumberKey] = item.CollectionCatalogNumber,
|
||||
[Models.Metadata.Rom.PublisherKey] = item.Publisher,
|
||||
[Models.Metadata.Rom.CommentKey] = item.Comment,
|
||||
|
||||
[Models.Metadata.Rom.ASRDetectedLangKey] = item.ASRDetectedLang,
|
||||
[Models.Metadata.Rom.ASRDetectedLangConfKey] = item.ASRDetectedLangConf,
|
||||
[Models.Metadata.Rom.ASRTranscribedLangKey] = item.ASRTranscribedLang,
|
||||
[Models.Metadata.Rom.WhisperASRModuleVersionKey] = item.WhisperASRModuleVersion,
|
||||
[Models.Metadata.Rom.WhisperModelHashKey] = item.WhisperModelHash,
|
||||
[Models.Metadata.Rom.WhisperModelNameKey] = item.WhisperModelName,
|
||||
[Models.Metadata.Rom.WhisperVersionKey] = item.WhisperVersion,
|
||||
|
||||
[Models.Metadata.Rom.ClothCoverDetectionModuleVersionKey] = item.ClothCoverDetectionModuleVersion,
|
||||
[Models.Metadata.Rom.hOCRCharToWordhOCRVersionKey] = item.hOCRCharToWordhOCRVersion,
|
||||
[Models.Metadata.Rom.hOCRCharToWordModuleVersionKey] = item.hOCRCharToWordModuleVersion,
|
||||
[Models.Metadata.Rom.hOCRFtsTexthOCRVersionKey] = item.hOCRFtsTexthOCRVersion,
|
||||
[Models.Metadata.Rom.hOCRFtsTextModuleVersionKey] = item.hOCRFtsTextModuleVersion,
|
||||
[Models.Metadata.Rom.hOCRPageIndexhOCRVersionKey] = item.hOCRPageIndexhOCRVersion,
|
||||
[Models.Metadata.Rom.hOCRPageIndexModuleVersionKey] = item.hOCRPageIndexModuleVersion,
|
||||
[Models.Metadata.Rom.TesseractOCRKey] = item.TesseractOCR,
|
||||
[Models.Metadata.Rom.TesseractOCRConvertedKey] = item.TesseractOCRConverted,
|
||||
[Models.Metadata.Rom.TesseractOCRDetectedLangKey] = item.TesseractOCRDetectedLang,
|
||||
[Models.Metadata.Rom.TesseractOCRDetectedLangConfKey] = item.TesseractOCRDetectedLangConf,
|
||||
[Models.Metadata.Rom.TesseractOCRDetectedScriptKey] = item.TesseractOCRDetectedScript,
|
||||
[Models.Metadata.Rom.TesseractOCRDetectedScriptConfKey] = item.TesseractOCRDetectedScriptConf,
|
||||
[Models.Metadata.Rom.TesseractOCRModuleVersionKey] = item.TesseractOCRModuleVersion,
|
||||
[Models.Metadata.Rom.TesseractOCRParametersKey] = item.TesseractOCRParameters,
|
||||
[Models.Metadata.Rom.PDFModuleVersionKey] = item.PDFModuleVersion,
|
||||
[Models.Metadata.Rom.WordConfidenceInterval0To10Key] = item.WordConfidenceInterval0To10,
|
||||
[Models.Metadata.Rom.WordConfidenceInterval11To20Key] = item.WordConfidenceInterval11To20,
|
||||
[Models.Metadata.Rom.WordConfidenceInterval21To30Key] = item.WordConfidenceInterval21To30,
|
||||
[Models.Metadata.Rom.WordConfidenceInterval31To40Key] = item.WordConfidenceInterval31To40,
|
||||
[Models.Metadata.Rom.WordConfidenceInterval41To50Key] = item.WordConfidenceInterval41To50,
|
||||
[Models.Metadata.Rom.WordConfidenceInterval51To60Key] = item.WordConfidenceInterval51To60,
|
||||
[Models.Metadata.Rom.WordConfidenceInterval61To70Key] = item.WordConfidenceInterval61To70,
|
||||
[Models.Metadata.Rom.WordConfidenceInterval71To80Key] = item.WordConfidenceInterval71To80,
|
||||
[Models.Metadata.Rom.WordConfidenceInterval81To90Key] = item.WordConfidenceInterval81To90,
|
||||
[Models.Metadata.Rom.WordConfidenceInterval91To100Key] = item.WordConfidenceInterval91To100,
|
||||
|
||||
[Models.Metadata.Rom.AlbumKey] = item.Album,
|
||||
[Models.Metadata.Rom.ArtistKey] = item.Artist,
|
||||
[Models.Metadata.Rom.BitrateKey] = item.Bitrate,
|
||||
[Models.Metadata.Rom.CreatorKey] = item.Creator,
|
||||
[Models.Metadata.Rom.HeightKey] = item.Height,
|
||||
[Models.Metadata.Rom.LengthKey] = item.Length,
|
||||
[Models.Metadata.Rom.PreviewImageKey] = item.PreviewImage,
|
||||
[Models.Metadata.Rom.RotationKey] = item.Rotation,
|
||||
[Models.Metadata.Rom.TitleKey] = item.Title,
|
||||
[Models.Metadata.Rom.TrackKey] = item.Track,
|
||||
[Models.Metadata.Rom.WidthKey] = item.Width,
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,212 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Readers;
|
||||
using SabreTools.Models.AttractMode;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// Separated value deserializer for AttractMode romlists
|
||||
/// </summary>
|
||||
public partial class AttractMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Deserializes an AttractMode romlist to the defined type
|
||||
/// </summary>
|
||||
/// <param name="path">Path to the file to deserialize</param>
|
||||
/// <returns>Deserialized data on success, null on failure</returns>
|
||||
public static MetadataFile? Deserialize(string path)
|
||||
{
|
||||
using var stream = PathProcessor.OpenStream(path);
|
||||
return Deserialize(stream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes an AttractMode romlist in a stream to the defined type
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream to deserialize</param>
|
||||
/// <returns>Deserialized data on success, null on failure</returns>
|
||||
public static MetadataFile? Deserialize(Stream? stream)
|
||||
{
|
||||
// If the stream is null
|
||||
if (stream == null)
|
||||
return default;
|
||||
|
||||
// Setup the reader and output
|
||||
var reader = new SeparatedValueReader(stream, Encoding.UTF8)
|
||||
{
|
||||
Separator = ';',
|
||||
VerifyFieldCount = false,
|
||||
};
|
||||
var dat = new MetadataFile();
|
||||
|
||||
// Read the header values first
|
||||
if (!reader.ReadHeader() || reader.HeaderValues == null)
|
||||
return null;
|
||||
|
||||
dat.Header = reader.HeaderValues.ToArray();
|
||||
|
||||
// Loop through the rows and parse out values
|
||||
var rows = new List<Row>();
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
// If we have no next line
|
||||
if (!reader.ReadNextLine() || reader.Line == null)
|
||||
break;
|
||||
|
||||
// Parse the line into a row
|
||||
Row row;
|
||||
if (reader.Line.Count < HeaderWithRomnameCount)
|
||||
{
|
||||
row = new Row
|
||||
{
|
||||
Name = reader.Line[0],
|
||||
Title = reader.Line[1],
|
||||
Emulator = reader.Line[2],
|
||||
CloneOf = reader.Line[3],
|
||||
Year = reader.Line[4],
|
||||
Manufacturer = reader.Line[5],
|
||||
Category = reader.Line[6],
|
||||
Players = reader.Line[7],
|
||||
Rotation = reader.Line[8],
|
||||
Control = reader.Line[9],
|
||||
Status = reader.Line[10],
|
||||
DisplayCount = reader.Line[11],
|
||||
DisplayType = reader.Line[12],
|
||||
AltRomname = reader.Line[13],
|
||||
AltTitle = reader.Line[14],
|
||||
Extra = reader.Line[15],
|
||||
Buttons = reader.Line[16],
|
||||
};
|
||||
|
||||
// If we have additional fields
|
||||
if (reader.Line.Count > HeaderWithoutRomnameCount)
|
||||
row.ADDITIONAL_ELEMENTS = reader.Line.Skip(HeaderWithoutRomnameCount).ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
row = new Row
|
||||
{
|
||||
Name = reader.Line[0],
|
||||
Title = reader.Line[1],
|
||||
Emulator = reader.Line[2],
|
||||
CloneOf = reader.Line[3],
|
||||
Year = reader.Line[4],
|
||||
Manufacturer = reader.Line[5],
|
||||
Category = reader.Line[6],
|
||||
Players = reader.Line[7],
|
||||
Rotation = reader.Line[8],
|
||||
Control = reader.Line[9],
|
||||
Status = reader.Line[10],
|
||||
DisplayCount = reader.Line[11],
|
||||
DisplayType = reader.Line[12],
|
||||
AltRomname = reader.Line[13],
|
||||
AltTitle = reader.Line[14],
|
||||
Extra = reader.Line[15],
|
||||
Buttons = reader.Line[16],
|
||||
};
|
||||
|
||||
// If we have additional fields
|
||||
if (reader.Line.Count > HeaderWithRomnameCount)
|
||||
row.ADDITIONAL_ELEMENTS = reader.Line.Skip(HeaderWithRomnameCount).ToArray();
|
||||
}
|
||||
|
||||
rows.Add(row);
|
||||
}
|
||||
|
||||
// Assign the rows to the Dat and return
|
||||
dat.Row = rows.ToArray();
|
||||
return dat;
|
||||
}
|
||||
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.MetadataFile"/> to <cref="Models.AttractMode.MetadataFile"/>
|
||||
/// </summary>
|
||||
public static MetadataFile? ConvertFromInternalModel(Models.Metadata.MetadataFile? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var header = item.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
|
||||
var metadataFile = header != null ? ConvertHeaderFromInternalModel(header) : new MetadataFile();
|
||||
|
||||
var machines = item.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
|
||||
if (machines != null && machines.Any())
|
||||
{
|
||||
metadataFile.Row = machines
|
||||
.Where(m => m != null)
|
||||
.SelectMany(ConvertMachineFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Header"/> to <cref="Models.AttractMode.MetadataFile"/>
|
||||
/// </summary>
|
||||
private static MetadataFile ConvertHeaderFromInternalModel(Models.Metadata.Header item)
|
||||
{
|
||||
var metadataFile = new MetadataFile
|
||||
{
|
||||
Header = item.ReadStringArray(Models.Metadata.Header.HeaderKey),
|
||||
};
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Machine"/> to an array of <cref="Models.AttractMode.Row"/>
|
||||
/// </summary>
|
||||
private static Row[] ConvertMachineFromInternalModel(Models.Metadata.Machine item)
|
||||
{
|
||||
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
|
||||
if (roms == null || !roms.Any())
|
||||
return Array.Empty<Row>();
|
||||
|
||||
return roms
|
||||
.Where(r => r != null)
|
||||
.Select(rom => ConvertFromInternalModel(rom, item))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.AttractMode.Row"/>
|
||||
/// </summary>
|
||||
private static Row ConvertFromInternalModel(Models.Metadata.Rom item, Models.Metadata.Machine parent)
|
||||
{
|
||||
var row = new Row
|
||||
{
|
||||
Name = parent.ReadString(Models.Metadata.Machine.NameKey),
|
||||
Title = item.ReadString(Models.Metadata.Rom.NameKey),
|
||||
Emulator = parent.ReadString(Models.Metadata.Machine.EmulatorKey),
|
||||
CloneOf = parent.ReadString(Models.Metadata.Machine.CloneOfKey),
|
||||
Year = parent.ReadString(Models.Metadata.Machine.YearKey),
|
||||
Manufacturer = parent.ReadString(Models.Metadata.Machine.ManufacturerKey),
|
||||
Category = parent.ReadString(Models.Metadata.Machine.CategoryKey),
|
||||
Players = parent.ReadString(Models.Metadata.Machine.PlayersKey),
|
||||
Rotation = parent.ReadString(Models.Metadata.Machine.RotationKey),
|
||||
Control = parent.ReadString(Models.Metadata.Machine.ControlKey),
|
||||
Status = parent.ReadString(Models.Metadata.Machine.StatusKey),
|
||||
DisplayCount = parent.ReadString(Models.Metadata.Machine.DisplayCountKey),
|
||||
DisplayType = parent.ReadString(Models.Metadata.Machine.DisplayTypeKey),
|
||||
AltRomname = item.ReadString(Models.Metadata.Rom.AltRomnameKey),
|
||||
AltTitle = item.ReadString(Models.Metadata.Rom.AltTitleKey),
|
||||
Extra = parent.ReadString(Models.Metadata.Machine.ExtraKey),
|
||||
Buttons = parent.ReadString(Models.Metadata.Machine.ButtonsKey),
|
||||
Favorite = parent.ReadString(Models.Metadata.Machine.FavoriteKey),
|
||||
Tags = parent.ReadString(Models.Metadata.Machine.TagsKey),
|
||||
PlayedCount = parent.ReadString(Models.Metadata.Machine.PlayedCountKey),
|
||||
PlayedTime = parent.ReadString(Models.Metadata.Machine.PlayedTimeKey),
|
||||
FileIsAvailable = item.ReadString(Models.Metadata.Rom.FileIsAvailableKey),
|
||||
};
|
||||
return row;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,189 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Writers;
|
||||
using SabreTools.Models.AttractMode;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// Separated value serializer for AttractMode romlists
|
||||
/// </summary>
|
||||
public partial class AttractMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializes the defined type to an AttractMode romlist
|
||||
/// </summary>
|
||||
/// <param name="metadataFile">Data to serialize</param>
|
||||
/// <param name="path">Path to the file to serialize to</param>
|
||||
/// <returns>True on successful serialization, false otherwise</returns>
|
||||
public static bool SerializeToFile(MetadataFile? metadataFile, string path)
|
||||
{
|
||||
using var stream = SerializeToStream(metadataFile);
|
||||
if (stream == null)
|
||||
return false;
|
||||
|
||||
using var fs = File.OpenWrite(path);
|
||||
stream.CopyTo(fs);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes the defined type to a stream
|
||||
/// </summary>
|
||||
/// <param name="metadataFile">Data to serialize</param>
|
||||
/// <returns>Stream containing serialized data on success, null otherwise</returns>
|
||||
public static Stream? SerializeToStream(MetadataFile? metadataFile)
|
||||
{
|
||||
// If the metadata file is null
|
||||
if (metadataFile == null)
|
||||
return null;
|
||||
|
||||
// Setup the writer and output
|
||||
var stream = new MemoryStream();
|
||||
var writer = new SeparatedValueWriter(stream, Encoding.UTF8)
|
||||
{
|
||||
Separator = ';',
|
||||
Quotes = false,
|
||||
VerifyFieldCount = false,
|
||||
};
|
||||
|
||||
// TODO: Include flag to write out long or short header
|
||||
// Write the short header
|
||||
writer.WriteString(HeaderWithoutRomname); // TODO: Convert to array of values
|
||||
|
||||
// Write out the rows, if they exist
|
||||
WriteRows(metadataFile.Row, writer);
|
||||
|
||||
// Return the stream
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
return stream;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write rows information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="rows">Array of Row objects representing the rows information</param>
|
||||
/// <param name="writer">SeparatedValueWriter representing the output</param>
|
||||
private static void WriteRows(Row[]? rows, SeparatedValueWriter writer)
|
||||
{
|
||||
// If the games information is missing, we can't do anything
|
||||
if (rows == null || !rows.Any())
|
||||
return;
|
||||
|
||||
// Loop through and write out the rows
|
||||
foreach (var row in rows)
|
||||
{
|
||||
var rowArray = new string?[]
|
||||
{
|
||||
row.Name,
|
||||
row.Title,
|
||||
row.Emulator,
|
||||
row.CloneOf,
|
||||
row.Year,
|
||||
row.Manufacturer,
|
||||
row.Category,
|
||||
row.Players,
|
||||
row.Rotation,
|
||||
row.Control,
|
||||
row.Status,
|
||||
row.DisplayCount,
|
||||
row.DisplayType,
|
||||
row.AltRomname,
|
||||
row.AltTitle,
|
||||
row.Extra,
|
||||
row.Buttons,
|
||||
};
|
||||
|
||||
writer.WriteValues(rowArray);
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.AttractMode.MetadataFile"/> to <cref="Models.Metadata.MetadataFile"/>
|
||||
/// </summary>
|
||||
public static Models.Metadata.MetadataFile? ConvertToInternalModel(MetadataFile? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var metadataFile = new Models.Metadata.MetadataFile
|
||||
{
|
||||
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
|
||||
};
|
||||
|
||||
if (item?.Row != null && item.Row.Any())
|
||||
{
|
||||
metadataFile[Models.Metadata.MetadataFile.MachineKey] = item.Row
|
||||
.Where(r => r != null)
|
||||
.Select(ConvertMachineToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.AttractMode.MetadataFile"/> to <cref="Models.Metadata.Header"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Header ConvertHeaderToInternalModel(MetadataFile item)
|
||||
{
|
||||
var header = new Models.Metadata.Header
|
||||
{
|
||||
[Models.Metadata.Header.HeaderKey] = item.Header,
|
||||
};
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.AttractMode.Row"/> to <cref="Models.Metadata.Machine"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Machine ConvertMachineToInternalModel(Row item)
|
||||
{
|
||||
var machine = new Models.Metadata.Machine
|
||||
{
|
||||
[Models.Metadata.Machine.NameKey] = item.Name,
|
||||
[Models.Metadata.Machine.EmulatorKey] = item.Emulator,
|
||||
[Models.Metadata.Machine.CloneOfKey] = item.CloneOf,
|
||||
[Models.Metadata.Machine.YearKey] = item.Year,
|
||||
[Models.Metadata.Machine.ManufacturerKey] = item.Manufacturer,
|
||||
[Models.Metadata.Machine.CategoryKey] = item.Category,
|
||||
[Models.Metadata.Machine.PlayersKey] = item.Players,
|
||||
[Models.Metadata.Machine.RotationKey] = item.Rotation,
|
||||
[Models.Metadata.Machine.ControlKey] = item.Control,
|
||||
[Models.Metadata.Machine.StatusKey] = item.Status,
|
||||
[Models.Metadata.Machine.DisplayCountKey] = item.DisplayCount,
|
||||
[Models.Metadata.Machine.DisplayTypeKey] = item.DisplayType,
|
||||
[Models.Metadata.Machine.ExtraKey] = item.Extra,
|
||||
[Models.Metadata.Machine.ButtonsKey] = item.Buttons,
|
||||
[Models.Metadata.Machine.FavoriteKey] = item.Favorite,
|
||||
[Models.Metadata.Machine.TagsKey] = item.Tags,
|
||||
[Models.Metadata.Machine.PlayedCountKey] = item.PlayedCount,
|
||||
[Models.Metadata.Machine.PlayedTimeKey] = item.PlayedTime,
|
||||
[Models.Metadata.Machine.PlayedTimeKey] = item.PlayedTime,
|
||||
[Models.Metadata.Machine.RomKey] = ConvertToInternalModel(item),
|
||||
};
|
||||
return machine;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.AttractMode.Row"/> to <cref="Models.Metadata.Rom"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Rom ConvertToInternalModel(Row item)
|
||||
{
|
||||
var rom = new Models.Metadata.Rom
|
||||
{
|
||||
[Models.Metadata.Rom.NameKey] = item.Title,
|
||||
[Models.Metadata.Rom.AltRomnameKey] = item.AltRomname,
|
||||
[Models.Metadata.Rom.AltTitleKey] = item.AltTitle,
|
||||
[Models.Metadata.Rom.FileIsAvailableKey] = item.FileIsAvailable,
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// Separated value serializer/deserializer for AttractMode romlists
|
||||
/// </summary>
|
||||
public partial class AttractMode
|
||||
{
|
||||
private const string HeaderWithoutRomname = "#Name;Title;Emulator;CloneOf;Year;Manufacturer;Category;Players;Rotation;Control;Status;DisplayCount;DisplayType;AltRomname;AltTitle;Extra;Buttons";
|
||||
private const int HeaderWithoutRomnameCount = 17;
|
||||
|
||||
private const string HeaderWithRomname = "#Romname;Title;Emulator;Cloneof;Year;Manufacturer;Category;Players;Rotation;Control;Status;DisplayCount;DisplayType;AltRomname;AltTitle;Extra;Buttons;Favourite;Tags;PlayedCount;PlayedTime;FileIsAvailable";
|
||||
private const int HeaderWithRomnameCount = 22;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,837 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Writers;
|
||||
using SabreTools.Models.ClrMamePro;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializer for ClrMamePro metadata files
|
||||
/// </summary>
|
||||
public partial class ClrMamePro
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializes the defined type to a ClrMamePro metadata file
|
||||
/// </summary>
|
||||
/// <param name="metadataFile">Data to serialize</param>
|
||||
/// <param name="path">Path to the file to serialize to</param>
|
||||
/// <param name="quotes">Enable quotes on write, false otherwise</param>
|
||||
/// <returns>True on successful serialization, false otherwise</returns>
|
||||
public static bool SerializeToFile(MetadataFile? metadataFile, string path, bool quotes)
|
||||
{
|
||||
using var stream = SerializeToStream(metadataFile, quotes);
|
||||
if (stream == null)
|
||||
return false;
|
||||
|
||||
using var fs = File.OpenWrite(path);
|
||||
stream.CopyTo(fs);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes the defined type to a stream
|
||||
/// </summary>
|
||||
/// <param name="metadataFile">Data to serialize</param>
|
||||
/// <param name="quotes">Enable quotes on write, false otherwise</param>
|
||||
/// <returns>Stream containing serialized data on success, null otherwise</returns>
|
||||
public static Stream? SerializeToStream(MetadataFile? metadataFile, bool quotes)
|
||||
{
|
||||
// If the metadata file is null
|
||||
if (metadataFile == null)
|
||||
return null;
|
||||
|
||||
// Setup the writer and output
|
||||
var stream = new MemoryStream();
|
||||
var writer = new ClrMameProWriter(stream, Encoding.UTF8) { Quotes = quotes };
|
||||
|
||||
// Write the header, if it exists
|
||||
WriteHeader(metadataFile.ClrMamePro, writer);
|
||||
|
||||
// Write out the games, if they exist
|
||||
WriteGames(metadataFile.Game, writer);
|
||||
|
||||
// Return the stream
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
return stream;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write header information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="header">ClrMamePro representing the header information</param>
|
||||
/// <param name="writer">ClrMameProWriter representing the output</param>
|
||||
private static void WriteHeader(Models.ClrMamePro.ClrMamePro? header, ClrMameProWriter writer)
|
||||
{
|
||||
// If the header information is missing, we can't do anything
|
||||
if (header == null)
|
||||
return;
|
||||
|
||||
writer.WriteStartElement("clrmamepro");
|
||||
|
||||
writer.WriteOptionalStandalone("name", header.Name);
|
||||
writer.WriteOptionalStandalone("description", header.Description);
|
||||
writer.WriteOptionalStandalone("rootdir", header.RootDir);
|
||||
writer.WriteOptionalStandalone("category", header.Category);
|
||||
writer.WriteOptionalStandalone("version", header.Version);
|
||||
writer.WriteOptionalStandalone("date", header.Date);
|
||||
writer.WriteOptionalStandalone("author", header.Author);
|
||||
writer.WriteOptionalStandalone("homepage", header.Homepage);
|
||||
writer.WriteOptionalStandalone("url", header.Url);
|
||||
writer.WriteOptionalStandalone("comment", header.Comment);
|
||||
writer.WriteOptionalStandalone("header", header.Header);
|
||||
writer.WriteOptionalStandalone("type", header.Type);
|
||||
writer.WriteOptionalStandalone("forcemerging", header.ForceMerging);
|
||||
writer.WriteOptionalStandalone("forcezipping", header.ForceZipping);
|
||||
writer.WriteOptionalStandalone("forcepacking", header.ForcePacking);
|
||||
|
||||
writer.WriteEndElement(); // clrmamepro
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write games information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="games">Array of GameBase objects representing the games information</param>
|
||||
/// <param name="writer">ClrMameProWriter representing the output</param>
|
||||
private static void WriteGames(GameBase[]? games, ClrMameProWriter writer)
|
||||
{
|
||||
// If the games information is missing, we can't do anything
|
||||
if (games == null || !games.Any())
|
||||
return;
|
||||
|
||||
// Loop through and write out the games
|
||||
foreach (var game in games)
|
||||
{
|
||||
WriteGame(game, writer);
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write game information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="game">GameBase object representing the game information</param>
|
||||
/// <param name="writer">ClrMameProWriter representing the output</param>
|
||||
private static void WriteGame(GameBase game, ClrMameProWriter writer)
|
||||
{
|
||||
// If the game information is missing, we can't do anything
|
||||
if (game == null)
|
||||
return;
|
||||
|
||||
switch (game)
|
||||
{
|
||||
case Game:
|
||||
writer.WriteStartElement("game");
|
||||
break;
|
||||
case Machine:
|
||||
writer.WriteStartElement("machine");
|
||||
break;
|
||||
case Resource:
|
||||
writer.WriteStartElement("resource");
|
||||
break;
|
||||
case Set:
|
||||
writer.WriteStartElement(name: "set");
|
||||
break;
|
||||
}
|
||||
|
||||
// Write the standalone values
|
||||
writer.WriteRequiredStandalone("name", game.Name, throwOnError: true);
|
||||
writer.WriteOptionalStandalone("description", game.Description);
|
||||
writer.WriteOptionalStandalone("year", game.Year);
|
||||
writer.WriteOptionalStandalone("manufacturer", game.Manufacturer);
|
||||
writer.WriteOptionalStandalone("category", game.Category);
|
||||
writer.WriteOptionalStandalone("cloneof", game.CloneOf);
|
||||
writer.WriteOptionalStandalone("romof", game.RomOf);
|
||||
writer.WriteOptionalStandalone("sampleof", game.SampleOf);
|
||||
|
||||
// Write the item values
|
||||
WriteReleases(game.Release, writer);
|
||||
WriteBiosSets(game.BiosSet, writer);
|
||||
WriteRoms(game.Rom, writer);
|
||||
WriteDisks(game.Disk, writer);
|
||||
WriteMedia(game.Media, writer);
|
||||
WriteSamples(game.Sample, writer);
|
||||
WriteArchives(game.Archive, writer);
|
||||
WriteChips(game.Chip, writer);
|
||||
WriteVideos(game.Video, writer);
|
||||
WriteSound(game.Sound, writer);
|
||||
WriteInput(game.Input, writer);
|
||||
WriteDipSwitches(game.DipSwitch, writer);
|
||||
WriteDriver(game.Driver, writer);
|
||||
|
||||
writer.WriteEndElement(); // game, machine, resource, set
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write releases information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="releases">Array of Release objects to write</param>
|
||||
/// <param name="writer">ClrMameProWriter representing the output</param>
|
||||
private static void WriteReleases(Release[]? releases, ClrMameProWriter writer)
|
||||
{
|
||||
// If the array is missing, we can't do anything
|
||||
if (releases == null)
|
||||
return;
|
||||
|
||||
foreach (var release in releases)
|
||||
{
|
||||
writer.WriteStartElement("release");
|
||||
writer.WriteRequiredAttributeString("name", release.Name, throwOnError: true);
|
||||
writer.WriteRequiredAttributeString("region", release.Region, throwOnError: true);
|
||||
writer.WriteOptionalAttributeString("language", release.Language);
|
||||
writer.WriteOptionalAttributeString("date", release.Date);
|
||||
writer.WriteOptionalAttributeString("default", release.Default);
|
||||
writer.WriteEndElement(); // release
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write biossets information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="biossets">Array of BiosSet objects to write</param>
|
||||
/// <param name="writer">ClrMameProWriter representing the output</param>
|
||||
private static void WriteBiosSets(BiosSet[]? biossets, ClrMameProWriter writer)
|
||||
{
|
||||
// If the array is missing, we can't do anything
|
||||
if (biossets == null)
|
||||
return;
|
||||
|
||||
foreach (var biosset in biossets)
|
||||
{
|
||||
writer.WriteStartElement("biosset");
|
||||
writer.WriteRequiredAttributeString("name", biosset.Name, throwOnError: true);
|
||||
writer.WriteRequiredAttributeString("description", biosset.Description, throwOnError: true);
|
||||
writer.WriteOptionalAttributeString("default", biosset.Default);
|
||||
writer.WriteEndElement(); // release
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write roms information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="roms">Array of Rom objects to write</param>
|
||||
/// <param name="writer">ClrMameProWriter representing the output</param>
|
||||
private static void WriteRoms(Rom[]? roms, ClrMameProWriter writer)
|
||||
{
|
||||
// If the array is missing, we can't do anything
|
||||
if (roms == null)
|
||||
return;
|
||||
|
||||
foreach (var rom in roms)
|
||||
{
|
||||
writer.WriteStartElement("rom");
|
||||
writer.WriteRequiredAttributeString("name", rom.Name, throwOnError: true);
|
||||
writer.WriteRequiredAttributeString("size", rom.Size, throwOnError: true);
|
||||
writer.WriteOptionalAttributeString("crc", rom.CRC);
|
||||
writer.WriteOptionalAttributeString("md5", rom.MD5);
|
||||
writer.WriteOptionalAttributeString("sha1", rom.SHA1);
|
||||
writer.WriteOptionalAttributeString("sha256", rom.SHA256);
|
||||
writer.WriteOptionalAttributeString("sha384", rom.SHA384);
|
||||
writer.WriteOptionalAttributeString("sha512", rom.SHA512);
|
||||
writer.WriteOptionalAttributeString("spamsum", rom.SpamSum);
|
||||
writer.WriteOptionalAttributeString("xxh3_64", rom.xxHash364);
|
||||
writer.WriteOptionalAttributeString("xxh3_128", rom.xxHash3128);
|
||||
writer.WriteOptionalAttributeString("merge", rom.Merge);
|
||||
writer.WriteOptionalAttributeString("status", rom.Status);
|
||||
writer.WriteOptionalAttributeString("region", rom.Region);
|
||||
writer.WriteOptionalAttributeString("flags", rom.Flags);
|
||||
writer.WriteOptionalAttributeString("offs", rom.Offs);
|
||||
writer.WriteOptionalAttributeString("serial", rom.Serial);
|
||||
writer.WriteOptionalAttributeString("header", rom.Header);
|
||||
writer.WriteOptionalAttributeString("date", rom.Date);
|
||||
writer.WriteOptionalAttributeString("inverted", rom.Inverted);
|
||||
writer.WriteOptionalAttributeString("mia", rom.MIA);
|
||||
writer.WriteEndElement(); // rom
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write disks information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="disks">Array of Disk objects to write</param>
|
||||
/// <param name="writer">ClrMameProWriter representing the output</param>
|
||||
private static void WriteDisks(Disk[]? disks, ClrMameProWriter writer)
|
||||
{
|
||||
// If the array is missing, we can't do anything
|
||||
if (disks == null)
|
||||
return;
|
||||
|
||||
foreach (var disk in disks)
|
||||
{
|
||||
writer.WriteStartElement("disk");
|
||||
writer.WriteRequiredAttributeString("name", disk.Name, throwOnError: true);
|
||||
writer.WriteOptionalAttributeString("md5", disk.MD5);
|
||||
writer.WriteOptionalAttributeString("sha1", disk.SHA1);
|
||||
writer.WriteOptionalAttributeString("merge", disk.Merge);
|
||||
writer.WriteOptionalAttributeString("status", disk.Status);
|
||||
writer.WriteOptionalAttributeString("flags", disk.Flags);
|
||||
writer.WriteEndElement(); // disk
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write medias information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="medias">Array of Media objects to write</param>
|
||||
/// <param name="writer">ClrMameProWriter representing the output</param>
|
||||
private static void WriteMedia(Media[]? medias, ClrMameProWriter writer)
|
||||
{
|
||||
// If the array is missing, we can't do anything
|
||||
if (medias == null)
|
||||
return;
|
||||
|
||||
foreach (var media in medias)
|
||||
{
|
||||
writer.WriteStartElement("media");
|
||||
writer.WriteRequiredAttributeString("name", media.Name, throwOnError: true);
|
||||
writer.WriteOptionalAttributeString("md5", media.MD5);
|
||||
writer.WriteOptionalAttributeString("sha1", media.SHA1);
|
||||
writer.WriteOptionalAttributeString("sha256", media.SHA256);
|
||||
writer.WriteOptionalAttributeString("spamsum", media.SpamSum);
|
||||
writer.WriteEndElement(); // media
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write samples information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="samples">Array of Sample objects to write</param>
|
||||
/// <param name="writer">ClrMameProWriter representing the output</param>
|
||||
private static void WriteSamples(Sample[]? samples, ClrMameProWriter writer)
|
||||
{
|
||||
// If the array is missing, we can't do anything
|
||||
if (samples == null)
|
||||
return;
|
||||
|
||||
foreach (var sample in samples)
|
||||
{
|
||||
writer.WriteStartElement("sample");
|
||||
writer.WriteRequiredAttributeString("name", sample.Name, throwOnError: true);
|
||||
writer.WriteEndElement(); // sample
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write archives information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="archives">Array of Archive objects to write</param>
|
||||
/// <param name="writer">ClrMameProWriter representing the output</param>
|
||||
private static void WriteArchives(Archive[]? archives, ClrMameProWriter writer)
|
||||
{
|
||||
// If the array is missing, we can't do anything
|
||||
if (archives == null)
|
||||
return;
|
||||
|
||||
foreach (var archive in archives)
|
||||
{
|
||||
writer.WriteStartElement("archive");
|
||||
writer.WriteRequiredAttributeString("name", archive.Name, throwOnError: true);
|
||||
writer.WriteEndElement(); // archive
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write chips information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="chips">Array of Chip objects to write</param>
|
||||
/// <param name="writer">ClrMameProWriter representing the output</param>
|
||||
private static void WriteChips(Chip[]? chips, ClrMameProWriter writer)
|
||||
{
|
||||
// If the array is missing, we can't do anything
|
||||
if (chips == null)
|
||||
return;
|
||||
|
||||
foreach (var chip in chips)
|
||||
{
|
||||
writer.WriteStartElement("chip");
|
||||
writer.WriteRequiredAttributeString("type", chip.Type, throwOnError: true);
|
||||
writer.WriteRequiredAttributeString("name", chip.Name, throwOnError: true);
|
||||
writer.WriteOptionalAttributeString("flags", chip.Flags);
|
||||
writer.WriteOptionalAttributeString("clock", chip.Clock);
|
||||
writer.WriteEndElement(); // chip
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write video information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="videos">Array of Video objects to write</param>
|
||||
/// <param name="writer">ClrMameProWriter representing the output</param>
|
||||
private static void WriteVideos(Video[]? videos, ClrMameProWriter writer)
|
||||
{
|
||||
// If the item is missing, we can't do anything
|
||||
if (videos == null)
|
||||
return;
|
||||
|
||||
foreach (var video in videos)
|
||||
{
|
||||
writer.WriteStartElement("video");
|
||||
writer.WriteRequiredAttributeString("screen", video.Screen, throwOnError: true);
|
||||
writer.WriteRequiredAttributeString("orientation", video.Orientation, throwOnError: true);
|
||||
writer.WriteOptionalAttributeString("x", video.X);
|
||||
writer.WriteOptionalAttributeString("y", video.Y);
|
||||
writer.WriteOptionalAttributeString("aspectx", video.AspectX);
|
||||
writer.WriteOptionalAttributeString("aspecty", video.AspectY);
|
||||
writer.WriteOptionalAttributeString("freq", video.Freq);
|
||||
writer.WriteEndElement(); // video
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write sound information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="sound">Sound object to write</param>
|
||||
/// <param name="writer">ClrMameProWriter representing the output</param>
|
||||
private static void WriteSound(Sound? sound, ClrMameProWriter writer)
|
||||
{
|
||||
// If the item is missing, we can't do anything
|
||||
if (sound == null)
|
||||
return;
|
||||
|
||||
writer.WriteStartElement("sound");
|
||||
writer.WriteRequiredAttributeString("channels", sound.Channels, throwOnError: true);
|
||||
writer.WriteEndElement(); // sound
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write input information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="input">Input object to write</param>
|
||||
/// <param name="writer">ClrMameProWriter representing the output</param>
|
||||
private static void WriteInput(Input? input, ClrMameProWriter writer)
|
||||
{
|
||||
// If the item is missing, we can't do anything
|
||||
if (input == null)
|
||||
return;
|
||||
|
||||
writer.WriteStartElement("input");
|
||||
writer.WriteRequiredAttributeString("players", input.Players, throwOnError: true);
|
||||
writer.WriteOptionalAttributeString("control", input.Control);
|
||||
writer.WriteRequiredAttributeString("buttons", input.Buttons, throwOnError: true);
|
||||
writer.WriteOptionalAttributeString("coins", input.Coins);
|
||||
writer.WriteOptionalAttributeString("tilt", input.Tilt);
|
||||
writer.WriteOptionalAttributeString("service", input.Service);
|
||||
writer.WriteEndElement(); // input
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write dipswitches information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="dipswitches">Array of DipSwitch objects to write</param>
|
||||
/// <param name="writer">ClrMameProWriter representing the output</param>
|
||||
private static void WriteDipSwitches(DipSwitch[]? dipswitches, ClrMameProWriter writer)
|
||||
{
|
||||
// If the array is missing, we can't do anything
|
||||
if (dipswitches == null)
|
||||
return;
|
||||
|
||||
foreach (var dipswitch in dipswitches)
|
||||
{
|
||||
writer.WriteStartElement("dipswitch");
|
||||
writer.WriteRequiredAttributeString("name", dipswitch.Name, throwOnError: true);
|
||||
foreach (var entry in dipswitch.Entry ?? Array.Empty<string>())
|
||||
{
|
||||
writer.WriteRequiredAttributeString("entry", entry);
|
||||
}
|
||||
writer.WriteOptionalAttributeString("default", dipswitch.Default);
|
||||
writer.WriteEndElement(); // dipswitch
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write driver information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="driver">Driver object to write</param>
|
||||
/// <param name="writer">ClrMameProWriter representing the output</param>
|
||||
private static void WriteDriver(Driver? driver, ClrMameProWriter writer)
|
||||
{
|
||||
// If the item is missing, we can't do anything
|
||||
if (driver == null)
|
||||
return;
|
||||
|
||||
writer.WriteStartElement("driver");
|
||||
writer.WriteRequiredAttributeString("status", driver.Status, throwOnError: true);
|
||||
writer.WriteOptionalAttributeString("color", driver.Color); // TODO: Probably actually required
|
||||
writer.WriteOptionalAttributeString("sound", driver.Sound); // TODO: Probably actually required
|
||||
writer.WriteOptionalAttributeString("palettesize", driver.PaletteSize);
|
||||
writer.WriteOptionalAttributeString("blit", driver.Blit);
|
||||
writer.WriteEndElement(); // driver
|
||||
}
|
||||
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.ClrMamePro.MetadataFile"/> to <cref="Models.Metadata.MetadataFile"/>
|
||||
/// </summary>
|
||||
public static Models.Metadata.MetadataFile? ConvertToInternalModel(MetadataFile? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var metadataFile = new Models.Metadata.MetadataFile();
|
||||
|
||||
if (item?.ClrMamePro != null)
|
||||
metadataFile[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item.ClrMamePro);
|
||||
|
||||
if (item?.Game != null && item.Game.Any())
|
||||
{
|
||||
metadataFile[Models.Metadata.MetadataFile.MachineKey] = item.Game
|
||||
.Where(g => g != null)
|
||||
.Select(ConvertMachineToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.ClrMamePro.ClrMamePro"/> to <cref="Models.Metadata.Header"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Header ConvertHeaderToInternalModel(Models.ClrMamePro.ClrMamePro item)
|
||||
{
|
||||
var header = new Models.Metadata.Header
|
||||
{
|
||||
[Models.Metadata.Header.NameKey] = item.Name,
|
||||
[Models.Metadata.Header.DescriptionKey] = item.Description,
|
||||
[Models.Metadata.Header.RootDirKey] = item.RootDir,
|
||||
[Models.Metadata.Header.CategoryKey] = item.Category,
|
||||
[Models.Metadata.Header.VersionKey] = item.Version,
|
||||
[Models.Metadata.Header.DateKey] = item.Date,
|
||||
[Models.Metadata.Header.AuthorKey] = item.Author,
|
||||
[Models.Metadata.Header.HomepageKey] = item.Homepage,
|
||||
[Models.Metadata.Header.UrlKey] = item.Url,
|
||||
[Models.Metadata.Header.CommentKey] = item.Comment,
|
||||
[Models.Metadata.Header.HeaderKey] = item.Header,
|
||||
[Models.Metadata.Header.TypeKey] = item.Type,
|
||||
[Models.Metadata.Header.ForceMergingKey] = item.ForceMerging,
|
||||
[Models.Metadata.Header.ForceZippingKey] = item.ForceZipping,
|
||||
[Models.Metadata.Header.ForcePackingKey] = item.ForcePacking,
|
||||
};
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.ClrMamePro.GameBase"/> to <cref="Models.Metadata.Machine"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Machine ConvertMachineToInternalModel(GameBase item)
|
||||
{
|
||||
var machine = new Models.Metadata.Machine
|
||||
{
|
||||
[Models.Metadata.Machine.NameKey] = item.Name,
|
||||
[Models.Metadata.Machine.DescriptionKey] = item.Description,
|
||||
[Models.Metadata.Machine.YearKey] = item.Year,
|
||||
[Models.Metadata.Machine.ManufacturerKey] = item.Manufacturer,
|
||||
[Models.Metadata.Machine.CategoryKey] = item.Category,
|
||||
[Models.Metadata.Machine.CloneOfKey] = item.CloneOf,
|
||||
[Models.Metadata.Machine.RomOfKey] = item.RomOf,
|
||||
[Models.Metadata.Machine.SampleOfKey] = item.SampleOf,
|
||||
};
|
||||
|
||||
if (item.Release != null && item.Release.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.ReleaseKey] = item.Release
|
||||
.Where(r => r != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.BiosSet != null && item.BiosSet.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.BiosSetKey] = item.BiosSet
|
||||
.Where(b => b != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.Rom != null && item.Rom.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.RomKey] = item.Rom
|
||||
.Where(r => r != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.Disk != null && item.Disk.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.DiskKey] = item.Disk
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.Media != null && item.Media.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.MediaKey] = item.Media
|
||||
.Where(m => m != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.Sample != null && item.Sample.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.SampleKey] = item.Sample
|
||||
.Where(s => s != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.Archive != null && item.Archive.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.ArchiveKey] = item.Archive
|
||||
.Where(a => a != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.Chip != null && item.Chip.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.ChipKey] = item.Chip
|
||||
.Where(c => c != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.Video != null)
|
||||
{
|
||||
machine[Models.Metadata.Machine.VideoKey] = item.Video
|
||||
.Where(v => v != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.Sound != null)
|
||||
machine[Models.Metadata.Machine.SoundKey] = ConvertToInternalModel(item.Sound);
|
||||
|
||||
if (item.Input != null)
|
||||
machine[Models.Metadata.Machine.InputKey] = ConvertToInternalModel(item.Input);
|
||||
|
||||
if (item.DipSwitch != null && item.DipSwitch.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.DipSwitchKey] = item.DipSwitch
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.Driver != null)
|
||||
machine[Models.Metadata.Machine.DriverKey] = ConvertToInternalModel(item.Driver);
|
||||
|
||||
return machine;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.ClrMamePro.Archive"/> to <cref="Models.Metadata.Archive"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Archive ConvertToInternalModel(Archive item)
|
||||
{
|
||||
var archive = new Models.Metadata.Archive
|
||||
{
|
||||
[Models.Metadata.Archive.NameKey] = item.Name,
|
||||
};
|
||||
return archive;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.ClrMamePro.BiosSet"/> to <cref="Models.Metadata.BiosSet"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.BiosSet ConvertToInternalModel(BiosSet item)
|
||||
{
|
||||
var biosset = new Models.Metadata.BiosSet
|
||||
{
|
||||
[Models.Metadata.BiosSet.NameKey] = item.Name,
|
||||
[Models.Metadata.BiosSet.DescriptionKey] = item.Description,
|
||||
[Models.Metadata.BiosSet.DefaultKey] = item.Default,
|
||||
};
|
||||
return biosset;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.ClrMamePro.Chip"/> to <cref="Models.Metadata.Chip"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Chip ConvertToInternalModel(Chip item)
|
||||
{
|
||||
var chip = new Models.Metadata.Chip
|
||||
{
|
||||
[Models.Metadata.Chip.ChipTypeKey] = item.Type,
|
||||
[Models.Metadata.Chip.NameKey] = item.Name,
|
||||
[Models.Metadata.Chip.FlagsKey] = item.Flags,
|
||||
[Models.Metadata.Chip.ClockKey] = item.Clock,
|
||||
};
|
||||
return chip;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.ClrMamePro.DipSwitch"/> to <cref="Models.Metadata.DipSwitch"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.DipSwitch ConvertToInternalModel(DipSwitch item)
|
||||
{
|
||||
var dipswitch = new Models.Metadata.DipSwitch
|
||||
{
|
||||
[Models.Metadata.DipSwitch.NameKey] = item.Name,
|
||||
[Models.Metadata.DipSwitch.EntryKey] = item.Entry,
|
||||
[Models.Metadata.DipSwitch.DefaultKey] = item.Default,
|
||||
};
|
||||
return dipswitch;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.ClrMamePro.Disk"/> to <cref="Models.Metadata.Disk"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Disk ConvertToInternalModel(Disk item)
|
||||
{
|
||||
var disk = new Models.Metadata.Disk
|
||||
{
|
||||
[Models.Metadata.Disk.NameKey] = item.Name,
|
||||
[Models.Metadata.Disk.MD5Key] = item.MD5,
|
||||
[Models.Metadata.Disk.SHA1Key] = item.SHA1,
|
||||
[Models.Metadata.Disk.MergeKey] = item.Merge,
|
||||
[Models.Metadata.Disk.StatusKey] = item.Status,
|
||||
[Models.Metadata.Disk.FlagsKey] = item.Flags,
|
||||
};
|
||||
return disk;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.ClrMamePro.Driver"/> to <cref="Models.Metadata.Driver"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Driver ConvertToInternalModel(Driver item)
|
||||
{
|
||||
var driver = new Models.Metadata.Driver
|
||||
{
|
||||
[Models.Metadata.Driver.StatusKey] = item.Status,
|
||||
[Models.Metadata.Driver.ColorKey] = item.Color,
|
||||
[Models.Metadata.Driver.SoundKey] = item.Sound,
|
||||
[Models.Metadata.Driver.PaletteSizeKey] = item.PaletteSize,
|
||||
[Models.Metadata.Driver.BlitKey] = item.Blit,
|
||||
};
|
||||
return driver;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.ClrMamePro.Input"/> to <cref="Models.Metadata.Input"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Input ConvertToInternalModel(Input item)
|
||||
{
|
||||
var input = new Models.Metadata.Input
|
||||
{
|
||||
[Models.Metadata.Input.PlayersKey] = item.Players,
|
||||
[Models.Metadata.Input.ControlKey] = item.Control,
|
||||
[Models.Metadata.Input.ButtonsKey] = item.Buttons,
|
||||
[Models.Metadata.Input.CoinsKey] = item.Coins,
|
||||
[Models.Metadata.Input.TiltKey] = item.Tilt,
|
||||
[Models.Metadata.Input.ServiceKey] = item.Service,
|
||||
};
|
||||
return input;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.ClrMamePro.Media"/> to <cref="Models.Metadata.Media"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Media ConvertToInternalModel(Media item)
|
||||
{
|
||||
var media = new Models.Metadata.Media
|
||||
{
|
||||
[Models.Metadata.Media.NameKey] = item.Name,
|
||||
[Models.Metadata.Media.MD5Key] = item.MD5,
|
||||
[Models.Metadata.Media.SHA1Key] = item.SHA1,
|
||||
[Models.Metadata.Media.SHA256Key] = item.SHA256,
|
||||
[Models.Metadata.Media.SpamSumKey] = item.SpamSum,
|
||||
};
|
||||
return media;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.ClrMamePro.Release"/> to <cref="Models.Metadata.Release"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Release ConvertToInternalModel(Release item)
|
||||
{
|
||||
var release = new Models.Metadata.Release
|
||||
{
|
||||
[Models.Metadata.Release.NameKey] = item.Name,
|
||||
[Models.Metadata.Release.RegionKey] = item.Region,
|
||||
[Models.Metadata.Release.LanguageKey] = item.Language,
|
||||
[Models.Metadata.Release.DateKey] = item.Date,
|
||||
[Models.Metadata.Release.DefaultKey] = item.Default,
|
||||
};
|
||||
return release;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.ClrMamePro.Rom"/> to <cref="Models.Metadata.Rom"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Rom ConvertToInternalModel(Rom item)
|
||||
{
|
||||
var rom = new Models.Metadata.Rom
|
||||
{
|
||||
[Models.Metadata.Rom.NameKey] = item.Name,
|
||||
[Models.Metadata.Rom.SizeKey] = item.Size,
|
||||
[Models.Metadata.Rom.CRCKey] = item.CRC,
|
||||
[Models.Metadata.Rom.MD5Key] = item.MD5,
|
||||
[Models.Metadata.Rom.SHA1Key] = item.SHA1,
|
||||
[Models.Metadata.Rom.SHA256Key] = item.SHA256,
|
||||
[Models.Metadata.Rom.SHA384Key] = item.SHA384,
|
||||
[Models.Metadata.Rom.SHA512Key] = item.SHA512,
|
||||
[Models.Metadata.Rom.SpamSumKey] = item.SpamSum,
|
||||
[Models.Metadata.Rom.xxHash364Key] = item.xxHash364,
|
||||
[Models.Metadata.Rom.xxHash3128Key] = item.xxHash3128,
|
||||
[Models.Metadata.Rom.MergeKey] = item.Merge,
|
||||
[Models.Metadata.Rom.StatusKey] = item.Status,
|
||||
[Models.Metadata.Rom.RegionKey] = item.Region,
|
||||
[Models.Metadata.Rom.FlagsKey] = item.Flags,
|
||||
[Models.Metadata.Rom.OffsetKey] = item.Offs,
|
||||
[Models.Metadata.Rom.SerialKey] = item.Serial,
|
||||
[Models.Metadata.Rom.HeaderKey] = item.Header,
|
||||
[Models.Metadata.Rom.DateKey] = item.Date,
|
||||
[Models.Metadata.Rom.InvertedKey] = item.Inverted,
|
||||
[Models.Metadata.Rom.MIAKey] = item.MIA,
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.ClrMamePro.Sample"/> to <cref="Models.Metadata.Sample"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Sample ConvertToInternalModel(Sample item)
|
||||
{
|
||||
var sample = new Models.Metadata.Sample
|
||||
{
|
||||
[Models.Metadata.Sample.NameKey] = item.Name,
|
||||
};
|
||||
return sample;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.ClrMamePro.Sound"/> to <cref="Models.Metadata.Sound"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Sound ConvertToInternalModel(Sound item)
|
||||
{
|
||||
var sound = new Models.Metadata.Sound
|
||||
{
|
||||
[Models.Metadata.Sound.ChannelsKey] = item.Channels,
|
||||
};
|
||||
return sound;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.ClrMamePro.Video"/> to <cref="Models.Metadata.Video"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Video ConvertToInternalModel(Video item)
|
||||
{
|
||||
var video = new Models.Metadata.Video
|
||||
{
|
||||
[Models.Metadata.Video.ScreenKey] = item.Screen,
|
||||
[Models.Metadata.Video.OrientationKey] = item.Orientation,
|
||||
[Models.Metadata.Video.WidthKey] = item.X,
|
||||
[Models.Metadata.Video.HeightKey] = item.Y,
|
||||
[Models.Metadata.Video.AspectXKey] = item.AspectX,
|
||||
[Models.Metadata.Video.AspectYKey] = item.AspectY,
|
||||
[Models.Metadata.Video.RefreshKey] = item.Freq,
|
||||
};
|
||||
return video;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,318 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Readers;
|
||||
using SabreTools.Models.DosCenter;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// Deserializer for DosCenter metadata files
|
||||
/// </summary>
|
||||
public partial class DosCenter
|
||||
{
|
||||
/// <summary>
|
||||
/// Deserializes a DosCenter metadata file to the defined type
|
||||
/// </summary>
|
||||
/// <param name="path">Path to the file to deserialize</param>
|
||||
/// <returns>Deserialized data on success, null on failure</returns>
|
||||
public static MetadataFile? Deserialize(string path)
|
||||
{
|
||||
using var stream = PathProcessor.OpenStream(path);
|
||||
return Deserialize(stream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes a DosCenter metadata file in a stream to the defined type
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream to deserialize</param>
|
||||
/// <returns>Deserialized data on success, null on failure</returns>
|
||||
public static MetadataFile? Deserialize(Stream? stream)
|
||||
{
|
||||
// If the stream is null
|
||||
if (stream == null)
|
||||
return default;
|
||||
|
||||
// Setup the reader and output
|
||||
var reader = new ClrMameProReader(stream, Encoding.UTF8) { DosCenter = true };
|
||||
var dat = new MetadataFile();
|
||||
|
||||
// Loop through and parse out the values
|
||||
string? lastTopLevel = reader.TopLevel;
|
||||
|
||||
Game? game = null;
|
||||
var games = new List<Game>();
|
||||
var files = new List<Models.DosCenter.File>();
|
||||
|
||||
var additional = new List<string>();
|
||||
var headerAdditional = new List<string>();
|
||||
var gameAdditional = new List<string>();
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
// If we have no next line
|
||||
if (!reader.ReadNextLine())
|
||||
break;
|
||||
|
||||
// Ignore certain row types
|
||||
switch (reader.RowType)
|
||||
{
|
||||
case CmpRowType.None:
|
||||
case CmpRowType.Comment:
|
||||
continue;
|
||||
case CmpRowType.EndTopLevel:
|
||||
switch (lastTopLevel)
|
||||
{
|
||||
case "doscenter":
|
||||
if (dat.DosCenter != null)
|
||||
dat.DosCenter.ADDITIONAL_ELEMENTS = headerAdditional.ToArray();
|
||||
|
||||
headerAdditional.Clear();
|
||||
break;
|
||||
case "game":
|
||||
if (game != null)
|
||||
{
|
||||
game.File = files.ToArray();
|
||||
game.ADDITIONAL_ELEMENTS = gameAdditional.ToArray();
|
||||
games.Add(game);
|
||||
}
|
||||
|
||||
game = null;
|
||||
files.Clear();
|
||||
gameAdditional.Clear();
|
||||
break;
|
||||
default:
|
||||
// No-op
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we're at the root
|
||||
if (reader.RowType == CmpRowType.TopLevel)
|
||||
{
|
||||
lastTopLevel = reader.TopLevel;
|
||||
switch (reader.TopLevel)
|
||||
{
|
||||
case "doscenter":
|
||||
dat.DosCenter = new Models.DosCenter.DosCenter();
|
||||
break;
|
||||
case "game":
|
||||
game = new Game();
|
||||
break;
|
||||
default:
|
||||
if (reader.CurrentLine != null)
|
||||
additional.Add(reader.CurrentLine);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we're in the doscenter block
|
||||
else if (reader.TopLevel == "doscenter" && reader.RowType == CmpRowType.Standalone)
|
||||
{
|
||||
// Create the block if we haven't already
|
||||
dat.DosCenter ??= new Models.DosCenter.DosCenter();
|
||||
|
||||
switch (reader.Standalone?.Key?.ToLowerInvariant())
|
||||
{
|
||||
case "name:":
|
||||
dat.DosCenter.Name = reader.Standalone?.Value;
|
||||
break;
|
||||
case "description:":
|
||||
dat.DosCenter.Description = reader.Standalone?.Value;
|
||||
break;
|
||||
case "version:":
|
||||
dat.DosCenter.Version = reader.Standalone?.Value;
|
||||
break;
|
||||
case "date:":
|
||||
dat.DosCenter.Date = reader.Standalone?.Value;
|
||||
break;
|
||||
case "author:":
|
||||
dat.DosCenter.Author = reader.Standalone?.Value;
|
||||
break;
|
||||
case "homepage:":
|
||||
dat.DosCenter.Homepage = reader.Standalone?.Value;
|
||||
break;
|
||||
case "comment:":
|
||||
dat.DosCenter.Comment = reader.Standalone?.Value;
|
||||
break;
|
||||
default:
|
||||
if (reader.CurrentLine != null)
|
||||
headerAdditional.Add(item: reader.CurrentLine);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we're in a game block
|
||||
else if (reader.TopLevel == "game" && reader.RowType == CmpRowType.Standalone)
|
||||
{
|
||||
// Create the block if we haven't already
|
||||
game ??= new Game();
|
||||
|
||||
switch (reader.Standalone?.Key?.ToLowerInvariant())
|
||||
{
|
||||
case "name":
|
||||
game.Name = reader.Standalone?.Value;
|
||||
break;
|
||||
default:
|
||||
if (reader.CurrentLine != null)
|
||||
gameAdditional.Add(item: reader.CurrentLine);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we're in a file block
|
||||
else if (reader.TopLevel == "game" && reader.RowType == CmpRowType.Internal)
|
||||
{
|
||||
// If we have an unknown type, log it
|
||||
if (reader.InternalName != "file")
|
||||
{
|
||||
if (reader.CurrentLine != null)
|
||||
gameAdditional.Add(reader.CurrentLine);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create the file and add to the list
|
||||
var file = CreateFile(reader);
|
||||
if (file != null)
|
||||
files.Add(file);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (reader.CurrentLine != null)
|
||||
additional.Add(item: reader.CurrentLine);
|
||||
}
|
||||
}
|
||||
|
||||
// Add extra pieces and return
|
||||
dat.Game = games.ToArray();
|
||||
dat.ADDITIONAL_ELEMENTS = additional.ToArray();
|
||||
return dat;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a File object from the current reader context
|
||||
/// </summary>
|
||||
/// <param name="reader">ClrMameProReader representing the metadata file</param>
|
||||
/// <returns>File object created from the reader context</returns>
|
||||
private static Models.DosCenter.File? CreateFile(ClrMameProReader reader)
|
||||
{
|
||||
if (reader.Internal == null)
|
||||
return null;
|
||||
|
||||
var itemAdditional = new List<string>();
|
||||
var file = new Models.DosCenter.File();
|
||||
foreach (var kvp in reader.Internal)
|
||||
{
|
||||
switch (kvp.Key?.ToLowerInvariant())
|
||||
{
|
||||
case "name":
|
||||
file.Name = kvp.Value;
|
||||
break;
|
||||
case "size":
|
||||
file.Size = kvp.Value;
|
||||
break;
|
||||
case "crc":
|
||||
file.CRC = kvp.Value;
|
||||
break;
|
||||
case "date":
|
||||
file.Date = kvp.Value;
|
||||
break;
|
||||
default:
|
||||
if (reader.CurrentLine != null)
|
||||
itemAdditional.Add(item: reader.CurrentLine);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
file.ADDITIONAL_ELEMENTS = itemAdditional.ToArray();
|
||||
return file;
|
||||
}
|
||||
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.MetadataFile"/> to <cref="Models.DosCenter.MetadataFile"/>
|
||||
/// </summary>
|
||||
public static MetadataFile? ConvertFromInternalModel(Models.Metadata.MetadataFile? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var metadataFile = new MetadataFile();
|
||||
|
||||
var header = item.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
|
||||
if (header != null)
|
||||
metadataFile.DosCenter = ConvertHeaderFromInternalModel(header);
|
||||
|
||||
var machines = item.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
|
||||
if (machines != null && machines.Any())
|
||||
{
|
||||
metadataFile.Game = machines
|
||||
.Where(m => m != null)
|
||||
.Select(ConvertMachineFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Header"/> to <cref="Models.DosCenter.DosCenter"/>
|
||||
/// </summary>
|
||||
private static Models.DosCenter.DosCenter ConvertHeaderFromInternalModel(Models.Metadata.Header item)
|
||||
{
|
||||
var dosCenter = new Models.DosCenter.DosCenter
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Header.NameKey),
|
||||
Description = item.ReadString(Models.Metadata.Header.DescriptionKey),
|
||||
Version = item.ReadString(Models.Metadata.Header.VersionKey),
|
||||
Date = item.ReadString(Models.Metadata.Header.DateKey),
|
||||
Author = item.ReadString(Models.Metadata.Header.AuthorKey),
|
||||
Homepage = item.ReadString(Models.Metadata.Header.HomepageKey),
|
||||
Comment = item.ReadString(Models.Metadata.Header.CommentKey),
|
||||
};
|
||||
return dosCenter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Machine"/> to <cref="Models.DosCenter.Game"/>
|
||||
/// </summary>
|
||||
private static Game ConvertMachineFromInternalModel(Models.Metadata.Machine item)
|
||||
{
|
||||
var game = new Game
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Machine.NameKey),
|
||||
};
|
||||
|
||||
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
|
||||
if (roms != null && roms.Any())
|
||||
{
|
||||
game.File = roms
|
||||
.Where(r => r != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return game;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.DosCenter.File"/>
|
||||
/// </summary>
|
||||
private static Models.DosCenter.File ConvertFromInternalModel(Models.Metadata.Rom item)
|
||||
{
|
||||
var file = new Models.DosCenter.File
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Rom.NameKey),
|
||||
Size = item.ReadString(Models.Metadata.Rom.SizeKey),
|
||||
CRC = item.ReadString(Models.Metadata.Rom.CRCKey),
|
||||
Date = item.ReadString(Models.Metadata.Rom.DateKey),
|
||||
};
|
||||
return file;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,231 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Writers;
|
||||
using SabreTools.Models.DosCenter;
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// Deserializer for DosCenter metadata files
|
||||
/// </summary>
|
||||
public partial class DosCenter
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializes the defined type to a DosCenter metadata file
|
||||
/// </summary>
|
||||
/// <param name="metadataFile">Data to serialize</param>
|
||||
/// <param name="path">Path to the file to serialize to</param>
|
||||
/// <returns>True on successful serialization, false otherwise</returns>
|
||||
public static bool SerializeToFile(MetadataFile? metadataFile, string path)
|
||||
{
|
||||
using var stream = SerializeToStream(metadataFile);
|
||||
if (stream == null)
|
||||
return false;
|
||||
|
||||
using var fs = System.IO.File.OpenWrite(path);
|
||||
stream.CopyTo(fs);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes the defined type to a stream
|
||||
/// </summary>
|
||||
/// <param name="metadataFile">Data to serialize</param>
|
||||
/// <returns>Stream containing serialized data on success, null otherwise</returns>
|
||||
public static Stream? SerializeToStream(MetadataFile? metadataFile)
|
||||
{
|
||||
// If the metadata file is null
|
||||
if (metadataFile == null)
|
||||
return null;
|
||||
|
||||
// Setup the writer and output
|
||||
var stream = new MemoryStream();
|
||||
var writer = new ClrMameProWriter(stream, Encoding.UTF8)
|
||||
{
|
||||
Quotes = false,
|
||||
};
|
||||
|
||||
// Write the header, if it exists
|
||||
WriteHeader(metadataFile.DosCenter, writer);
|
||||
|
||||
// Write out the games, if they exist
|
||||
WriteGames(metadataFile.Game, writer);
|
||||
|
||||
// Return the stream
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
return stream;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write header information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="header">DosCenter representing the header information</param>
|
||||
/// <param name="writer">ClrMameProWriter representing the output</param>
|
||||
private static void WriteHeader(Models.DosCenter.DosCenter? header, ClrMameProWriter writer)
|
||||
{
|
||||
// If the header information is missing, we can't do anything
|
||||
if (header == null)
|
||||
return;
|
||||
|
||||
writer.WriteStartElement("DOSCenter");
|
||||
|
||||
writer.WriteOptionalStandalone("Name:", header.Name);
|
||||
writer.WriteOptionalStandalone("Description:", header.Description);
|
||||
writer.WriteOptionalStandalone("Version:", header.Version);
|
||||
writer.WriteOptionalStandalone("Date:", header.Date);
|
||||
writer.WriteOptionalStandalone("Author:", header.Author);
|
||||
writer.WriteOptionalStandalone("Homepage:", header.Homepage);
|
||||
writer.WriteOptionalStandalone("Comment:", header.Comment);
|
||||
|
||||
writer.WriteEndElement(); // doscenter
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write games information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="games">Array of Game objects representing the games information</param>
|
||||
/// <param name="writer">ClrMameProWriter representing the output</param>
|
||||
private static void WriteGames(Game[]? games, ClrMameProWriter writer)
|
||||
{
|
||||
// If the games information is missing, we can't do anything
|
||||
if (games == null || !games.Any())
|
||||
return;
|
||||
|
||||
// Loop through and write out the games
|
||||
foreach (var game in games)
|
||||
{
|
||||
WriteGame(game, writer);
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write game information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="game">Game object representing the game information</param>
|
||||
/// <param name="writer">ClrMameProWriter representing the output</param>
|
||||
private static void WriteGame(Game game, ClrMameProWriter writer)
|
||||
{
|
||||
// If the game information is missing, we can't do anything
|
||||
if (game == null)
|
||||
return;
|
||||
|
||||
writer.WriteStartElement("game");
|
||||
|
||||
// Write the standalone values
|
||||
writer.WriteRequiredStandalone("name", game.Name, throwOnError: true);
|
||||
|
||||
// Write the item values
|
||||
WriteFiles(game.File, writer);
|
||||
|
||||
writer.WriteEndElement(); // game
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write files information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="files">Array of File objects to write</param>
|
||||
/// <param name="writer">ClrMameProWriter representing the output</param>
|
||||
private static void WriteFiles(Models.DosCenter.File[]? files, ClrMameProWriter writer)
|
||||
{
|
||||
// If the array is missing, we can't do anything
|
||||
if (files == null)
|
||||
return;
|
||||
|
||||
foreach (var file in files)
|
||||
{
|
||||
writer.WriteStartElement("file");
|
||||
|
||||
writer.WriteRequiredAttributeString("name", file.Name, throwOnError: true);
|
||||
writer.WriteRequiredAttributeString("size", file.Size, throwOnError: true);
|
||||
writer.WriteOptionalAttributeString("date", file.Date);
|
||||
writer.WriteRequiredAttributeString("crc", file.CRC?.ToUpperInvariant(), throwOnError: true);
|
||||
|
||||
writer.WriteEndElement(); // file
|
||||
}
|
||||
}
|
||||
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.DosCenter.MetadataFile"/> to <cref="Models.Metadata.MetadataFile"/>
|
||||
/// </summary>
|
||||
public static Models.Metadata.MetadataFile? ConvertToInternalModel(MetadataFile? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var metadataFile = new Models.Metadata.MetadataFile();
|
||||
|
||||
if (item?.DosCenter != null)
|
||||
metadataFile[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item.DosCenter);
|
||||
|
||||
if (item?.Game != null && item.Game.Any())
|
||||
{
|
||||
metadataFile[Models.Metadata.MetadataFile.MachineKey] = item.Game
|
||||
.Where(g => g != null)
|
||||
.Select(ConvertMachineToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.DosCenter.DosCenter"/> to <cref="Models.Metadata.Header"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Header ConvertHeaderToInternalModel(Models.DosCenter.DosCenter item)
|
||||
{
|
||||
var header = new Models.Metadata.Header
|
||||
{
|
||||
[Models.Metadata.Header.NameKey] = item.Name,
|
||||
[Models.Metadata.Header.DescriptionKey] = item.Description,
|
||||
[Models.Metadata.Header.VersionKey] = item.Version,
|
||||
[Models.Metadata.Header.DateKey] = item.Date,
|
||||
[Models.Metadata.Header.AuthorKey] = item.Author,
|
||||
[Models.Metadata.Header.HomepageKey] = item.Homepage,
|
||||
[Models.Metadata.Header.CommentKey] = item.Comment,
|
||||
};
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.DosCenter.Game"/> to <cref="Models.Metadata.Machine"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Machine ConvertMachineToInternalModel(Game item)
|
||||
{
|
||||
var machine = new Models.Metadata.Machine
|
||||
{
|
||||
[Models.Metadata.Machine.NameKey] = item.Name,
|
||||
};
|
||||
|
||||
if (item.File != null && item.File.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.RomKey] = item.File
|
||||
.Where(f => f != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return machine;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.DosCenter.File"/> to <cref="Models.Metadata.Rom"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Rom ConvertToInternalModel(Models.DosCenter.File item)
|
||||
{
|
||||
var rom = new Models.Metadata.Rom
|
||||
{
|
||||
[Models.Metadata.Rom.NameKey] = item.Name,
|
||||
[Models.Metadata.Rom.SizeKey] = item.Size,
|
||||
[Models.Metadata.Rom.CRCKey] = item.CRC,
|
||||
[Models.Metadata.Rom.DateKey] = item.Date,
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Readers;
|
||||
using SabreTools.Models.EverdriveSMDB;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// Separated value deserializer for Everdrive SMDBs
|
||||
/// </summary>
|
||||
public partial class EverdriveSMDB
|
||||
{
|
||||
/// <summary>
|
||||
/// Deserializes an Everdrive SMDB to the defined type
|
||||
/// </summary>
|
||||
/// <param name="path">Path to the file to deserialize</param>
|
||||
/// <returns>Deserialized data on success, null on failure</returns>
|
||||
public static MetadataFile? Deserialize(string path)
|
||||
{
|
||||
using var stream = PathProcessor.OpenStream(path);
|
||||
return Deserialize(stream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes an Everdrive SMDB in a stream to the defined type
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream to deserialize</param>
|
||||
/// <returns>Deserialized data on success, null on failure</returns>
|
||||
public static MetadataFile? Deserialize(Stream? stream)
|
||||
{
|
||||
// If the stream is null
|
||||
if (stream == null)
|
||||
return default;
|
||||
|
||||
// Setup the reader and output
|
||||
var reader = new SeparatedValueReader(stream, Encoding.UTF8)
|
||||
{
|
||||
Header = false,
|
||||
Separator = '\t',
|
||||
VerifyFieldCount = false,
|
||||
};
|
||||
var dat = new MetadataFile();
|
||||
|
||||
// Loop through the rows and parse out values
|
||||
var rows = new List<Row>();
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
// If we have no next line
|
||||
if (!reader.ReadNextLine() || reader.Line == null)
|
||||
break;
|
||||
|
||||
// Parse the line into a row
|
||||
var row = new Row
|
||||
{
|
||||
SHA256 = reader.Line[0],
|
||||
Name = reader.Line[1],
|
||||
SHA1 = reader.Line[2],
|
||||
MD5 = reader.Line[3],
|
||||
CRC32 = reader.Line[4],
|
||||
};
|
||||
|
||||
// If we have the size field
|
||||
if (reader.Line.Count > 5)
|
||||
row.Size = reader.Line[5];
|
||||
|
||||
// If we have additional fields
|
||||
if (reader.Line.Count > 6)
|
||||
row.ADDITIONAL_ELEMENTS = reader.Line.Skip(5).ToArray();
|
||||
|
||||
rows.Add(row);
|
||||
}
|
||||
|
||||
// Assign the rows to the Dat and return
|
||||
dat.Row = rows.ToArray();
|
||||
return dat;
|
||||
}
|
||||
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.MetadataFile"/> to <cref="Models.EverdriveSMDB.MetadataFile"/>
|
||||
/// </summary>
|
||||
public static MetadataFile? ConvertFromInternalModel(Models.Metadata.MetadataFile? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var metadataFile = new MetadataFile();
|
||||
|
||||
var machines = item.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
|
||||
if (machines != null && machines.Any())
|
||||
{
|
||||
metadataFile.Row = machines
|
||||
.Where(m => m != null)
|
||||
.SelectMany(ConvertMachineFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Machine"/> to an array of <cref="Models.EverdriveSMDB.Row"/>
|
||||
/// </summary>
|
||||
private static Row[] ConvertMachineFromInternalModel(Models.Metadata.Machine item)
|
||||
{
|
||||
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
|
||||
if (roms == null || !roms.Any())
|
||||
return Array.Empty<Row>();
|
||||
|
||||
return roms
|
||||
.Where(r => r != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.EverdriveSMDB.Row"/>
|
||||
/// </summary>
|
||||
private static Row ConvertFromInternalModel(Models.Metadata.Rom item)
|
||||
{
|
||||
var row = new Row
|
||||
{
|
||||
SHA256 = item.ReadString(Models.Metadata.Rom.SHA256Key),
|
||||
Name = item.ReadString(Models.Metadata.Rom.NameKey),
|
||||
SHA1 = item.ReadString(Models.Metadata.Rom.SHA1Key),
|
||||
MD5 = item.ReadString(Models.Metadata.Rom.MD5Key),
|
||||
CRC32 = item.ReadString(Models.Metadata.Rom.CRCKey),
|
||||
Size = item.ReadString(Models.Metadata.Rom.SizeKey),
|
||||
};
|
||||
return row;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Writers;
|
||||
using SabreTools.Models.EverdriveSMDB;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// Separated value serializer for Everdrive SMDBs
|
||||
/// </summary>
|
||||
public partial class EverdriveSMDB
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializes the defined type to an Everdrive SMDB file
|
||||
/// </summary>
|
||||
/// <param name="metadataFile">Data to serialize</param>
|
||||
/// <param name="path">Path to the file to serialize to</param>
|
||||
/// <returns>True on successful serialization, false otherwise</returns>
|
||||
public static bool SerializeToFile(MetadataFile? metadataFile, string path)
|
||||
{
|
||||
using var stream = SerializeToStream(metadataFile);
|
||||
if (stream == null)
|
||||
return false;
|
||||
|
||||
using var fs = File.OpenWrite(path);
|
||||
stream.CopyTo(fs);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes the defined type to a stream
|
||||
/// </summary>
|
||||
/// <param name="metadataFile">Data to serialize</param>
|
||||
/// <returns>Stream containing serialized data on success, null otherwise</returns>
|
||||
public static Stream? SerializeToStream(MetadataFile? metadataFile)
|
||||
{
|
||||
// If the metadata file is null
|
||||
if (metadataFile == null)
|
||||
return null;
|
||||
|
||||
// Setup the writer and output
|
||||
var stream = new MemoryStream();
|
||||
var writer = new SeparatedValueWriter(stream, Encoding.UTF8) { Separator = '\t', Quotes = false };
|
||||
|
||||
// Write out the rows, if they exist
|
||||
WriteRows(metadataFile.Row, writer);
|
||||
|
||||
// Return the stream
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
return stream;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write rows information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="rows">Array of Row objects representing the rows information</param>
|
||||
/// <param name="writer">SeparatedValueWriter representing the output</param>
|
||||
private static void WriteRows(Row[]? rows, SeparatedValueWriter writer)
|
||||
{
|
||||
// If the games information is missing, we can't do anything
|
||||
if (rows == null || !rows.Any())
|
||||
return;
|
||||
|
||||
// Loop through and write out the rows
|
||||
foreach (var row in rows)
|
||||
{
|
||||
if (row == null)
|
||||
continue;
|
||||
|
||||
var rowArray = new List<string?>
|
||||
{
|
||||
row.SHA256,
|
||||
row.Name,
|
||||
row.SHA1,
|
||||
row.MD5,
|
||||
row.CRC32,
|
||||
};
|
||||
|
||||
if (row.Size != null)
|
||||
rowArray.Add(row.Size);
|
||||
|
||||
writer.WriteValues(rowArray.ToArray());
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.EverdriveSMDB.MetadataFile"/> to <cref="Models.Metadata.MetadataFile"/>
|
||||
/// </summary>
|
||||
public static Models.Metadata.MetadataFile? ConvertToInternalModel(MetadataFile? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var metadataFile = new Models.Metadata.MetadataFile
|
||||
{
|
||||
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(),
|
||||
};
|
||||
|
||||
if (item?.Row != null && item.Row.Any())
|
||||
{
|
||||
metadataFile[Models.Metadata.MetadataFile.MachineKey] = item.Row
|
||||
.Where(r => r != null)
|
||||
.Select(ConvertMachineToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.EverdriveSMDB.MetadataFile"/> to <cref=Models.Metadata."Header"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Header ConvertHeaderToInternalModel()
|
||||
{
|
||||
var header = new Models.Metadata.Header
|
||||
{
|
||||
[Models.Metadata.Header.NameKey] = "Everdrive SMDB",
|
||||
};
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.EverdriveSMDB.Row"/> to <cref="Models.Metadata.Machine"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Machine ConvertMachineToInternalModel(Row item)
|
||||
{
|
||||
var machine = new Models.Metadata.Machine
|
||||
{
|
||||
[Models.Metadata.Machine.RomKey] = ConvertToInternalModel(item),
|
||||
};
|
||||
return machine;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.EverdriveSMDB.Row"/> to <cref="Models.Metadata.Rom"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Rom ConvertToInternalModel(Row item)
|
||||
{
|
||||
var rom = new Models.Metadata.Rom
|
||||
{
|
||||
[Models.Metadata.Rom.SHA256Key] = item.SHA256,
|
||||
[Models.Metadata.Rom.NameKey] = item.Name,
|
||||
[Models.Metadata.Rom.SHA1Key] = item.SHA1,
|
||||
[Models.Metadata.Rom.MD5Key] = item.MD5,
|
||||
[Models.Metadata.Rom.CRCKey] = item.CRC32,
|
||||
[Models.Metadata.Rom.SizeKey] = item.Size,
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,379 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Core;
|
||||
using SabreTools.Models.Hashfile;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// Deserializer for hashfile variants
|
||||
/// </summary>
|
||||
public partial class Hashfile
|
||||
{
|
||||
/// <summary>
|
||||
/// Deserializes a hashfile variant to the defined type
|
||||
/// </summary>
|
||||
/// <param name="path">Path to the file to deserialize</param>
|
||||
/// <param name="hash">Hash corresponding to the hashfile variant</param>
|
||||
/// <returns>Deserialized data on success, null on failure</returns>
|
||||
public static Models.Hashfile.Hashfile? Deserialize(string path, Hash hash)
|
||||
{
|
||||
using var stream = PathProcessor.OpenStream(path);
|
||||
return Deserialize(stream, hash);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes a hashfile variant in a stream to the defined type
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream to deserialize</param>
|
||||
/// <param name="hash">Hash corresponding to the hashfile variant</param>
|
||||
/// <returns>Deserialized data on success, null on failure</returns>
|
||||
public static Models.Hashfile.Hashfile? Deserialize(Stream? stream, Hash hash)
|
||||
{
|
||||
// If the stream is null
|
||||
if (stream == null)
|
||||
return default;
|
||||
|
||||
// Setup the reader and output
|
||||
var reader = new StreamReader(stream);
|
||||
var dat = new Models.Hashfile.Hashfile();
|
||||
var additional = new List<string>();
|
||||
|
||||
// Loop through the rows and parse out values
|
||||
var hashes = new List<object>();
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
// Read and split the line
|
||||
string? line = reader.ReadLine();
|
||||
string[]? lineParts = line?.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||
if (lineParts == null)
|
||||
continue;
|
||||
|
||||
// Parse the line into a hash
|
||||
switch (hash)
|
||||
{
|
||||
case Hash.CRC:
|
||||
var sfv = new SFV
|
||||
{
|
||||
File = string.Join(" ", lineParts[..^1]),
|
||||
Hash = string.Join(" ", lineParts[^1]),
|
||||
};
|
||||
hashes.Add(sfv);
|
||||
break;
|
||||
case Hash.MD5:
|
||||
var md5 = new MD5
|
||||
{
|
||||
Hash = lineParts[0],
|
||||
File = string.Join(" ", lineParts[1..]),
|
||||
};
|
||||
hashes.Add(md5);
|
||||
break;
|
||||
case Hash.SHA1:
|
||||
var sha1 = new SHA1
|
||||
{
|
||||
Hash = lineParts[0],
|
||||
File = string.Join(" ", lineParts[1..]),
|
||||
};
|
||||
hashes.Add(sha1);
|
||||
break;
|
||||
case Hash.SHA256:
|
||||
var sha256 = new SHA256
|
||||
{
|
||||
Hash = lineParts[0],
|
||||
File = string.Join(" ", lineParts[1..]),
|
||||
};
|
||||
hashes.Add(sha256);
|
||||
break;
|
||||
case Hash.SHA384:
|
||||
var sha384 = new SHA384
|
||||
{
|
||||
Hash = lineParts[0],
|
||||
File = string.Join(" ", lineParts[1..]),
|
||||
};
|
||||
hashes.Add(sha384);
|
||||
break;
|
||||
case Hash.SHA512:
|
||||
var sha512 = new SHA512
|
||||
{
|
||||
Hash = lineParts[0],
|
||||
File = string.Join(" ", lineParts[1..]),
|
||||
};
|
||||
hashes.Add(sha512);
|
||||
break;
|
||||
case Hash.SpamSum:
|
||||
var spamSum = new SpamSum
|
||||
{
|
||||
Hash = lineParts[0],
|
||||
File = string.Join(" ", lineParts[1..]),
|
||||
};
|
||||
hashes.Add(spamSum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Assign the hashes to the hashfile and return
|
||||
switch (hash)
|
||||
{
|
||||
case Hash.CRC:
|
||||
dat.SFV = hashes.Cast<SFV>().ToArray();
|
||||
break;
|
||||
case Hash.MD5:
|
||||
dat.MD5 = hashes.Cast<MD5>().ToArray();
|
||||
break;
|
||||
case Hash.SHA1:
|
||||
dat.SHA1 = hashes.Cast<SHA1>().ToArray();
|
||||
break;
|
||||
case Hash.SHA256:
|
||||
dat.SHA256 = hashes.Cast<SHA256>().ToArray();
|
||||
break;
|
||||
case Hash.SHA384:
|
||||
dat.SHA384 = hashes.Cast<SHA384>().ToArray();
|
||||
break;
|
||||
case Hash.SHA512:
|
||||
dat.SHA512 = hashes.Cast<SHA512>().ToArray();
|
||||
break;
|
||||
case Hash.SpamSum:
|
||||
dat.SpamSum = hashes.Cast<SpamSum>().ToArray();
|
||||
break;
|
||||
}
|
||||
dat.ADDITIONAL_ELEMENTS = additional.ToArray();
|
||||
return dat;
|
||||
}
|
||||
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.MetadataFile"/> to an array of <cref="Models.Hashfile.Hashfile"/>
|
||||
/// </summary>
|
||||
/// <remarks>TODO: Add machine name prefixes to all items</remarks>
|
||||
public static Models.Hashfile.Hashfile? ConvertFromInternalModel(Models.Metadata.MetadataFile? item, Hash hash)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var machines = item.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
|
||||
if (machines == null || !machines.Any())
|
||||
return null;
|
||||
|
||||
var hashfiles = machines
|
||||
.Where(m => m != null)
|
||||
.Select(machine => ConvertMachineFromInternalModel(machine, hash));
|
||||
|
||||
var sfvs = new List<SFV>();
|
||||
var md5s = new List<MD5>();
|
||||
var sha1s = new List<SHA1>();
|
||||
var sha256s = new List<SHA256>();
|
||||
var sha384s = new List<SHA384>();
|
||||
var sha512s = new List<SHA512>();
|
||||
var spamsums = new List<SpamSum>();
|
||||
|
||||
foreach (var hashfile in hashfiles)
|
||||
{
|
||||
if (hashfile.SFV != null && hashfile.SFV.Any())
|
||||
sfvs.AddRange(hashfile.SFV);
|
||||
if (hashfile.MD5 != null && hashfile.MD5.Any())
|
||||
md5s.AddRange(hashfile.MD5);
|
||||
if (hashfile.SHA1 != null && hashfile.SHA1.Any())
|
||||
sha1s.AddRange(hashfile.SHA1);
|
||||
if (hashfile.SHA256 != null && hashfile.SHA256.Any())
|
||||
sha256s.AddRange(hashfile.SHA256);
|
||||
if (hashfile.SHA384 != null && hashfile.SHA384.Any())
|
||||
sha384s.AddRange(hashfile.SHA384);
|
||||
if (hashfile.SHA512 != null && hashfile.SHA512.Any())
|
||||
sha512s.AddRange(hashfile.SHA512);
|
||||
if (hashfile.SpamSum != null && hashfile.SpamSum.Any())
|
||||
spamsums.AddRange(hashfile.SpamSum);
|
||||
}
|
||||
|
||||
var hashfileItem = new Models.Hashfile.Hashfile();
|
||||
|
||||
if (sfvs.Any())
|
||||
hashfileItem.SFV = sfvs.ToArray();
|
||||
if (md5s.Any())
|
||||
hashfileItem.MD5 = md5s.ToArray();
|
||||
if (sha1s.Any())
|
||||
hashfileItem.SHA1 = sha1s.ToArray();
|
||||
if (sha256s.Any())
|
||||
hashfileItem.SHA256 = sha256s.ToArray();
|
||||
if (sha384s.Any())
|
||||
hashfileItem.SHA384 = sha384s.ToArray();
|
||||
if (sha512s.Any())
|
||||
hashfileItem.SHA512 = sha512s.ToArray();
|
||||
if (spamsums.Any())
|
||||
hashfileItem.SpamSum = spamsums.ToArray();
|
||||
|
||||
return hashfileItem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.MetadataFile"/> to an array of <cref="Models.Hashfile.Hashfile"/>
|
||||
/// </summary>
|
||||
public static Models.Hashfile.Hashfile[]? ConvertArrayFromInternalModel(Models.Metadata.MetadataFile? item, Hash hash)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var machines = item.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
|
||||
if (machines != null && machines.Any())
|
||||
{
|
||||
return machines
|
||||
.Where(m => m != null)
|
||||
.Select(machine => ConvertMachineFromInternalModel(machine, hash))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Machine"/> to <cref="Models.Hashfile.Hashfile"/>
|
||||
/// </summary>
|
||||
private static Models.Hashfile.Hashfile ConvertMachineFromInternalModel(Models.Metadata.Machine item, Hash hash)
|
||||
{
|
||||
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
|
||||
if (roms == null)
|
||||
return new Models.Hashfile.Hashfile();
|
||||
|
||||
return new Models.Hashfile.Hashfile
|
||||
{
|
||||
SFV = hash == Hash.CRC
|
||||
? roms
|
||||
.Where(r => r != null)
|
||||
.Select(ConvertToSFV)
|
||||
.ToArray()
|
||||
: null,
|
||||
MD5 = hash == Hash.MD5
|
||||
? roms
|
||||
.Where(r => r != null)
|
||||
.Select(ConvertToMD5)
|
||||
.ToArray()
|
||||
: null,
|
||||
SHA1 = hash == Hash.SHA1
|
||||
? roms
|
||||
.Where(r => r != null)
|
||||
.Select(ConvertToSHA1)
|
||||
.ToArray()
|
||||
: null,
|
||||
SHA256 = hash == Hash.SHA256
|
||||
? roms
|
||||
.Where(r => r != null)
|
||||
.Select(ConvertToSHA256)
|
||||
.ToArray()
|
||||
: null,
|
||||
SHA384 = hash == Hash.SHA384
|
||||
? roms
|
||||
.Where(r => r != null)
|
||||
.Select(ConvertToSHA384)
|
||||
.ToArray()
|
||||
: null,
|
||||
SHA512 = hash == Hash.SHA512
|
||||
? roms
|
||||
.Where(r => r != null)
|
||||
.Select(ConvertToSHA512)
|
||||
.ToArray()
|
||||
: null,
|
||||
SpamSum = hash == Hash.SpamSum
|
||||
? roms
|
||||
.Where(r => r != null)
|
||||
.Select(ConvertToSpamSum)
|
||||
.ToArray()
|
||||
: null,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.Hashfile.MD5"/>
|
||||
/// </summary>
|
||||
private static MD5 ConvertToMD5(Models.Metadata.Rom item)
|
||||
{
|
||||
var md5 = new MD5
|
||||
{
|
||||
Hash = item.ReadString(Models.Metadata.Rom.MD5Key),
|
||||
File = item.ReadString(Models.Metadata.Rom.NameKey),
|
||||
};
|
||||
return md5;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.Hashfile.SFV"/>
|
||||
/// </summary>
|
||||
private static SFV ConvertToSFV(Models.Metadata.Rom item)
|
||||
{
|
||||
var sfv = new SFV
|
||||
{
|
||||
File = item.ReadString(Models.Metadata.Rom.NameKey),
|
||||
Hash = item.ReadString(Models.Metadata.Rom.CRCKey),
|
||||
};
|
||||
return sfv;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.Hashfile.SHA1"/>
|
||||
/// </summary>
|
||||
private static SHA1 ConvertToSHA1(Models.Metadata.Rom item)
|
||||
{
|
||||
var sha1 = new SHA1
|
||||
{
|
||||
Hash = item.ReadString(Models.Metadata.Rom.SHA1Key),
|
||||
File = item.ReadString(Models.Metadata.Rom.NameKey),
|
||||
};
|
||||
return sha1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.Hashfile.SHA256"/>
|
||||
/// </summary>
|
||||
private static SHA256 ConvertToSHA256(Models.Metadata.Rom item)
|
||||
{
|
||||
var sha256 = new SHA256
|
||||
{
|
||||
Hash = item.ReadString(Models.Metadata.Rom.SHA256Key),
|
||||
File = item.ReadString(Models.Metadata.Rom.NameKey),
|
||||
};
|
||||
return sha256;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.Hashfile.SHA384"/>
|
||||
/// </summary>
|
||||
private static SHA384 ConvertToSHA384(Models.Metadata.Rom item)
|
||||
{
|
||||
var sha384 = new SHA384
|
||||
{
|
||||
Hash = item.ReadString(Models.Metadata.Rom.SHA384Key),
|
||||
File = item.ReadString(Models.Metadata.Rom.NameKey),
|
||||
};
|
||||
return sha384;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.Hashfile.SHA512"/>
|
||||
/// </summary>
|
||||
private static SHA512 ConvertToSHA512(Models.Metadata.Rom item)
|
||||
{
|
||||
var sha512 = new SHA512
|
||||
{
|
||||
Hash = item.ReadString(Models.Metadata.Rom.SHA512Key),
|
||||
File = item.ReadString(Models.Metadata.Rom.NameKey),
|
||||
};
|
||||
return sha512;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.Hashfile.SpamSum"/>
|
||||
/// </summary>
|
||||
private static SpamSum ConvertToSpamSum(Models.Metadata.Rom item)
|
||||
{
|
||||
var spamsum = new SpamSum
|
||||
{
|
||||
Hash = item.ReadString(Models.Metadata.Rom.SpamSumKey),
|
||||
File = item.ReadString(Models.Metadata.Rom.NameKey),
|
||||
};
|
||||
return spamsum;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,407 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SabreTools.Core;
|
||||
using SabreTools.IO.Writers;
|
||||
using SabreTools.Models.Hashfile;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializer for hashfile variants
|
||||
/// </summary>
|
||||
public partial class Hashfile
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializes the defined type to a hashfile variant file
|
||||
/// </summary>
|
||||
/// <param name="hashfile">Data to serialize</param>
|
||||
/// <param name="path">Path to the file to serialize to</param>
|
||||
/// <param name="hash">Hash corresponding to the hashfile variant</param>
|
||||
/// <returns>True on successful serialization, false otherwise</returns>
|
||||
public static bool SerializeToFile(Models.Hashfile.Hashfile? hashfile, string path, Hash hash)
|
||||
{
|
||||
using var stream = SerializeToStream(hashfile, hash);
|
||||
if (stream == null)
|
||||
return false;
|
||||
|
||||
using var fs = File.OpenWrite(path);
|
||||
stream.CopyTo(fs);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes the defined type to a stream
|
||||
/// </summary>
|
||||
/// <param name="hashfile">Data to serialize</param>
|
||||
/// <param name="hash">Hash corresponding to the hashfile variant</param>
|
||||
/// <returns>Stream containing serialized data on success, null otherwise</returns>
|
||||
public static Stream? SerializeToStream(Models.Hashfile.Hashfile? hashfile, Hash hash)
|
||||
{
|
||||
// If the metadata file is null
|
||||
if (hashfile == null)
|
||||
return null;
|
||||
|
||||
// Setup the writer and output
|
||||
var stream = new MemoryStream();
|
||||
var writer = new SeparatedValueWriter(stream, Encoding.UTF8)
|
||||
{
|
||||
Separator = ' ',
|
||||
Quotes = false,
|
||||
VerifyFieldCount = false,
|
||||
};
|
||||
|
||||
// Write out the items, if they exist
|
||||
switch (hash)
|
||||
{
|
||||
case Hash.CRC:
|
||||
WriteSFV(hashfile.SFV, writer);
|
||||
break;
|
||||
case Hash.MD5:
|
||||
WriteMD5(hashfile.MD5, writer);
|
||||
break;
|
||||
case Hash.SHA1:
|
||||
WriteSHA1(hashfile.SHA1, writer);
|
||||
break;
|
||||
case Hash.SHA256:
|
||||
WriteSHA256(hashfile.SHA256, writer);
|
||||
break;
|
||||
case Hash.SHA384:
|
||||
WriteSHA384(hashfile.SHA384, writer);
|
||||
break;
|
||||
case Hash.SHA512:
|
||||
WriteSHA512(hashfile.SHA512, writer);
|
||||
break;
|
||||
case Hash.SpamSum:
|
||||
WriteSpamSum(hashfile.SpamSum, writer);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(hash));
|
||||
}
|
||||
|
||||
// Return the stream
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
return stream;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write SFV information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="sfvs">Array of SFV objects representing the files</param>
|
||||
/// <param name="writer">SeparatedValueWriter representing the output</param>
|
||||
private static void WriteSFV(SFV[]? sfvs, SeparatedValueWriter writer)
|
||||
{
|
||||
// If the item information is missing, we can't do anything
|
||||
if (sfvs == null || !sfvs.Any())
|
||||
return;
|
||||
|
||||
// Loop through and write out the items
|
||||
foreach (var sfv in sfvs)
|
||||
{
|
||||
if (sfv == null)
|
||||
continue;
|
||||
if (string.IsNullOrWhiteSpace(sfv.File) || string.IsNullOrWhiteSpace(sfv.Hash))
|
||||
continue;
|
||||
|
||||
writer.WriteValues(new string[] { sfv.File, sfv.Hash });
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write MD5 information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="md5s">Array of MD5 objects representing the files</param>
|
||||
/// <param name="writer">SeparatedValueWriter representing the output</param>
|
||||
private static void WriteMD5(MD5[]? md5s, SeparatedValueWriter writer)
|
||||
{
|
||||
// If the item information is missing, we can't do anything
|
||||
if (md5s == null || !md5s.Any())
|
||||
return;
|
||||
|
||||
// Loop through and write out the items
|
||||
foreach (var md5 in md5s)
|
||||
{
|
||||
if (md5 == null)
|
||||
continue;
|
||||
if (string.IsNullOrWhiteSpace(md5.Hash) || string.IsNullOrWhiteSpace(md5.File))
|
||||
continue;
|
||||
|
||||
writer.WriteValues(new string[] { md5.Hash, md5.File });
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write SHA1 information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="sha1s">Array of SHA1 objects representing the files</param>
|
||||
/// <param name="writer">SeparatedValueWriter representing the output</param>
|
||||
private static void WriteSHA1(SHA1[]? sha1s, SeparatedValueWriter writer)
|
||||
{
|
||||
// If the item information is missing, we can't do anything
|
||||
if (sha1s == null || !sha1s.Any())
|
||||
return;
|
||||
|
||||
// Loop through and write out the items
|
||||
foreach (var sha1 in sha1s)
|
||||
{
|
||||
if (sha1 == null)
|
||||
continue;
|
||||
if (string.IsNullOrWhiteSpace(sha1.Hash) || string.IsNullOrWhiteSpace(sha1.File))
|
||||
continue;
|
||||
|
||||
writer.WriteValues(new string[] { sha1.Hash, sha1.File });
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write SHA256 information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="sha256s">Array of SHA256 objects representing the files</param>
|
||||
/// <param name="writer">SeparatedValueWriter representing the output</param>
|
||||
private static void WriteSHA256(SHA256[]? sha256s, SeparatedValueWriter writer)
|
||||
{
|
||||
// If the item information is missing, we can't do anything
|
||||
if (sha256s == null || !sha256s.Any())
|
||||
return;
|
||||
|
||||
// Loop through and write out the items
|
||||
foreach (var sha256 in sha256s)
|
||||
{
|
||||
if (sha256 == null)
|
||||
continue;
|
||||
if (string.IsNullOrWhiteSpace(sha256.Hash) || string.IsNullOrWhiteSpace(sha256.File))
|
||||
continue;
|
||||
|
||||
writer.WriteValues(new string[] { sha256.Hash, sha256.File });
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write SHA384 information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="sha384s">Array of SHA384 objects representing the files</param>
|
||||
/// <param name="writer">SeparatedValueWriter representing the output</param>
|
||||
private static void WriteSHA384(SHA384[]? sha384s, SeparatedValueWriter writer)
|
||||
{
|
||||
// If the item information is missing, we can't do anything
|
||||
if (sha384s == null || !sha384s.Any())
|
||||
return;
|
||||
|
||||
// Loop through and write out the items
|
||||
foreach (var sha384 in sha384s)
|
||||
{
|
||||
if (sha384 == null)
|
||||
continue;
|
||||
if (string.IsNullOrWhiteSpace(sha384.Hash) || string.IsNullOrWhiteSpace(sha384.File))
|
||||
continue;
|
||||
|
||||
writer.WriteValues(new string[] { sha384.Hash, sha384.File });
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write SHA512 information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="sha512s">Array of SHA512 objects representing the files</param>
|
||||
/// <param name="writer">SeparatedValueWriter representing the output</param>
|
||||
private static void WriteSHA512(SHA512[]? sha512s, SeparatedValueWriter writer)
|
||||
{
|
||||
// If the item information is missing, we can't do anything
|
||||
if (sha512s == null || !sha512s.Any())
|
||||
return;
|
||||
|
||||
// Loop through and write out the items
|
||||
foreach (var sha512 in sha512s)
|
||||
{
|
||||
if (sha512 == null)
|
||||
continue;
|
||||
if (string.IsNullOrWhiteSpace(sha512.Hash) || string.IsNullOrWhiteSpace(sha512.File))
|
||||
continue;
|
||||
|
||||
writer.WriteValues(new string[] { sha512.Hash, sha512.File });
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write SpamSum information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="spamsums">Array of SpamSum objects representing the files</param>
|
||||
/// <param name="writer">SeparatedValueWriter representing the output</param>
|
||||
private static void WriteSpamSum(SpamSum[]? spamsums, SeparatedValueWriter writer)
|
||||
{
|
||||
// If the item information is missing, we can't do anything
|
||||
if (spamsums == null || !spamsums.Any())
|
||||
return;
|
||||
|
||||
// Loop through and write out the items
|
||||
foreach (var spamsum in spamsums)
|
||||
{
|
||||
if (spamsum == null)
|
||||
continue;
|
||||
if (string.IsNullOrWhiteSpace(spamsum.Hash) || string.IsNullOrWhiteSpace(spamsum.File))
|
||||
continue;
|
||||
|
||||
writer.WriteValues(new string[] { spamsum.Hash, spamsum.File });
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Hashfile.Hashfile"/> to <cref="Models.Metadata.MetadataFile"/>
|
||||
/// </summary>
|
||||
public static Models.Metadata.MetadataFile? ConvertToInternalModel(Models.Hashfile.Hashfile? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var metadataFile = new Models.Metadata.MetadataFile
|
||||
{
|
||||
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(),
|
||||
};
|
||||
|
||||
var machine = ConvertMachineToInternalModel(item);
|
||||
metadataFile[Models.Metadata.MetadataFile.MachineKey] = new Models.Metadata.Machine[] { machine };
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Hashfile.Hashfile"/> to <cref="Models.Metadata.Header"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Header ConvertHeaderToInternalModel()
|
||||
{
|
||||
var header = new Models.Metadata.Header
|
||||
{
|
||||
[Models.Metadata.Header.NameKey] = "Hashfile",
|
||||
};
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Hashfile.Hashfile"/> to <cref="Models.Metadata.Machine"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Machine ConvertMachineToInternalModel(Models.Hashfile.Hashfile item)
|
||||
{
|
||||
var machine = new Models.Metadata.Machine();
|
||||
|
||||
if (item.SFV != null && item.SFV.Any())
|
||||
machine[Models.Metadata.Machine.RomKey] = item.SFV.Select(ConvertToInternalModel).ToArray();
|
||||
else if (item.MD5 != null && item.MD5.Any())
|
||||
machine[Models.Metadata.Machine.RomKey] = item.MD5.Select(ConvertToInternalModel).ToArray();
|
||||
else if (item.SHA1 != null && item.SHA1.Any())
|
||||
machine[Models.Metadata.Machine.RomKey] = item.SHA1.Select(ConvertToInternalModel).ToArray();
|
||||
else if (item.SHA256 != null && item.SHA256.Any())
|
||||
machine[Models.Metadata.Machine.RomKey] = item.SHA256.Select(ConvertToInternalModel).ToArray();
|
||||
else if (item.SHA384 != null && item.SHA384.Any())
|
||||
machine[Models.Metadata.Machine.RomKey] = item.SHA384.Select(ConvertToInternalModel).ToArray();
|
||||
else if (item.SHA512 != null && item.SHA512.Any())
|
||||
machine[Models.Metadata.Machine.RomKey] = item.SHA512.Select(ConvertToInternalModel).ToArray();
|
||||
else if (item.SpamSum != null && item.SpamSum.Any())
|
||||
machine[Models.Metadata.Machine.RomKey] = item.SpamSum.Select(ConvertToInternalModel).ToArray();
|
||||
|
||||
return machine;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Hashfile.MD5"/> to <cref="Models.Metadata.Rom"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Rom ConvertToInternalModel(MD5 item)
|
||||
{
|
||||
var rom = new Models.Metadata.Rom
|
||||
{
|
||||
[Models.Metadata.Rom.MD5Key] = item.Hash,
|
||||
[Models.Metadata.Rom.NameKey] = item.File,
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Hashfile.SFV"/> to <cref="Models.Metadata.Rom"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Rom ConvertToInternalModel(SFV item)
|
||||
{
|
||||
var rom = new Models.Metadata.Rom
|
||||
{
|
||||
[Models.Metadata.Rom.NameKey] = item.File,
|
||||
[Models.Metadata.Rom.CRCKey] = item.Hash,
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Hashfile.SHA1"/> to <cref="Models.Metadata.Rom"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Rom ConvertToInternalModel(SHA1 item)
|
||||
{
|
||||
var rom = new Models.Metadata.Rom
|
||||
{
|
||||
[Models.Metadata.Rom.SHA1Key] = item.Hash,
|
||||
[Models.Metadata.Rom.NameKey] = item.File,
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Hashfile.SHA256"/> to <cref="Models.Metadata.Rom"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Rom ConvertToInternalModel(SHA256 item)
|
||||
{
|
||||
var rom = new Models.Metadata.Rom
|
||||
{
|
||||
[Models.Metadata.Rom.SHA256Key] = item.Hash,
|
||||
[Models.Metadata.Rom.NameKey] = item.File,
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Hashfile.SHA384"/> to <cref="Models.Metadata.Rom"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Rom ConvertToInternalModel(SHA384 item)
|
||||
{
|
||||
var rom = new Models.Metadata.Rom
|
||||
{
|
||||
[Models.Metadata.Rom.SHA384Key] = item.Hash,
|
||||
[Models.Metadata.Rom.NameKey] = item.File,
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Hashfile.SHA512"/> to <cref="Models.Metadata.Rom"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Rom ConvertToInternalModel(SHA512 item)
|
||||
{
|
||||
var rom = new Models.Metadata.Rom
|
||||
{
|
||||
[Models.Metadata.Rom.SHA512Key] = item.Hash,
|
||||
[Models.Metadata.Rom.NameKey] = item.File,
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Hashfile.SpamSum"/> to <cref="Models.Metadata.Rom"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Rom ConvertToInternalModel(SpamSum item)
|
||||
{
|
||||
var rom = new Models.Metadata.Rom
|
||||
{
|
||||
[Models.Metadata.Rom.SpamSumKey] = item.Hash,
|
||||
[Models.Metadata.Rom.NameKey] = item.File,
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using SabreTools.Models.Metadata;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
public class Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Extract nested items from a Dump
|
||||
/// </summary>
|
||||
public static DatItem[]? ExtractItems(Dump? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var datItems = new List<DatItem>();
|
||||
|
||||
var rom = item.Read<Rom>(Dump.RomKey);
|
||||
if (rom != null)
|
||||
datItems.Add(rom);
|
||||
|
||||
var megaRom = item.Read<Rom>(Dump.MegaRomKey);
|
||||
if (megaRom != null)
|
||||
datItems.Add(megaRom);
|
||||
|
||||
var sccPlusCart = item.Read<Rom>(Dump.SCCPlusCartKey);
|
||||
if (sccPlusCart != null)
|
||||
datItems.Add(sccPlusCart);
|
||||
|
||||
return datItems.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract nested items from a Part
|
||||
/// </summary>
|
||||
public static DatItem[]? ExtractItems(Part? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var datItems = new List<DatItem>();
|
||||
|
||||
var features = item.Read<Feature[]>(Part.FeatureKey);
|
||||
if (features != null && features.Any())
|
||||
datItems.AddRange(features);
|
||||
|
||||
var dataAreas = item.Read<DataArea[]>(Part.DataAreaKey);
|
||||
if (dataAreas != null && dataAreas.Any())
|
||||
{
|
||||
datItems.AddRange(dataAreas
|
||||
.Where(d => d != null)
|
||||
.SelectMany(ExtractItems));
|
||||
}
|
||||
|
||||
var diskAreas = item.Read<DiskArea[]>(Part.DiskAreaKey);
|
||||
if (diskAreas != null && diskAreas.Any())
|
||||
{
|
||||
datItems.AddRange(diskAreas
|
||||
.Where(d => d != null)
|
||||
.SelectMany(ExtractItems));
|
||||
}
|
||||
|
||||
var dipSwitches = item.Read<DipSwitch[]>(Part.DipSwitchKey);
|
||||
if (dipSwitches != null && dipSwitches.Any())
|
||||
{
|
||||
datItems.AddRange(dipSwitches
|
||||
.Where(d => d != null));
|
||||
}
|
||||
|
||||
return datItems.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract nested items from a DataArea
|
||||
/// </summary>
|
||||
private static Rom[] ExtractItems(DataArea item)
|
||||
{
|
||||
var roms = item.Read<Rom[]>(DataArea.RomKey);
|
||||
if (roms == null || !roms.Any())
|
||||
return Array.Empty<Rom>();
|
||||
|
||||
return roms.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract nested items from a DiskArea
|
||||
/// </summary>
|
||||
private static Disk[] ExtractItems(DiskArea item)
|
||||
{
|
||||
var roms = item.Read<Disk[]>(DiskArea.DiskKey);
|
||||
if (roms == null || !roms.Any())
|
||||
return Array.Empty<Disk>();
|
||||
|
||||
return roms.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,287 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SabreTools.Models.Listrom;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// Deserializer for MAME listrom files
|
||||
/// </summary>
|
||||
public partial class Listrom
|
||||
{
|
||||
/// <summary>
|
||||
/// Deserializes a MAME listrom file to the defined type
|
||||
/// </summary>
|
||||
/// <param name="path">Path to the file to deserialize</param>
|
||||
/// <returns>Deserialized data on success, null on failure</returns>
|
||||
public static MetadataFile? Deserialize(string path)
|
||||
{
|
||||
using var stream = PathProcessor.OpenStream(path);
|
||||
return Deserialize(stream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes a MAME listrom file in a stream to the defined type
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream to deserialize</param>
|
||||
/// <returns>Deserialized data on success, null on failure</returns>
|
||||
public static MetadataFile? Deserialize(Stream? stream)
|
||||
{
|
||||
// If the stream is null
|
||||
if (stream == null)
|
||||
return default;
|
||||
|
||||
// Setup the reader and output
|
||||
var reader = new StreamReader(stream, Encoding.UTF8);
|
||||
var dat = new MetadataFile();
|
||||
|
||||
Set? set = null;
|
||||
var sets = new List<Set>();
|
||||
var rows = new List<Row>();
|
||||
|
||||
var additional = new List<string>();
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
// Read the line and don't split yet
|
||||
string? line = reader.ReadLine();
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// If we have a set to process
|
||||
if (set != null)
|
||||
{
|
||||
set.Row = rows.ToArray();
|
||||
sets.Add(set);
|
||||
set = null;
|
||||
rows.Clear();
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Set lines are unique
|
||||
if (line.StartsWith("ROMs required for driver"))
|
||||
{
|
||||
string driver = line["ROMs required for driver".Length..].Trim('"', ' ', '.');
|
||||
set = new Set { Driver = driver };
|
||||
continue;
|
||||
}
|
||||
else if (line.StartsWith("No ROMs required for driver"))
|
||||
{
|
||||
string driver = line["No ROMs required for driver".Length..].Trim('"', ' ', '.');
|
||||
set = new Set { Driver = driver };
|
||||
continue;
|
||||
}
|
||||
else if (line.StartsWith("ROMs required for device"))
|
||||
{
|
||||
string device = line["ROMs required for device".Length..].Trim('"', ' ', '.');
|
||||
set = new Set { Device = device };
|
||||
continue;
|
||||
}
|
||||
else if (line.StartsWith("No ROMs required for device"))
|
||||
{
|
||||
string device = line["No ROMs required for device".Length..].Trim('"', ' ', '.');
|
||||
set = new Set { Device = device };
|
||||
continue;
|
||||
}
|
||||
else if (line.Equals("Name Size Checksum", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// No-op
|
||||
continue;
|
||||
}
|
||||
|
||||
// Split the line for the name iteratively
|
||||
string[] lineParts = line.Split(" ", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||
if (lineParts.Length == 1)
|
||||
lineParts = line.Split(" ", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||
if (lineParts.Length == 1)
|
||||
lineParts = line.Split(" ", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||
if (lineParts.Length == 1)
|
||||
lineParts = line.Split(" ", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||
|
||||
// Read the name and set the rest of the line for processing
|
||||
string name = lineParts[0];
|
||||
string trimmedLine = line[name.Length..];
|
||||
if (trimmedLine == null)
|
||||
continue;
|
||||
|
||||
lineParts = trimmedLine.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||
|
||||
// The number of items in the row explains what type of row it is
|
||||
var row = new Row();
|
||||
switch (lineParts.Length)
|
||||
{
|
||||
// Normal CHD (Name, MD5/SHA1)
|
||||
case 1:
|
||||
row.Name = name;
|
||||
if (line.Contains("MD5("))
|
||||
row.MD5 = lineParts[0]["MD5".Length..].Trim('(', ')');
|
||||
else
|
||||
row.SHA1 = lineParts[0]["SHA1".Length..].Trim('(', ')');
|
||||
break;
|
||||
|
||||
// Normal ROM (Name, Size, CRC, SHA1)
|
||||
case 3 when line.Contains("CRC"):
|
||||
row.Name = name;
|
||||
row.Size = lineParts[0];
|
||||
row.CRC = lineParts[1]["CRC".Length..].Trim('(', ')');
|
||||
row.SHA1 = lineParts[2]["SHA1".Length..].Trim('(', ')');
|
||||
break;
|
||||
|
||||
// Bad CHD (Name, BAD, SHA1, BAD_DUMP)
|
||||
case 3 when line.Contains("BAD_DUMP"):
|
||||
row.Name = name;
|
||||
row.Bad = true;
|
||||
if (line.Contains("MD5("))
|
||||
row.MD5 = lineParts[1]["MD5".Length..].Trim('(', ')');
|
||||
else
|
||||
row.SHA1 = lineParts[1]["SHA1".Length..].Trim('(', ')');
|
||||
break;
|
||||
|
||||
// Nodump CHD (Name, NO GOOD DUMP KNOWN)
|
||||
case 4 when line.Contains("NO GOOD DUMP KNOWN"):
|
||||
row.Name = name;
|
||||
row.NoGoodDumpKnown = true;
|
||||
break;
|
||||
|
||||
// Bad ROM (Name, Size, BAD, CRC, MD5/SHA1, BAD_DUMP)
|
||||
case 5 when line.Contains("BAD_DUMP"):
|
||||
row.Name = name;
|
||||
row.Size = lineParts[0];
|
||||
row.Bad = true;
|
||||
row.CRC = lineParts[2]["CRC".Length..].Trim('(', ')');
|
||||
if (line.Contains("MD5("))
|
||||
row.SHA1 = lineParts[3]["MD5".Length..].Trim('(', ')');
|
||||
else
|
||||
row.SHA1 = lineParts[3]["SHA1".Length..].Trim('(', ')');
|
||||
break;
|
||||
|
||||
// Nodump ROM (Name, Size, NO GOOD DUMP KNOWN)
|
||||
case 5 when line.Contains("NO GOOD DUMP KNOWN"):
|
||||
row.Name = name;
|
||||
row.Size = lineParts[0];
|
||||
row.NoGoodDumpKnown = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
row = null;
|
||||
additional.Add(line);
|
||||
break;
|
||||
}
|
||||
|
||||
if (row != null)
|
||||
rows.Add(row);
|
||||
}
|
||||
|
||||
// If we have a set to process
|
||||
if (set != null)
|
||||
{
|
||||
set.Row = rows.ToArray();
|
||||
sets.Add(set);
|
||||
set = null;
|
||||
rows.Clear();
|
||||
}
|
||||
|
||||
// Add extra pieces and return
|
||||
dat.Set = sets.ToArray();
|
||||
dat.ADDITIONAL_ELEMENTS = additional.ToArray();
|
||||
return dat;
|
||||
}
|
||||
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.MetadataFile"/> to <cref="Models.Listrom.MetadataFile"/>
|
||||
/// </summary>
|
||||
public static MetadataFile? ConvertFromInternalModel(Models.Metadata.MetadataFile? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var metadataFile = new MetadataFile();
|
||||
|
||||
var machines = item.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
|
||||
if (machines != null && machines.Any())
|
||||
{
|
||||
metadataFile.Set = machines
|
||||
.Where(m => m != null)
|
||||
.Select(ConvertMachineFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Machine"/> to <cref="Models.Listrom.Set"/>
|
||||
/// </summary>
|
||||
private static Set ConvertMachineFromInternalModel(Models.Metadata.Machine item)
|
||||
{
|
||||
var set = new Set();
|
||||
if (item.ReadString(Models.Metadata.Machine.IsDeviceKey) == "yes")
|
||||
set.Device = item.ReadString(Models.Metadata.Machine.NameKey);
|
||||
else
|
||||
set.Driver = item.ReadString(Models.Metadata.Machine.NameKey);
|
||||
|
||||
var rowItems = new List<Row>();
|
||||
|
||||
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
|
||||
if (roms != null)
|
||||
{
|
||||
rowItems.AddRange(roms.Where(r => r != null).Select(ConvertFromInternalModel));
|
||||
}
|
||||
|
||||
var disks = item.Read<Models.Metadata.Disk[]>(Models.Metadata.Machine.DiskKey);
|
||||
if (disks != null)
|
||||
rowItems.AddRange(disks.Where(d => d != null).Select(ConvertFromInternalModel));
|
||||
|
||||
set.Row = rowItems.ToArray();
|
||||
return set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Disk"/> to <cref="Models.Listrom.Row"/>
|
||||
/// </summary>
|
||||
private static Row ConvertFromInternalModel(Models.Metadata.Disk item)
|
||||
{
|
||||
var row = new Row
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Disk.NameKey),
|
||||
MD5 = item.ReadString(Models.Metadata.Disk.MD5Key),
|
||||
SHA1 = item.ReadString(Models.Metadata.Disk.SHA1Key),
|
||||
};
|
||||
|
||||
if (item[Models.Metadata.Disk.StatusKey] as string == "nodump")
|
||||
row.NoGoodDumpKnown = true;
|
||||
else if (item[Models.Metadata.Disk.StatusKey] as string == "baddump")
|
||||
row.Bad = true;
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.Listrom.Row"/>
|
||||
/// </summary>
|
||||
private static Row ConvertFromInternalModel(Models.Metadata.Rom item)
|
||||
{
|
||||
var row = new Row
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Rom.NameKey),
|
||||
Size = item.ReadString(Models.Metadata.Rom.SizeKey),
|
||||
CRC = item.ReadString(Models.Metadata.Rom.CRCKey),
|
||||
SHA1 = item.ReadString(Models.Metadata.Rom.SHA1Key),
|
||||
};
|
||||
|
||||
if (item[Models.Metadata.Rom.StatusKey] as string == "nodump")
|
||||
row.NoGoodDumpKnown = true;
|
||||
else if (item[Models.Metadata.Rom.StatusKey] as string == "baddump")
|
||||
row.Bad = true;
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,294 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SabreTools.Models.Listrom;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// Deserializer for MAME listrom files
|
||||
/// </summary>
|
||||
public partial class Listrom
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializes the defined type to a MAME listrom file
|
||||
/// </summary>
|
||||
/// <param name="metadataFile">Data to serialize</param>
|
||||
/// <param name="path">Path to the file to serialize to</param>
|
||||
/// <returns>True on successful serialization, false otherwise</returns>
|
||||
public static bool SerializeToFile(MetadataFile? metadataFile, string path)
|
||||
{
|
||||
using var stream = SerializeToStream(metadataFile);
|
||||
if (stream == null)
|
||||
return false;
|
||||
|
||||
using var fs = File.OpenWrite(path);
|
||||
stream.CopyTo(fs);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes the defined type to a stream
|
||||
/// </summary>
|
||||
/// <param name="metadataFile">Data to serialize</param>
|
||||
/// <returns>Stream containing serialized data on success, null otherwise</returns>
|
||||
public static Stream? SerializeToStream(MetadataFile? metadataFile)
|
||||
{
|
||||
// If the metadata file is null
|
||||
if (metadataFile == null)
|
||||
return null;
|
||||
|
||||
// Setup the writer and output
|
||||
var stream = new MemoryStream();
|
||||
var writer = new StreamWriter(stream, Encoding.UTF8);
|
||||
|
||||
// Write out the sets, if they exist
|
||||
WriteSets(metadataFile.Set, writer);
|
||||
|
||||
// Return the stream
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
return stream;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write sets information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="sets">Array of Set objects representing the sets information</param>
|
||||
/// <param name="writer">StreamWriter representing the output</param>
|
||||
private static void WriteSets(Set[]? sets, StreamWriter writer)
|
||||
{
|
||||
// If the games information is missing, we can't do anything
|
||||
if (sets == null || !sets.Any())
|
||||
return;
|
||||
|
||||
// Loop through and write out the games
|
||||
foreach (var set in sets)
|
||||
{
|
||||
WriteSet(set, writer);
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write set information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="set">Set object representing the set information</param>
|
||||
/// <param name="writer">StreamWriter representing the output</param>
|
||||
private static void WriteSet(Set set, StreamWriter writer)
|
||||
{
|
||||
// If the set information is missing, we can't do anything
|
||||
if (set == null)
|
||||
return;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(set.Driver))
|
||||
{
|
||||
if (set.Row != null && set.Row.Any())
|
||||
{
|
||||
writer.WriteLine($"ROMs required for driver \"{set.Driver}\".");
|
||||
writer.WriteLine("Name Size Checksum");
|
||||
writer.Flush();
|
||||
|
||||
WriteRows(set.Row, writer);
|
||||
|
||||
writer.WriteLine();
|
||||
writer.Flush();
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteLine($"No ROMs required for driver \"{set.Driver}\".");
|
||||
writer.WriteLine();
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(set.Device))
|
||||
{
|
||||
if (set.Row != null && set.Row.Any())
|
||||
{
|
||||
writer.WriteLine($"ROMs required for device \"{set.Device}\".");
|
||||
writer.WriteLine("Name Size Checksum");
|
||||
writer.Flush();
|
||||
|
||||
WriteRows(set.Row, writer);
|
||||
|
||||
writer.WriteLine();
|
||||
writer.Flush();
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteLine($"No ROMs required for device \"{set.Device}\".");
|
||||
writer.WriteLine();
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write rows information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="rows">Array of Row objects to write</param>
|
||||
/// <param name="writer">StreamWriter representing the output</param>
|
||||
private static void WriteRows(Row[]? rows, StreamWriter writer)
|
||||
{
|
||||
// If the array is missing, we can't do anything
|
||||
if (rows == null)
|
||||
return;
|
||||
|
||||
foreach (var row in rows)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(row.Name))
|
||||
continue;
|
||||
|
||||
var rowBuilder = new StringBuilder();
|
||||
|
||||
int padding = 40 - (row.Size?.Length ?? 0);
|
||||
if (padding < row.Name.Length)
|
||||
padding = row.Name.Length + 2;
|
||||
|
||||
rowBuilder.Append($"{row.Name.PadRight(padding, ' ')}");
|
||||
if (row.Size != null)
|
||||
rowBuilder.Append($"{row.Size} ");
|
||||
|
||||
if (row.NoGoodDumpKnown)
|
||||
{
|
||||
rowBuilder.Append("NO GOOD DUMP KNOWN");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (row.Bad)
|
||||
rowBuilder.Append("BAD ");
|
||||
|
||||
if (row.Size != null)
|
||||
{
|
||||
rowBuilder.Append($"CRC({row.CRC}) ");
|
||||
rowBuilder.Append($"SHA1({row.SHA1}) ");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(row.MD5))
|
||||
rowBuilder.Append($"MD5({row.MD5}) ");
|
||||
else
|
||||
rowBuilder.Append($"SHA1({row.SHA1}) ");
|
||||
}
|
||||
|
||||
if (row.Bad)
|
||||
rowBuilder.Append("BAD_DUMP");
|
||||
}
|
||||
|
||||
writer.WriteLine(rowBuilder.ToString().TrimEnd());
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listrom.MetadataFile"/> to <cref="Models.Metadata.MetadataFile"/>
|
||||
/// </summary>
|
||||
public static Models.Metadata.MetadataFile? ConvertToInternalModel(MetadataFile? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var metadataFile = new Models.Metadata.MetadataFile
|
||||
{
|
||||
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(),
|
||||
};
|
||||
|
||||
if (item?.Set != null && item.Set.Any())
|
||||
{
|
||||
metadataFile[Models.Metadata.MetadataFile.MachineKey] = item.Set
|
||||
.Where(s => s != null)
|
||||
.Select(ConvertMachineToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listrom.MetadataFile"/> to <cref="Header"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Header ConvertHeaderToInternalModel()
|
||||
{
|
||||
var header = new Models.Metadata.Header
|
||||
{
|
||||
[Models.Metadata.Header.NameKey] = "MAME Listrom",
|
||||
};
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listrom.Set"/> to <cref="Models.Metadata.Machine"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Machine ConvertMachineToInternalModel(Set item)
|
||||
{
|
||||
var machine = new Models.Metadata.Machine();
|
||||
if (!string.IsNullOrWhiteSpace(item.Device))
|
||||
{
|
||||
machine[Models.Metadata.Machine.NameKey] = item.Device;
|
||||
machine[Models.Metadata.Machine.IsDeviceKey] = "yes";
|
||||
}
|
||||
else
|
||||
{
|
||||
machine[Models.Metadata.Machine.NameKey] = item.Driver;
|
||||
}
|
||||
|
||||
if (item.Row != null && item.Row.Any())
|
||||
{
|
||||
var datItems = new List<Models.Metadata.DatItem>();
|
||||
foreach (var file in item.Row)
|
||||
{
|
||||
datItems.Add(ConvertToInternalModel(file));
|
||||
}
|
||||
|
||||
machine[Models.Metadata.Machine.DiskKey] = datItems.Where(i => i.ReadString(Models.Metadata.DatItem.TypeKey) == "disk")?.ToArray();
|
||||
machine[Models.Metadata.Machine.RomKey] = datItems.Where(i => i.ReadString(Models.Metadata.DatItem.TypeKey) == "rom")?.ToArray();
|
||||
}
|
||||
|
||||
return machine;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listrom.Row"/> to <cref="Models.Metadata.DatItem"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.DatItem ConvertToInternalModel(Row item)
|
||||
{
|
||||
if (item.Size == null)
|
||||
{
|
||||
var disk = new Models.Metadata.Disk
|
||||
{
|
||||
[Models.Metadata.Disk.NameKey] = item.Name,
|
||||
[Models.Metadata.Disk.MD5Key] = item.MD5,
|
||||
[Models.Metadata.Disk.SHA1Key] = item.SHA1,
|
||||
};
|
||||
|
||||
if (item.NoGoodDumpKnown)
|
||||
disk[Models.Metadata.Disk.StatusKey] = "nodump";
|
||||
else if (item.Bad)
|
||||
disk[Models.Metadata.Disk.StatusKey] = "baddump";
|
||||
|
||||
return disk;
|
||||
}
|
||||
else
|
||||
{
|
||||
var rom = new Models.Metadata.Rom
|
||||
{
|
||||
[Models.Metadata.Rom.NameKey] = item.Name,
|
||||
[Models.Metadata.Rom.SizeKey] = item.Size,
|
||||
[Models.Metadata.Rom.CRCKey] = item.CRC,
|
||||
[Models.Metadata.Rom.SHA1Key] = item.SHA1,
|
||||
};
|
||||
|
||||
if (item.NoGoodDumpKnown)
|
||||
rom[Models.Metadata.Rom.StatusKey] = "nodump";
|
||||
else if (item.Bad)
|
||||
rom[Models.Metadata.Rom.StatusKey] = "baddump";
|
||||
|
||||
return rom;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,843 +0,0 @@
|
||||
using System.Linq;
|
||||
using SabreTools.Models.Listxml;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// XML deserializer for MAME listxml files
|
||||
/// </summary>
|
||||
public partial class Listxml : XmlSerializer<Mame>
|
||||
{
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Models.Metadata.MetadataFile"/> to <cref="Models.Listxml.M1"/>
|
||||
/// </summary>
|
||||
public static M1? ConvertM1FromInternalModel(Models.Metadata.MetadataFile? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var header = item.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
|
||||
var m1 = header != null ? ConvertM1FromInternalModel(header) : new M1();
|
||||
|
||||
var machines = item.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
|
||||
if (machines != null && machines.Any())
|
||||
{
|
||||
m1.Game = machines
|
||||
.Where(m => m != null)
|
||||
.Select(ConvertMachineFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Models.Metadata.MetadataFile"/> to <cref="Models.Listxml.Mame"/>
|
||||
/// </summary>
|
||||
public static Mame? ConvertMameFromInternalModel(Models.Metadata.MetadataFile? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var header = item.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
|
||||
var mame = header != null ? ConvertMameFromInternalModel(header) : new Mame();
|
||||
|
||||
var machines = item.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
|
||||
if (machines != null && machines.Any())
|
||||
{
|
||||
mame.Game = machines
|
||||
.Where(m => m != null)
|
||||
.Select(ConvertMachineFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return mame;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Models.Metadata.Header"/> to <cref="Models.Listxml.M1"/>
|
||||
/// </summary>
|
||||
private static M1 ConvertM1FromInternalModel(Models.Metadata.Header item)
|
||||
{
|
||||
var m1 = new M1
|
||||
{
|
||||
Version = item.ReadString(Models.Metadata.Header.VersionKey),
|
||||
};
|
||||
return m1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Models.Metadata.Header"/> to <cref="Models.Listxml.Mame"/>
|
||||
/// </summary>
|
||||
private static Mame ConvertMameFromInternalModel(Models.Metadata.Header item)
|
||||
{
|
||||
var mame = new Mame
|
||||
{
|
||||
Build = item.ReadString(Models.Metadata.Header.BuildKey),
|
||||
Debug = item.ReadString(Models.Metadata.Header.DebugKey),
|
||||
MameConfig = item.ReadString(Models.Metadata.Header.MameConfigKey),
|
||||
};
|
||||
|
||||
return mame;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Models.Metadata.Machine"/> to <cref="Models.Listxml.GameBase"/>
|
||||
/// </summary>
|
||||
private static GameBase ConvertMachineFromInternalModel(Models.Metadata.Machine item)
|
||||
{
|
||||
var machine = new Machine
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Machine.NameKey),
|
||||
SourceFile = item.ReadString(Models.Metadata.Machine.SourceFileKey),
|
||||
IsBios = item.ReadString(Models.Metadata.Machine.IsBiosKey),
|
||||
IsDevice = item.ReadString(Models.Metadata.Machine.IsDeviceKey),
|
||||
IsMechanical = item.ReadString(Models.Metadata.Machine.IsMechanicalKey),
|
||||
Runnable = item.ReadString(Models.Metadata.Machine.RunnableKey),
|
||||
CloneOf = item.ReadString(Models.Metadata.Machine.CloneOfKey),
|
||||
RomOf = item.ReadString(Models.Metadata.Machine.RomOfKey),
|
||||
SampleOf = item.ReadString(Models.Metadata.Machine.SampleOfKey),
|
||||
Description = item.ReadString(Models.Metadata.Machine.DescriptionKey),
|
||||
Year = item.ReadString(Models.Metadata.Machine.YearKey),
|
||||
Manufacturer = item.ReadString(Models.Metadata.Machine.ManufacturerKey),
|
||||
History = item.ReadString(Models.Metadata.Machine.HistoryKey),
|
||||
};
|
||||
|
||||
var biosSets = item.Read<Models.Metadata.BiosSet[]>(Models.Metadata.Machine.BiosSetKey);
|
||||
if (biosSets != null && biosSets.Any())
|
||||
{
|
||||
machine.BiosSet = biosSets
|
||||
.Where(b => b != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
|
||||
if (roms != null && roms.Any())
|
||||
{
|
||||
machine.Rom = roms
|
||||
.Where(r => r != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var disks = item.Read<Models.Metadata.Disk[]>(Models.Metadata.Machine.DiskKey);
|
||||
if (disks != null && disks.Any())
|
||||
{
|
||||
machine.Disk = disks
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var deviceRefs = item.Read<Models.Metadata.DeviceRef[]>(Models.Metadata.Machine.DeviceRefKey);
|
||||
if (deviceRefs != null && deviceRefs.Any())
|
||||
{
|
||||
machine.DeviceRef = deviceRefs
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var samples = item.Read<Models.Metadata.Sample[]>(Models.Metadata.Machine.SampleKey);
|
||||
if (samples != null && samples.Any())
|
||||
{
|
||||
machine.Sample = samples
|
||||
.Where(s => s != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var chips = item.Read<Models.Metadata.Chip[]>(Models.Metadata.Machine.ChipKey);
|
||||
if (chips != null && chips.Any())
|
||||
{
|
||||
machine.Chip = chips
|
||||
.Where(c => c != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var displays = item.Read<Models.Metadata.Display[]>(Models.Metadata.Machine.DisplayKey);
|
||||
if (displays != null && displays.Any())
|
||||
{
|
||||
machine.Display = displays
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var videos = item.Read<Models.Metadata.Video[]>(Models.Metadata.Machine.VideoKey);
|
||||
if (videos != null && videos.Any())
|
||||
{
|
||||
machine.Video = videos
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var sound = item.Read<Models.Metadata.Sound>(Models.Metadata.Machine.SoundKey);
|
||||
if (sound != null)
|
||||
machine.Sound = ConvertFromInternalModel(sound);
|
||||
|
||||
var input = item.Read<Models.Metadata.Input>(Models.Metadata.Machine.InputKey);
|
||||
if (input != null)
|
||||
machine.Input = ConvertFromInternalModel(input);
|
||||
|
||||
var dipSwitches = item.Read<Models.Metadata.DipSwitch[]>(Models.Metadata.Machine.DipSwitchKey);
|
||||
if (dipSwitches != null && dipSwitches.Any())
|
||||
{
|
||||
machine.DipSwitch = dipSwitches
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var configurations = item.Read<Models.Metadata.Configuration[]>(Models.Metadata.Machine.ConfigurationKey);
|
||||
if (configurations != null && configurations.Any())
|
||||
{
|
||||
machine.Configuration = configurations
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var ports = item.Read<Models.Metadata.Port[]>(Models.Metadata.Machine.PortKey);
|
||||
if (ports != null && ports.Any())
|
||||
{
|
||||
machine.Port = ports
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var adjusters = item.Read<Models.Metadata.Adjuster[]>(Models.Metadata.Machine.AdjusterKey);
|
||||
if (adjusters != null && adjusters.Any())
|
||||
{
|
||||
machine.Adjuster = adjusters
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var driver = item.Read<Models.Metadata.Driver>(Models.Metadata.Machine.DriverKey);
|
||||
if (driver != null)
|
||||
machine.Driver = ConvertFromInternalModel(driver);
|
||||
|
||||
var features = item.Read<Models.Metadata.Feature[]>(Models.Metadata.Machine.FeatureKey);
|
||||
if (features != null && features.Any())
|
||||
{
|
||||
machine.Feature = features
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var devices = item.Read<Models.Metadata.Device[]>(Models.Metadata.Machine.DeviceKey);
|
||||
if (devices != null && devices.Any())
|
||||
{
|
||||
machine.Device = devices
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var slots = item.Read<Models.Metadata.Slot[]>(Models.Metadata.Machine.SlotKey);
|
||||
if (slots != null && slots.Any())
|
||||
{
|
||||
machine.Slot = slots
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var softwareLists = item.Read<Models.Metadata.SoftwareList[]>(Models.Metadata.Machine.SoftwareListKey);
|
||||
if (softwareLists != null && softwareLists.Any())
|
||||
{
|
||||
machine.SoftwareList = softwareLists
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var ramOptions = item.Read<Models.Metadata.RamOption[]>(Models.Metadata.Machine.RamOptionKey);
|
||||
if (ramOptions != null && ramOptions.Any())
|
||||
{
|
||||
machine.RamOption = ramOptions
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return machine;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Models.Metadata.Adjuster"/> to <cref="Models.Listxml.Adjuster"/>
|
||||
/// </summary>
|
||||
private static Adjuster ConvertFromInternalModel(Models.Metadata.Adjuster item)
|
||||
{
|
||||
var adjuster = new Adjuster
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Adjuster.NameKey),
|
||||
Default = item.ReadString(Models.Metadata.Adjuster.DefaultKey),
|
||||
};
|
||||
|
||||
var condition = item.Read<Models.Metadata.Condition>(Models.Metadata.Adjuster.ConditionKey);
|
||||
if (condition != null)
|
||||
adjuster.Condition = ConvertFromInternalModel(condition);
|
||||
|
||||
return adjuster;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Models.Metadata.Analog"/> to <cref="Models.Listxml.Analog"/>
|
||||
/// </summary>
|
||||
private static Analog ConvertFromInternalModel(Models.Metadata.Analog item)
|
||||
{
|
||||
var analog = new Analog
|
||||
{
|
||||
Mask = item.ReadString(Models.Metadata.Analog.MaskKey),
|
||||
};
|
||||
return analog;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Models.Metadata.BiosSet"/> to <cref="Models.Listxml.BiosSet"/>
|
||||
/// </summary>
|
||||
private static BiosSet ConvertFromInternalModel(Models.Metadata.BiosSet item)
|
||||
{
|
||||
var biosset = new BiosSet
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.BiosSet.NameKey),
|
||||
Description = item.ReadString(Models.Metadata.BiosSet.DescriptionKey),
|
||||
Default = item.ReadString(Models.Metadata.BiosSet.DefaultKey),
|
||||
};
|
||||
return biosset;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Models.Metadata.Chip"/> to <cref="Models.Listxml.Chip"/>
|
||||
/// </summary>
|
||||
private static Chip ConvertFromInternalModel(Models.Metadata.Chip item)
|
||||
{
|
||||
var chip = new Chip
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Chip.NameKey),
|
||||
Tag = item.ReadString(Models.Metadata.Chip.TagKey),
|
||||
Type = item.ReadString(Models.Metadata.Chip.TypeKey),
|
||||
SoundOnly = item.ReadString(Models.Metadata.Chip.SoundOnlyKey),
|
||||
Clock = item.ReadString(Models.Metadata.Chip.ClockKey),
|
||||
};
|
||||
return chip;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Models.Metadata.Condition"/> to <cref="Models.Listxml.Condition"/>
|
||||
/// </summary>
|
||||
private static Condition ConvertFromInternalModel(Models.Metadata.Condition item)
|
||||
{
|
||||
var condition = new Condition
|
||||
{
|
||||
Tag = item.ReadString(Models.Metadata.Condition.TagKey),
|
||||
Mask = item.ReadString(Models.Metadata.Condition.MaskKey),
|
||||
Relation = item.ReadString(Models.Metadata.Condition.RelationKey),
|
||||
Value = item.ReadString(Models.Metadata.Condition.ValueKey),
|
||||
};
|
||||
return condition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Models.Metadata.Configuration"/> to <cref="Models.Listxml.Configuration"/>
|
||||
/// </summary>
|
||||
private static Configuration ConvertFromInternalModel(Models.Metadata.Configuration item)
|
||||
{
|
||||
var configuration = new Configuration
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Configuration.NameKey),
|
||||
Tag = item.ReadString(Models.Metadata.Configuration.TagKey),
|
||||
Mask = item.ReadString(Models.Metadata.Configuration.MaskKey),
|
||||
};
|
||||
|
||||
var condition = item.Read<Models.Metadata.Condition>(Models.Metadata.Configuration.ConditionKey);
|
||||
if (condition != null)
|
||||
configuration.Condition = ConvertFromInternalModel(condition);
|
||||
|
||||
var confLocations = item.Read<Models.Metadata.ConfLocation[]>(Models.Metadata.Configuration.ConfLocationKey);
|
||||
if (confLocations != null && confLocations.Any())
|
||||
{
|
||||
configuration.ConfLocation = confLocations
|
||||
.Where(c => c != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var confSettings = item.Read<Models.Metadata.ConfSetting[]>(Models.Metadata.Configuration.ConfSettingKey);
|
||||
if (confSettings != null && confSettings.Any())
|
||||
{
|
||||
configuration.ConfSetting = confSettings
|
||||
.Where(c => c != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return configuration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Models.Metadata.ConfLocation"/> to <cref="Models.Listxml.ConfLocation"/>
|
||||
/// </summary>
|
||||
private static ConfLocation ConvertFromInternalModel(Models.Metadata.ConfLocation item)
|
||||
{
|
||||
var confLocation = new ConfLocation
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.ConfLocation.NameKey),
|
||||
Number = item.ReadString(Models.Metadata.ConfLocation.NumberKey),
|
||||
Inverted = item.ReadString(Models.Metadata.ConfLocation.InvertedKey),
|
||||
};
|
||||
return confLocation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Models.Metadata.ConfSetting"/> to <cref="Models.Listxml.ConfSetting"/>
|
||||
/// </summary>
|
||||
private static ConfSetting ConvertFromInternalModel(Models.Metadata.ConfSetting item)
|
||||
{
|
||||
var confSetting = new ConfSetting
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.ConfSetting.NameKey),
|
||||
Value = item.ReadString(Models.Metadata.ConfSetting.ValueKey),
|
||||
Default = item.ReadString(Models.Metadata.ConfSetting.DefaultKey),
|
||||
};
|
||||
|
||||
var condition = item.Read<Models.Metadata.Condition>(Models.Metadata.ConfSetting.ConditionKey);
|
||||
if (condition != null)
|
||||
confSetting.Condition = ConvertFromInternalModel(condition);
|
||||
|
||||
return confSetting;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Models.Metadata.Control"/> to <cref="Models.Listxml.Control"/>
|
||||
/// </summary>
|
||||
private static Control ConvertFromInternalModel(Models.Metadata.Control item)
|
||||
{
|
||||
var control = new Control
|
||||
{
|
||||
Type = item.ReadString(Models.Metadata.Control.TypeKey),
|
||||
Player = item.ReadString(Models.Metadata.Control.PlayerKey),
|
||||
Buttons = item.ReadString(Models.Metadata.Control.ButtonsKey),
|
||||
ReqButtons = item.ReadString(Models.Metadata.Control.ReqButtonsKey),
|
||||
Minimum = item.ReadString(Models.Metadata.Control.MinimumKey),
|
||||
Maximum = item.ReadString(Models.Metadata.Control.MaximumKey),
|
||||
Sensitivity = item.ReadString(Models.Metadata.Control.SensitivityKey),
|
||||
KeyDelta = item.ReadString(Models.Metadata.Control.KeyDeltaKey),
|
||||
Reverse = item.ReadString(Models.Metadata.Control.ReverseKey),
|
||||
Ways = item.ReadString(Models.Metadata.Control.WaysKey),
|
||||
Ways2 = item.ReadString(Models.Metadata.Control.Ways2Key),
|
||||
Ways3 = item.ReadString(Models.Metadata.Control.Ways3Key),
|
||||
};
|
||||
return control;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Models.Metadata.Device"/> to <cref="Models.Listxml.Device"/>
|
||||
/// </summary>
|
||||
private static Device ConvertFromInternalModel(Models.Metadata.Device item)
|
||||
{
|
||||
var device = new Device
|
||||
{
|
||||
Type = item.ReadString(Models.Metadata.Device.TypeKey),
|
||||
Tag = item.ReadString(Models.Metadata.Device.TagKey),
|
||||
FixedImage = item.ReadString(Models.Metadata.Device.FixedImageKey),
|
||||
Mandatory = item.ReadString(Models.Metadata.Device.MandatoryKey),
|
||||
Interface = item.ReadString(Models.Metadata.Device.InterfaceKey),
|
||||
};
|
||||
|
||||
var instance = item.Read<Models.Metadata.Instance>(Models.Metadata.Device.InstanceKey);
|
||||
if (instance != null)
|
||||
device.Instance = ConvertFromInternalModel(instance);
|
||||
|
||||
var extensions = item.Read<Models.Metadata.Extension[]>(Models.Metadata.Device.ExtensionKey);
|
||||
if (extensions != null && extensions.Any())
|
||||
{
|
||||
device.Extension = extensions
|
||||
.Where(e => e != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.DeviceRef"/> to <cref="Models.Listxml.DeviceRef"/>
|
||||
/// </summary>
|
||||
private static DeviceRef ConvertFromInternalModel(Models.Metadata.DeviceRef item)
|
||||
{
|
||||
var deviceRef = new DeviceRef
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.DeviceRef.NameKey),
|
||||
};
|
||||
return deviceRef;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.DipLocation"/> to <cref="Models.Listxml.DipLocation"/>
|
||||
/// </summary>
|
||||
private static DipLocation ConvertFromInternalModel(Models.Metadata.DipLocation item)
|
||||
{
|
||||
var dipLocation = new DipLocation
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.DipLocation.NameKey),
|
||||
Number = item.ReadString(Models.Metadata.DipLocation.NumberKey),
|
||||
Inverted = item.ReadString(Models.Metadata.DipLocation.InvertedKey),
|
||||
};
|
||||
return dipLocation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.DipSwitch"/> to <cref="Models.Listxml.DipSwitch"/>
|
||||
/// </summary>
|
||||
private static DipSwitch ConvertFromInternalModel(Models.Metadata.DipSwitch item)
|
||||
{
|
||||
var dipSwitch = new DipSwitch
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.DipSwitch.NameKey),
|
||||
Tag = item.ReadString(Models.Metadata.DipSwitch.TagKey),
|
||||
Mask = item.ReadString(Models.Metadata.DipSwitch.MaskKey),
|
||||
};
|
||||
|
||||
var condition = item.Read<Models.Metadata.Condition>(Models.Metadata.DipSwitch.ConditionKey);
|
||||
if (condition != null)
|
||||
dipSwitch.Condition = ConvertFromInternalModel(condition);
|
||||
|
||||
var dipLocations = item.Read<Models.Metadata.DipLocation[]>(Models.Metadata.DipSwitch.DipLocationKey);
|
||||
if (dipLocations != null && dipLocations.Any())
|
||||
{
|
||||
dipSwitch.DipLocation = dipLocations
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var dipValues = item.Read<Models.Metadata.DipValue[]>(Models.Metadata.DipSwitch.DipValueKey);
|
||||
if (dipValues != null && dipValues.Any())
|
||||
{
|
||||
dipSwitch.DipValue = dipValues
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return dipSwitch;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.DipValue"/> to <cref="Models.Listxml.DipValue"/>
|
||||
/// </summary>
|
||||
private static DipValue ConvertFromInternalModel(Models.Metadata.DipValue item)
|
||||
{
|
||||
var dipValue = new DipValue
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.DipValue.NameKey),
|
||||
Value = item.ReadString(Models.Metadata.DipValue.ValueKey),
|
||||
Default = item.ReadString(Models.Metadata.DipValue.DefaultKey),
|
||||
};
|
||||
|
||||
var condition = item.Read<Models.Metadata.Condition>(Models.Metadata.DipValue.ConditionKey);
|
||||
if (condition != null)
|
||||
dipValue.Condition = ConvertFromInternalModel(condition);
|
||||
|
||||
return dipValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Disk"/> to <cref="Models.Listxml.Disk"/>
|
||||
/// </summary>
|
||||
private static Disk ConvertFromInternalModel(Models.Metadata.Disk item)
|
||||
{
|
||||
var disk = new Disk
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Disk.NameKey),
|
||||
MD5 = item.ReadString(Models.Metadata.Disk.MD5Key),
|
||||
SHA1 = item.ReadString(Models.Metadata.Disk.SHA1Key),
|
||||
Merge = item.ReadString(Models.Metadata.Disk.MergeKey),
|
||||
Region = item.ReadString(Models.Metadata.Disk.RegionKey),
|
||||
Index = item.ReadString(Models.Metadata.Disk.IndexKey),
|
||||
Writable = item.ReadString(Models.Metadata.Disk.WritableKey),
|
||||
Status = item.ReadString(Models.Metadata.Disk.StatusKey),
|
||||
Optional = item.ReadString(Models.Metadata.Disk.OptionalKey),
|
||||
};
|
||||
return disk;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Display"/> to <cref="Models.Listxml.Display"/>
|
||||
/// </summary>
|
||||
private static Display ConvertFromInternalModel(Models.Metadata.Display item)
|
||||
{
|
||||
var display = new Display
|
||||
{
|
||||
Tag = item.ReadString(Models.Metadata.Display.TagKey),
|
||||
Type = item.ReadString(Models.Metadata.Display.TypeKey),
|
||||
Rotate = item.ReadString(Models.Metadata.Display.RotateKey),
|
||||
FlipX = item.ReadString(Models.Metadata.Display.FlipXKey),
|
||||
Width = item.ReadString(Models.Metadata.Display.WidthKey),
|
||||
Height = item.ReadString(Models.Metadata.Display.HeightKey),
|
||||
Refresh = item.ReadString(Models.Metadata.Display.RefreshKey),
|
||||
PixClock = item.ReadString(Models.Metadata.Display.PixClockKey),
|
||||
HTotal = item.ReadString(Models.Metadata.Display.HTotalKey),
|
||||
HBEnd = item.ReadString(Models.Metadata.Display.HBEndKey),
|
||||
HBStart = item.ReadString(Models.Metadata.Display.HBStartKey),
|
||||
VTotal = item.ReadString(Models.Metadata.Display.VTotalKey),
|
||||
VBEnd = item.ReadString(Models.Metadata.Display.VBEndKey),
|
||||
VBStart = item.ReadString(Models.Metadata.Display.VBStartKey),
|
||||
};
|
||||
return display;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Driver"/> to <cref="Models.Listxml.Driver"/>
|
||||
/// </summary>
|
||||
private static Driver ConvertFromInternalModel(Models.Metadata.Driver item)
|
||||
{
|
||||
var driver = new Driver
|
||||
{
|
||||
Status = item.ReadString(Models.Metadata.Driver.StatusKey),
|
||||
Color = item.ReadString(Models.Metadata.Driver.ColorKey),
|
||||
Sound = item.ReadString(Models.Metadata.Driver.SoundKey),
|
||||
PaletteSize = item.ReadString(Models.Metadata.Driver.PaletteSizeKey),
|
||||
Emulation = item.ReadString(Models.Metadata.Driver.EmulationKey),
|
||||
Cocktail = item.ReadString(Models.Metadata.Driver.CocktailKey),
|
||||
SaveState = item.ReadString(Models.Metadata.Driver.SaveStateKey),
|
||||
RequiresArtwork = item.ReadString(Models.Metadata.Driver.RequiresArtworkKey),
|
||||
Unofficial = item.ReadString(Models.Metadata.Driver.UnofficialKey),
|
||||
NoSoundHardware = item.ReadString(Models.Metadata.Driver.NoSoundHardwareKey),
|
||||
Incomplete = item.ReadString(Models.Metadata.Driver.IncompleteKey),
|
||||
};
|
||||
return driver;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Extension"/> to <cref="Models.Listxml.Extension"/>
|
||||
/// </summary>
|
||||
private static Extension ConvertFromInternalModel(Models.Metadata.Extension item)
|
||||
{
|
||||
var extension = new Extension
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Extension.NameKey),
|
||||
};
|
||||
return extension;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Feature"/> to <cref="Models.Listxml.Feature"/>
|
||||
/// </summary>
|
||||
private static Feature ConvertFromInternalModel(Models.Metadata.Feature item)
|
||||
{
|
||||
var feature = new Feature
|
||||
{
|
||||
Type = item.ReadString(Models.Metadata.Feature.TypeKey),
|
||||
Status = item.ReadString(Models.Metadata.Feature.StatusKey),
|
||||
Overall = item.ReadString(Models.Metadata.Feature.OverallKey),
|
||||
};
|
||||
return feature;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Input"/> to <cref="Models.Listxml.Input"/>
|
||||
/// </summary>
|
||||
private static Input ConvertFromInternalModel(Models.Metadata.Input item)
|
||||
{
|
||||
var input = new Input
|
||||
{
|
||||
Service = item.ReadString(Models.Metadata.Input.ServiceKey),
|
||||
Tilt = item.ReadString(Models.Metadata.Input.TiltKey),
|
||||
Players = item.ReadString(Models.Metadata.Input.PlayersKey),
|
||||
ControlAttr = item.ReadString(Models.Metadata.Input.ControlKey),
|
||||
Buttons = item.ReadString(Models.Metadata.Input.ButtonsKey),
|
||||
Coins = item.ReadString(Models.Metadata.Input.CoinsKey),
|
||||
};
|
||||
|
||||
var controls = item.Read<Models.Metadata.Control[]>(Models.Metadata.Input.ControlKey);
|
||||
if (controls != null && controls.Any())
|
||||
{
|
||||
input.Control = controls
|
||||
.Where(c => c != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Instance"/> to <cref="Models.Listxml.Instance"/>
|
||||
/// </summary>
|
||||
private static Instance ConvertFromInternalModel(Models.Metadata.Instance item)
|
||||
{
|
||||
var instance = new Instance
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Instance.NameKey),
|
||||
BriefName = item.ReadString(Models.Metadata.Instance.BriefNameKey),
|
||||
};
|
||||
return instance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Port"/> to <cref="Models.Listxml.Port"/>
|
||||
/// </summary>
|
||||
private static Port ConvertFromInternalModel(Models.Metadata.Port item)
|
||||
{
|
||||
var port = new Port
|
||||
{
|
||||
Tag = item.ReadString(Models.Metadata.Port.TagKey),
|
||||
};
|
||||
|
||||
var analogs = item.Read<Models.Metadata.Analog[]>(Models.Metadata.Port.AnalogKey);
|
||||
if (analogs != null && analogs.Any())
|
||||
{
|
||||
port.Analog = analogs
|
||||
.Where(a => a != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.RamOption"/> to <cref="Models.Listxml.RamOption"/>
|
||||
/// </summary>
|
||||
private static RamOption ConvertFromInternalModel(Models.Metadata.RamOption item)
|
||||
{
|
||||
var ramOption = new RamOption
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.RamOption.NameKey),
|
||||
Default = item.ReadString(Models.Metadata.RamOption.DefaultKey),
|
||||
Content = item.ReadString(Models.Metadata.RamOption.ContentKey),
|
||||
};
|
||||
return ramOption;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.Listxml.Rom"/>
|
||||
/// </summary>
|
||||
private static Rom ConvertFromInternalModel(Models.Metadata.Rom item)
|
||||
{
|
||||
var rom = new Rom
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Rom.NameKey),
|
||||
Bios = item.ReadString(Models.Metadata.Rom.BiosKey),
|
||||
Size = item.ReadString(Models.Metadata.Rom.SizeKey),
|
||||
CRC = item.ReadString(Models.Metadata.Rom.CRCKey),
|
||||
SHA1 = item.ReadString(Models.Metadata.Rom.SHA1Key),
|
||||
Merge = item.ReadString(Models.Metadata.Rom.MergeKey),
|
||||
Region = item.ReadString(Models.Metadata.Rom.RegionKey),
|
||||
Offset = item.ReadString(Models.Metadata.Rom.OffsetKey),
|
||||
Status = item.ReadString(Models.Metadata.Rom.StatusKey),
|
||||
Optional = item.ReadString(Models.Metadata.Rom.OptionalKey),
|
||||
Dispose = item.ReadString(Models.Metadata.Rom.DisposeKey),
|
||||
SoundOnly = item.ReadString(Models.Metadata.Rom.SoundOnlyKey),
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Sample"/> to <cref="Models.Listxml.Sample"/>
|
||||
/// </summary>
|
||||
private static Sample ConvertFromInternalModel(Models.Metadata.Sample item)
|
||||
{
|
||||
var sample = new Sample
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Sample.NameKey),
|
||||
};
|
||||
return sample;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Slot"/> to <cref="Models.Listxml.Slot"/>
|
||||
/// </summary>
|
||||
private static Slot ConvertFromInternalModel(Models.Metadata.Slot item)
|
||||
{
|
||||
var slot = new Slot
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Slot.NameKey),
|
||||
};
|
||||
|
||||
var slotOptions = item.Read<Models.Metadata.SlotOption[]>(Models.Metadata.Slot.SlotOptionKey);
|
||||
if (slotOptions != null && slotOptions.Any())
|
||||
{
|
||||
slot.SlotOption = slotOptions
|
||||
.Where(s => s != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.SlotOption"/> to <cref="Models.Listxml.SlotOption"/>
|
||||
/// </summary>
|
||||
private static SlotOption ConvertFromInternalModel(Models.Metadata.SlotOption item)
|
||||
{
|
||||
var slotOption = new SlotOption
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.SlotOption.NameKey),
|
||||
DevName = item.ReadString(Models.Metadata.SlotOption.DevNameKey),
|
||||
Default = item.ReadString(Models.Metadata.SlotOption.DefaultKey),
|
||||
};
|
||||
return slotOption;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.SoftwareList"/> to <cref="Models.Listxml.SoftwareList"/>
|
||||
/// </summary>
|
||||
private static SoftwareList ConvertFromInternalModel(Models.Metadata.SoftwareList item)
|
||||
{
|
||||
var softwareList = new SoftwareList
|
||||
{
|
||||
Tag = item.ReadString(Models.Metadata.SoftwareList.TagKey),
|
||||
Name = item.ReadString(Models.Metadata.SoftwareList.NameKey),
|
||||
Status = item.ReadString(Models.Metadata.SoftwareList.StatusKey),
|
||||
Filter = item.ReadString(Models.Metadata.SoftwareList.FilterKey),
|
||||
};
|
||||
return softwareList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Sound"/> to <cref="Models.Listxml.Sound"/>
|
||||
/// </summary>
|
||||
private static Sound ConvertFromInternalModel(Models.Metadata.Sound item)
|
||||
{
|
||||
var sound = new Sound
|
||||
{
|
||||
Channels = item.ReadString(Models.Metadata.Sound.ChannelsKey),
|
||||
};
|
||||
return sound;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Video"/> to <cref="Models.Listxml.Video"/>
|
||||
/// </summary>
|
||||
private static Video ConvertFromInternalModel(Models.Metadata.Video item)
|
||||
{
|
||||
var video = new Video
|
||||
{
|
||||
Screen = item.ReadString(Models.Metadata.Video.ScreenKey),
|
||||
Orientation = item.ReadString(Models.Metadata.Video.OrientationKey),
|
||||
Width = item.ReadString(Models.Metadata.Video.WidthKey),
|
||||
Height = item.ReadString(Models.Metadata.Video.HeightKey),
|
||||
AspectX = item.ReadString(Models.Metadata.Video.AspectXKey),
|
||||
AspectY = item.ReadString(Models.Metadata.Video.AspectYKey),
|
||||
Refresh = item.ReadString(Models.Metadata.Video.RefreshKey),
|
||||
};
|
||||
return video;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,811 +0,0 @@
|
||||
using System.Linq;
|
||||
using SabreTools.Models.Listxml;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// XML serializer for MAME listxml files
|
||||
/// </summary>
|
||||
public partial class Listxml : XmlSerializer<Mame>
|
||||
{
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.M1"/> to <cref="Models.Metadata.MetadataFile"/>
|
||||
/// </summary>
|
||||
public static Models.Metadata.MetadataFile? ConvertToInternalModel(M1? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var metadataFile = new Models.Metadata.MetadataFile
|
||||
{
|
||||
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
|
||||
};
|
||||
|
||||
if (item?.Game != null && item.Game.Any())
|
||||
{
|
||||
metadataFile[Models.Metadata.MetadataFile.MachineKey] = item.Game
|
||||
.Where(g => g != null)
|
||||
.Select(ConvertMachineToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.Mame"/> to <cref="Models.Metadata.MetadataFile"/>
|
||||
/// </summary>
|
||||
public static Models.Metadata.MetadataFile? ConvertToInternalModel(Mame? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var metadataFile = new Models.Metadata.MetadataFile
|
||||
{
|
||||
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
|
||||
};
|
||||
|
||||
if (item?.Game != null && item.Game.Any())
|
||||
{
|
||||
metadataFile[Models.Metadata.MetadataFile.MachineKey] = item.Game
|
||||
.Where(g => g != null)
|
||||
.Select(ConvertMachineToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.M1"/> to <cref="Models.Metadata.Header"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Header ConvertHeaderToInternalModel(M1 item)
|
||||
{
|
||||
var header = new Models.Metadata.Header
|
||||
{
|
||||
[Models.Metadata.Header.VersionKey] = item.Version,
|
||||
};
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.Mame"/> to <cref="Models.Metadata.Header"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Header ConvertHeaderToInternalModel(Mame item)
|
||||
{
|
||||
var header = new Models.Metadata.Header
|
||||
{
|
||||
[Models.Metadata.Header.BuildKey] = item.Build,
|
||||
[Models.Metadata.Header.DebugKey] = item.Debug,
|
||||
[Models.Metadata.Header.MameConfigKey] = item.MameConfig,
|
||||
};
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.GameBase"/> to <cref="Models.Metadata.Machine"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Machine ConvertMachineToInternalModel(GameBase item)
|
||||
{
|
||||
var machine = new Models.Metadata.Machine
|
||||
{
|
||||
[Models.Metadata.Machine.NameKey] = item.Name,
|
||||
[Models.Metadata.Machine.SourceFileKey] = item.SourceFile,
|
||||
[Models.Metadata.Machine.IsBiosKey] = item.IsBios,
|
||||
[Models.Metadata.Machine.IsDeviceKey] = item.IsDevice,
|
||||
[Models.Metadata.Machine.IsMechanicalKey] = item.IsMechanical,
|
||||
[Models.Metadata.Machine.RunnableKey] = item.Runnable,
|
||||
[Models.Metadata.Machine.CloneOfKey] = item.CloneOf,
|
||||
[Models.Metadata.Machine.RomOfKey] = item.RomOf,
|
||||
[Models.Metadata.Machine.SampleOfKey] = item.SampleOf,
|
||||
[Models.Metadata.Machine.DescriptionKey] = item.Description,
|
||||
[Models.Metadata.Machine.YearKey] = item.Year,
|
||||
[Models.Metadata.Machine.ManufacturerKey] = item.Manufacturer,
|
||||
[Models.Metadata.Machine.HistoryKey] = item.History,
|
||||
};
|
||||
|
||||
if (item.BiosSet != null && item.BiosSet.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.BiosSetKey] = item.BiosSet
|
||||
.Where(b => b != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.Rom != null && item.Rom.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.RomKey] = item.Rom
|
||||
.Where(r => r != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.Disk != null && item.Disk.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.DiskKey] = item.Disk
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.DeviceRef != null && item.DeviceRef.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.DeviceRefKey] = item.DeviceRef
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.Sample != null && item.Sample.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.SampleKey] = item.Sample
|
||||
.Where(s => s != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.Chip != null && item.Chip.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.ChipKey] = item.Chip
|
||||
.Where(c => c != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.Display != null && item.Display.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.DisplayKey] = item.Display
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.Video != null && item.Video.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.VideoKey] = item.Video
|
||||
.Where(v => v != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.Sound != null)
|
||||
machine[Models.Metadata.Machine.SoundKey] = ConvertToInternalModel(item.Sound);
|
||||
|
||||
if (item.Input != null)
|
||||
machine[Models.Metadata.Machine.InputKey] = ConvertToInternalModel(item.Input);
|
||||
|
||||
if (item.DipSwitch != null && item.DipSwitch.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.DipSwitchKey] = item.DipSwitch
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.Configuration != null && item.Configuration.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.ConfigurationKey] = item.Configuration
|
||||
.Where(c => c != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.Port != null && item.Port.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.PortKey] = item.Port
|
||||
.Where(p => p != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.Adjuster != null && item.Adjuster.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.AdjusterKey] = item.Adjuster
|
||||
.Where(a => a != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.Driver != null)
|
||||
machine[Models.Metadata.Machine.DriverKey] = ConvertToInternalModel(item.Driver);
|
||||
|
||||
if (item.Feature != null && item.Feature.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.FeatureKey] = item.Feature
|
||||
.Where(f => f != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.Device != null && item.Device.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.DeviceKey] = item.Device
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.Slot != null && item.Slot.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.SlotKey] = item.Slot
|
||||
.Where(s => s != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.SoftwareList != null && item.SoftwareList.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.SoftwareListKey] = item.SoftwareList
|
||||
.Where(s => s != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.RamOption != null && item.RamOption.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.RamOptionKey] = item.RamOption
|
||||
.Where(r => r != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return machine;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.Adjuster"/> to <cref="Models.Metadata.Adjuster"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Adjuster ConvertToInternalModel(Adjuster item)
|
||||
{
|
||||
var adjuster = new Models.Metadata.Adjuster
|
||||
{
|
||||
[Models.Metadata.Adjuster.NameKey] = item.Name,
|
||||
[Models.Metadata.Adjuster.DefaultKey] = item.Default,
|
||||
};
|
||||
|
||||
if (item.Condition != null)
|
||||
adjuster[Models.Metadata.Adjuster.ConditionKey] = ConvertToInternalModel(item.Condition);
|
||||
|
||||
return adjuster;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.Analog"/> to <cref="Models.Metadata.Analog"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Analog ConvertToInternalModel(Analog item)
|
||||
{
|
||||
var analog = new Models.Metadata.Analog
|
||||
{
|
||||
[Models.Metadata.Analog.MaskKey] = item.Mask,
|
||||
};
|
||||
return analog;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.BiosSet"/> to <cref="Models.Metadata.BiosSet"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.BiosSet ConvertToInternalModel(BiosSet item)
|
||||
{
|
||||
var biosset = new Models.Metadata.BiosSet
|
||||
{
|
||||
[Models.Metadata.BiosSet.NameKey] = item.Name,
|
||||
[Models.Metadata.BiosSet.DescriptionKey] = item.Description,
|
||||
[Models.Metadata.BiosSet.DefaultKey] = item.Default,
|
||||
};
|
||||
return biosset;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.Chip"/> to <cref="Models.Metadata.Chip"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Chip ConvertToInternalModel(Chip item)
|
||||
{
|
||||
var chip = new Models.Metadata.Chip
|
||||
{
|
||||
[Models.Metadata.Chip.NameKey] = item.Name,
|
||||
[Models.Metadata.Chip.TagKey] = item.Tag,
|
||||
[Models.Metadata.Chip.TypeKey] = item.Type,
|
||||
[Models.Metadata.Chip.SoundOnlyKey] = item.SoundOnly,
|
||||
[Models.Metadata.Chip.ClockKey] = item.Clock,
|
||||
};
|
||||
return chip;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.Condition"/> to <cref="Models.Metadata.Condition"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Condition ConvertToInternalModel(Condition item)
|
||||
{
|
||||
var condition = new Models.Metadata.Condition
|
||||
{
|
||||
[Models.Metadata.Condition.TagKey] = item.Tag,
|
||||
[Models.Metadata.Condition.MaskKey] = item.Mask,
|
||||
[Models.Metadata.Condition.RelationKey] = item.Relation,
|
||||
[Models.Metadata.Condition.ValueKey] = item.Value,
|
||||
};
|
||||
return condition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.Configuration"/> to <cref="Models.Metadata.Configuration"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Configuration ConvertToInternalModel(Configuration item)
|
||||
{
|
||||
var configuration = new Models.Metadata.Configuration
|
||||
{
|
||||
[Models.Metadata.Configuration.NameKey] = item.Name,
|
||||
[Models.Metadata.Configuration.TagKey] = item.Tag,
|
||||
[Models.Metadata.Configuration.MaskKey] = item.Mask,
|
||||
};
|
||||
|
||||
if (item.Condition != null)
|
||||
configuration[Models.Metadata.Configuration.ConditionKey] = ConvertToInternalModel(item.Condition);
|
||||
|
||||
if (item.ConfLocation != null && item.ConfLocation.Any())
|
||||
{
|
||||
configuration[Models.Metadata.Configuration.ConfLocationKey] = item.ConfLocation
|
||||
.Where(c => c != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.ConfSetting != null && item.ConfSetting.Any())
|
||||
{
|
||||
configuration[Models.Metadata.Configuration.ConfSettingKey] = item.ConfSetting
|
||||
.Where(c => c != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return configuration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.ConfLocation"/> to <cref="Models.Metadata.ConfLocation"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.ConfLocation ConvertToInternalModel(ConfLocation item)
|
||||
{
|
||||
var confLocation = new Models.Metadata.ConfLocation
|
||||
{
|
||||
[Models.Metadata.ConfLocation.NameKey] = item.Name,
|
||||
[Models.Metadata.ConfLocation.NumberKey] = item.Number,
|
||||
[Models.Metadata.ConfLocation.InvertedKey] = item.Inverted,
|
||||
};
|
||||
return confLocation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.ConfSetting"/> to <cref="Models.Metadata.ConfSetting"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.ConfSetting ConvertToInternalModel(ConfSetting item)
|
||||
{
|
||||
var confSetting = new Models.Metadata.ConfSetting
|
||||
{
|
||||
[Models.Metadata.ConfSetting.NameKey] = item.Name,
|
||||
[Models.Metadata.ConfSetting.ValueKey] = item.Value,
|
||||
[Models.Metadata.ConfSetting.DefaultKey] = item.Default,
|
||||
};
|
||||
|
||||
if (item.Condition != null)
|
||||
confSetting[Models.Metadata.ConfSetting.ConditionKey] = ConvertToInternalModel(item.Condition);
|
||||
|
||||
return confSetting;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.Control"/> to <cref="Models.Metadata.Control"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Control ConvertToInternalModel(Control item)
|
||||
{
|
||||
var control = new Models.Metadata.Control
|
||||
{
|
||||
[Models.Metadata.Control.TypeKey] = item.Type,
|
||||
[Models.Metadata.Control.PlayerKey] = item.Player,
|
||||
[Models.Metadata.Control.ButtonsKey] = item.Buttons,
|
||||
[Models.Metadata.Control.ReqButtonsKey] = item.ReqButtons,
|
||||
[Models.Metadata.Control.MinimumKey] = item.Minimum,
|
||||
[Models.Metadata.Control.MaximumKey] = item.Maximum,
|
||||
[Models.Metadata.Control.SensitivityKey] = item.Sensitivity,
|
||||
[Models.Metadata.Control.KeyDeltaKey] = item.KeyDelta,
|
||||
[Models.Metadata.Control.ReverseKey] = item.Reverse,
|
||||
[Models.Metadata.Control.WaysKey] = item.Ways,
|
||||
[Models.Metadata.Control.Ways2Key] = item.Ways2,
|
||||
[Models.Metadata.Control.Ways3Key] = item.Ways3,
|
||||
};
|
||||
return control;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.Device"/> to <cref="Models.Metadata.Device"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Device ConvertToInternalModel(Device item)
|
||||
{
|
||||
var device = new Models.Metadata.Device
|
||||
{
|
||||
[Models.Metadata.Device.TypeKey] = item.Type,
|
||||
[Models.Metadata.Device.TagKey] = item.Tag,
|
||||
[Models.Metadata.Device.FixedImageKey] = item.FixedImage,
|
||||
[Models.Metadata.Device.MandatoryKey] = item.Mandatory,
|
||||
[Models.Metadata.Device.InterfaceKey] = item.Interface,
|
||||
};
|
||||
|
||||
if (item.Instance != null)
|
||||
device[Models.Metadata.Device.InstanceKey] = ConvertToInternalModel(item.Instance);
|
||||
|
||||
if (item.Extension != null && item.Extension.Any())
|
||||
{
|
||||
device[Models.Metadata.Device.ExtensionKey] = item.Extension
|
||||
.Where(e => e != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.DeviceRef"/> to <cref="Models.Metadata.DeviceRef"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.DeviceRef ConvertToInternalModel(DeviceRef item)
|
||||
{
|
||||
var deviceRef = new Models.Metadata.DeviceRef
|
||||
{
|
||||
[Models.Metadata.DeviceRef.NameKey] = item.Name,
|
||||
};
|
||||
return deviceRef;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.DipLocation"/> to <cref="Models.Metadata.DipLocation"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.DipLocation ConvertToInternalModel(DipLocation item)
|
||||
{
|
||||
var dipLocation = new Models.Metadata.DipLocation
|
||||
{
|
||||
[Models.Metadata.DipLocation.NameKey] = item.Name,
|
||||
[Models.Metadata.DipLocation.NumberKey] = item.Number,
|
||||
[Models.Metadata.DipLocation.InvertedKey] = item.Inverted,
|
||||
};
|
||||
return dipLocation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.DipSwitch"/> to <cref="Models.Metadata.DipSwitch"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.DipSwitch ConvertToInternalModel(DipSwitch item)
|
||||
{
|
||||
var dipSwitch = new Models.Metadata.DipSwitch
|
||||
{
|
||||
[Models.Metadata.DipSwitch.NameKey] = item.Name,
|
||||
[Models.Metadata.DipSwitch.TagKey] = item.Tag,
|
||||
[Models.Metadata.DipSwitch.MaskKey] = item.Mask,
|
||||
};
|
||||
|
||||
if (item.Condition != null)
|
||||
dipSwitch[Models.Metadata.DipSwitch.ConditionKey] = ConvertToInternalModel(item.Condition);
|
||||
|
||||
if (item.DipLocation != null && item.DipLocation.Any())
|
||||
{
|
||||
dipSwitch[Models.Metadata.DipSwitch.DipLocationKey] = item.DipLocation
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (item.DipValue != null && item.DipValue.Any())
|
||||
{
|
||||
dipSwitch[Models.Metadata.DipSwitch.DipValueKey] = item.DipValue
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return dipSwitch;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.DipValue"/> to <cref="Models.Metadata.DipValue"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.DipValue ConvertToInternalModel(DipValue item)
|
||||
{
|
||||
var dipValue = new Models.Metadata.DipValue
|
||||
{
|
||||
[Models.Metadata.DipValue.NameKey] = item.Name,
|
||||
[Models.Metadata.DipValue.ValueKey] = item.Value,
|
||||
[Models.Metadata.DipValue.DefaultKey] = item.Default,
|
||||
};
|
||||
|
||||
if (item.Condition != null)
|
||||
dipValue[Models.Metadata.DipValue.ConditionKey] = ConvertToInternalModel(item.Condition);
|
||||
|
||||
return dipValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.Disk"/> to <cref="Models.Metadata.Disk"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Disk ConvertToInternalModel(Disk item)
|
||||
{
|
||||
var disk = new Models.Metadata.Disk
|
||||
{
|
||||
[Models.Metadata.Disk.NameKey] = item.Name,
|
||||
[Models.Metadata.Disk.MD5Key] = item.MD5,
|
||||
[Models.Metadata.Disk.SHA1Key] = item.SHA1,
|
||||
[Models.Metadata.Disk.MergeKey] = item.Merge,
|
||||
[Models.Metadata.Disk.RegionKey] = item.Region,
|
||||
[Models.Metadata.Disk.IndexKey] = item.Index,
|
||||
[Models.Metadata.Disk.WritableKey] = item.Writable,
|
||||
[Models.Metadata.Disk.StatusKey] = item.Status,
|
||||
[Models.Metadata.Disk.OptionalKey] = item.Optional,
|
||||
};
|
||||
return disk;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.Display"/> to <cref="Models.Metadata.Display"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Display ConvertToInternalModel(Display item)
|
||||
{
|
||||
var display = new Models.Metadata.Display
|
||||
{
|
||||
[Models.Metadata.Display.TagKey] = item.Tag,
|
||||
[Models.Metadata.Display.TypeKey] = item.Type,
|
||||
[Models.Metadata.Display.RotateKey] = item.Rotate,
|
||||
[Models.Metadata.Display.FlipXKey] = item.FlipX,
|
||||
[Models.Metadata.Display.WidthKey] = item.Width,
|
||||
[Models.Metadata.Display.HeightKey] = item.Height,
|
||||
[Models.Metadata.Display.RefreshKey] = item.Refresh,
|
||||
[Models.Metadata.Display.PixClockKey] = item.PixClock,
|
||||
[Models.Metadata.Display.HTotalKey] = item.HTotal,
|
||||
[Models.Metadata.Display.HBEndKey] = item.HBEnd,
|
||||
[Models.Metadata.Display.HBStartKey] = item.HBStart,
|
||||
[Models.Metadata.Display.VTotalKey] = item.VTotal,
|
||||
[Models.Metadata.Display.VBEndKey] = item.VBEnd,
|
||||
[Models.Metadata.Display.VBStartKey] = item.VBStart,
|
||||
};
|
||||
return display;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.Driver"/> to <cref="Models.Metadata.Driver"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Driver ConvertToInternalModel(Driver item)
|
||||
{
|
||||
var driver = new Models.Metadata.Driver
|
||||
{
|
||||
[Models.Metadata.Driver.StatusKey] = item.Status,
|
||||
[Models.Metadata.Driver.ColorKey] = item.Color,
|
||||
[Models.Metadata.Driver.SoundKey] = item.Sound,
|
||||
[Models.Metadata.Driver.PaletteSizeKey] = item.PaletteSize,
|
||||
[Models.Metadata.Driver.EmulationKey] = item.Emulation,
|
||||
[Models.Metadata.Driver.CocktailKey] = item.Cocktail,
|
||||
[Models.Metadata.Driver.SaveStateKey] = item.SaveState,
|
||||
[Models.Metadata.Driver.RequiresArtworkKey] = item.RequiresArtwork,
|
||||
[Models.Metadata.Driver.UnofficialKey] = item.Unofficial,
|
||||
[Models.Metadata.Driver.NoSoundHardwareKey] = item.NoSoundHardware,
|
||||
[Models.Metadata.Driver.IncompleteKey] = item.Incomplete,
|
||||
};
|
||||
return driver;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.Extension"/> to <cref="Models.Metadata.Extension"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Extension ConvertToInternalModel(Extension item)
|
||||
{
|
||||
var extension = new Models.Metadata.Extension
|
||||
{
|
||||
[Models.Metadata.Extension.NameKey] = item.Name,
|
||||
};
|
||||
return extension;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.Feature"/> to <cref="Models.Metadata.Feature"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Feature ConvertToInternalModel(Feature item)
|
||||
{
|
||||
var feature = new Models.Metadata.Feature
|
||||
{
|
||||
[Models.Metadata.Feature.TypeKey] = item.Type,
|
||||
[Models.Metadata.Feature.StatusKey] = item.Status,
|
||||
[Models.Metadata.Feature.OverallKey] = item.Overall,
|
||||
};
|
||||
return feature;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.Input"/> to <cref="Models.Metadata.Input"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Input ConvertToInternalModel(Input item)
|
||||
{
|
||||
var input = new Models.Metadata.Input
|
||||
{
|
||||
[Models.Metadata.Input.ServiceKey] = item.Service,
|
||||
[Models.Metadata.Input.TiltKey] = item.Tilt,
|
||||
[Models.Metadata.Input.PlayersKey] = item.Players,
|
||||
[Models.Metadata.Input.ControlKey] = item.ControlAttr,
|
||||
[Models.Metadata.Input.ButtonsKey] = item.Buttons,
|
||||
[Models.Metadata.Input.CoinsKey] = item.Coins,
|
||||
};
|
||||
|
||||
if (item.Control != null && item.Control.Any())
|
||||
{
|
||||
input[Models.Metadata.Input.ControlKey] = item.Control
|
||||
.Where(c => c != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.Instance"/> to <cref="Models.Metadata.Instance"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Instance ConvertToInternalModel(Instance item)
|
||||
{
|
||||
var instance = new Models.Metadata.Instance
|
||||
{
|
||||
[Models.Metadata.Instance.NameKey] = item.Name,
|
||||
[Models.Metadata.Instance.BriefNameKey] = item.BriefName,
|
||||
};
|
||||
return instance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.Port"/> to <cref="Models.Metadata.Port"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Port ConvertToInternalModel(Port item)
|
||||
{
|
||||
var port = new Models.Metadata.Port
|
||||
{
|
||||
[Models.Metadata.Port.TagKey] = item.Tag,
|
||||
};
|
||||
|
||||
if (item.Analog != null && item.Analog.Any())
|
||||
{
|
||||
port[Models.Metadata.Port.AnalogKey] = item.Analog
|
||||
.Where(a => a != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.RamOption"/> to <cref="Models.Metadata.RamOption"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.RamOption ConvertToInternalModel(RamOption item)
|
||||
{
|
||||
var ramOption = new Models.Metadata.RamOption
|
||||
{
|
||||
[Models.Metadata.RamOption.NameKey] = item.Name,
|
||||
[Models.Metadata.RamOption.DefaultKey] = item.Default,
|
||||
[Models.Metadata.RamOption.ContentKey] = item.Content,
|
||||
};
|
||||
return ramOption;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.Rom"/> to <cref="Models.Metadata.Rom"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Rom ConvertToInternalModel(Rom item)
|
||||
{
|
||||
var rom = new Models.Metadata.Rom
|
||||
{
|
||||
[Models.Metadata.Rom.NameKey] = item.Name,
|
||||
[Models.Metadata.Rom.BiosKey] = item.Bios,
|
||||
[Models.Metadata.Rom.SizeKey] = item.Size,
|
||||
[Models.Metadata.Rom.CRCKey] = item.CRC,
|
||||
[Models.Metadata.Rom.SHA1Key] = item.SHA1,
|
||||
[Models.Metadata.Rom.MergeKey] = item.Merge,
|
||||
[Models.Metadata.Rom.RegionKey] = item.Region,
|
||||
[Models.Metadata.Rom.OffsetKey] = item.Offset,
|
||||
[Models.Metadata.Rom.StatusKey] = item.Status,
|
||||
[Models.Metadata.Rom.OptionalKey] = item.Optional,
|
||||
[Models.Metadata.Rom.DisposeKey] = item.Dispose,
|
||||
[Models.Metadata.Rom.SoundOnlyKey] = item.SoundOnly,
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.Sample"/> to <cref="Models.Metadata.Sample"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Sample ConvertToInternalModel(Sample item)
|
||||
{
|
||||
var sample = new Models.Metadata.Sample
|
||||
{
|
||||
[Models.Metadata.Sample.NameKey] = item.Name,
|
||||
};
|
||||
return sample;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.Slot"/> to <cref="Models.Metadata.Slot"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Slot ConvertToInternalModel(Slot item)
|
||||
{
|
||||
var slot = new Models.Metadata.Slot
|
||||
{
|
||||
[Models.Metadata.Slot.NameKey] = item.Name,
|
||||
};
|
||||
|
||||
if (item.SlotOption != null && item.SlotOption.Any())
|
||||
{
|
||||
slot[Models.Metadata.Slot.SlotOptionKey] = item.SlotOption
|
||||
.Where(s => s != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.SlotOption"/> to <cref="Models.Metadata.SlotOption"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.SlotOption ConvertToInternalModel(SlotOption item)
|
||||
{
|
||||
var slotOption = new Models.Metadata.SlotOption
|
||||
{
|
||||
[Models.Metadata.SlotOption.NameKey] = item.Name,
|
||||
[Models.Metadata.SlotOption.DevNameKey] = item.DevName,
|
||||
[Models.Metadata.SlotOption.DefaultKey] = item.Default,
|
||||
};
|
||||
return slotOption;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.SoftwareList"/> to <cref="Models.Metadata.SoftwareList"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.SoftwareList ConvertToInternalModel(SoftwareList item)
|
||||
{
|
||||
var softwareList = new Models.Metadata.SoftwareList
|
||||
{
|
||||
[Models.Metadata.SoftwareList.TagKey] = item.Tag,
|
||||
[Models.Metadata.SoftwareList.NameKey] = item.Name,
|
||||
[Models.Metadata.SoftwareList.StatusKey] = item.Status,
|
||||
[Models.Metadata.SoftwareList.FilterKey] = item.Filter,
|
||||
};
|
||||
return softwareList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.Sound"/> to <cref="Models.Metadata.Sound"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Sound ConvertToInternalModel(Sound item)
|
||||
{
|
||||
var sound = new Models.Metadata.Sound
|
||||
{
|
||||
[Models.Metadata.Sound.ChannelsKey] = item.Channels,
|
||||
};
|
||||
return sound;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Listxml.Video"/> to <cref="Models.Metadata.Video"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Video ConvertToInternalModel(Video item)
|
||||
{
|
||||
var video = new Models.Metadata.Video
|
||||
{
|
||||
[Models.Metadata.Video.ScreenKey] = item.Screen,
|
||||
[Models.Metadata.Video.OrientationKey] = item.Orientation,
|
||||
[Models.Metadata.Video.WidthKey] = item.Width,
|
||||
[Models.Metadata.Video.HeightKey] = item.Height,
|
||||
[Models.Metadata.Video.AspectXKey] = item.AspectX,
|
||||
[Models.Metadata.Video.AspectYKey] = item.AspectY,
|
||||
[Models.Metadata.Video.RefreshKey] = item.Refresh,
|
||||
};
|
||||
return video;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,387 +0,0 @@
|
||||
using System.Linq;
|
||||
using SabreTools.Models.Logiqx;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// XML deserializer for Logiqx-derived metadata files
|
||||
/// </summary>
|
||||
public partial class Logiqx : XmlSerializer<Datafile>
|
||||
{
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.MetadataFile"/> to <cref="Models.Logiqx.Datafile"/>
|
||||
/// </summary>
|
||||
public static Datafile? ConvertFromInternalModel(Models.Metadata.MetadataFile? item, bool game = false)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var datafile = new Datafile
|
||||
{
|
||||
Build = item.ReadString(Models.Metadata.Header.BuildKey),
|
||||
Debug = item.ReadString(Models.Metadata.Header.DebugKey),
|
||||
SchemaLocation = item.ReadString(Models.Metadata.Header.SchemaLocationKey),
|
||||
};
|
||||
|
||||
var header = item.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
|
||||
if (header != null)
|
||||
datafile.Header = ConvertHeaderFromInternalModel(header);
|
||||
|
||||
// TODO: Handle Dir items - Currently need to be generated from the machines
|
||||
var machines = item.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
|
||||
if (machines != null && machines.Any())
|
||||
{
|
||||
datafile.Game = machines
|
||||
.Where(m => m != null)
|
||||
.Select(machine => ConvertMachineFromInternalModel(machine, game))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return datafile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Header"/> to <cref="Models.Logiqx.Header"/>
|
||||
/// </summary>
|
||||
private static Header ConvertHeaderFromInternalModel(Models.Metadata.Header item)
|
||||
{
|
||||
var header = new Header
|
||||
{
|
||||
Id = item.ReadString(Models.Metadata.Header.IdKey),
|
||||
Name = item.ReadString(Models.Metadata.Header.NameKey),
|
||||
Description = item.ReadString(Models.Metadata.Header.DescriptionKey),
|
||||
RootDir = item.ReadString(Models.Metadata.Header.RootDirKey),
|
||||
Category = item.ReadString(Models.Metadata.Header.CategoryKey),
|
||||
Version = item.ReadString(Models.Metadata.Header.VersionKey),
|
||||
Date = item.ReadString(Models.Metadata.Header.DateKey),
|
||||
Author = item.ReadString(Models.Metadata.Header.AuthorKey),
|
||||
Email = item.ReadString(Models.Metadata.Header.EmailKey),
|
||||
Homepage = item.ReadString(Models.Metadata.Header.HomepageKey),
|
||||
Url = item.ReadString(Models.Metadata.Header.UrlKey),
|
||||
Comment = item.ReadString(Models.Metadata.Header.CommentKey),
|
||||
Type = item.ReadString(Models.Metadata.Header.TypeKey),
|
||||
};
|
||||
|
||||
if (item.ContainsKey(Models.Metadata.Header.HeaderKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.ForceMergingKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.ForceNodumpKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.ForcePackingKey))
|
||||
{
|
||||
header.ClrMamePro = new Models.Logiqx.ClrMamePro
|
||||
{
|
||||
Header = item.ReadString(Models.Metadata.Header.HeaderKey),
|
||||
ForceMerging = item.ReadString(Models.Metadata.Header.ForceMergingKey),
|
||||
ForceNodump = item.ReadString(Models.Metadata.Header.ForceNodumpKey),
|
||||
ForcePacking = item.ReadString(Models.Metadata.Header.ForcePackingKey),
|
||||
};
|
||||
}
|
||||
|
||||
if (item.ContainsKey(Models.Metadata.Header.PluginKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.RomModeKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.BiosModeKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.SampleModeKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.LockRomModeKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.LockBiosModeKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.LockSampleModeKey))
|
||||
{
|
||||
header.RomCenter = new Models.Logiqx.RomCenter
|
||||
{
|
||||
Plugin = item.ReadString(Models.Metadata.Header.PluginKey),
|
||||
RomMode = item.ReadString(Models.Metadata.Header.RomModeKey),
|
||||
BiosMode = item.ReadString(Models.Metadata.Header.BiosModeKey),
|
||||
SampleMode = item.ReadString(Models.Metadata.Header.SampleModeKey),
|
||||
LockRomMode = item.ReadString(Models.Metadata.Header.LockRomModeKey),
|
||||
LockBiosMode = item.ReadString(Models.Metadata.Header.LockBiosModeKey),
|
||||
LockSampleMode = item.ReadString(Models.Metadata.Header.LockSampleModeKey),
|
||||
};
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Machine"/> to <cref="Models.Logiqx.GameBase"/>
|
||||
/// </summary>
|
||||
private static GameBase ConvertMachineFromInternalModel(Models.Metadata.Machine item, bool game = false)
|
||||
{
|
||||
GameBase gameBase = game ? new Game() : new Machine();
|
||||
|
||||
gameBase.Name = item.ReadString(Models.Metadata.Machine.NameKey);
|
||||
gameBase.SourceFile = item.ReadString(Models.Metadata.Machine.SourceFileKey);
|
||||
gameBase.IsBios = item.ReadString(Models.Metadata.Machine.IsBiosKey);
|
||||
gameBase.IsDevice = item.ReadString(Models.Metadata.Machine.IsDeviceKey);
|
||||
gameBase.IsMechanical = item.ReadString(Models.Metadata.Machine.IsMechanicalKey);
|
||||
gameBase.CloneOf = item.ReadString(Models.Metadata.Machine.CloneOfKey);
|
||||
gameBase.RomOf = item.ReadString(Models.Metadata.Machine.RomOfKey);
|
||||
gameBase.SampleOf = item.ReadString(Models.Metadata.Machine.SampleOfKey);
|
||||
gameBase.Board = item.ReadString(Models.Metadata.Machine.BoardKey);
|
||||
gameBase.RebuildTo = item.ReadString(Models.Metadata.Machine.RebuildToKey);
|
||||
gameBase.Id = item.ReadString(Models.Metadata.Machine.IdKey);
|
||||
gameBase.CloneOfId = item.ReadString(Models.Metadata.Machine.CloneOfIdKey);
|
||||
gameBase.Runnable = item.ReadString(Models.Metadata.Machine.RunnableKey);
|
||||
gameBase.Comment = item.ReadStringArray(Models.Metadata.Machine.CommentKey);
|
||||
gameBase.Description = item.ReadString(Models.Metadata.Machine.DescriptionKey);
|
||||
gameBase.Year = item.ReadString(Models.Metadata.Machine.YearKey);
|
||||
gameBase.Manufacturer = item.ReadString(Models.Metadata.Machine.ManufacturerKey);
|
||||
gameBase.Publisher = item.ReadString(Models.Metadata.Machine.PublisherKey);
|
||||
gameBase.Category = item.ReadStringArray(Models.Metadata.Machine.CategoryKey);
|
||||
|
||||
var trurip = item.Read<Trurip>(Models.Metadata.Machine.TruripKey);
|
||||
if (trurip != null)
|
||||
gameBase.Trurip = trurip;
|
||||
|
||||
var releases = item.Read<Models.Metadata.Release[]>(Models.Metadata.Machine.ReleaseKey);
|
||||
if (releases != null && releases.Any())
|
||||
{
|
||||
gameBase.Release = releases
|
||||
.Where(r => r != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var biosSets = item.Read<Models.Metadata.BiosSet[]>(Models.Metadata.Machine.BiosSetKey);
|
||||
if (biosSets != null && biosSets.Any())
|
||||
{
|
||||
gameBase.BiosSet = biosSets
|
||||
.Where(b => b != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
|
||||
if (roms != null && roms.Any())
|
||||
{
|
||||
gameBase.Rom = roms
|
||||
.Where(r => r != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var disks = item.Read<Models.Metadata.Disk[]>(Models.Metadata.Machine.DiskKey);
|
||||
if (disks != null && disks.Any())
|
||||
{
|
||||
gameBase.Disk = disks
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var medias = item.Read<Models.Metadata.Media[]>(Models.Metadata.Machine.MediaKey);
|
||||
if (medias != null && medias.Any())
|
||||
{
|
||||
gameBase.Media = medias
|
||||
.Where(m => m != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var deviceRefs = item.Read<Models.Metadata.DeviceRef[]>(Models.Metadata.Machine.DeviceRefKey);
|
||||
if (deviceRefs != null && deviceRefs.Any())
|
||||
{
|
||||
gameBase.DeviceRef = deviceRefs
|
||||
.Where(m => m != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var samples = item.Read<Models.Metadata.Sample[]>(Models.Metadata.Machine.SampleKey);
|
||||
if (samples != null && samples.Any())
|
||||
{
|
||||
gameBase.Sample = samples
|
||||
.Where(m => m != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var archives = item.Read<Models.Metadata.Archive[]>(Models.Metadata.Machine.ArchiveKey);
|
||||
if (archives != null && archives.Any())
|
||||
{
|
||||
gameBase.Archive = archives
|
||||
.Where(m => m != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var driver = item.Read<Models.Metadata.Driver>(Models.Metadata.Machine.DriverKey);
|
||||
if (driver != null)
|
||||
gameBase.Driver = ConvertFromInternalModel(driver);
|
||||
|
||||
var softwareLists = item.Read<Models.Metadata.SoftwareList[]>(Models.Metadata.Machine.SoftwareListKey);
|
||||
if (softwareLists != null && softwareLists.Any())
|
||||
{
|
||||
gameBase.SoftwareList = softwareLists
|
||||
.Where(m => m != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return gameBase;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Archive"/> to <cref="Models.Logiqx.Archive"/>
|
||||
/// </summary>
|
||||
private static Archive ConvertFromInternalModel(Models.Metadata.Archive item)
|
||||
{
|
||||
var archive = new Archive
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Archive.NameKey),
|
||||
};
|
||||
return archive;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.BiosSet"/> to <cref="Models.Logiqx.BiosSet"/>
|
||||
/// </summary>
|
||||
private static BiosSet ConvertFromInternalModel(Models.Metadata.BiosSet item)
|
||||
{
|
||||
var biosset = new BiosSet
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.BiosSet.NameKey),
|
||||
Description = item.ReadString(Models.Metadata.BiosSet.DescriptionKey),
|
||||
Default = item.ReadString(Models.Metadata.BiosSet.DefaultKey),
|
||||
};
|
||||
return biosset;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.DeviceRef"/> to <cref="Models.Logiqx.DeviceRef"/>
|
||||
/// </summary>
|
||||
private static DeviceRef ConvertFromInternalModel(Models.Metadata.DeviceRef item)
|
||||
{
|
||||
var deviceRef = new DeviceRef
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.DipSwitch.NameKey),
|
||||
};
|
||||
return deviceRef;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Disk"/> to <cref="Models.Logiqx.Disk"/>
|
||||
/// </summary>
|
||||
private static Disk ConvertFromInternalModel(Models.Metadata.Disk item)
|
||||
{
|
||||
var disk = new Disk
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Disk.NameKey),
|
||||
MD5 = item.ReadString(Models.Metadata.Disk.MD5Key),
|
||||
SHA1 = item.ReadString(Models.Metadata.Disk.SHA1Key),
|
||||
Merge = item.ReadString(Models.Metadata.Disk.MergeKey),
|
||||
Status = item.ReadString(Models.Metadata.Disk.StatusKey),
|
||||
Region = item.ReadString(Models.Metadata.Disk.RegionKey),
|
||||
};
|
||||
return disk;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Driver"/> to <cref="Models.Logiqx.Driver"/>
|
||||
/// </summary>
|
||||
private static Driver ConvertFromInternalModel(Models.Metadata.Driver item)
|
||||
{
|
||||
var driver = new Driver
|
||||
{
|
||||
Status = item.ReadString(Models.Metadata.Driver.StatusKey),
|
||||
Emulation = item.ReadString(Models.Metadata.Driver.EmulationKey),
|
||||
Cocktail = item.ReadString(Models.Metadata.Driver.CocktailKey),
|
||||
SaveState = item.ReadString(Models.Metadata.Driver.SaveStateKey),
|
||||
RequiresArtwork = item.ReadString(Models.Metadata.Driver.RequiresArtworkKey),
|
||||
Unofficial = item.ReadString(Models.Metadata.Driver.UnofficialKey),
|
||||
NoSoundHardware = item.ReadString(Models.Metadata.Driver.NoSoundHardwareKey),
|
||||
Incomplete = item.ReadString(Models.Metadata.Driver.IncompleteKey),
|
||||
};
|
||||
return driver;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Media"/> to <cref="Models.Logiqx.Media"/>
|
||||
/// </summary>
|
||||
private static Media ConvertFromInternalModel(Models.Metadata.Media item)
|
||||
{
|
||||
var media = new Media
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Media.NameKey),
|
||||
MD5 = item.ReadString(Models.Metadata.Media.MD5Key),
|
||||
SHA1 = item.ReadString(Models.Metadata.Media.SHA1Key),
|
||||
SHA256 = item.ReadString(Models.Metadata.Media.SHA256Key),
|
||||
SpamSum = item.ReadString(Models.Metadata.Media.SpamSumKey),
|
||||
};
|
||||
return media;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Release"/> to <cref="Models.Logiqx.Release"/>
|
||||
/// </summary>
|
||||
private static Release ConvertFromInternalModel(Models.Metadata.Release item)
|
||||
{
|
||||
var release = new Release
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Release.NameKey),
|
||||
Region = item.ReadString(Models.Metadata.Release.RegionKey),
|
||||
Language = item.ReadString(Models.Metadata.Release.LanguageKey),
|
||||
Date = item.ReadString(Models.Metadata.Release.DateKey),
|
||||
Default = item.ReadString(Models.Metadata.Release.DefaultKey),
|
||||
};
|
||||
return release;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.Logiqx.Rom"/>
|
||||
/// </summary>
|
||||
private static Rom ConvertFromInternalModel(Models.Metadata.Rom item)
|
||||
{
|
||||
var rom = new Rom
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Rom.NameKey),
|
||||
Size = item.ReadString(Models.Metadata.Rom.SizeKey),
|
||||
CRC = item.ReadString(Models.Metadata.Rom.CRCKey),
|
||||
MD5 = item.ReadString(Models.Metadata.Rom.MD5Key),
|
||||
SHA1 = item.ReadString(Models.Metadata.Rom.SHA1Key),
|
||||
SHA256 = item.ReadString(Models.Metadata.Rom.SHA256Key),
|
||||
SHA384 = item.ReadString(Models.Metadata.Rom.SHA384Key),
|
||||
SHA512 = item.ReadString(Models.Metadata.Rom.SHA512Key),
|
||||
SpamSum = item.ReadString(Models.Metadata.Rom.SpamSumKey),
|
||||
xxHash364 = item.ReadString(Models.Metadata.Rom.xxHash364Key),
|
||||
xxHash3128 = item.ReadString(Models.Metadata.Rom.xxHash3128Key),
|
||||
Merge = item.ReadString(Models.Metadata.Rom.MergeKey),
|
||||
Status = item.ReadString(Models.Metadata.Rom.StatusKey),
|
||||
Serial = item.ReadString(Models.Metadata.Rom.SerialKey),
|
||||
Header = item.ReadString(Models.Metadata.Rom.HeaderKey),
|
||||
Date = item.ReadString(Models.Metadata.Rom.DateKey),
|
||||
Inverted = item.ReadString(Models.Metadata.Rom.InvertedKey),
|
||||
MIA = item.ReadString(Models.Metadata.Rom.MIAKey),
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Sample"/> to <cref="Models.Logiqx.Sample"/>
|
||||
/// </summary>
|
||||
private static Sample ConvertFromInternalModel(Models.Metadata.Sample item)
|
||||
{
|
||||
var sample = new Sample
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Sample.NameKey),
|
||||
};
|
||||
return sample;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.SoftwareList"/> to <cref="Models.Logiqx.SoftwareList"/>
|
||||
/// </summary>
|
||||
private static SoftwareList ConvertFromInternalModel(Models.Metadata.SoftwareList item)
|
||||
{
|
||||
var softwareList = new SoftwareList
|
||||
{
|
||||
Tag = item.ReadString(Models.Metadata.SoftwareList.TagKey),
|
||||
Name = item.ReadString(Models.Metadata.SoftwareList.NameKey),
|
||||
Status = item.ReadString(Models.Metadata.SoftwareList.StatusKey),
|
||||
Filter = item.ReadString(Models.Metadata.SoftwareList.FilterKey),
|
||||
};
|
||||
return softwareList;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,362 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Models.Logiqx;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// XML serializer for Logiqx-derived metadata files
|
||||
/// </summary>
|
||||
public partial class Logiqx : XmlSerializer<Datafile>
|
||||
{
|
||||
/// <inheritdoc cref="SerializeToFile(Datafile, string, string?, string?, string?, string?)" />
|
||||
public static bool SerializeToFileWithDocType(Datafile obj, string path)
|
||||
=> SerializeToFile(obj, path, DocTypeName, DocTypePubId, DocTypeSysId, DocTypeSysId);
|
||||
|
||||
/// <inheritdoc cref="SerializeToStream(Datafile, string?, string?, string?, string?)" />
|
||||
public static Stream? SerializeToStreamWithDocType(Datafile obj, string path)
|
||||
=> SerializeToStream(obj, DocTypeName, DocTypePubId, DocTypeSysId, DocTypeSysId);
|
||||
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Logiqx.Datafile"/> to <cref="Models.Metadata.MetadataFile"/>
|
||||
/// </summary>
|
||||
public static Models.Metadata.MetadataFile? ConvertToInternalModel(Datafile? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var metadataFile = new Models.Metadata.MetadataFile
|
||||
{
|
||||
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
|
||||
};
|
||||
|
||||
var machines = new List<Models.Metadata.Machine>();
|
||||
|
||||
if (item.Game != null && item.Game.Any())
|
||||
{
|
||||
machines.AddRange(item.Game
|
||||
.Where(g => g != null)
|
||||
.Select(ConvertMachineToInternalModel));
|
||||
}
|
||||
|
||||
if (item.Dir != null && item.Dir.Any())
|
||||
{
|
||||
machines.AddRange(item.Dir
|
||||
.Where(d => d != null)
|
||||
.SelectMany(ConvertDirToInternalModel));
|
||||
}
|
||||
|
||||
if (machines.Any())
|
||||
metadataFile[Models.Metadata.MetadataFile.MachineKey] = machines.ToArray();
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Logiqx.Datafile"/> to <cref="Models.Metadata.Header"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Header ConvertHeaderToInternalModel(Datafile item)
|
||||
{
|
||||
var header = item.Header != null ? ConvertHeaderToInternalModel(item.Header) : new Models.Metadata.Header();
|
||||
|
||||
header[Models.Metadata.Header.BuildKey] = item.Build;
|
||||
header[Models.Metadata.Header.DebugKey] = item.Debug;
|
||||
header[Models.Metadata.Header.SchemaLocationKey] = item.SchemaLocation;
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Logiqx.Header"/> to <cref="Models.Metadata.Header"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Header ConvertHeaderToInternalModel(Header item)
|
||||
{
|
||||
var header = new Models.Metadata.Header
|
||||
{
|
||||
[Models.Metadata.Header.IdKey] = item.Id,
|
||||
[Models.Metadata.Header.NameKey] = item.Name,
|
||||
[Models.Metadata.Header.DescriptionKey] = item.Description,
|
||||
[Models.Metadata.Header.RootDirKey] = item.RootDir,
|
||||
[Models.Metadata.Header.CategoryKey] = item.Category,
|
||||
[Models.Metadata.Header.VersionKey] = item.Version,
|
||||
[Models.Metadata.Header.DateKey] = item.Date,
|
||||
[Models.Metadata.Header.AuthorKey] = item.Author,
|
||||
[Models.Metadata.Header.EmailKey] = item.Email,
|
||||
[Models.Metadata.Header.HomepageKey] = item.Homepage,
|
||||
[Models.Metadata.Header.UrlKey] = item.Url,
|
||||
[Models.Metadata.Header.CommentKey] = item.Comment,
|
||||
[Models.Metadata.Header.TypeKey] = item.Type,
|
||||
};
|
||||
|
||||
if (item.ClrMamePro != null)
|
||||
{
|
||||
header[Models.Metadata.Header.HeaderKey] = item.ClrMamePro.Header;
|
||||
header[Models.Metadata.Header.ForceMergingKey] = item.ClrMamePro.ForceMerging;
|
||||
header[Models.Metadata.Header.ForceNodumpKey] = item.ClrMamePro.ForceNodump;
|
||||
header[Models.Metadata.Header.ForcePackingKey] = item.ClrMamePro.ForcePacking;
|
||||
}
|
||||
|
||||
if (item.RomCenter != null)
|
||||
{
|
||||
header[Models.Metadata.Header.PluginKey] = item.RomCenter.Plugin;
|
||||
header[Models.Metadata.Header.RomModeKey] = item.RomCenter.RomMode;
|
||||
header[Models.Metadata.Header.BiosModeKey] = item.RomCenter.BiosMode;
|
||||
header[Models.Metadata.Header.SampleModeKey] = item.RomCenter.SampleMode;
|
||||
header[Models.Metadata.Header.LockRomModeKey] = item.RomCenter.LockRomMode;
|
||||
header[Models.Metadata.Header.LockBiosModeKey] = item.RomCenter.LockBiosMode;
|
||||
header[Models.Metadata.Header.LockSampleModeKey] = item.RomCenter.LockSampleMode;
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Logiqx.Dir"/> to an array of <cref="Models.Metadata.Machine"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Machine[] ConvertDirToInternalModel(Dir item)
|
||||
{
|
||||
if (item.Game == null || !item.Game.Any())
|
||||
return Array.Empty<Models.Metadata.Machine>();
|
||||
|
||||
return item.Game
|
||||
.Where(g => g != null)
|
||||
.Select(game =>
|
||||
{
|
||||
var machine = ConvertMachineToInternalModel(game);
|
||||
machine[Models.Metadata.Machine.DirNameKey] = item.Name;
|
||||
return machine;
|
||||
})
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Logiqx.GameBase"/> to <cref="Models.Metadata.Machine"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Machine ConvertMachineToInternalModel(GameBase item)
|
||||
{
|
||||
var machine = new Models.Metadata.Machine
|
||||
{
|
||||
[Models.Metadata.Machine.NameKey] = item.Name,
|
||||
[Models.Metadata.Machine.SourceFileKey] = item.SourceFile,
|
||||
[Models.Metadata.Machine.IsBiosKey] = item.IsBios,
|
||||
[Models.Metadata.Machine.IsDeviceKey] = item.IsDevice,
|
||||
[Models.Metadata.Machine.IsMechanicalKey] = item.IsMechanical,
|
||||
[Models.Metadata.Machine.CloneOfKey] = item.CloneOf,
|
||||
[Models.Metadata.Machine.RomOfKey] = item.RomOf,
|
||||
[Models.Metadata.Machine.SampleOfKey] = item.SampleOf,
|
||||
[Models.Metadata.Machine.BoardKey] = item.Board,
|
||||
[Models.Metadata.Machine.RebuildToKey] = item.RebuildTo,
|
||||
[Models.Metadata.Machine.IdKey] = item.Id,
|
||||
[Models.Metadata.Machine.CloneOfIdKey] = item.CloneOfId,
|
||||
[Models.Metadata.Machine.RunnableKey] = item.Runnable,
|
||||
[Models.Metadata.Machine.CommentKey] = item.Comment,
|
||||
[Models.Metadata.Machine.DescriptionKey] = item.Description,
|
||||
[Models.Metadata.Machine.YearKey] = item.Year,
|
||||
[Models.Metadata.Machine.ManufacturerKey] = item.Manufacturer,
|
||||
[Models.Metadata.Machine.PublisherKey] = item.Publisher,
|
||||
[Models.Metadata.Machine.CategoryKey] = item.Category,
|
||||
[Models.Metadata.Machine.TruripKey] = item.Trurip,
|
||||
};
|
||||
|
||||
if (item.Release != null && item.Release.Any())
|
||||
machine[Models.Metadata.Machine.ReleaseKey] = item.Release.Select(ConvertToInternalModel).ToArray();
|
||||
|
||||
if (item.BiosSet != null && item.BiosSet.Any())
|
||||
machine[Models.Metadata.Machine.BiosSetKey] = item.BiosSet.Select(ConvertToInternalModel).ToArray();
|
||||
|
||||
if (item.Rom != null && item.Rom.Any())
|
||||
machine[Models.Metadata.Machine.RomKey] = item.Rom.Select(ConvertToInternalModel).ToArray();
|
||||
|
||||
if (item.Disk != null && item.Disk.Any())
|
||||
machine[Models.Metadata.Machine.DiskKey] = item.Disk.Select(ConvertToInternalModel).ToArray();
|
||||
|
||||
if (item.Media != null && item.Media.Any())
|
||||
machine[Models.Metadata.Machine.MediaKey] = item.Media.Select(ConvertToInternalModel).ToArray();
|
||||
|
||||
if (item.DeviceRef != null && item.DeviceRef.Any())
|
||||
machine[Models.Metadata.Machine.DeviceRefKey] = item.DeviceRef.Select(ConvertToInternalModel).ToArray();
|
||||
|
||||
if (item.Sample != null && item.Sample.Any())
|
||||
machine[Models.Metadata.Machine.SampleKey] = item.Sample.Select(ConvertToInternalModel).ToArray();
|
||||
|
||||
if (item.Archive != null && item.Archive.Any())
|
||||
machine[Models.Metadata.Machine.ArchiveKey] = item.Archive.Select(ConvertToInternalModel).ToArray();
|
||||
|
||||
if (item.Driver != null)
|
||||
machine[Models.Metadata.Machine.DriverKey] = ConvertToInternalModel(item.Driver);
|
||||
|
||||
if (item.SoftwareList != null && item.SoftwareList.Any())
|
||||
machine[Models.Metadata.Machine.SoftwareListKey] = item.SoftwareList.Select(ConvertToInternalModel).ToArray();
|
||||
|
||||
return machine;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Logiqx.Archive"/> to <cref="Models.Metadata.Archive"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Archive ConvertToInternalModel(Archive item)
|
||||
{
|
||||
var archive = new Models.Metadata.Archive
|
||||
{
|
||||
[Models.Metadata.Archive.NameKey] = item.Name,
|
||||
};
|
||||
return archive;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Logiqx.BiosSet"/> to <cref="Models.Metadata.BiosSet"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.BiosSet ConvertToInternalModel(BiosSet item)
|
||||
{
|
||||
var biosset = new Models.Metadata.BiosSet
|
||||
{
|
||||
[Models.Metadata.BiosSet.NameKey] = item.Name,
|
||||
[Models.Metadata.BiosSet.DescriptionKey] = item.Description,
|
||||
[Models.Metadata.BiosSet.DefaultKey] = item.Default,
|
||||
};
|
||||
return biosset;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Logiqx.DeviceRef"/> to <cref="Models.Metadata.DeviceRef"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.DeviceRef ConvertToInternalModel(DeviceRef item)
|
||||
{
|
||||
var deviceRef = new Models.Metadata.DeviceRef
|
||||
{
|
||||
[Models.Metadata.DeviceRef.NameKey] = item.Name,
|
||||
};
|
||||
return deviceRef;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Logiqx.Disk"/> to <cref="Models.Metadata.Disk"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Disk ConvertToInternalModel(Disk item)
|
||||
{
|
||||
var disk = new Models.Metadata.Disk
|
||||
{
|
||||
[Models.Metadata.Disk.NameKey] = item.Name,
|
||||
[Models.Metadata.Disk.MD5Key] = item.MD5,
|
||||
[Models.Metadata.Disk.SHA1Key] = item.SHA1,
|
||||
[Models.Metadata.Disk.MergeKey] = item.Merge,
|
||||
[Models.Metadata.Disk.StatusKey] = item.Status,
|
||||
[Models.Metadata.Disk.RegionKey] = item.Region,
|
||||
};
|
||||
return disk;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Logiqx.Driver"/> to <cref="Models.Metadata.Driver"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Driver ConvertToInternalModel(Driver item)
|
||||
{
|
||||
var driver = new Models.Metadata.Driver
|
||||
{
|
||||
[Models.Metadata.Driver.StatusKey] = item.Status,
|
||||
[Models.Metadata.Driver.EmulationKey] = item.Emulation,
|
||||
[Models.Metadata.Driver.CocktailKey] = item.Cocktail,
|
||||
[Models.Metadata.Driver.SaveStateKey] = item.SaveState,
|
||||
[Models.Metadata.Driver.RequiresArtworkKey] = item.RequiresArtwork,
|
||||
[Models.Metadata.Driver.UnofficialKey] = item.Unofficial,
|
||||
[Models.Metadata.Driver.NoSoundHardwareKey] = item.NoSoundHardware,
|
||||
[Models.Metadata.Driver.IncompleteKey] = item.Incomplete,
|
||||
};
|
||||
return driver;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Logiqx.Media"/> to <cref="Models.Metadata.Media"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Media ConvertToInternalModel(Media item)
|
||||
{
|
||||
var media = new Models.Metadata.Media
|
||||
{
|
||||
[Models.Metadata.Media.NameKey] = item.Name,
|
||||
[Models.Metadata.Media.MD5Key] = item.MD5,
|
||||
[Models.Metadata.Media.SHA1Key] = item.SHA1,
|
||||
[Models.Metadata.Media.SHA256Key] = item.SHA256,
|
||||
[Models.Metadata.Media.SpamSumKey] = item.SpamSum,
|
||||
};
|
||||
return media;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Logiqx.Release"/> to <cref="Models.Metadata.Release"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Release ConvertToInternalModel(Release item)
|
||||
{
|
||||
var release = new Models.Metadata.Release
|
||||
{
|
||||
[Models.Metadata.Release.NameKey] = item.Name,
|
||||
[Models.Metadata.Release.RegionKey] = item.Region,
|
||||
[Models.Metadata.Release.LanguageKey] = item.Language,
|
||||
[Models.Metadata.Release.DateKey] = item.Date,
|
||||
[Models.Metadata.Release.DefaultKey] = item.Default,
|
||||
};
|
||||
return release;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Logiqx.Rom"/> to <cref="Models.Metadata.Rom"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Rom ConvertToInternalModel(Rom item)
|
||||
{
|
||||
var rom = new Models.Metadata.Rom
|
||||
{
|
||||
[Models.Metadata.Rom.NameKey] = item.Name,
|
||||
[Models.Metadata.Rom.SizeKey] = item.Size,
|
||||
[Models.Metadata.Rom.CRCKey] = item.CRC,
|
||||
[Models.Metadata.Rom.MD5Key] = item.MD5,
|
||||
[Models.Metadata.Rom.SHA1Key] = item.SHA1,
|
||||
[Models.Metadata.Rom.SHA256Key] = item.SHA256,
|
||||
[Models.Metadata.Rom.SHA384Key] = item.SHA384,
|
||||
[Models.Metadata.Rom.SHA512Key] = item.SHA512,
|
||||
[Models.Metadata.Rom.SpamSumKey] = item.SpamSum,
|
||||
[Models.Metadata.Rom.xxHash364Key] = item.xxHash364,
|
||||
[Models.Metadata.Rom.xxHash3128Key] = item.xxHash3128,
|
||||
[Models.Metadata.Rom.MergeKey] = item.Merge,
|
||||
[Models.Metadata.Rom.StatusKey] = item.Status,
|
||||
[Models.Metadata.Rom.SerialKey] = item.Serial,
|
||||
[Models.Metadata.Rom.HeaderKey] = item.Header,
|
||||
[Models.Metadata.Rom.DateKey] = item.Date,
|
||||
[Models.Metadata.Rom.InvertedKey] = item.Inverted,
|
||||
[Models.Metadata.Rom.MIAKey] = item.MIA,
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Logiqx.Sample"/> to <cref="Models.Metadata.Sample"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Sample ConvertToInternalModel(Sample item)
|
||||
{
|
||||
var sample = new Models.Metadata.Sample
|
||||
{
|
||||
[Models.Metadata.Sample.NameKey] = item.Name,
|
||||
};
|
||||
return sample;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Logiqx.SoftwareList"/> to <cref="Models.Metadata.SoftwareList"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.SoftwareList ConvertToInternalModel(SoftwareList item)
|
||||
{
|
||||
var softwareList = new Models.Metadata.SoftwareList
|
||||
{
|
||||
[Models.Metadata.SoftwareList.TagKey] = item.Tag,
|
||||
[Models.Metadata.SoftwareList.NameKey] = item.Name,
|
||||
[Models.Metadata.SoftwareList.StatusKey] = item.Status,
|
||||
[Models.Metadata.SoftwareList.FilterKey] = item.Filter,
|
||||
};
|
||||
return softwareList;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// XML deserializer for Logiqx-derived metadata files
|
||||
/// </summary>
|
||||
public partial class Logiqx : XmlSerializer<Models.Logiqx.Datafile>
|
||||
{
|
||||
/// <summary>
|
||||
/// name field for DOCTYPE
|
||||
/// </summary>
|
||||
public const string? DocTypeName = "datafile";
|
||||
|
||||
/// <summary>
|
||||
/// pubid field for DOCTYPE
|
||||
/// </summary>
|
||||
public const string? DocTypePubId = "-//Logiqx//DTD ROM Management Datafile//EN";
|
||||
|
||||
/// <summary>
|
||||
/// sysid field for DOCTYPE
|
||||
/// </summary>
|
||||
public const string? DocTypeSysId = "http://www.logiqx.com/Dats/datafile.dtd";
|
||||
|
||||
/// <summary>
|
||||
/// subset field for DOCTYPE
|
||||
/// </summary>
|
||||
public const string? DocTypeSubset = null;
|
||||
}
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
using System.Linq;
|
||||
using SabreTools.Models.OfflineList;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// XML deserializer for OfflineList metadata files
|
||||
/// </summary>
|
||||
public partial class OfflineList : XmlSerializer<Dat>
|
||||
{
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.MetadataFile"/> to <cref="Models.OfflineList.Dat"/>
|
||||
/// </summary>
|
||||
public static Dat? ConvertFromInternalModel(Models.Metadata.MetadataFile? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var header = item.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
|
||||
var dat = header != null ? ConvertHeaderFromInternalModel(header) : new Dat();
|
||||
|
||||
var machines = item.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
|
||||
if (machines != null && machines.Any())
|
||||
{
|
||||
dat.Games = new Games
|
||||
{
|
||||
Game = machines
|
||||
.Where(m => m != null)
|
||||
.Select(ConvertMachineFromInternalModel)
|
||||
.ToArray()
|
||||
};
|
||||
}
|
||||
|
||||
return dat;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Header"/> to <cref="Models.OfflineList.Dat"/>
|
||||
/// </summary>
|
||||
private static Dat ConvertHeaderFromInternalModel(Models.Metadata.Header item)
|
||||
{
|
||||
var dat = new Dat
|
||||
{
|
||||
NoNamespaceSchemaLocation = item.ReadString(Models.Metadata.Header.SchemaLocationKey),
|
||||
};
|
||||
|
||||
if (item.ContainsKey(Models.Metadata.Header.NameKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.ImFolderKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.DatVersionKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.SystemKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.ScreenshotsWidthKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.ScreenshotsHeightKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.InfosKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.CanOpenKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.NewDatKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.SearchKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.RomTitleKey))
|
||||
{
|
||||
dat.Configuration = new Configuration
|
||||
{
|
||||
DatName = item.ReadString(Models.Metadata.Header.NameKey),
|
||||
ImFolder = item.ReadString(Models.Metadata.Header.ImFolderKey),
|
||||
DatVersion = item.ReadString(Models.Metadata.Header.DatVersionKey),
|
||||
System = item.ReadString(Models.Metadata.Header.SystemKey),
|
||||
ScreenshotsWidth = item.ReadString(Models.Metadata.Header.ScreenshotsWidthKey),
|
||||
ScreenshotsHeight = item.ReadString(Models.Metadata.Header.ScreenshotsHeightKey),
|
||||
Infos = item.Read<Infos>(Models.Metadata.Header.InfosKey),
|
||||
CanOpen = item.Read<CanOpen>(Models.Metadata.Header.CanOpenKey),
|
||||
NewDat = item.Read<NewDat>(Models.Metadata.Header.NewDatKey),
|
||||
Search = item.Read<Search>(Models.Metadata.Header.SearchKey),
|
||||
RomTitle = item.ReadString(Models.Metadata.Header.RomTitleKey),
|
||||
};
|
||||
}
|
||||
|
||||
if (item.ContainsKey(Models.Metadata.Header.ImagesKey))
|
||||
{
|
||||
dat.GUI = new GUI
|
||||
{
|
||||
Images = item.Read<Images>(Models.Metadata.Header.ImagesKey),
|
||||
};
|
||||
}
|
||||
|
||||
return dat;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Machine"/> to <cref="Models.OfflineList.Game"/>
|
||||
/// </summary>
|
||||
private static Game ConvertMachineFromInternalModel(Models.Metadata.Machine item)
|
||||
{
|
||||
var game = new Game
|
||||
{
|
||||
ImageNumber = item.ReadString(Models.Metadata.Machine.ImageNumberKey),
|
||||
ReleaseNumber = item.ReadString(Models.Metadata.Machine.ReleaseNumberKey),
|
||||
Title = item.ReadString(Models.Metadata.Machine.NameKey),
|
||||
SaveType = item.ReadString(Models.Metadata.Machine.SaveTypeKey),
|
||||
Publisher = item.ReadString(Models.Metadata.Machine.PublisherKey),
|
||||
Location = item.ReadString(Models.Metadata.Machine.LocationKey),
|
||||
SourceRom = item.ReadString(Models.Metadata.Machine.SourceRomKey),
|
||||
Language = item.ReadString(Models.Metadata.Machine.LanguageKey),
|
||||
Im1CRC = item.ReadString(Models.Metadata.Machine.Im1CRCKey),
|
||||
Im2CRC = item.ReadString(Models.Metadata.Machine.Im2CRCKey),
|
||||
Comment = item.ReadString(Models.Metadata.Machine.CommentKey),
|
||||
DuplicateID = item.ReadString(Models.Metadata.Machine.DuplicateIDKey),
|
||||
};
|
||||
|
||||
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
|
||||
if (roms != null && roms.Any())
|
||||
{
|
||||
game.RomSize = roms
|
||||
.Select(rom => rom.ReadString(Models.Metadata.Rom.SizeKey))
|
||||
.FirstOrDefault(s => s != null);
|
||||
|
||||
var romCRCs = roms
|
||||
.Where(r => r != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
|
||||
game.Files = new Files { RomCRC = romCRCs };
|
||||
}
|
||||
|
||||
return game;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.OfflineList.FileRomCRC"/>
|
||||
/// </summary>
|
||||
private static FileRomCRC ConvertFromInternalModel(Models.Metadata.Rom item)
|
||||
{
|
||||
var fileRomCRC = new FileRomCRC
|
||||
{
|
||||
Extension = item.ReadString(Models.Metadata.Rom.ExtensionKey),
|
||||
Content = item.ReadString(Models.Metadata.Rom.CRCKey),
|
||||
};
|
||||
return fileRomCRC;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
using System.Linq;
|
||||
using SabreTools.Models.OfflineList;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// XML serializer for OfflineList metadata files
|
||||
/// </summary>
|
||||
public partial class OfflineList : XmlSerializer<Dat>
|
||||
{
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.OfflineList.Dat"/> to <cref="Models.Metadata.MetadataFile"/>
|
||||
/// </summary>
|
||||
public static Models.Metadata.MetadataFile? ConvertToInternalModel(Dat? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var metadataFile = new Models.Metadata.MetadataFile
|
||||
{
|
||||
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
|
||||
};
|
||||
|
||||
if (item?.Games?.Game != null && item.Games.Game.Any())
|
||||
{
|
||||
metadataFile[Models.Metadata.MetadataFile.MachineKey] = item.Games.Game
|
||||
.Where(g => g != null)
|
||||
.Select(ConvertMachineToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.OfflineList.Dat"/> to <cref="Models.Metadata.Header"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Header ConvertHeaderToInternalModel(Dat item)
|
||||
{
|
||||
var header = new Models.Metadata.Header
|
||||
{
|
||||
[Models.Metadata.Header.SchemaLocationKey] = item.NoNamespaceSchemaLocation,
|
||||
};
|
||||
|
||||
if (item.Configuration != null)
|
||||
{
|
||||
header[Models.Metadata.Header.NameKey] = item.Configuration.DatName;
|
||||
header[Models.Metadata.Header.ImFolderKey] = item.Configuration.ImFolder;
|
||||
header[Models.Metadata.Header.DatVersionKey] = item.Configuration.DatVersion;
|
||||
header[Models.Metadata.Header.SystemKey] = item.Configuration.System;
|
||||
header[Models.Metadata.Header.ScreenshotsWidthKey] = item.Configuration.ScreenshotsWidth;
|
||||
header[Models.Metadata.Header.ScreenshotsHeightKey] = item.Configuration.ScreenshotsHeight;
|
||||
header[Models.Metadata.Header.InfosKey] = item.Configuration.Infos;
|
||||
header[Models.Metadata.Header.CanOpenKey] = item.Configuration.CanOpen;
|
||||
header[Models.Metadata.Header.NewDatKey] = item.Configuration.NewDat;
|
||||
header[Models.Metadata.Header.SearchKey] = item.Configuration.Search;
|
||||
header[Models.Metadata.Header.RomTitleKey] = item.Configuration.RomTitle;
|
||||
}
|
||||
|
||||
if (item.GUI != null)
|
||||
{
|
||||
header[Models.Metadata.Header.ImagesKey] = item.GUI.Images;
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.OfflineList.Game"/> to <cref="Models.Metadata.Machine"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Machine ConvertMachineToInternalModel(Game item)
|
||||
{
|
||||
var machine = new Models.Metadata.Machine
|
||||
{
|
||||
[Models.Metadata.Machine.ImageNumberKey] = item.ImageNumber,
|
||||
[Models.Metadata.Machine.ReleaseNumberKey] = item.ReleaseNumber,
|
||||
[Models.Metadata.Machine.NameKey] = item.Title,
|
||||
[Models.Metadata.Machine.SaveTypeKey] = item.SaveType,
|
||||
[Models.Metadata.Machine.PublisherKey] = item.Publisher,
|
||||
[Models.Metadata.Machine.LocationKey] = item.Location,
|
||||
[Models.Metadata.Machine.SourceRomKey] = item.SourceRom,
|
||||
[Models.Metadata.Machine.LanguageKey] = item.Language,
|
||||
[Models.Metadata.Machine.Im1CRCKey] = item.Im1CRC,
|
||||
[Models.Metadata.Machine.Im2CRCKey] = item.Im2CRC,
|
||||
[Models.Metadata.Machine.CommentKey] = item.Comment,
|
||||
[Models.Metadata.Machine.DuplicateIDKey] = item.DuplicateID,
|
||||
};
|
||||
|
||||
if (item.Files?.RomCRC != null && item.Files.RomCRC.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.RomKey] = item.Files.RomCRC
|
||||
.Where(r => r != null)
|
||||
.Select(romCRC =>
|
||||
{
|
||||
var rom = ConvertToInternalModel(romCRC);
|
||||
rom[Models.Metadata.Rom.SizeKey] = item.RomSize;
|
||||
return rom;
|
||||
})
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return machine;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.OfflineList.FileRomCRC"/> to <cref="Models.Metadata.Rom"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Rom ConvertToInternalModel(FileRomCRC item)
|
||||
{
|
||||
var rom = new Models.Metadata.Rom
|
||||
{
|
||||
[Models.Metadata.Rom.ExtensionKey] = item.Extension,
|
||||
[Models.Metadata.Rom.CRCKey] = item.Content,
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,161 +0,0 @@
|
||||
using System.Linq;
|
||||
using SabreTools.Models.OpenMSX;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// XML deserializer for OpenMSX software database files
|
||||
/// </summary>
|
||||
public partial class OpenMSX : XmlSerializer<SoftwareDb>
|
||||
{
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.MetadataFile"/> to <cref="Models.OpenMSX.SoftwareDb"/>
|
||||
/// </summary>
|
||||
public static SoftwareDb? ConvertFromInternalModel(Models.Metadata.MetadataFile? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var header = item.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
|
||||
var softwareDb = header != null ? ConvertHeaderFromInternalModel(header) : new SoftwareDb();
|
||||
|
||||
var machines = item.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
|
||||
if (machines != null && machines.Any())
|
||||
{
|
||||
softwareDb.Software = machines
|
||||
.Where(m => m != null)
|
||||
.Select(ConvertMachineFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return softwareDb;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Header"/> to <cref="Models.OpenMSX.SoftwareDb"/>
|
||||
/// </summary>
|
||||
private static SoftwareDb ConvertHeaderFromInternalModel(Models.Metadata.Header item)
|
||||
{
|
||||
var softwareDb = new SoftwareDb
|
||||
{
|
||||
Timestamp = item.ReadString(Models.Metadata.Header.TimestampKey),
|
||||
};
|
||||
return softwareDb;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Machine"/> to <cref="Models.OpenMSX.Software"/>
|
||||
/// </summary>
|
||||
private static Software ConvertMachineFromInternalModel(Models.Metadata.Machine item)
|
||||
{
|
||||
var game = new Software
|
||||
{
|
||||
Title = item.ReadString(Models.Metadata.Machine.NameKey),
|
||||
GenMSXID = item.ReadString(Models.Metadata.Machine.GenMSXIDKey),
|
||||
System = item.ReadString(Models.Metadata.Machine.SystemKey),
|
||||
Company = item.ReadString(Models.Metadata.Machine.CompanyKey),
|
||||
Year = item.ReadString(Models.Metadata.Machine.YearKey),
|
||||
Country = item.ReadString(Models.Metadata.Machine.CountryKey),
|
||||
};
|
||||
|
||||
var dumps = item.Read<Models.Metadata.Dump[]>(Models.Metadata.Machine.DumpKey);
|
||||
if (dumps != null && dumps.Any())
|
||||
{
|
||||
game.Dump = dumps
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return game;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Dump"/> to <cref="Models.OpenMSX.Dump"/>
|
||||
/// </summary>
|
||||
private static Dump ConvertFromInternalModel(Models.Metadata.Dump item)
|
||||
{
|
||||
var dump = new Dump();
|
||||
|
||||
var original = item.Read<Models.Metadata.Original>(Models.Metadata.Dump.OriginalKey);
|
||||
if (original != null)
|
||||
dump.Original = ConvertFromInternalModel(original);
|
||||
|
||||
var rom = item.Read<Models.Metadata.Rom>(Models.Metadata.Dump.RomKey);
|
||||
if (rom != null)
|
||||
dump.Rom = ConvertRomFromInternalModel(rom);
|
||||
|
||||
var megaRom = item.Read<Models.Metadata.Rom>(Models.Metadata.Dump.MegaRomKey);
|
||||
if (megaRom != null)
|
||||
dump.Rom = ConvertMegaRomFromInternalModel(megaRom);
|
||||
|
||||
var sccPlusCart = item.Read<Models.Metadata.Rom>(Models.Metadata.Dump.SCCPlusCartKey);
|
||||
if (sccPlusCart != null)
|
||||
dump.Rom = ConvertSCCPlusCartFromInternalModel(sccPlusCart);
|
||||
|
||||
return dump;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.OpenMSX.MegaRom"/>
|
||||
/// </summary>
|
||||
private static MegaRom ConvertMegaRomFromInternalModel(Models.Metadata.Rom item)
|
||||
{
|
||||
var megaRom = new MegaRom
|
||||
{
|
||||
Start = item.ReadString(Models.Metadata.Rom.StartKey),
|
||||
Type = item.ReadString(Models.Metadata.Rom.TypeKey),
|
||||
Hash = item.ReadString(Models.Metadata.Rom.SHA1Key),
|
||||
Remark = item.ReadString(Models.Metadata.Rom.RemarkKey),
|
||||
};
|
||||
return megaRom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Original"/> to <cref="Models.OpenMSX.Original"/>
|
||||
/// </summary>
|
||||
private static Original ConvertFromInternalModel(Models.Metadata.Original item)
|
||||
{
|
||||
var original = new Original
|
||||
{
|
||||
Value = item.ReadString(Models.Metadata.Original.ValueKey),
|
||||
Content = item.ReadString(Models.Metadata.Original.ContentKey),
|
||||
};
|
||||
return original;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.OpenMSX.Rom"/>
|
||||
/// </summary>
|
||||
private static Rom ConvertRomFromInternalModel(Models.Metadata.Rom item)
|
||||
{
|
||||
var rom = new Rom
|
||||
{
|
||||
Start = item.ReadString(Models.Metadata.Rom.StartKey),
|
||||
Type = item.ReadString(Models.Metadata.Rom.TypeKey),
|
||||
Hash = item.ReadString(Models.Metadata.Rom.SHA1Key),
|
||||
Remark = item.ReadString(Models.Metadata.Rom.RemarkKey),
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.OpenMSX.SCCPlusCart"/>
|
||||
/// </summary>
|
||||
private static SCCPlusCart ConvertSCCPlusCartFromInternalModel(Models.Metadata.Rom item)
|
||||
{
|
||||
var sccPlusCart = new SCCPlusCart
|
||||
{
|
||||
Start = item.ReadString(Models.Metadata.Rom.StartKey),
|
||||
Type = item.ReadString(Models.Metadata.Rom.TypeKey),
|
||||
Hash = item.ReadString(Models.Metadata.Rom.SHA1Key),
|
||||
Remark = item.ReadString(Models.Metadata.Rom.RemarkKey),
|
||||
};
|
||||
return sccPlusCart;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Models.OpenMSX;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// XML serializer for OpenMSX software database files
|
||||
/// </summary>
|
||||
public partial class OpenMSX : XmlSerializer<SoftwareDb>
|
||||
{
|
||||
/// <inheritdoc cref="SerializeToFile(SoftwareDb, string, string?, string?, string?, string?)" />
|
||||
public static bool SerializeToFileWithDocType(SoftwareDb obj, string path)
|
||||
=> SerializeToFile(obj, path, DocTypeName, DocTypePubId, DocTypeSysId, DocTypeSysId);
|
||||
|
||||
/// <inheritdoc cref="SerializeToStream(SoftwareDb, string?, string?, string?, string?)" />
|
||||
public static Stream? SerializeToStreamWithDocType(SoftwareDb obj, string path)
|
||||
=> SerializeToStream(obj, DocTypeName, DocTypePubId, DocTypeSysId, DocTypeSysId);
|
||||
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.OpenMSX.SoftwareDb"/> to <cref="Models.Metadata.MetadataFile"/>
|
||||
/// </summary>
|
||||
public static Models.Metadata.MetadataFile? ConvertToInternalModel(SoftwareDb? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var metadataFile = new Models.Metadata.MetadataFile
|
||||
{
|
||||
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
|
||||
};
|
||||
|
||||
if (item?.Software != null && item.Software.Any())
|
||||
{
|
||||
metadataFile[Models.Metadata.MetadataFile.MachineKey] = item.Software
|
||||
.Where(s => s != null)
|
||||
.Select(ConvertMachineToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.OpenMSX.SoftwareDb"/> to <cref="Models.Metadata.Header"/>
|
||||
/// </summary>
|
||||
public static Models.Metadata.Header ConvertHeaderToInternalModel(SoftwareDb item)
|
||||
{
|
||||
var header = new Models.Metadata.Header
|
||||
{
|
||||
[Models.Metadata.Header.TimestampKey] = item.Timestamp,
|
||||
};
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.OpenMSX.Software"/> to <cref="Models.Metadata.Machine"/>
|
||||
/// </summary>
|
||||
public static Models.Metadata.Machine ConvertMachineToInternalModel(Software item)
|
||||
{
|
||||
var machine = new Models.Metadata.Machine
|
||||
{
|
||||
[Models.Metadata.Machine.NameKey] = item.Title,
|
||||
[Models.Metadata.Machine.GenMSXIDKey] = item.GenMSXID,
|
||||
[Models.Metadata.Machine.SystemKey] = item.System,
|
||||
[Models.Metadata.Machine.CompanyKey] = item.Company,
|
||||
[Models.Metadata.Machine.YearKey] = item.Year,
|
||||
[Models.Metadata.Machine.CountryKey] = item.Country,
|
||||
};
|
||||
|
||||
if (item.Dump != null && item.Dump.Any())
|
||||
{
|
||||
machine[Models.Metadata.Machine.DumpKey] = item.Dump
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return machine;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.OpenMSX.Dump"/> to <cref="Models.Metadata.Dump"/>
|
||||
/// </summary>
|
||||
public static Models.Metadata.Dump ConvertToInternalModel(Dump item)
|
||||
{
|
||||
var dump = new Models.Metadata.Dump();
|
||||
|
||||
if (item.Original != null)
|
||||
dump[Models.Metadata.Dump.OriginalKey] = ConvertToInternalModel(item.Original);
|
||||
|
||||
if (item.Rom != null)
|
||||
{
|
||||
switch (item.Rom)
|
||||
{
|
||||
case Rom rom:
|
||||
dump[Models.Metadata.Dump.RomKey] = ConvertToInternalModel(rom);
|
||||
break;
|
||||
|
||||
case MegaRom megaRom:
|
||||
dump[Models.Metadata.Dump.MegaRomKey] = ConvertToInternalModel(megaRom);
|
||||
break;
|
||||
|
||||
case SCCPlusCart sccPlusCart:
|
||||
dump[Models.Metadata.Dump.SCCPlusCartKey] = ConvertToInternalModel(sccPlusCart);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return dump;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.OpenMSX.Original"/> to <cref="Models.Metadata.Rom"/>
|
||||
/// </summary>
|
||||
public static Models.Metadata.Original ConvertToInternalModel(Original item)
|
||||
{
|
||||
var original = new Models.Metadata.Original
|
||||
{
|
||||
[Models.Metadata.Original.ValueKey] = item.Value,
|
||||
[Models.Metadata.Original.ContentKey] = item.Content,
|
||||
};
|
||||
return original;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.OpenMSX.RomBase"/> to <cref="Models.Metadata.Rom"/>
|
||||
/// </summary>
|
||||
public static Models.Metadata.Rom ConvertToInternalModel(RomBase item)
|
||||
{
|
||||
var rom = new Models.Metadata.Rom
|
||||
{
|
||||
[Models.Metadata.Rom.StartKey] = item.Start,
|
||||
[Models.Metadata.Rom.TypeKey] = item.Type,
|
||||
[Models.Metadata.Rom.SHA1Key] = item.Hash,
|
||||
[Models.Metadata.Rom.RemarkKey] = item.Remark,
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// XML deserializer for OpenMSX software database files
|
||||
/// </summary>
|
||||
public partial class OpenMSX : XmlSerializer<Models.OpenMSX.SoftwareDb>
|
||||
{
|
||||
/// <summary>
|
||||
/// name field for DOCTYPE
|
||||
/// </summary>
|
||||
public const string? DocTypeName = "softwaredb";
|
||||
|
||||
/// <summary>
|
||||
/// pubid field for DOCTYPE
|
||||
/// </summary>
|
||||
public const string? DocTypePubId = null;
|
||||
|
||||
/// <summary>
|
||||
/// sysid field for DOCTYPE
|
||||
/// </summary>
|
||||
public const string? DocTypeSysId = "softwaredb1.dtd";
|
||||
|
||||
/// <summary>
|
||||
/// subset field for DOCTYPE
|
||||
/// </summary>
|
||||
public const string? DocTypeSubset = null;
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
internal class PathProcessor
|
||||
{
|
||||
/// <summary>
|
||||
/// Opens a path as a stream in a safe manner, decompressing if needed
|
||||
/// </summary>
|
||||
/// <param name="path">Path to open as a stream</param>
|
||||
/// <returns>Stream representing the file, null on error</returns>
|
||||
public static Stream? OpenStream(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
// If we don't have a file
|
||||
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
|
||||
return null;
|
||||
|
||||
// Open the file for deserialization
|
||||
var stream = File.OpenRead(path);
|
||||
|
||||
// Get the extension to determine if additional handling is needed
|
||||
string ext = Path.GetExtension(path).TrimStart('.');
|
||||
|
||||
// Determine what we do based on the extension
|
||||
if (string.Equals(ext, "gz", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new GZipStream(stream, CompressionMode.Decompress);
|
||||
}
|
||||
else if (string.Equals(ext, "zip", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// TODO: Support zip-compressed files
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// TODO: Handle logging the exception
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
# SabreTools.Serialization
|
||||
|
||||
This library comprises of serializers that both read and write from files and streams to the dedicated models as well as convert to and from the common internal models. This library is partially used by the current parsing and writing code but none of the internal model serialization is used.
|
||||
@@ -1,350 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Readers;
|
||||
using SabreTools.Models.RomCenter;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// Deserializer for RomCenter INI files
|
||||
/// </summary>
|
||||
public partial class RomCenter
|
||||
{
|
||||
/// <summary>
|
||||
/// Deserializes a RomCenter INI file to the defined type
|
||||
/// </summary>
|
||||
/// <param name="path">Path to the file to deserialize</param>
|
||||
/// <returns>Deserialized data on success, null on failure</returns>
|
||||
public static MetadataFile? Deserialize(string path)
|
||||
{
|
||||
using var stream = PathProcessor.OpenStream(path);
|
||||
return Deserialize(stream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes a RomCenter INI file in a stream to the defined type
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream to deserialize</param>
|
||||
/// <returns>Deserialized data on success, null on failure</returns>
|
||||
public static MetadataFile? Deserialize(Stream? stream)
|
||||
{
|
||||
// If the stream is null
|
||||
if (stream == null)
|
||||
return default;
|
||||
|
||||
// Setup the reader and output
|
||||
var reader = new IniReader(stream, Encoding.UTF8)
|
||||
{
|
||||
ValidateRows = false,
|
||||
};
|
||||
var dat = new MetadataFile();
|
||||
|
||||
// Loop through and parse out the values
|
||||
var roms = new List<Rom>();
|
||||
var additional = new List<string>();
|
||||
var creditsAdditional = new List<string>();
|
||||
var datAdditional = new List<string>();
|
||||
var emulatorAdditional = new List<string>();
|
||||
var gamesAdditional = new List<string>();
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
// If we have no next line
|
||||
if (!reader.ReadNextLine())
|
||||
break;
|
||||
|
||||
// Ignore certain row types
|
||||
switch (reader.RowType)
|
||||
{
|
||||
case IniRowType.None:
|
||||
case IniRowType.Comment:
|
||||
continue;
|
||||
case IniRowType.SectionHeader:
|
||||
switch (reader.Section?.ToLowerInvariant())
|
||||
{
|
||||
case "credits":
|
||||
dat.Credits ??= new Credits();
|
||||
break;
|
||||
case "dat":
|
||||
dat.Dat ??= new Dat();
|
||||
break;
|
||||
case "emulator":
|
||||
dat.Emulator ??= new Emulator();
|
||||
break;
|
||||
case "games":
|
||||
dat.Games ??= new Games();
|
||||
break;
|
||||
default:
|
||||
if (reader.CurrentLine != null)
|
||||
additional.Add(reader.CurrentLine);
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we're in credits
|
||||
if (reader.Section?.ToLowerInvariant() == "credits")
|
||||
{
|
||||
// Create the section if we haven't already
|
||||
dat.Credits ??= new Credits();
|
||||
|
||||
switch (reader.KeyValuePair?.Key?.ToLowerInvariant())
|
||||
{
|
||||
case "author":
|
||||
dat.Credits.Author = reader.KeyValuePair?.Value;
|
||||
break;
|
||||
case "version":
|
||||
dat.Credits.Version = reader.KeyValuePair?.Value;
|
||||
break;
|
||||
case "email":
|
||||
dat.Credits.Email = reader.KeyValuePair?.Value;
|
||||
break;
|
||||
case "homepage":
|
||||
dat.Credits.Homepage = reader.KeyValuePair?.Value;
|
||||
break;
|
||||
case "url":
|
||||
dat.Credits.Url = reader.KeyValuePair?.Value;
|
||||
break;
|
||||
case "date":
|
||||
dat.Credits.Date = reader.KeyValuePair?.Value;
|
||||
break;
|
||||
case "comment":
|
||||
dat.Credits.Comment = reader.KeyValuePair?.Value;
|
||||
break;
|
||||
default:
|
||||
if (reader.CurrentLine != null)
|
||||
creditsAdditional.Add(reader.CurrentLine);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we're in dat
|
||||
else if (reader.Section?.ToLowerInvariant() == "dat")
|
||||
{
|
||||
// Create the section if we haven't already
|
||||
dat.Dat ??= new Dat();
|
||||
|
||||
switch (reader.KeyValuePair?.Key?.ToLowerInvariant())
|
||||
{
|
||||
case "version":
|
||||
dat.Dat.Version = reader.KeyValuePair?.Value;
|
||||
break;
|
||||
case "plugin":
|
||||
dat.Dat.Plugin = reader.KeyValuePair?.Value;
|
||||
break;
|
||||
case "split":
|
||||
dat.Dat.Split = reader.KeyValuePair?.Value;
|
||||
break;
|
||||
case "merge":
|
||||
dat.Dat.Merge = reader.KeyValuePair?.Value;
|
||||
break;
|
||||
default:
|
||||
if (reader.CurrentLine != null)
|
||||
datAdditional.Add(reader.CurrentLine);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we're in emulator
|
||||
else if (reader.Section?.ToLowerInvariant() == "emulator")
|
||||
{
|
||||
// Create the section if we haven't already
|
||||
dat.Emulator ??= new Emulator();
|
||||
|
||||
switch (reader.KeyValuePair?.Key?.ToLowerInvariant())
|
||||
{
|
||||
case "refname":
|
||||
dat.Emulator.RefName = reader.KeyValuePair?.Value;
|
||||
break;
|
||||
case "version":
|
||||
dat.Emulator.Version = reader.KeyValuePair?.Value;
|
||||
break;
|
||||
default:
|
||||
if (reader.CurrentLine != null)
|
||||
emulatorAdditional.Add(reader.CurrentLine);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we're in games
|
||||
else if (reader.Section?.ToLowerInvariant() == "games")
|
||||
{
|
||||
// Create the section if we haven't already
|
||||
dat.Games ??= new Games();
|
||||
|
||||
// If the line doesn't contain the delimiter
|
||||
if (!(reader.CurrentLine?.Contains('¬') ?? false))
|
||||
{
|
||||
if (reader.CurrentLine != null)
|
||||
gamesAdditional.Add(reader.CurrentLine);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise, separate out the line
|
||||
string[] splitLine = reader.CurrentLine.Split('¬');
|
||||
var rom = new Rom
|
||||
{
|
||||
// EMPTY = splitLine[0]
|
||||
ParentName = splitLine[1],
|
||||
ParentDescription = splitLine[2],
|
||||
GameName = splitLine[3],
|
||||
GameDescription = splitLine[4],
|
||||
RomName = splitLine[5],
|
||||
RomCRC = splitLine[6],
|
||||
RomSize = splitLine[7],
|
||||
RomOf = splitLine[8],
|
||||
MergeName = splitLine[9],
|
||||
// EMPTY = splitLine[10]
|
||||
};
|
||||
|
||||
if (splitLine.Length > 11)
|
||||
rom.ADDITIONAL_ELEMENTS = splitLine.Skip(11).ToArray();
|
||||
|
||||
roms.Add(rom);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (reader.CurrentLine != null)
|
||||
additional.Add(reader.CurrentLine);
|
||||
}
|
||||
}
|
||||
|
||||
// Add extra pieces and return
|
||||
dat.ADDITIONAL_ELEMENTS = additional.Where(s => s != null).ToArray();
|
||||
if (dat.Credits != null)
|
||||
dat.Credits.ADDITIONAL_ELEMENTS = creditsAdditional.Where(s => s != null).ToArray();
|
||||
if (dat.Dat != null)
|
||||
dat.Dat.ADDITIONAL_ELEMENTS = datAdditional.Where(s => s != null).ToArray();
|
||||
if (dat.Emulator != null)
|
||||
dat.Emulator.ADDITIONAL_ELEMENTS = emulatorAdditional.Where(s => s != null).ToArray();
|
||||
if (dat.Games != null)
|
||||
{
|
||||
dat.Games.Rom = roms.ToArray();
|
||||
dat.Games.ADDITIONAL_ELEMENTS = gamesAdditional.Where(s => s != null).Select(s => s).ToArray();
|
||||
}
|
||||
return dat;
|
||||
}
|
||||
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.MetadataFile"/> to <cref="Models.RomCenter.MetadataFile"/>
|
||||
/// </summary>
|
||||
public static MetadataFile? ConvertFromInternalModel(Models.Metadata.MetadataFile? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var header = item.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
|
||||
var metadataFile = header != null ? ConvertHeaderFromInternalModel(header) : new MetadataFile();
|
||||
|
||||
var machines = item.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
|
||||
if (machines != null && machines.Any())
|
||||
{
|
||||
metadataFile.Games = new Games
|
||||
{
|
||||
Rom = machines
|
||||
.Where(m => m != null)
|
||||
.SelectMany(ConvertMachineFromInternalModel)
|
||||
.ToArray()
|
||||
};
|
||||
}
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Header"/> to <cref="Models.RomCenter.MetadataFile"/>
|
||||
/// </summary>
|
||||
private static MetadataFile ConvertHeaderFromInternalModel(Models.Metadata.Header item)
|
||||
{
|
||||
var metadataFile = new MetadataFile();
|
||||
|
||||
if (item.ContainsKey(Models.Metadata.Header.AuthorKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.VersionKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.EmailKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.HomepageKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.UrlKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.DateKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.CommentKey))
|
||||
{
|
||||
metadataFile.Credits = new Credits
|
||||
{
|
||||
Author = item.ReadString(Models.Metadata.Header.AuthorKey),
|
||||
Version = item.ReadString(Models.Metadata.Header.VersionKey),
|
||||
Email = item.ReadString(Models.Metadata.Header.EmailKey),
|
||||
Homepage = item.ReadString(Models.Metadata.Header.HomepageKey),
|
||||
Url = item.ReadString(Models.Metadata.Header.UrlKey),
|
||||
Date = item.ReadString(Models.Metadata.Header.DateKey),
|
||||
Comment = item.ReadString(Models.Metadata.Header.CommentKey),
|
||||
};
|
||||
}
|
||||
|
||||
if (item.ContainsKey(Models.Metadata.Header.DatVersionKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.PluginKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.ForceMergingKey))
|
||||
{
|
||||
metadataFile.Dat = new Dat
|
||||
{
|
||||
Version = item.ReadString(Models.Metadata.Header.DatVersionKey),
|
||||
Plugin = item.ReadString(Models.Metadata.Header.PluginKey),
|
||||
Split = item.ReadString(Models.Metadata.Header.ForceMergingKey) == "split" ? "yes" : "no",
|
||||
Merge = item.ReadString(Models.Metadata.Header.ForceMergingKey) == "merge" ? "yes" : "no",
|
||||
};
|
||||
}
|
||||
|
||||
if (item.ContainsKey(Models.Metadata.Header.RefNameKey)
|
||||
|| item.ContainsKey(Models.Metadata.Header.EmulatorVersionKey))
|
||||
{
|
||||
metadataFile.Emulator = new Emulator
|
||||
{
|
||||
RefName = item.ReadString(Models.Metadata.Header.RefNameKey),
|
||||
Version = item.ReadString(Models.Metadata.Header.EmulatorVersionKey),
|
||||
};
|
||||
}
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Machine"/> to an array of <cref="Models.RomCenter.Rom"/>
|
||||
/// </summary>
|
||||
private static Rom[] ConvertMachineFromInternalModel(Models.Metadata.Machine item)
|
||||
{
|
||||
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
|
||||
if (roms == null)
|
||||
return Array.Empty<Rom>();
|
||||
|
||||
return roms
|
||||
.Where(r => r != null)
|
||||
.Select(rom => ConvertFromInternalModel(rom, item))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.RomCenter.Rom"/>
|
||||
/// </summary>
|
||||
private static Rom ConvertFromInternalModel(Models.Metadata.Rom item, Models.Metadata.Machine parent)
|
||||
{
|
||||
var row = new Rom
|
||||
{
|
||||
RomName = item.ReadString(Models.Metadata.Rom.NameKey),
|
||||
RomCRC = item.ReadString(Models.Metadata.Rom.CRCKey),
|
||||
RomSize = item.ReadString(Models.Metadata.Rom.SizeKey),
|
||||
MergeName = item.ReadString(Models.Metadata.Rom.MergeKey),
|
||||
|
||||
ParentName = parent.ReadString(Models.Metadata.Machine.RomOfKey),
|
||||
//ParentDescription = parent.ReadString(Models.Metadata.Machine.ParentDescriptionKey), // This is unmappable
|
||||
GameName = parent.ReadString(Models.Metadata.Machine.NameKey),
|
||||
GameDescription = parent.ReadString(Models.Metadata.Machine.DescriptionKey),
|
||||
};
|
||||
return row;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,273 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Writers;
|
||||
using SabreTools.Models.RomCenter;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializer for RomCenter INI files
|
||||
/// </summary>
|
||||
public partial class RomCenter
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializes the defined type to a RomCenter INI file
|
||||
/// </summary>
|
||||
/// <param name="metadataFile">Data to serialize</param>
|
||||
/// <param name="path">Path to the file to serialize to</param>
|
||||
/// <returns>True on successful serialization, false otherwise</returns>
|
||||
public static bool SerializeToFile(MetadataFile? metadataFile, string path)
|
||||
{
|
||||
using var stream = SerializeToStream(metadataFile);
|
||||
if (stream == null)
|
||||
return false;
|
||||
|
||||
using var fs = File.OpenWrite(path);
|
||||
stream.CopyTo(fs);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes the defined type to a stream
|
||||
/// </summary>
|
||||
/// <param name="metadataFile">Data to serialize</param>
|
||||
/// <returns>Stream containing serialized data on success, null otherwise</returns>
|
||||
public static Stream? SerializeToStream(MetadataFile? metadataFile)
|
||||
{
|
||||
// If the metadata file is null
|
||||
if (metadataFile == null)
|
||||
return null;
|
||||
|
||||
// Setup the writer and output
|
||||
var stream = new MemoryStream();
|
||||
var writer = new IniWriter(stream, Encoding.UTF8);
|
||||
|
||||
// Write out the credits section
|
||||
WriteCredits(metadataFile.Credits, writer);
|
||||
|
||||
// Write out the dat section
|
||||
WriteDat(metadataFile.Dat, writer);
|
||||
|
||||
// Write out the emulator section
|
||||
WriteEmulator(metadataFile.Emulator, writer);
|
||||
|
||||
// Write out the games
|
||||
WriteGames(metadataFile.Games, writer);
|
||||
|
||||
// Return the stream
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
return stream;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write credits information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="credits">Credits object representing the credits information</param>
|
||||
/// <param name="writer">IniWriter representing the output</param>
|
||||
private static void WriteCredits(Credits? credits, IniWriter writer)
|
||||
{
|
||||
// If the credits information is missing, we can't do anything
|
||||
if (credits == null)
|
||||
return;
|
||||
|
||||
writer.WriteSection("credits");
|
||||
|
||||
writer.WriteKeyValuePair("author", credits.Author);
|
||||
writer.WriteKeyValuePair("version", credits.Version);
|
||||
writer.WriteKeyValuePair("email", credits.Email);
|
||||
writer.WriteKeyValuePair("homepage", credits.Homepage);
|
||||
writer.WriteKeyValuePair("url", credits.Url);
|
||||
writer.WriteKeyValuePair("date", credits.Date);
|
||||
writer.WriteKeyValuePair("comment", credits.Comment);
|
||||
writer.WriteLine();
|
||||
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write dat information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="dat">Dat object representing the dat information</param>
|
||||
/// <param name="writer">IniWriter representing the output</param>
|
||||
private static void WriteDat(Dat? dat, IniWriter writer)
|
||||
{
|
||||
// If the dat information is missing, we can't do anything
|
||||
if (dat == null)
|
||||
return;
|
||||
|
||||
writer.WriteSection("dat");
|
||||
|
||||
writer.WriteKeyValuePair("version", dat.Version);
|
||||
writer.WriteKeyValuePair("plugin", dat.Plugin);
|
||||
writer.WriteKeyValuePair("split", dat.Split);
|
||||
writer.WriteKeyValuePair("merge", dat.Merge);
|
||||
writer.WriteLine();
|
||||
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write emulator information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="emulator">Emulator object representing the emulator information</param>
|
||||
/// <param name="writer">IniWriter representing the output</param>
|
||||
private static void WriteEmulator(Emulator? emulator, IniWriter writer)
|
||||
{
|
||||
// If the emulator information is missing, we can't do anything
|
||||
if (emulator == null)
|
||||
return;
|
||||
|
||||
writer.WriteSection("emulator");
|
||||
|
||||
writer.WriteKeyValuePair("refname", emulator.RefName);
|
||||
writer.WriteKeyValuePair("version", emulator.Version);
|
||||
writer.WriteLine();
|
||||
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write games information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="games">Games object representing the games information</param>
|
||||
/// <param name="writer">IniWriter representing the output</param>
|
||||
private static void WriteGames(Games? games, IniWriter writer)
|
||||
{
|
||||
// If the games information is missing, we can't do anything
|
||||
if (games?.Rom == null || !games.Rom.Any())
|
||||
return;
|
||||
|
||||
writer.WriteSection("games");
|
||||
|
||||
foreach (var rom in games.Rom)
|
||||
{
|
||||
var romBuilder = new StringBuilder();
|
||||
|
||||
romBuilder.Append('¬');
|
||||
romBuilder.Append(rom.ParentName);
|
||||
romBuilder.Append('¬');
|
||||
romBuilder.Append(rom.ParentDescription);
|
||||
romBuilder.Append('¬');
|
||||
romBuilder.Append(rom.GameName);
|
||||
romBuilder.Append('¬');
|
||||
romBuilder.Append(rom.GameDescription);
|
||||
romBuilder.Append('¬');
|
||||
romBuilder.Append(rom.RomName);
|
||||
romBuilder.Append('¬');
|
||||
romBuilder.Append(rom.RomCRC);
|
||||
romBuilder.Append('¬');
|
||||
romBuilder.Append(rom.RomSize);
|
||||
romBuilder.Append('¬');
|
||||
romBuilder.Append(rom.RomOf);
|
||||
romBuilder.Append('¬');
|
||||
romBuilder.Append(rom.MergeName);
|
||||
romBuilder.Append('¬');
|
||||
romBuilder.Append('\n');
|
||||
|
||||
writer.WriteString(romBuilder.ToString());
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
writer.WriteLine();
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.RomCenter.MetadataFile"/> to <cref="Models.Metadata.MetadataFile"/>
|
||||
/// </summary>
|
||||
public static Models.Metadata.MetadataFile? ConvertToInternalModel(MetadataFile? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var metadataFile = new Models.Metadata.MetadataFile
|
||||
{
|
||||
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
|
||||
};
|
||||
|
||||
if (item?.Games?.Rom != null && item.Games.Rom.Any())
|
||||
{
|
||||
metadataFile[Models.Metadata.MetadataFile.MachineKey] = item.Games.Rom
|
||||
.Where(r => r != null)
|
||||
.Select(ConvertMachineToInternalModel).ToArray();
|
||||
}
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.RomCenter.MetadataFile"/> to <cref="Models.Metadata.Header"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Header ConvertHeaderToInternalModel(MetadataFile item)
|
||||
{
|
||||
var header = new Models.Metadata.Header();
|
||||
|
||||
if (item.Credits != null)
|
||||
{
|
||||
header[Models.Metadata.Header.AuthorKey] = item.Credits.Author;
|
||||
header[Models.Metadata.Header.VersionKey] = item.Credits.Version;
|
||||
header[Models.Metadata.Header.EmailKey] = item.Credits.Email;
|
||||
header[Models.Metadata.Header.HomepageKey] = item.Credits.Homepage;
|
||||
header[Models.Metadata.Header.UrlKey] = item.Credits.Url;
|
||||
header[Models.Metadata.Header.DateKey] = item.Credits.Date;
|
||||
header[Models.Metadata.Header.CommentKey] = item.Credits.Comment;
|
||||
}
|
||||
|
||||
if (item.Dat != null)
|
||||
{
|
||||
header[Models.Metadata.Header.DatVersionKey] = item.Dat.Version;
|
||||
header[Models.Metadata.Header.PluginKey] = item.Dat.Plugin;
|
||||
|
||||
if (item.Dat.Split == "yes" || item.Dat.Split == "1")
|
||||
header[Models.Metadata.Header.ForceMergingKey] = "split";
|
||||
else if (item.Dat.Merge == "yes" || item.Dat.Merge == "1")
|
||||
header[Models.Metadata.Header.ForceMergingKey] = "merge";
|
||||
}
|
||||
|
||||
if (item.Emulator != null)
|
||||
{
|
||||
header[Models.Metadata.Header.RefNameKey] = item.Emulator.RefName;
|
||||
header[Models.Metadata.Header.EmulatorVersionKey] = item.Emulator.Version;
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.RomCenter.Game"/> to <cref="Models.Metadata.Machine"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Machine ConvertMachineToInternalModel(Rom item)
|
||||
{
|
||||
var machine = new Models.Metadata.Machine
|
||||
{
|
||||
[Models.Metadata.Machine.RomOfKey] = item.ParentName,
|
||||
//[Models.Metadata.Machine.ParentDescriptionKey] = item.ParentDescription, // This is unmappable
|
||||
[Models.Metadata.Machine.NameKey] = item.GameName,
|
||||
[Models.Metadata.Machine.DescriptionKey] = item.GameDescription,
|
||||
[Models.Metadata.Machine.RomKey] = new Models.Metadata.Rom[] { ConvertToInternalModel(item) },
|
||||
};
|
||||
|
||||
return machine;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.RomCenter.Rom"/> to <cref="Models.Metadata.Rom"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Rom ConvertToInternalModel(Rom item)
|
||||
{
|
||||
var rom = new Models.Metadata.Rom
|
||||
{
|
||||
[Models.Metadata.Rom.NameKey] = item.RomName,
|
||||
[Models.Metadata.Rom.CRCKey] = item.RomCRC,
|
||||
[Models.Metadata.Rom.SizeKey] = item.RomSize,
|
||||
[Models.Metadata.Rom.MergeKey] = item.MergeName,
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SabreTools.Core\SabreTools.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SabreTools.IO" Version="1.1.1" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,257 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Readers;
|
||||
using SabreTools.Models.SeparatedValue;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// Deserializer for separated-value variants
|
||||
/// </summary>
|
||||
public partial class SeparatedValue
|
||||
{
|
||||
/// <summary>
|
||||
/// Deserializes a separated-value variant to the defined type
|
||||
/// </summary>
|
||||
/// <param name="path">Path to the file to deserialize</param>
|
||||
/// <param name="delim">Character delimiter between values</param>
|
||||
/// <returns>Deserialized data on success, null on failure</returns>
|
||||
public static MetadataFile? Deserialize(string path, char delim)
|
||||
{
|
||||
using var stream = PathProcessor.OpenStream(path);
|
||||
return Deserialize(stream, delim);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes a separated-value variant in a stream to the defined type
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream to deserialize</param>
|
||||
/// <param name="delim">Character delimiter between values</param>
|
||||
/// <returns>Deserialized data on success, null on failure</returns>
|
||||
public static MetadataFile? Deserialize(Stream? stream, char delim)
|
||||
{
|
||||
// If the stream is null
|
||||
if (stream == null)
|
||||
return default;
|
||||
|
||||
// Setup the reader and output
|
||||
var reader = new SeparatedValueReader(stream, Encoding.UTF8)
|
||||
{
|
||||
Header = true,
|
||||
Separator = delim,
|
||||
VerifyFieldCount = false,
|
||||
};
|
||||
var dat = new MetadataFile();
|
||||
|
||||
// Read the header values first
|
||||
if (!reader.ReadHeader() || reader.HeaderValues == null)
|
||||
return null;
|
||||
|
||||
dat.Header = reader.HeaderValues.ToArray();
|
||||
|
||||
// Loop through the rows and parse out values
|
||||
var rows = new List<Row>();
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
// If we have no next line
|
||||
if (!reader.ReadNextLine() || reader.Line == null)
|
||||
break;
|
||||
|
||||
// Parse the line into a row
|
||||
Row? row = null;
|
||||
if (reader.Line.Count < HeaderWithExtendedHashesCount)
|
||||
{
|
||||
row = new Row
|
||||
{
|
||||
FileName = reader.Line[0],
|
||||
InternalName = reader.Line[1],
|
||||
Description = reader.Line[2],
|
||||
GameName = reader.Line[3],
|
||||
GameDescription = reader.Line[4],
|
||||
Type = reader.Line[5],
|
||||
RomName = reader.Line[6],
|
||||
DiskName = reader.Line[7],
|
||||
Size = reader.Line[8],
|
||||
CRC = reader.Line[9],
|
||||
MD5 = reader.Line[10],
|
||||
SHA1 = reader.Line[11],
|
||||
SHA256 = reader.Line[12],
|
||||
Status = reader.Line[13],
|
||||
};
|
||||
|
||||
// If we have additional fields
|
||||
if (reader.Line.Count > HeaderWithoutExtendedHashesCount)
|
||||
row.ADDITIONAL_ELEMENTS = reader.Line.Skip(HeaderWithoutExtendedHashesCount).ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
row = new Row
|
||||
{
|
||||
FileName = reader.Line[0],
|
||||
InternalName = reader.Line[1],
|
||||
Description = reader.Line[2],
|
||||
GameName = reader.Line[3],
|
||||
GameDescription = reader.Line[4],
|
||||
Type = reader.Line[5],
|
||||
RomName = reader.Line[6],
|
||||
DiskName = reader.Line[7],
|
||||
Size = reader.Line[8],
|
||||
CRC = reader.Line[9],
|
||||
MD5 = reader.Line[10],
|
||||
SHA1 = reader.Line[11],
|
||||
SHA256 = reader.Line[12],
|
||||
SHA384 = reader.Line[13],
|
||||
SHA512 = reader.Line[14],
|
||||
SpamSum = reader.Line[15],
|
||||
Status = reader.Line[16],
|
||||
};
|
||||
|
||||
// If we have additional fields
|
||||
if (reader.Line.Count > HeaderWithExtendedHashesCount)
|
||||
row.ADDITIONAL_ELEMENTS = reader.Line.Skip(HeaderWithExtendedHashesCount).ToArray();
|
||||
}
|
||||
rows.Add(row);
|
||||
}
|
||||
|
||||
// Assign the rows to the Dat and return
|
||||
dat.Row = rows.ToArray();
|
||||
return dat;
|
||||
}
|
||||
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.MetadataFile"/> to <cref="Models.SeparatedValue.MetadataFile"/>
|
||||
/// </summary>
|
||||
public static MetadataFile? ConvertFromInternalModel(Models.Metadata.MetadataFile? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var header = item.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
|
||||
var metadataFile = header != null ? ConvertHeaderFromInternalModel(header) : new MetadataFile();
|
||||
|
||||
var machines = item.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
|
||||
if (machines != null && machines.Any())
|
||||
{
|
||||
metadataFile.Row = machines
|
||||
.Where(m => m != null)
|
||||
.SelectMany(ConvertMachineFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Header"/> to <cref="Models.SeparatedValue.MetadataFile"/>
|
||||
/// </summary>
|
||||
private static MetadataFile ConvertHeaderFromInternalModel(Models.Metadata.Header item)
|
||||
{
|
||||
var metadataFile = new MetadataFile
|
||||
{
|
||||
Header = item.ReadStringArray(Models.Metadata.Header.HeaderKey),
|
||||
};
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Machine"/> to an array of <cref="Models.SeparatedValue.Row"/>
|
||||
/// </summary>
|
||||
private static Row[] ConvertMachineFromInternalModel(Models.Metadata.Machine item)
|
||||
{
|
||||
var rowItems = new List<Row>();
|
||||
|
||||
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
|
||||
if (roms != null && roms.Any())
|
||||
{
|
||||
rowItems.AddRange(roms
|
||||
.Where(r => r != null)
|
||||
.Select(rom => ConvertFromInternalModel(rom, item)));
|
||||
}
|
||||
|
||||
var disks = item.Read<Models.Metadata.Disk[]>(Models.Metadata.Machine.DiskKey);
|
||||
if (disks != null && disks.Any())
|
||||
{
|
||||
rowItems.AddRange(disks
|
||||
.Where(d => d != null)
|
||||
.Select(disk => ConvertFromInternalModel(disk, item)));
|
||||
}
|
||||
|
||||
var media = item.Read<Models.Metadata.Media[]>(Models.Metadata.Machine.MediaKey);
|
||||
if (media != null && media.Any())
|
||||
{
|
||||
rowItems.AddRange(media
|
||||
.Where(m => m != null)
|
||||
.Select(medium => ConvertFromInternalModel(medium, item)));
|
||||
}
|
||||
|
||||
return rowItems.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Disk"/> to <cref="Models.SeparatedValue.Row"/>
|
||||
/// </summary>
|
||||
private static Row ConvertFromInternalModel(Models.Metadata.Disk item, Models.Metadata.Machine parent)
|
||||
{
|
||||
var row = new Row
|
||||
{
|
||||
GameName = parent.ReadString(Models.Metadata.Machine.NameKey),
|
||||
Description = parent.ReadString(Models.Metadata.Machine.DescriptionKey),
|
||||
Type = "disk",
|
||||
DiskName = item.ReadString(Models.Metadata.Disk.NameKey),
|
||||
MD5 = item.ReadString(Models.Metadata.Disk.MD5Key),
|
||||
SHA1 = item.ReadString(Models.Metadata.Disk.SHA1Key),
|
||||
Status = item.ReadString(Models.Metadata.Disk.StatusKey),
|
||||
};
|
||||
return row;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Media"/> to <cref="Models.SeparatedValue.Row"/>
|
||||
/// </summary>
|
||||
private static Row ConvertFromInternalModel(Models.Metadata.Media item, Models.Metadata.Machine parent)
|
||||
{
|
||||
var row = new Row
|
||||
{
|
||||
GameName = parent.ReadString(Models.Metadata.Machine.NameKey),
|
||||
Description = parent.ReadString(Models.Metadata.Machine.DescriptionKey),
|
||||
Type = "media",
|
||||
DiskName = item.ReadString(Models.Metadata.Media.NameKey),
|
||||
MD5 = item.ReadString(Models.Metadata.Media.MD5Key),
|
||||
SHA1 = item.ReadString(Models.Metadata.Media.SHA1Key),
|
||||
SHA256 = item.ReadString(Models.Metadata.Media.SHA256Key),
|
||||
SpamSum = item.ReadString(Models.Metadata.Media.SpamSumKey),
|
||||
};
|
||||
return row;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.SeparatedValue.Row"/>
|
||||
/// </summary>
|
||||
private static Row ConvertFromInternalModel(Models.Metadata.Rom item, Models.Metadata.Machine parent)
|
||||
{
|
||||
var row = new Row
|
||||
{
|
||||
GameName = parent?.ReadString(Models.Metadata.Machine.NameKey),
|
||||
Description = parent?.ReadString(Models.Metadata.Machine.DescriptionKey),
|
||||
Type = "rom",
|
||||
RomName = item.ReadString(Models.Metadata.Rom.NameKey),
|
||||
Size = item.ReadString(Models.Metadata.Rom.SizeKey),
|
||||
CRC = item.ReadString(Models.Metadata.Rom.CRCKey),
|
||||
MD5 = item.ReadString(Models.Metadata.Rom.MD5Key),
|
||||
SHA1 = item.ReadString(Models.Metadata.Rom.SHA1Key),
|
||||
SHA256 = item.ReadString(Models.Metadata.Rom.SHA256Key),
|
||||
SHA384 = item.ReadString(Models.Metadata.Rom.SHA384Key),
|
||||
SHA512 = item.ReadString(Models.Metadata.Rom.SHA512Key),
|
||||
SpamSum = item.ReadString(Models.Metadata.Rom.SpamSumKey),
|
||||
Status = item.ReadString(Models.Metadata.Rom.StatusKey),
|
||||
};
|
||||
return row;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,244 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Writers;
|
||||
using SabreTools.Models.SeparatedValue;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializer for separated-value variants
|
||||
/// </summary>
|
||||
public partial class SeparatedValue
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializes the defined type to a separated-value variant
|
||||
/// </summary>
|
||||
/// <param name="metadataFile">Data to serialize</param>
|
||||
/// <param name="path">Path to the file to serialize to</param>
|
||||
/// <param name="delim">Character delimiter between values</param>
|
||||
/// <returns>True on successful serialization, false otherwise</returns>
|
||||
public static bool SerializeToFile(MetadataFile? metadataFile, string path, char delim)
|
||||
{
|
||||
using var stream = SerializeToStream(metadataFile, delim);
|
||||
if (stream == null)
|
||||
return false;
|
||||
|
||||
using var fs = File.OpenWrite(path);
|
||||
stream.CopyTo(fs);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes the defined type to a stream
|
||||
/// </summary>
|
||||
/// <param name="metadataFile">Data to serialize</param>
|
||||
/// <param name="delim">Character delimiter between values</param>
|
||||
/// <returns>Stream containing serialized data on success, null otherwise</returns>
|
||||
public static Stream? SerializeToStream(MetadataFile? metadataFile, char delim)
|
||||
{
|
||||
// If the metadata file is null
|
||||
if (metadataFile == null)
|
||||
return null;
|
||||
|
||||
// Setup the writer and output
|
||||
var stream = new MemoryStream();
|
||||
var writer = new SeparatedValueWriter(stream, Encoding.UTF8) { Separator = delim, Quotes = true };
|
||||
|
||||
// TODO: Include flag to write out long or short header
|
||||
// Write the short header
|
||||
WriteHeader(writer);
|
||||
|
||||
// Write out the rows, if they exist
|
||||
WriteRows(metadataFile.Row, writer);
|
||||
|
||||
// Return the stream
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
return stream;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write header information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="writer">SeparatedValueWriter representing the output</param>
|
||||
private static void WriteHeader(SeparatedValueWriter writer)
|
||||
{
|
||||
var headerArray = new string?[]
|
||||
{
|
||||
"File Name",
|
||||
"Internal Name",
|
||||
"Description",
|
||||
"Game Name",
|
||||
"Game Description",
|
||||
"Type",
|
||||
"Rom Name",
|
||||
"Disk Name",
|
||||
"Size",
|
||||
"CRC",
|
||||
"MD5",
|
||||
"SHA1",
|
||||
"SHA256",
|
||||
//"SHA384",
|
||||
//"SHA512",
|
||||
//"SpamSum",
|
||||
"Status",
|
||||
};
|
||||
|
||||
writer.WriteHeader(headerArray);
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write rows information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="rows">Array of Row objects representing the rows information</param>
|
||||
/// <param name="writer">SeparatedValueWriter representing the output</param>
|
||||
private static void WriteRows(Row[]? rows, SeparatedValueWriter writer)
|
||||
{
|
||||
// If the games information is missing, we can't do anything
|
||||
if (rows == null || !rows.Any())
|
||||
return;
|
||||
|
||||
// Loop through and write out the rows
|
||||
foreach (var row in rows)
|
||||
{
|
||||
var rowArray = new string?[]
|
||||
{
|
||||
row.FileName,
|
||||
row.InternalName,
|
||||
row.Description,
|
||||
row.GameName,
|
||||
row.GameDescription,
|
||||
row.Type,
|
||||
row.RomName,
|
||||
row.DiskName,
|
||||
row.Size,
|
||||
row.CRC,
|
||||
row.MD5,
|
||||
row.SHA1,
|
||||
row.SHA256,
|
||||
//row.SHA384,
|
||||
//row.SHA512,
|
||||
//row.SpamSum,
|
||||
row.Status,
|
||||
};
|
||||
|
||||
writer.WriteValues(rowArray);
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.SeparatedValue.MetadataFile"/> to <cref="Models.Metadata.MetadataFile"/>
|
||||
/// </summary>
|
||||
public static Models.Metadata.MetadataFile? ConvertToInternalModel(MetadataFile? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var metadataFile = new Models.Metadata.MetadataFile
|
||||
{
|
||||
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
|
||||
};
|
||||
|
||||
if (item?.Row != null && item.Row.Any())
|
||||
metadataFile[Models.Metadata.MetadataFile.MachineKey] = item.Row.Select(ConvertMachineToInternalModel).ToArray();
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.SeparatedValue.MetadataFile"/> to <cref="Models.Metadata.Header"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Header ConvertHeaderToInternalModel(MetadataFile item)
|
||||
{
|
||||
var header = new Models.Metadata.Header
|
||||
{
|
||||
[Models.Metadata.Header.HeaderKey] = item.Header,
|
||||
};
|
||||
|
||||
if (item.Row != null && item.Row.Any())
|
||||
{
|
||||
var first = item.Row[0];
|
||||
//header[Models.Metadata.Header.FileNameKey] = first.FileName; // Not possible to map
|
||||
header[Models.Metadata.Header.NameKey] = first.FileName;
|
||||
header[Models.Metadata.Header.DescriptionKey] = first.Description;
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.SeparatedValue.Row"/> to <cref="Models.Metadata.Machine"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Machine ConvertMachineToInternalModel(Row item)
|
||||
{
|
||||
var machine = new Models.Metadata.Machine
|
||||
{
|
||||
[Models.Metadata.Machine.NameKey] = item.GameName,
|
||||
[Models.Metadata.Machine.DescriptionKey] = item.GameDescription,
|
||||
};
|
||||
|
||||
var datItem = ConvertToInternalModel(item);
|
||||
switch (datItem)
|
||||
{
|
||||
case Models.Metadata.Disk disk:
|
||||
machine[Models.Metadata.Machine.DiskKey] = new Models.Metadata.Disk[] { disk };
|
||||
break;
|
||||
|
||||
case Models.Metadata.Media media:
|
||||
machine[Models.Metadata.Machine.MediaKey] = new Models.Metadata.Media[] { media };
|
||||
break;
|
||||
|
||||
case Models.Metadata.Rom rom:
|
||||
machine[Models.Metadata.Machine.RomKey] = new Models.Metadata.Rom[] { rom };
|
||||
break;
|
||||
}
|
||||
|
||||
return machine;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.SeparatedValue.Row"/> to <cref="Models.Metadata.DatItem"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.DatItem? ConvertToInternalModel(Row item)
|
||||
{
|
||||
return item.Type switch
|
||||
{
|
||||
"disk" => new Models.Metadata.Disk
|
||||
{
|
||||
[Models.Metadata.Disk.NameKey] = item.DiskName,
|
||||
[Models.Metadata.Disk.MD5Key] = item.MD5,
|
||||
[Models.Metadata.Disk.SHA1Key] = item.SHA1,
|
||||
[Models.Metadata.Disk.StatusKey] = item.Status,
|
||||
},
|
||||
"media" => new Models.Metadata.Media
|
||||
{
|
||||
[Models.Metadata.Media.NameKey] = item.DiskName,
|
||||
[Models.Metadata.Media.MD5Key] = item.MD5,
|
||||
[Models.Metadata.Media.SHA1Key] = item.SHA1,
|
||||
[Models.Metadata.Media.SHA256Key] = item.SHA256,
|
||||
[Models.Metadata.Media.SpamSumKey] = item.SpamSum,
|
||||
},
|
||||
"rom" => new Models.Metadata.Rom
|
||||
{
|
||||
[Models.Metadata.Rom.NameKey] = item.RomName,
|
||||
[Models.Metadata.Rom.SizeKey] = item.Size,
|
||||
[Models.Metadata.Rom.CRCKey] = item.CRC,
|
||||
[Models.Metadata.Rom.MD5Key] = item.MD5,
|
||||
[Models.Metadata.Rom.SHA1Key] = item.SHA1,
|
||||
[Models.Metadata.Rom.SHA256Key] = item.SHA256,
|
||||
[Models.Metadata.Rom.SHA384Key] = item.SHA384,
|
||||
[Models.Metadata.Rom.SHA512Key] = item.SHA512,
|
||||
[Models.Metadata.Rom.SpamSumKey] = item.SpamSum,
|
||||
[Models.Metadata.Rom.StatusKey] = item.Status,
|
||||
},
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents separated-value variants
|
||||
/// </summary>
|
||||
public partial class SeparatedValue
|
||||
{
|
||||
private const int HeaderWithoutExtendedHashesCount = 14;
|
||||
|
||||
private const int HeaderWithExtendedHashesCount = 17;
|
||||
}
|
||||
}
|
||||
@@ -1,308 +0,0 @@
|
||||
using System.Linq;
|
||||
using SabreTools.Models.SoftwareList;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// XML deserializer for MAME softwarelist files
|
||||
/// </summary>
|
||||
public partial class SoftawreList : XmlSerializer<SoftwareList>
|
||||
{
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.MetadataFile"/> to <cref="Models.SoftawreList.SoftwareList"/>
|
||||
/// </summary>
|
||||
public static SoftwareList? ConvertFromInternalModel(Models.Metadata.MetadataFile? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var header = item.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
|
||||
var metadataFile = header != null ? ConvertHeaderFromInternalModel(header) : new SoftwareList();
|
||||
|
||||
var machines = item.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
|
||||
if (machines != null && machines.Any())
|
||||
{
|
||||
metadataFile.Software = machines
|
||||
.Where(m => m != null)
|
||||
.Select(ConvertMachineFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Header"/> to <cref="Models.SoftwareList.SoftwareList"/>
|
||||
/// </summary>
|
||||
private static SoftwareList ConvertHeaderFromInternalModel(Models.Metadata.Header item)
|
||||
{
|
||||
var softwareList = new SoftwareList
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Header.NameKey),
|
||||
Description = item.ReadString(Models.Metadata.Header.DescriptionKey),
|
||||
Notes = item.ReadString(Models.Metadata.Header.NotesKey),
|
||||
};
|
||||
return softwareList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Machine"/> to <cref="Models.SoftwareList.Software"/>
|
||||
/// </summary>
|
||||
private static Software ConvertMachineFromInternalModel(Models.Metadata.Machine item)
|
||||
{
|
||||
var software = new Software
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Machine.NameKey),
|
||||
CloneOf = item.ReadString(Models.Metadata.Machine.CloneOfKey),
|
||||
Supported = item.ReadString(Models.Metadata.Machine.SupportedKey),
|
||||
Description = item.ReadString(Models.Metadata.Machine.DescriptionKey),
|
||||
Year = item.ReadString(Models.Metadata.Machine.YearKey),
|
||||
Publisher = item.ReadString(Models.Metadata.Machine.PublisherKey),
|
||||
Notes = item.ReadString(Models.Metadata.Machine.NotesKey),
|
||||
};
|
||||
|
||||
var infos = item.Read<Models.Metadata.Info[]>(Models.Metadata.Machine.InfoKey);
|
||||
if (infos != null && infos.Any())
|
||||
{
|
||||
software.Info = infos
|
||||
.Where(i => i != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var sharedFeats = item.Read<Models.Metadata.SharedFeat[]>(Models.Metadata.Machine.SharedFeatKey);
|
||||
if (sharedFeats != null && sharedFeats.Any())
|
||||
{
|
||||
software.SharedFeat = sharedFeats
|
||||
.Where(s => s != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var parts = item.Read<Models.Metadata.Part[]>(Models.Metadata.Machine.PartKey);
|
||||
if (parts != null && parts.Any())
|
||||
{
|
||||
software.Part = parts
|
||||
.Where(p => p != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return software;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.DataArea"/> to <cref="Models.SoftwareList.DataArea"/>
|
||||
/// </summary>
|
||||
private static DataArea ConvertFromInternalModel(Models.Metadata.DataArea item)
|
||||
{
|
||||
var dataArea = new DataArea
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.DataArea.NameKey),
|
||||
Size = item.ReadString(Models.Metadata.DataArea.SizeKey),
|
||||
Width = item.ReadString(Models.Metadata.DataArea.WidthKey),
|
||||
Endianness = item.ReadString(Models.Metadata.DataArea.EndiannessKey),
|
||||
};
|
||||
|
||||
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.DataArea.RomKey);
|
||||
if (roms != null && roms.Any())
|
||||
{
|
||||
dataArea.Rom = roms
|
||||
.Where(r => r != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return dataArea;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.DipSwitch"/> to <cref="Models.SoftwareList.DipSwitch"/>
|
||||
/// </summary>
|
||||
private static DipSwitch ConvertFromInternalModel(Models.Metadata.DipSwitch item)
|
||||
{
|
||||
var dipSwitch = new DipSwitch
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.DipSwitch.NameKey),
|
||||
Tag = item.ReadString(Models.Metadata.DipSwitch.TagKey),
|
||||
Mask = item.ReadString(Models.Metadata.DipSwitch.MaskKey),
|
||||
};
|
||||
|
||||
var dipValues = item.Read<Models.Metadata.DipValue[]>(Models.Metadata.DipSwitch.DipValueKey);
|
||||
if (dipValues != null && dipValues.Any())
|
||||
{
|
||||
dipSwitch.DipValue = dipValues
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return dipSwitch;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.DipValue"/> to <cref="Models.SoftwareList.DipValue"/>
|
||||
/// </summary>
|
||||
private static DipValue ConvertFromInternalModel(Models.Metadata.DipValue item)
|
||||
{
|
||||
var dipValue = new DipValue
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.DipValue.NameKey),
|
||||
Value = item.ReadString(Models.Metadata.DipValue.ValueKey),
|
||||
Default = item.ReadString(Models.Metadata.DipValue.DefaultKey),
|
||||
};
|
||||
return dipValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Disk"/> to <cref="Models.SoftwareList.Disk"/>
|
||||
/// </summary>
|
||||
private static Disk ConvertFromInternalModel(Models.Metadata.Disk item)
|
||||
{
|
||||
var disk = new Disk
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Disk.NameKey),
|
||||
MD5 = item.ReadString(Models.Metadata.Disk.MD5Key),
|
||||
SHA1 = item.ReadString(Models.Metadata.Disk.SHA1Key),
|
||||
Status = item.ReadString(Models.Metadata.Disk.StatusKey),
|
||||
Writeable = item.ReadString(Models.Metadata.Disk.WritableKey),
|
||||
};
|
||||
return disk;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.DiskArea"/> to <cref="Models.SoftwareList.DiskArea"/>
|
||||
/// </summary>
|
||||
private static DiskArea ConvertFromInternalModel(Models.Metadata.DiskArea item)
|
||||
{
|
||||
var diskArea = new DiskArea
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.DiskArea.NameKey),
|
||||
};
|
||||
|
||||
var disks = item.Read<Models.Metadata.Disk[]>(Models.Metadata.DiskArea.DiskKey);
|
||||
if (disks != null && disks.Any())
|
||||
{
|
||||
diskArea.Disk = disks
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return diskArea;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Feature"/> to <cref="Models.SoftwareList.Feature"/>
|
||||
/// </summary>
|
||||
private static Feature ConvertFromInternalModel(Models.Metadata.Feature item)
|
||||
{
|
||||
var feature = new Feature
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Feature.NameKey),
|
||||
Value = item.ReadString(Models.Metadata.Feature.ValueKey),
|
||||
};
|
||||
return feature;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Info"/> to <cref="Models.SoftwareList.Info"/>
|
||||
/// </summary>
|
||||
private static Info ConvertFromInternalModel(Models.Metadata.Info item)
|
||||
{
|
||||
var info = new Info
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Info.NameKey),
|
||||
Value = item.ReadString(Models.Metadata.Info.ValueKey),
|
||||
};
|
||||
return info;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Part"/> to <cref="Models.SoftwareList.Part"/>
|
||||
/// </summary>
|
||||
private static Part ConvertFromInternalModel(Models.Metadata.Part item)
|
||||
{
|
||||
var part = new Part
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Part.NameKey),
|
||||
Interface = item.ReadString(Models.Metadata.Part.InterfaceKey),
|
||||
};
|
||||
|
||||
var features = item.Read<Models.Metadata.Feature[]>(Models.Metadata.Part.FeatureKey);
|
||||
if (features != null && features.Any())
|
||||
{
|
||||
part.Feature = features
|
||||
.Where(f => f != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var dataAreas = item.Read<Models.Metadata.DataArea[]>(Models.Metadata.Part.DataAreaKey);
|
||||
if (dataAreas != null && dataAreas.Any())
|
||||
{
|
||||
part.DataArea = dataAreas
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var diskAreas = item.Read<Models.Metadata.DiskArea[]>(Models.Metadata.Part.DiskAreaKey);
|
||||
if (diskAreas != null && diskAreas.Any())
|
||||
{
|
||||
part.DiskArea = diskAreas
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
var dipSwitches = item.Read<Models.Metadata.DipSwitch[]>(Models.Metadata.Part.DipSwitchKey);
|
||||
if (dipSwitches != null && dipSwitches.Any())
|
||||
{
|
||||
part.DipSwitch = dipSwitches
|
||||
.Where(d => d != null)
|
||||
.Select(ConvertFromInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return part;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.SoftwareList.Rom"/>
|
||||
/// </summary>
|
||||
private static Rom ConvertFromInternalModel(Models.Metadata.Rom item)
|
||||
{
|
||||
var rom = new Rom
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.Rom.NameKey),
|
||||
Size = item.ReadString(Models.Metadata.Rom.SizeKey),
|
||||
Length = item.ReadString(Models.Metadata.Rom.LengthKey),
|
||||
CRC = item.ReadString(Models.Metadata.Rom.CRCKey),
|
||||
SHA1 = item.ReadString(Models.Metadata.Rom.SHA1Key),
|
||||
Offset = item.ReadString(Models.Metadata.Rom.OffsetKey),
|
||||
Value = item.ReadString(Models.Metadata.Rom.ValueKey),
|
||||
Status = item.ReadString(Models.Metadata.Rom.StatusKey),
|
||||
LoadFlag = item.ReadString(Models.Metadata.Rom.LoadFlagKey),
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.Metadata.SharedFeat"/> to <cref="Models.SoftwareList.SharedFeat"/>
|
||||
/// </summary>
|
||||
private static SharedFeat ConvertFromInternalModel(Models.Metadata.SharedFeat item)
|
||||
{
|
||||
var sharedFeat = new SharedFeat
|
||||
{
|
||||
Name = item.ReadString(Models.Metadata.SharedFeat.NameKey),
|
||||
Value = item.ReadString(Models.Metadata.SharedFeat.ValueKey),
|
||||
};
|
||||
return sharedFeat;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,258 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Models.SoftwareList;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// XML serializer for MAME softwarelist files
|
||||
/// </summary>
|
||||
public partial class SoftawreList : XmlSerializer<SoftwareList>
|
||||
{
|
||||
/// <inheritdoc cref="SerializeToFile(SoftwareList, string, string?, string?, string?, string?)" />
|
||||
public static bool SerializeToFileWithDocType(SoftwareList obj, string path)
|
||||
=> SerializeToFile(obj, path, DocTypeName, DocTypePubId, DocTypeSysId, DocTypeSysId);
|
||||
|
||||
/// <inheritdoc cref="SerializeToStream(SoftwareList, string?, string?, string?, string?)" />
|
||||
public static Stream? SerializeToStreamWithDocType(SoftwareList obj, string path)
|
||||
=> SerializeToStream(obj, DocTypeName, DocTypePubId, DocTypeSysId, DocTypeSysId);
|
||||
|
||||
#region Internal
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.SoftwareList.SoftwareList"/> to <cref="Models.Metadata.MetadataFile"/>
|
||||
/// </summary>
|
||||
public static Models.Metadata.MetadataFile? ConvertToInternalModel(SoftwareList? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var metadataFile = new Models.Metadata.MetadataFile
|
||||
{
|
||||
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
|
||||
};
|
||||
|
||||
if (item?.Software != null && item.Software.Any())
|
||||
{
|
||||
metadataFile[Models.Metadata.MetadataFile.MachineKey] = item.Software
|
||||
.Where(s => s != null)
|
||||
.Select(ConvertMachineToInternalModel)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.SoftwareList.SoftwareList"/> to <cref="Models.Metadata.Header"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Header ConvertHeaderToInternalModel(SoftwareList item)
|
||||
{
|
||||
var header = new Models.Metadata.Header
|
||||
{
|
||||
[Models.Metadata.Header.NameKey] = item.Name,
|
||||
[Models.Metadata.Header.DescriptionKey] = item.Description,
|
||||
[Models.Metadata.Header.NotesKey] = item.Notes,
|
||||
};
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.SoftwareList.Software"/> to <cref="Models.Metadata.Machine"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Machine ConvertMachineToInternalModel(Software item)
|
||||
{
|
||||
var machine = new Models.Metadata.Machine
|
||||
{
|
||||
[Models.Metadata.Machine.NameKey] = item.Name,
|
||||
[Models.Metadata.Machine.CloneOfKey] = item.CloneOf,
|
||||
[Models.Metadata.Machine.SupportedKey] = item.Supported,
|
||||
[Models.Metadata.Machine.DescriptionKey] = item.Description,
|
||||
[Models.Metadata.Machine.YearKey] = item.Year,
|
||||
[Models.Metadata.Machine.PublisherKey] = item.Publisher,
|
||||
[Models.Metadata.Machine.NotesKey] = item.Notes,
|
||||
};
|
||||
|
||||
if (item.Info != null && item.Info.Any())
|
||||
machine[Models.Metadata.Machine.InfoKey] = item.Info.Select(ConvertToInternalModel).ToArray();
|
||||
|
||||
if (item.SharedFeat != null && item.SharedFeat.Any())
|
||||
machine[Models.Metadata.Machine.SharedFeatKey] = item.SharedFeat.Select(ConvertToInternalModel).ToArray();
|
||||
|
||||
if (item.Part != null && item.Part.Any())
|
||||
machine[Models.Metadata.Machine.PartKey] = item.Part.Select(ConvertToInternalModel).ToArray();
|
||||
|
||||
return machine;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.SoftwareList.DataArea"/> to <cref="Models.Metadata.DataArea"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.DataArea ConvertToInternalModel(DataArea item)
|
||||
{
|
||||
var dataArea = new Models.Metadata.DataArea
|
||||
{
|
||||
[Models.Metadata.DataArea.NameKey] = item.Name,
|
||||
[Models.Metadata.DataArea.SizeKey] = item.Size,
|
||||
[Models.Metadata.DataArea.WidthKey] = item.Width,
|
||||
[Models.Metadata.DataArea.EndiannessKey] = item.Endianness,
|
||||
};
|
||||
|
||||
if (item.Rom != null && item.Rom.Any())
|
||||
dataArea[Models.Metadata.DataArea.RomKey] = item.Rom.Select(ConvertToInternalModel).ToArray();
|
||||
|
||||
return dataArea;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.SoftwareList.DipSwitch"/> to <cref="Models.Metadata.DipSwitch"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.DipSwitch ConvertToInternalModel(DipSwitch item)
|
||||
{
|
||||
var dipSwitch = new Models.Metadata.DipSwitch
|
||||
{
|
||||
[Models.Metadata.DipSwitch.NameKey] = item.Name,
|
||||
[Models.Metadata.DipSwitch.TagKey] = item.Tag,
|
||||
[Models.Metadata.DipSwitch.MaskKey] = item.Mask,
|
||||
};
|
||||
|
||||
if (item.DipValue != null && item.DipValue.Any())
|
||||
dipSwitch[Models.Metadata.DipSwitch.DipValueKey] = item.DipValue.Select(ConvertToInternalModel).ToArray();
|
||||
|
||||
return dipSwitch;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.SoftwareList.DipValue"/> to <cref="Models.Metadata.DipValue"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.DipValue ConvertToInternalModel(DipValue item)
|
||||
{
|
||||
var dipValue = new Models.Metadata.DipValue
|
||||
{
|
||||
[Models.Metadata.DipValue.NameKey] = item.Name,
|
||||
[Models.Metadata.DipValue.ValueKey] = item.Value,
|
||||
[Models.Metadata.DipValue.DefaultKey] = item.Default,
|
||||
};
|
||||
return dipValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.SoftwareList.Disk"/> to <cref="Models.Metadata.Disk"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Disk ConvertToInternalModel(Disk item)
|
||||
{
|
||||
var disk = new Models.Metadata.Disk
|
||||
{
|
||||
[Models.Metadata.Disk.NameKey] = item.Name,
|
||||
[Models.Metadata.Disk.MD5Key] = item.MD5,
|
||||
[Models.Metadata.Disk.SHA1Key] = item.SHA1,
|
||||
[Models.Metadata.Disk.StatusKey] = item.Status,
|
||||
[Models.Metadata.Disk.WritableKey] = item.Writeable,
|
||||
};
|
||||
return disk;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.SoftwareList.DiskArea"/> to <cref="Models.Metadata.DiskArea"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.DiskArea ConvertToInternalModel(DiskArea item)
|
||||
{
|
||||
var diskArea = new Models.Metadata.DiskArea
|
||||
{
|
||||
[Models.Metadata.DiskArea.NameKey] = item.Name,
|
||||
};
|
||||
|
||||
if (item.Disk != null && item.Disk.Any())
|
||||
diskArea[Models.Metadata.DiskArea.DiskKey] = item.Disk.Select(ConvertToInternalModel).ToArray();
|
||||
|
||||
return diskArea;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.SoftwareList.Feature"/> to <cref="Models.Metadata.Feature"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Feature ConvertToInternalModel(Feature item)
|
||||
{
|
||||
var feature = new Models.Metadata.Feature
|
||||
{
|
||||
[Models.Metadata.Feature.NameKey] = item.Name,
|
||||
[Models.Metadata.Feature.ValueKey] = item.Value,
|
||||
};
|
||||
return feature;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.SoftwareList.Info"/> to <cref="Models.Metadata.Info"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Info ConvertToInternalModel(Info item)
|
||||
{
|
||||
var info = new Models.Metadata.Info
|
||||
{
|
||||
[Models.Metadata.Info.NameKey] = item.Name,
|
||||
[Models.Metadata.Info.ValueKey] = item.Value,
|
||||
};
|
||||
return info;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.SoftwareList.Part"/> to <cref="Models.Metadata.Part"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Part ConvertToInternalModel(Part item)
|
||||
{
|
||||
var part = new Models.Metadata.Part
|
||||
{
|
||||
[Models.Metadata.Part.NameKey] = item.Name,
|
||||
[Models.Metadata.Part.InterfaceKey] = item.Interface,
|
||||
};
|
||||
|
||||
if (item.Feature != null && item.Feature.Any())
|
||||
part[Models.Metadata.Part.FeatureKey] = item.Feature.Select(ConvertToInternalModel).ToArray();
|
||||
|
||||
if (item.DataArea != null && item.DataArea.Any())
|
||||
part[Models.Metadata.Part.DataAreaKey] = item.DataArea.Select(ConvertToInternalModel).ToArray();
|
||||
|
||||
if (item.DiskArea != null && item.DiskArea.Any())
|
||||
part[Models.Metadata.Part.DiskAreaKey] = item.DiskArea.Select(ConvertToInternalModel).ToArray();
|
||||
|
||||
if (item.DipSwitch != null && item.DipSwitch.Any())
|
||||
part[Models.Metadata.Part.DipSwitchKey] = item.DipSwitch.Select(ConvertToInternalModel).ToArray();
|
||||
|
||||
return part;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.SoftwareList.Rom"/> to <cref="Models.Metadata.Rom"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Rom ConvertToInternalModel(Rom item)
|
||||
{
|
||||
var rom = new Models.Metadata.Rom
|
||||
{
|
||||
[Models.Metadata.Rom.NameKey] = item.Name,
|
||||
[Models.Metadata.Rom.SizeKey] = item.Size,
|
||||
[Models.Metadata.Rom.LengthKey] = item.Length,
|
||||
[Models.Metadata.Rom.CRCKey] = item.CRC,
|
||||
[Models.Metadata.Rom.SHA1Key] = item.SHA1,
|
||||
[Models.Metadata.Rom.OffsetKey] = item.Offset,
|
||||
[Models.Metadata.Rom.ValueKey] = item.Value,
|
||||
[Models.Metadata.Rom.StatusKey] = item.Status,
|
||||
[Models.Metadata.Rom.LoadFlagKey] = item.LoadFlag,
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <cref="Models.SoftwareList.SharedFeat"/> to <cref="Models.Metadata.SharedFeat"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.SharedFeat ConvertToInternalModel(SharedFeat item)
|
||||
{
|
||||
var sharedFeat = new Models.Metadata.SharedFeat
|
||||
{
|
||||
[Models.Metadata.SharedFeat.NameKey] = item.Name,
|
||||
[Models.Metadata.SharedFeat.ValueKey] = item.Value,
|
||||
};
|
||||
return sharedFeat;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// XML deserializer for MAME softwarelist files
|
||||
/// </summary>
|
||||
public partial class SoftawreList : XmlSerializer<Models.SoftwareList.SoftwareList>
|
||||
{
|
||||
/// <summary>
|
||||
/// name field for DOCTYPE
|
||||
/// </summary>
|
||||
public const string? DocTypeName = "softwarelist";
|
||||
|
||||
/// <summary>
|
||||
/// pubid field for DOCTYPE
|
||||
/// </summary>
|
||||
public const string? DocTypePubId = null;
|
||||
|
||||
/// <summary>
|
||||
/// sysid field for DOCTYPE
|
||||
/// </summary>
|
||||
public const string? DocTypeSysId = "softwarelist.dtd";
|
||||
|
||||
/// <summary>
|
||||
/// subset field for DOCTYPE
|
||||
/// </summary>
|
||||
public const string? DocTypeSubset = null;
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Xml.Schema;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// XML deserializer for nullable types
|
||||
/// </summary>
|
||||
public abstract partial class XmlSerializer<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Deserializes an XML file to the defined type
|
||||
/// </summary>
|
||||
/// <param name="path">Path to the file to deserialize</param>
|
||||
/// <returns>Deserialized data on success, null on failure</returns>
|
||||
public static T? Deserialize(string path)
|
||||
{
|
||||
using var stream = PathProcessor.OpenStream(path);
|
||||
return Deserialize(stream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes an XML file in a stream to the defined type
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream to deserialize</param>
|
||||
/// <returns>Deserialized data on success, null on failure</returns>
|
||||
public static T? Deserialize(Stream? stream)
|
||||
{
|
||||
// If the stream is null
|
||||
if (stream == null)
|
||||
return default;
|
||||
|
||||
// Setup the serializer and the reader
|
||||
var serializer = new XmlSerializer(typeof(T));
|
||||
var settings = new XmlReaderSettings
|
||||
{
|
||||
CheckCharacters = false,
|
||||
DtdProcessing = DtdProcessing.Ignore,
|
||||
ValidationFlags = XmlSchemaValidationFlags.None,
|
||||
ValidationType = ValidationType.None,
|
||||
};
|
||||
var streamReader = new StreamReader(stream);
|
||||
var xmlReader = XmlReader.Create(streamReader, settings);
|
||||
|
||||
// Perform the deserialization and return
|
||||
return (T?)serializer.Deserialize(xmlReader);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// XML serializer for nullable types
|
||||
/// </summary>
|
||||
public abstract partial class XmlSerializer<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializes the defined type to an XML file
|
||||
/// </summary>
|
||||
/// <param name="obj">Data to serialize</param>
|
||||
/// <param name="path">Path to the file to serialize to</param>
|
||||
/// <param name="obj">Data to serialize</param>
|
||||
/// <returns>True on successful serialization, false otherwise</returns>
|
||||
public static bool SerializeToFile(T? obj, string path)
|
||||
=> SerializeToFile(obj, path, null, null, null, null);
|
||||
|
||||
/// <summary>
|
||||
/// Serializes the defined type to an XML file
|
||||
/// </summary>
|
||||
/// <param name="obj">Data to serialize</param>
|
||||
/// <param name="path">Path to the file to serialize to</param>
|
||||
/// <param name="obj">Data to serialize</param>
|
||||
/// <param name="name">Optional DOCTYPE name</param>
|
||||
/// <param name="pubid">Optional DOCTYPE pubid</param>
|
||||
/// <param name="sysid">Optional DOCTYPE sysid</param>
|
||||
/// <param name="subset">Optional DOCTYPE name</param>
|
||||
/// <returns>True on successful serialization, false otherwise</returns>
|
||||
protected static bool SerializeToFile(T? obj, string path, string? name = null, string? pubid = null, string? sysid = null, string? subset = null)
|
||||
{
|
||||
using var stream = SerializeToStream(obj, name, pubid, sysid, subset);
|
||||
if (stream == null)
|
||||
return false;
|
||||
|
||||
using var fs = File.OpenWrite(path);
|
||||
stream.CopyTo(fs);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes the defined type to a stream
|
||||
/// </summary>
|
||||
/// <param name="obj">Data to serialize</param>
|
||||
/// <returns>Stream containing serialized data on success, null otherwise</returns>
|
||||
public static Stream? SerializeToStream(T? obj)
|
||||
=> SerializeToStream(obj, null, null, null, null);
|
||||
|
||||
/// <summary>
|
||||
/// Serializes the defined type to a stream
|
||||
/// </summary>
|
||||
/// <param name="obj">Data to serialize</param>
|
||||
/// <param name="name">Optional DOCTYPE name</param>
|
||||
/// <param name="pubid">Optional DOCTYPE pubid</param>
|
||||
/// <param name="sysid">Optional DOCTYPE sysid</param>
|
||||
/// <param name="subset">Optional DOCTYPE name</param>
|
||||
/// <returns>Stream containing serialized data on success, null otherwise</returns>
|
||||
protected static Stream? SerializeToStream(T? obj, string? name = null, string? pubid = null, string? sysid = null, string? subset = null)
|
||||
{
|
||||
// If the object is null
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
// Setup the serializer and the reader
|
||||
var serializer = new XmlSerializer(typeof(T));
|
||||
var settings = new XmlWriterSettings
|
||||
{
|
||||
CheckCharacters = false,
|
||||
Encoding = Encoding.UTF8,
|
||||
Indent = true,
|
||||
IndentChars = "\t",
|
||||
NewLineChars = "\n",
|
||||
};
|
||||
var stream = new MemoryStream();
|
||||
var streamWriter = new StreamWriter(stream);
|
||||
var xmlWriter = XmlWriter.Create(streamWriter, settings);
|
||||
|
||||
// Write the doctype if provided
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
xmlWriter.WriteDocType(name, pubid, sysid, subset);
|
||||
|
||||
// Perform the deserialization and return
|
||||
serializer.Serialize(xmlWriter, obj);
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
return stream;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@
|
||||
<ProjectReference Include="..\SabreTools.DatTools\SabreTools.DatTools.csproj" />
|
||||
<ProjectReference Include="..\SabreTools.FileTypes\SabreTools.FileTypes.csproj" />
|
||||
<ProjectReference Include="..\SabreTools.Filtering\SabreTools.Filtering.csproj" />
|
||||
<ProjectReference Include="..\SabreTools.Serialization\SabreTools.Serialization.csproj" />
|
||||
<ProjectReference Include="..\SabreTools.Skippers\SabreTools.Skippers.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -33,7 +32,8 @@
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
|
||||
<PackageReference Include="SabreTools.IO" Version="1.1.1" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.1.0" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.1.1" />
|
||||
<PackageReference Include="SabreTools.Serialization" Version="1.1.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.2" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace SabreTools.Test.Parser
|
||||
string filename = System.IO.Path.Combine(Environment.CurrentDirectory, "TestData", path);
|
||||
|
||||
// Deserialize the file
|
||||
var dat = Serialization.ArchiveDotOrg.Deserialize(filename);
|
||||
var dat = new Serialization.Files.ArchiveDotOrg().Deserialize(filename);
|
||||
|
||||
// Validate the values
|
||||
Assert.NotNull(dat?.File);
|
||||
@@ -46,7 +46,7 @@ namespace SabreTools.Test.Parser
|
||||
string filename = System.IO.Path.Combine(Environment.CurrentDirectory, "TestData", path);
|
||||
|
||||
// Deserialize the file
|
||||
var dat = Serialization.AttractMode.Deserialize(filename);
|
||||
var dat = new Serialization.Files.AttractMode().Deserialize(filename);
|
||||
|
||||
// Validate texpected: he values
|
||||
Assert.NotNull(dat?.Row);
|
||||
@@ -68,7 +68,7 @@ namespace SabreTools.Test.Parser
|
||||
string filename = System.IO.Path.Combine(Environment.CurrentDirectory, "TestData", path);
|
||||
|
||||
// Deserialize the file
|
||||
var dat = Serialization.ClrMamePro.Deserialize(filename, quotes: true);
|
||||
var dat = new Serialization.Files.ClrMamePro().Deserialize(filename, quotes: true);
|
||||
|
||||
// Validate the values
|
||||
if (expectHeader)
|
||||
@@ -163,7 +163,7 @@ namespace SabreTools.Test.Parser
|
||||
string filename = System.IO.Path.Combine(Environment.CurrentDirectory, "TestData", path);
|
||||
|
||||
// Deserialize the file
|
||||
var dat = Serialization.DosCenter.Deserialize(filename);
|
||||
var dat = new Serialization.Files.DosCenter().Deserialize(filename);
|
||||
|
||||
// Validate the values
|
||||
Assert.NotNull(dat?.DosCenter);
|
||||
@@ -190,7 +190,7 @@ namespace SabreTools.Test.Parser
|
||||
string filename = System.IO.Path.Combine(Environment.CurrentDirectory, "TestData", path);
|
||||
|
||||
// Deserialize the file
|
||||
var dat = Serialization.EverdriveSMDB.Deserialize(filename);
|
||||
var dat = new Serialization.Files.EverdriveSMDB().Deserialize(filename);
|
||||
|
||||
// Validate the values
|
||||
Assert.NotNull(dat?.Row);
|
||||
@@ -217,7 +217,7 @@ namespace SabreTools.Test.Parser
|
||||
string filename = System.IO.Path.Combine(Environment.CurrentDirectory, "TestData", path);
|
||||
|
||||
// Deserialize the file
|
||||
var dat = Serialization.Hashfile.Deserialize(filename, hash);
|
||||
var dat = new Serialization.Files.Hashfile().Deserialize(filename, hash);
|
||||
|
||||
// Validate the values
|
||||
Assert.NotNull(dat);
|
||||
@@ -258,7 +258,7 @@ namespace SabreTools.Test.Parser
|
||||
string filename = System.IO.Path.Combine(Environment.CurrentDirectory, "TestData", path);
|
||||
|
||||
// Deserialize the file
|
||||
var dat = Serialization.Listrom.Deserialize(filename);
|
||||
var dat = new Serialization.Files.Listrom().Deserialize(filename);
|
||||
|
||||
// Validate the values
|
||||
Assert.NotNull(dat?.Set);
|
||||
@@ -277,7 +277,7 @@ namespace SabreTools.Test.Parser
|
||||
string filename = System.IO.Path.Combine(Environment.CurrentDirectory, "TestData", path);
|
||||
|
||||
// Deserialize the file
|
||||
var dat = Serialization.Listxml.Deserialize(filename);
|
||||
var dat = new Serialization.Files.Listxml().Deserialize(filename);
|
||||
|
||||
// Validate the values
|
||||
Assert.NotNull(dat?.Game);
|
||||
@@ -506,7 +506,7 @@ namespace SabreTools.Test.Parser
|
||||
string filename = System.IO.Path.Combine(Environment.CurrentDirectory, "TestData", path);
|
||||
|
||||
// Deserialize the file
|
||||
var dat = Serialization.Logiqx.Deserialize(filename);
|
||||
var dat = new Serialization.Files.Logiqx().Deserialize(filename);
|
||||
|
||||
// Validate the values
|
||||
Assert.NotNull(dat?.Game);
|
||||
@@ -694,7 +694,7 @@ namespace SabreTools.Test.Parser
|
||||
string filename = System.IO.Path.Combine(Environment.CurrentDirectory, "TestData", path);
|
||||
|
||||
// Deserialize the file
|
||||
var dat = Serialization.OfflineList.Deserialize(filename);
|
||||
var dat = new Serialization.Files.OfflineList().Deserialize(filename);
|
||||
|
||||
// Validate the values
|
||||
Assert.NotNull(dat?.Games?.Game);
|
||||
@@ -899,7 +899,7 @@ namespace SabreTools.Test.Parser
|
||||
string filename = System.IO.Path.Combine(Environment.CurrentDirectory, "TestData", path);
|
||||
|
||||
// Deserialize the file
|
||||
var dat = Serialization.OpenMSX.Deserialize(filename);
|
||||
var dat = new Serialization.Files.OpenMSX().Deserialize(filename);
|
||||
|
||||
// Validate the values
|
||||
Assert.NotNull(dat);
|
||||
@@ -942,7 +942,7 @@ namespace SabreTools.Test.Parser
|
||||
string filename = System.IO.Path.Combine(Environment.CurrentDirectory, "TestData", path);
|
||||
|
||||
// Deserialize the file
|
||||
var dat = Serialization.RomCenter.Deserialize(filename);
|
||||
var dat = new Serialization.Files.RomCenter().Deserialize(filename);
|
||||
|
||||
// Validate the values
|
||||
Assert.NotNull(dat?.Games?.Rom);
|
||||
@@ -982,7 +982,7 @@ namespace SabreTools.Test.Parser
|
||||
string filename = System.IO.Path.Combine(Environment.CurrentDirectory, "TestData", path);
|
||||
|
||||
// Deserialize the file
|
||||
var dat = Serialization.SeparatedValue.Deserialize(filename, delim);
|
||||
var dat = new Serialization.Files.SeparatedValue().Deserialize(filename, delim);
|
||||
|
||||
// Validate the values
|
||||
Assert.NotNull(dat);
|
||||
@@ -1005,7 +1005,7 @@ namespace SabreTools.Test.Parser
|
||||
string filename = System.IO.Path.Combine(Environment.CurrentDirectory, "TestData", path);
|
||||
|
||||
// Deserialize the file
|
||||
var dat = Serialization.SoftawreList.Deserialize(filename);
|
||||
var dat = new Serialization.Files.SoftawreList().Deserialize(filename);
|
||||
|
||||
// Validate the values
|
||||
Assert.NotNull(dat);
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace SabreTools.Test.Parser
|
||||
var dat = GenerateOpenMSX();
|
||||
|
||||
// Deserialize the file
|
||||
var stream = Serialization.OpenMSX.SerializeToStream(dat) as System.IO.MemoryStream;
|
||||
var stream = new Serialization.Files.OpenMSX.SerializeToStream(dat) as System.IO.MemoryStream;
|
||||
|
||||
// Validate the values
|
||||
Assert.NotNull(stream);
|
||||
|
||||
@@ -36,8 +36,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SabreTools.Reports", "Sabre
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SabreTools.Test", "SabreTools.Test\SabreTools.Test.csproj", "{5B4E67D5-F4DA-4750-8FE2-04D08E343791}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SabreTools.Serialization", "SabreTools.Serialization\SabreTools.Serialization.csproj", "{E610285C-10E6-4724-B22C-4EADC11789B1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SabreTools.Filter", "SabreTools.Filter\SabreTools.Filter.csproj", "{2A7A27A9-5FB9-4F6D-88F3-67120668A029}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NaturalSort", "NaturalSort\NaturalSort.csproj", "{F7180B1C-7CFB-4526-8FF5-C31E7B049378}"
|
||||
@@ -154,14 +152,6 @@ Global
|
||||
{5B4E67D5-F4DA-4750-8FE2-04D08E343791}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5B4E67D5-F4DA-4750-8FE2-04D08E343791}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{5B4E67D5-F4DA-4750-8FE2-04D08E343791}.Release|x64.Build.0 = Release|Any CPU
|
||||
{E610285C-10E6-4724-B22C-4EADC11789B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E610285C-10E6-4724-B22C-4EADC11789B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E610285C-10E6-4724-B22C-4EADC11789B1}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{E610285C-10E6-4724-B22C-4EADC11789B1}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{E610285C-10E6-4724-B22C-4EADC11789B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E610285C-10E6-4724-B22C-4EADC11789B1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E610285C-10E6-4724-B22C-4EADC11789B1}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{E610285C-10E6-4724-B22C-4EADC11789B1}.Release|x64.Build.0 = Release|Any CPU
|
||||
{2A7A27A9-5FB9-4F6D-88F3-67120668A029}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2A7A27A9-5FB9-4F6D-88F3-67120668A029}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2A7A27A9-5FB9-4F6D-88F3-67120668A029}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
|
||||
Reference in New Issue
Block a user