Libraries

This change looks dramatic, but it's just separating out the already-split namespaces into separate top-level folders. In theory, every single one could be built into their own Nuget package. `SabreTools.Serialization` still builds the normal Nuget package that is used by all other projects and includes all namespaces.
This commit is contained in:
Matt Nadareski
2026-03-21 16:26:56 -04:00
parent bec0aeb04c
commit 7689c6dd07
1495 changed files with 841 additions and 338 deletions

View File

@@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using SabreTools.Data.Models.ArchiveDotOrg;
namespace SabreTools.Serialization.CrossModel
{
public partial class ArchiveDotOrg : BaseMetadataSerializer<Files>
{
/// <inheritdoc/>
public override Files? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{
if (obj is null)
return null;
var files = new Files();
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
var items = new List<File>();
foreach (var machine in machines ?? [])
{
items.AddRange(ConvertFromInternalModel(machine));
}
files.File = [.. items];
return files;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Machine"/> to an array of <see cref="File"/>
/// </summary>
private static File[] ConvertFromInternalModel(Data.Models.Metadata.Machine item)
{
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms is null)
return [];
return Array.ConvertAll(roms, ConvertFromInternalModel);
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="File"/>
/// </summary>
private static File ConvertFromInternalModel(Data.Models.Metadata.Rom item)
{
var file = new File
{
Name = item.ReadString(Data.Models.Metadata.Rom.NameKey),
Source = item.ReadString(Data.Models.Metadata.Rom.SourceKey),
BitTorrentMagnetHash = item.ReadString(Data.Models.Metadata.Rom.BitTorrentMagnetHashKey),
LastModifiedTime = item.ReadString(Data.Models.Metadata.Rom.LastModifiedTimeKey),
Size = item.ReadString(Data.Models.Metadata.Rom.SizeKey),
MD5 = item.ReadString(Data.Models.Metadata.Rom.MD5Key),
CRC32 = item.ReadString(Data.Models.Metadata.Rom.CRCKey),
SHA1 = item.ReadString(Data.Models.Metadata.Rom.SHA1Key),
FileCount = item.ReadString(Data.Models.Metadata.Rom.FileCountKey),
Format = item.ReadString(Data.Models.Metadata.Rom.FormatKey),
Original = item.ReadString(Data.Models.Metadata.Rom.OriginalKey),
Summation = item.ReadString(Data.Models.Metadata.Rom.SummationKey),
MatrixNumber = item.ReadString(Data.Models.Metadata.Rom.MatrixNumberKey),
CollectionCatalogNumber = item.ReadString(Data.Models.Metadata.Rom.CollectionCatalogNumberKey),
Publisher = item.ReadString(Data.Models.Metadata.Rom.PublisherKey),
Comment = item.ReadString(Data.Models.Metadata.Rom.CommentKey),
ASRDetectedLang = item.ReadString(Data.Models.Metadata.Rom.ASRDetectedLangKey),
ASRDetectedLangConf = item.ReadString(Data.Models.Metadata.Rom.ASRDetectedLangConfKey),
ASRTranscribedLang = item.ReadString(Data.Models.Metadata.Rom.ASRTranscribedLangKey),
WhisperASRModuleVersion = item.ReadString(Data.Models.Metadata.Rom.WhisperASRModuleVersionKey),
WhisperModelHash = item.ReadString(Data.Models.Metadata.Rom.WhisperModelHashKey),
WhisperModelName = item.ReadString(Data.Models.Metadata.Rom.WhisperModelNameKey),
WhisperVersion = item.ReadString(Data.Models.Metadata.Rom.WhisperVersionKey),
ClothCoverDetectionModuleVersion = item.ReadString(Data.Models.Metadata.Rom.ClothCoverDetectionModuleVersionKey),
hOCRCharToWordhOCRVersion = item.ReadString(Data.Models.Metadata.Rom.hOCRCharToWordhOCRVersionKey),
hOCRCharToWordModuleVersion = item.ReadString(Data.Models.Metadata.Rom.hOCRCharToWordModuleVersionKey),
hOCRFtsTexthOCRVersion = item.ReadString(Data.Models.Metadata.Rom.hOCRFtsTexthOCRVersionKey),
hOCRFtsTextModuleVersion = item.ReadString(Data.Models.Metadata.Rom.hOCRFtsTextModuleVersionKey),
hOCRPageIndexhOCRVersion = item.ReadString(Data.Models.Metadata.Rom.hOCRPageIndexhOCRVersionKey),
hOCRPageIndexModuleVersion = item.ReadString(Data.Models.Metadata.Rom.hOCRPageIndexModuleVersionKey),
TesseractOCR = item.ReadString(Data.Models.Metadata.Rom.TesseractOCRKey),
TesseractOCRConverted = item.ReadString(Data.Models.Metadata.Rom.TesseractOCRConvertedKey),
TesseractOCRDetectedLang = item.ReadString(Data.Models.Metadata.Rom.TesseractOCRDetectedLangKey),
TesseractOCRDetectedLangConf = item.ReadString(Data.Models.Metadata.Rom.TesseractOCRDetectedLangConfKey),
TesseractOCRDetectedScript = item.ReadString(Data.Models.Metadata.Rom.TesseractOCRDetectedScriptKey),
TesseractOCRDetectedScriptConf = item.ReadString(Data.Models.Metadata.Rom.TesseractOCRDetectedScriptConfKey),
TesseractOCRModuleVersion = item.ReadString(Data.Models.Metadata.Rom.TesseractOCRModuleVersionKey),
TesseractOCRParameters = item.ReadString(Data.Models.Metadata.Rom.TesseractOCRParametersKey),
PDFModuleVersion = item.ReadString(Data.Models.Metadata.Rom.PDFModuleVersionKey),
WordConfidenceInterval0To10 = item.ReadString(Data.Models.Metadata.Rom.WordConfidenceInterval0To10Key),
WordConfidenceInterval11To20 = item.ReadString(Data.Models.Metadata.Rom.WordConfidenceInterval11To20Key),
WordConfidenceInterval21To30 = item.ReadString(Data.Models.Metadata.Rom.WordConfidenceInterval21To30Key),
WordConfidenceInterval31To40 = item.ReadString(Data.Models.Metadata.Rom.WordConfidenceInterval31To40Key),
WordConfidenceInterval41To50 = item.ReadString(Data.Models.Metadata.Rom.WordConfidenceInterval41To50Key),
WordConfidenceInterval51To60 = item.ReadString(Data.Models.Metadata.Rom.WordConfidenceInterval51To60Key),
WordConfidenceInterval61To70 = item.ReadString(Data.Models.Metadata.Rom.WordConfidenceInterval61To70Key),
WordConfidenceInterval71To80 = item.ReadString(Data.Models.Metadata.Rom.WordConfidenceInterval71To80Key),
WordConfidenceInterval81To90 = item.ReadString(Data.Models.Metadata.Rom.WordConfidenceInterval81To90Key),
WordConfidenceInterval91To100 = item.ReadString(Data.Models.Metadata.Rom.WordConfidenceInterval91To100Key),
Album = item.ReadString(Data.Models.Metadata.Rom.AlbumKey),
Artist = item.ReadString(Data.Models.Metadata.Rom.ArtistKey),
Bitrate = item.ReadString(Data.Models.Metadata.Rom.BitrateKey),
Creator = item.ReadString(Data.Models.Metadata.Rom.CreatorKey),
Height = item.ReadString(Data.Models.Metadata.Rom.HeightKey),
Length = item.ReadString(Data.Models.Metadata.Rom.LengthKey),
PreviewImage = item.ReadString(Data.Models.Metadata.Rom.PreviewImageKey),
Rotation = item.ReadString(Data.Models.Metadata.Rom.RotationKey),
Title = item.ReadString(Data.Models.Metadata.Rom.TitleKey),
Track = item.ReadString(Data.Models.Metadata.Rom.TrackKey),
Width = item.ReadString(Data.Models.Metadata.Rom.WidthKey),
};
return file;
}
}
}

View File

@@ -0,0 +1,131 @@
using System;
using SabreTools.Data.Models.ArchiveDotOrg;
namespace SabreTools.Serialization.CrossModel
{
public partial class ArchiveDotOrg : BaseMetadataSerializer<Files>
{
/// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(Files? item)
{
if (item is null)
return null;
var metadataFile = new Data.Models.Metadata.MetadataFile
{
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(),
};
if (item?.File is not null && item.File.Length > 0)
{
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(item.File, ConvertMachineToInternalModel);
}
return metadataFile;
}
/// <summary>
/// Convert from <see cref="Files"/> to <see cref="Models.Metadata.Header"/>
/// </summary>
private static Data.Models.Metadata.Header ConvertHeaderToInternalModel()
{
var header = new Data.Models.Metadata.Header
{
[Data.Models.Metadata.Header.NameKey] = "archive.org",
};
return header;
}
/// <summary>
/// Convert from <see cref="File"/> to <see cref="Models.Metadata.Machine"/>
/// </summary>
private static Data.Models.Metadata.Machine ConvertMachineToInternalModel(File? item)
{
var machine = new Data.Models.Metadata.Machine();
var rom = ConvertToInternalModel(item);
if (rom is not null)
machine[Data.Models.Metadata.Machine.RomKey] = new Data.Models.Metadata.Rom[] { rom };
return machine;
}
/// <summary>
/// Convert from <see cref="File"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
private static Data.Models.Metadata.Rom? ConvertToInternalModel(File? item)
{
if (item is null)
return null;
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.NameKey] = item.Name,
[Data.Models.Metadata.Rom.SourceKey] = item.Source,
[Data.Models.Metadata.Rom.BitTorrentMagnetHashKey] = item.BitTorrentMagnetHash,
[Data.Models.Metadata.Rom.LastModifiedTimeKey] = item.LastModifiedTime,
[Data.Models.Metadata.Rom.SizeKey] = item.Size,
[Data.Models.Metadata.Rom.MD5Key] = item.MD5,
[Data.Models.Metadata.Rom.CRCKey] = item.CRC32,
[Data.Models.Metadata.Rom.SHA1Key] = item.SHA1,
[Data.Models.Metadata.Rom.FileCountKey] = item.FileCount,
[Data.Models.Metadata.Rom.FormatKey] = item.Format,
[Data.Models.Metadata.Rom.OriginalKey] = item.Original,
[Data.Models.Metadata.Rom.SummationKey] = item.Summation,
[Data.Models.Metadata.Rom.MatrixNumberKey] = item.MatrixNumber,
[Data.Models.Metadata.Rom.CollectionCatalogNumberKey] = item.CollectionCatalogNumber,
[Data.Models.Metadata.Rom.PublisherKey] = item.Publisher,
[Data.Models.Metadata.Rom.CommentKey] = item.Comment,
[Data.Models.Metadata.Rom.ASRDetectedLangKey] = item.ASRDetectedLang,
[Data.Models.Metadata.Rom.ASRDetectedLangConfKey] = item.ASRDetectedLangConf,
[Data.Models.Metadata.Rom.ASRTranscribedLangKey] = item.ASRTranscribedLang,
[Data.Models.Metadata.Rom.WhisperASRModuleVersionKey] = item.WhisperASRModuleVersion,
[Data.Models.Metadata.Rom.WhisperModelHashKey] = item.WhisperModelHash,
[Data.Models.Metadata.Rom.WhisperModelNameKey] = item.WhisperModelName,
[Data.Models.Metadata.Rom.WhisperVersionKey] = item.WhisperVersion,
[Data.Models.Metadata.Rom.ClothCoverDetectionModuleVersionKey] = item.ClothCoverDetectionModuleVersion,
[Data.Models.Metadata.Rom.hOCRCharToWordhOCRVersionKey] = item.hOCRCharToWordhOCRVersion,
[Data.Models.Metadata.Rom.hOCRCharToWordModuleVersionKey] = item.hOCRCharToWordModuleVersion,
[Data.Models.Metadata.Rom.hOCRFtsTexthOCRVersionKey] = item.hOCRFtsTexthOCRVersion,
[Data.Models.Metadata.Rom.hOCRFtsTextModuleVersionKey] = item.hOCRFtsTextModuleVersion,
[Data.Models.Metadata.Rom.hOCRPageIndexhOCRVersionKey] = item.hOCRPageIndexhOCRVersion,
[Data.Models.Metadata.Rom.hOCRPageIndexModuleVersionKey] = item.hOCRPageIndexModuleVersion,
[Data.Models.Metadata.Rom.TesseractOCRKey] = item.TesseractOCR,
[Data.Models.Metadata.Rom.TesseractOCRConvertedKey] = item.TesseractOCRConverted,
[Data.Models.Metadata.Rom.TesseractOCRDetectedLangKey] = item.TesseractOCRDetectedLang,
[Data.Models.Metadata.Rom.TesseractOCRDetectedLangConfKey] = item.TesseractOCRDetectedLangConf,
[Data.Models.Metadata.Rom.TesseractOCRDetectedScriptKey] = item.TesseractOCRDetectedScript,
[Data.Models.Metadata.Rom.TesseractOCRDetectedScriptConfKey] = item.TesseractOCRDetectedScriptConf,
[Data.Models.Metadata.Rom.TesseractOCRModuleVersionKey] = item.TesseractOCRModuleVersion,
[Data.Models.Metadata.Rom.TesseractOCRParametersKey] = item.TesseractOCRParameters,
[Data.Models.Metadata.Rom.PDFModuleVersionKey] = item.PDFModuleVersion,
[Data.Models.Metadata.Rom.WordConfidenceInterval0To10Key] = item.WordConfidenceInterval0To10,
[Data.Models.Metadata.Rom.WordConfidenceInterval11To20Key] = item.WordConfidenceInterval11To20,
[Data.Models.Metadata.Rom.WordConfidenceInterval21To30Key] = item.WordConfidenceInterval21To30,
[Data.Models.Metadata.Rom.WordConfidenceInterval31To40Key] = item.WordConfidenceInterval31To40,
[Data.Models.Metadata.Rom.WordConfidenceInterval41To50Key] = item.WordConfidenceInterval41To50,
[Data.Models.Metadata.Rom.WordConfidenceInterval51To60Key] = item.WordConfidenceInterval51To60,
[Data.Models.Metadata.Rom.WordConfidenceInterval61To70Key] = item.WordConfidenceInterval61To70,
[Data.Models.Metadata.Rom.WordConfidenceInterval71To80Key] = item.WordConfidenceInterval71To80,
[Data.Models.Metadata.Rom.WordConfidenceInterval81To90Key] = item.WordConfidenceInterval81To90,
[Data.Models.Metadata.Rom.WordConfidenceInterval91To100Key] = item.WordConfidenceInterval91To100,
[Data.Models.Metadata.Rom.AlbumKey] = item.Album,
[Data.Models.Metadata.Rom.ArtistKey] = item.Artist,
[Data.Models.Metadata.Rom.BitrateKey] = item.Bitrate,
[Data.Models.Metadata.Rom.CreatorKey] = item.Creator,
[Data.Models.Metadata.Rom.HeightKey] = item.Height,
[Data.Models.Metadata.Rom.LengthKey] = item.Length,
[Data.Models.Metadata.Rom.PreviewImageKey] = item.PreviewImage,
[Data.Models.Metadata.Rom.RotationKey] = item.Rotation,
[Data.Models.Metadata.Rom.TitleKey] = item.Title,
[Data.Models.Metadata.Rom.TrackKey] = item.Track,
[Data.Models.Metadata.Rom.WidthKey] = item.Width,
};
return rom;
}
}
}

View File

@@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using SabreTools.Data.Models.AttractMode;
namespace SabreTools.Serialization.CrossModel
{
public partial class AttractMode : BaseMetadataSerializer<MetadataFile>
{
/// <inheritdoc/>
public override MetadataFile? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{
if (obj is null)
return null;
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
var metadataFile = header is not null ? ConvertHeaderFromInternalModel(header) : new MetadataFile();
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
var items = new List<Row>();
foreach (var machine in machines ?? [])
{
items.AddRange(ConvertMachineFromInternalModel(machine));
}
metadataFile.Row = [.. items];
return metadataFile;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Header"/> to <see cref="MetadataFile"/>
/// </summary>
private static MetadataFile ConvertHeaderFromInternalModel(Data.Models.Metadata.Header item)
{
var metadataFile = new MetadataFile
{
Header = item.ReadStringArray(Data.Models.Metadata.Header.HeaderKey),
};
return metadataFile;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Machine"/> to an array of <see cref="Row"/>
/// </summary>
private static Row[] ConvertMachineFromInternalModel(Data.Models.Metadata.Machine item)
{
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms is null || roms.Length == 0)
return [];
return Array.ConvertAll(roms, r => ConvertFromInternalModel(r, item));
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="Row"/>
/// </summary>
private static Row ConvertFromInternalModel(Data.Models.Metadata.Rom item, Data.Models.Metadata.Machine parent)
{
var row = new Row
{
Name = parent.ReadString(Data.Models.Metadata.Machine.NameKey),
Title = item.ReadString(Data.Models.Metadata.Rom.NameKey),
Emulator = parent.ReadString(Data.Models.Metadata.Machine.EmulatorKey),
CloneOf = parent.ReadString(Data.Models.Metadata.Machine.CloneOfKey),
Year = parent.ReadString(Data.Models.Metadata.Machine.YearKey),
Manufacturer = parent.ReadString(Data.Models.Metadata.Machine.ManufacturerKey),
Category = parent.ReadString(Data.Models.Metadata.Machine.CategoryKey),
Players = parent.ReadString(Data.Models.Metadata.Machine.PlayersKey),
Rotation = parent.ReadString(Data.Models.Metadata.Machine.RotationKey),
Control = parent.ReadString(Data.Models.Metadata.Machine.ControlKey),
Status = parent.ReadString(Data.Models.Metadata.Machine.StatusKey),
DisplayCount = parent.ReadString(Data.Models.Metadata.Machine.DisplayCountKey),
DisplayType = parent.ReadString(Data.Models.Metadata.Machine.DisplayTypeKey),
AltRomname = item.ReadString(Data.Models.Metadata.Rom.AltRomnameKey),
AltTitle = item.ReadString(Data.Models.Metadata.Rom.AltTitleKey),
Extra = parent.ReadString(Data.Models.Metadata.Machine.ExtraKey),
Buttons = parent.ReadString(Data.Models.Metadata.Machine.ButtonsKey),
Favorite = parent.ReadString(Data.Models.Metadata.Machine.FavoriteKey),
Tags = parent.ReadString(Data.Models.Metadata.Machine.TagsKey),
PlayedCount = parent.ReadString(Data.Models.Metadata.Machine.PlayedCountKey),
PlayedTime = parent.ReadString(Data.Models.Metadata.Machine.PlayedTimeKey),
FileIsAvailable = item.ReadString(Data.Models.Metadata.Rom.FileIsAvailableKey),
};
return row;
}
}
}

View File

@@ -0,0 +1,88 @@
using System;
using SabreTools.Data.Models.AttractMode;
namespace SabreTools.Serialization.CrossModel
{
public partial class AttractMode : BaseMetadataSerializer<MetadataFile>
{
/// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
{
if (obj is null)
return null;
var metadataFile = new Data.Models.Metadata.MetadataFile
{
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(obj),
};
if (obj?.Row is not null && obj.Row.Length > 0)
{
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(obj.Row, ConvertMachineToInternalModel);
}
return metadataFile;
}
/// <summary>
/// Convert from <see cref="MetadataFile"/> to <see cref="Models.Metadata.Header"/>
/// </summary>
private static Data.Models.Metadata.Header ConvertHeaderToInternalModel(MetadataFile item)
{
var header = new Data.Models.Metadata.Header
{
[Data.Models.Metadata.Header.HeaderKey] = item.Header,
};
return header;
}
/// <summary>
/// Convert from <see cref="Row"/> to <see cref="Models.Metadata.Machine"/>
/// </summary>
private static Data.Models.Metadata.Machine? ConvertMachineToInternalModel(Row? item)
{
if (item is null)
return null;
var machine = new Data.Models.Metadata.Machine
{
[Data.Models.Metadata.Machine.NameKey] = item.Name,
[Data.Models.Metadata.Machine.EmulatorKey] = item.Emulator,
[Data.Models.Metadata.Machine.CloneOfKey] = item.CloneOf,
[Data.Models.Metadata.Machine.YearKey] = item.Year,
[Data.Models.Metadata.Machine.ManufacturerKey] = item.Manufacturer,
[Data.Models.Metadata.Machine.CategoryKey] = item.Category,
[Data.Models.Metadata.Machine.PlayersKey] = item.Players,
[Data.Models.Metadata.Machine.RotationKey] = item.Rotation,
[Data.Models.Metadata.Machine.ControlKey] = item.Control,
[Data.Models.Metadata.Machine.StatusKey] = item.Status,
[Data.Models.Metadata.Machine.DisplayCountKey] = item.DisplayCount,
[Data.Models.Metadata.Machine.DisplayTypeKey] = item.DisplayType,
[Data.Models.Metadata.Machine.ExtraKey] = item.Extra,
[Data.Models.Metadata.Machine.ButtonsKey] = item.Buttons,
[Data.Models.Metadata.Machine.FavoriteKey] = item.Favorite,
[Data.Models.Metadata.Machine.TagsKey] = item.Tags,
[Data.Models.Metadata.Machine.PlayedCountKey] = item.PlayedCount,
[Data.Models.Metadata.Machine.PlayedTimeKey] = item.PlayedTime,
[Data.Models.Metadata.Machine.RomKey] = new Data.Models.Metadata.Rom[] { ConvertToInternalModel(item) },
};
return machine;
}
/// <summary>
/// Convert from <see cref="Row"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
private static Data.Models.Metadata.Rom ConvertToInternalModel(Row item)
{
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.NameKey] = item.Title,
[Data.Models.Metadata.Rom.AltRomnameKey] = item.AltRomname,
[Data.Models.Metadata.Rom.AltTitleKey] = item.AltTitle,
[Data.Models.Metadata.Rom.FileIsAvailableKey] = item.FileIsAvailable,
};
return rom;
}
}
}

View File

@@ -0,0 +1,20 @@
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Serialization.CrossModel
{
/// <summary>
/// Base class for <see cref="MetadataFile"/> cross-model serializers
/// </summary>
/// <typeparam name="TModel">Model convertable to <see cref="MetadataFile"/></typeparam>
public abstract class BaseMetadataSerializer<TModel> : ICrossModel<TModel, MetadataFile>
{
/// <inheritdoc/>
public bool Debug { get; set; } = false;
/// <inheritdoc/>
public abstract TModel? Deserialize(MetadataFile? obj);
/// <inheritdoc/>
public abstract MetadataFile? Serialize(TModel? obj);
}
}

View File

@@ -0,0 +1,368 @@
using System;
using SabreTools.Data.Models.ClrMamePro;
#pragma warning disable CA1822 // Mark members as static
namespace SabreTools.Serialization.CrossModel
{
public partial class ClrMamePro : BaseMetadataSerializer<MetadataFile>
{
/// <inheritdoc/>
public override MetadataFile? Deserialize(Data.Models.Metadata.MetadataFile? obj)
=> Deserialize(obj, true);
/// <inheritdoc cref="Deserialize(Data.Models.Metadata.MetadataFile)"/>
public MetadataFile? Deserialize(Data.Models.Metadata.MetadataFile? obj, bool game)
{
if (obj is null)
return null;
var metadataFile = new MetadataFile();
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
if (header is not null)
metadataFile.ClrMamePro = ConvertHeaderFromInternalModel(header);
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
if (machines is not null && machines.Length > 0)
{
metadataFile.Game
= Array.ConvertAll(machines, m => ConvertMachineFromInternalModel(m, game));
}
var info = obj.Read<Data.Models.Metadata.InfoSource>(Data.Models.Metadata.MetadataFile.InfoSourceKey);
if (info is not null)
metadataFile.Info = ConvertInfoSourceFromInternalModel(info);
return metadataFile;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Header"/> to <see cref="Models.ClrMamePro.ClrMamePro"/>
/// </summary>
private static Data.Models.ClrMamePro.ClrMamePro ConvertHeaderFromInternalModel(Data.Models.Metadata.Header item)
{
var clrMamePro = new Data.Models.ClrMamePro.ClrMamePro
{
Name = item.ReadString(Data.Models.Metadata.Header.NameKey),
Description = item.ReadString(Data.Models.Metadata.Header.DescriptionKey),
RootDir = item.ReadString(Data.Models.Metadata.Header.RootDirKey),
Category = item.ReadString(Data.Models.Metadata.Header.CategoryKey),
Version = item.ReadString(Data.Models.Metadata.Header.VersionKey),
Date = item.ReadString(Data.Models.Metadata.Header.DateKey),
Author = item.ReadString(Data.Models.Metadata.Header.AuthorKey),
Homepage = item.ReadString(Data.Models.Metadata.Header.HomepageKey),
Url = item.ReadString(Data.Models.Metadata.Header.UrlKey),
Comment = item.ReadString(Data.Models.Metadata.Header.CommentKey),
Header = item.ReadString(Data.Models.Metadata.Header.HeaderKey),
Type = item.ReadString(Data.Models.Metadata.Header.TypeKey),
ForceMerging = item.ReadString(Data.Models.Metadata.Header.ForceMergingKey),
ForceZipping = item.ReadString(Data.Models.Metadata.Header.ForceZippingKey),
ForcePacking = item.ReadString(Data.Models.Metadata.Header.ForcePackingKey),
};
return clrMamePro;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Archive"/> to <see cref="Machine"/>
/// </summary>
private static GameBase ConvertMachineFromInternalModel(Data.Models.Metadata.Machine item, bool game)
{
GameBase gameBase = game ? new Game() : new Machine();
gameBase.Name = item.ReadString(Data.Models.Metadata.Machine.NameKey);
gameBase.Description = item.ReadString(Data.Models.Metadata.Machine.DescriptionKey);
// gameBase.DriverStatus = item.ReadString(Data.Models.Metadata.Machine.DriverKey); // TODO: Needs metadata mapping
gameBase.Year = item.ReadString(Data.Models.Metadata.Machine.YearKey);
gameBase.Manufacturer = item.ReadString(Data.Models.Metadata.Machine.ManufacturerKey);
gameBase.Category = item.ReadString(Data.Models.Metadata.Machine.CategoryKey);
gameBase.CloneOf = item.ReadString(Data.Models.Metadata.Machine.CloneOfKey);
gameBase.RomOf = item.ReadString(Data.Models.Metadata.Machine.RomOfKey);
gameBase.SampleOf = item.ReadString(Data.Models.Metadata.Machine.SampleOfKey);
var releases = item.Read<Data.Models.Metadata.Release[]>(Data.Models.Metadata.Machine.ReleaseKey);
if (releases is not null && releases.Length > 0)
gameBase.Release = Array.ConvertAll(releases, ConvertFromInternalModel);
var biosSets = item.Read<Data.Models.Metadata.BiosSet[]>(Data.Models.Metadata.Machine.BiosSetKey);
if (biosSets is not null && biosSets.Length > 0)
gameBase.BiosSet = Array.ConvertAll(biosSets, ConvertFromInternalModel);
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms is not null && roms.Length > 0)
gameBase.Rom = Array.ConvertAll(roms, ConvertFromInternalModel);
var disks = item.Read<Data.Models.Metadata.Disk[]>(Data.Models.Metadata.Machine.DiskKey);
if (disks is not null && disks.Length > 0)
gameBase.Disk = Array.ConvertAll(disks, ConvertFromInternalModel);
var medias = item.Read<Data.Models.Metadata.Media[]>(Data.Models.Metadata.Machine.MediaKey);
if (medias is not null && medias.Length > 0)
gameBase.Media = Array.ConvertAll(medias, ConvertFromInternalModel);
var samples = item.Read<Data.Models.Metadata.Sample[]>(Data.Models.Metadata.Machine.SampleKey);
if (samples is not null && samples.Length > 0)
gameBase.Sample = Array.ConvertAll(samples, ConvertFromInternalModel);
var archives = item.Read<Data.Models.Metadata.Archive[]>(Data.Models.Metadata.Machine.ArchiveKey);
if (archives is not null && archives.Length > 0)
gameBase.Archive = Array.ConvertAll(archives, ConvertFromInternalModel);
var chips = item.Read<Data.Models.Metadata.Chip[]>(Data.Models.Metadata.Machine.ChipKey);
if (chips is not null && chips.Length > 0)
gameBase.Chip = Array.ConvertAll(chips, ConvertFromInternalModel);
var videos = item.Read<Data.Models.Metadata.Video[]>(Data.Models.Metadata.Machine.VideoKey);
if (videos is not null && videos.Length > 0)
gameBase.Video = Array.ConvertAll(videos, ConvertFromInternalModel);
var sound = item.Read<Data.Models.Metadata.Sound>(Data.Models.Metadata.Machine.SoundKey);
if (sound is not null)
gameBase.Sound = ConvertFromInternalModel(sound);
var input = item.Read<Data.Models.Metadata.Input>(Data.Models.Metadata.Machine.InputKey);
if (input is not null)
gameBase.Input = ConvertFromInternalModel(input);
var dipSwitches = item.Read<Data.Models.Metadata.DipSwitch[]>(Data.Models.Metadata.Machine.DipSwitchKey);
if (dipSwitches is not null && dipSwitches.Length > 0)
gameBase.DipSwitch = Array.ConvertAll(dipSwitches, ConvertFromInternalModel);
var driver = item.Read<Data.Models.Metadata.Driver>(Data.Models.Metadata.Machine.DriverKey);
if (driver is not null)
gameBase.Driver = ConvertFromInternalModel(driver);
return gameBase;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Archive"/> to <see cref="Archive"/>
/// </summary>
private static Archive ConvertFromInternalModel(Data.Models.Metadata.Archive item)
{
var archive = new Archive
{
Name = item.ReadString(Data.Models.Metadata.Archive.NameKey),
};
return archive;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.BiosSet"/> to <see cref="BiosSet"/>
/// </summary>
private static BiosSet ConvertFromInternalModel(Data.Models.Metadata.BiosSet item)
{
var biosset = new BiosSet
{
Name = item.ReadString(Data.Models.Metadata.BiosSet.NameKey),
Description = item.ReadString(Data.Models.Metadata.BiosSet.DescriptionKey),
Default = item.ReadString(Data.Models.Metadata.BiosSet.DefaultKey),
};
return biosset;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Chip"/> to <see cref="Chip"/>
/// </summary>
private static Chip ConvertFromInternalModel(Data.Models.Metadata.Chip item)
{
var chip = new Chip
{
Type = item.ReadString(Data.Models.Metadata.Chip.ChipTypeKey),
Name = item.ReadString(Data.Models.Metadata.Chip.NameKey),
Flags = item.ReadString(Data.Models.Metadata.Chip.FlagsKey),
Clock = item.ReadString(Data.Models.Metadata.Chip.ClockKey),
};
return chip;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.DipSwitch"/> to <see cref="DipSwitch"/>
/// </summary>
private static DipSwitch ConvertFromInternalModel(Data.Models.Metadata.DipSwitch item)
{
var dipswitch = new DipSwitch
{
Name = item.ReadString(Data.Models.Metadata.DipSwitch.NameKey),
Entry = item[Data.Models.Metadata.DipSwitch.EntryKey] as string[],
Default = item.ReadString(Data.Models.Metadata.DipSwitch.DefaultKey),
};
return dipswitch;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Disk"/> to <see cref="Disk"/>
/// </summary>
private static Disk ConvertFromInternalModel(Data.Models.Metadata.Disk item)
{
var disk = new Disk
{
Name = item.ReadString(Data.Models.Metadata.Disk.NameKey),
MD5 = item.ReadString(Data.Models.Metadata.Disk.MD5Key),
SHA1 = item.ReadString(Data.Models.Metadata.Disk.SHA1Key),
Merge = item.ReadString(Data.Models.Metadata.Disk.MergeKey),
Status = item.ReadString(Data.Models.Metadata.Disk.StatusKey),
Flags = item.ReadString(Data.Models.Metadata.Disk.FlagsKey),
};
return disk;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Driver"/> to <see cref="Driver"/>
/// </summary>
private static Driver ConvertFromInternalModel(Data.Models.Metadata.Driver item)
{
var driver = new Driver
{
Status = item.ReadString(Data.Models.Metadata.Driver.StatusKey),
Color = item.ReadString(Data.Models.Metadata.Driver.ColorKey),
Sound = item.ReadString(Data.Models.Metadata.Driver.SoundKey),
PaletteSize = item.ReadString(Data.Models.Metadata.Driver.PaletteSizeKey),
Blit = item.ReadString(Data.Models.Metadata.Driver.BlitKey),
};
return driver;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Input"/> to <see cref="Input"/>
/// </summary>
private static Input ConvertFromInternalModel(Data.Models.Metadata.Input item)
{
var input = new Input
{
Players = item.ReadString(Data.Models.Metadata.Input.PlayersKey),
Control = item.ReadString(Data.Models.Metadata.Input.ControlKey),
Buttons = item.ReadString(Data.Models.Metadata.Input.ButtonsKey),
Coins = item.ReadString(Data.Models.Metadata.Input.CoinsKey),
Tilt = item.ReadString(Data.Models.Metadata.Input.TiltKey),
Service = item.ReadString(Data.Models.Metadata.Input.ServiceKey),
};
return input;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Media"/> to <see cref="Media"/>
/// </summary>
private static Media ConvertFromInternalModel(Data.Models.Metadata.Media item)
{
var media = new Media
{
Name = item.ReadString(Data.Models.Metadata.Media.NameKey),
MD5 = item.ReadString(Data.Models.Metadata.Media.MD5Key),
SHA1 = item.ReadString(Data.Models.Metadata.Media.SHA1Key),
SHA256 = item.ReadString(Data.Models.Metadata.Media.SHA256Key),
SpamSum = item.ReadString(Data.Models.Metadata.Media.SpamSumKey),
};
return media;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Release"/> to <see cref="Release"/>
/// </summary>
private static Release ConvertFromInternalModel(Data.Models.Metadata.Release item)
{
var release = new Release
{
Name = item.ReadString(Data.Models.Metadata.Release.NameKey),
Region = item.ReadString(Data.Models.Metadata.Release.RegionKey),
Language = item.ReadString(Data.Models.Metadata.Release.LanguageKey),
Date = item.ReadString(Data.Models.Metadata.Release.DateKey),
Default = item.ReadString(Data.Models.Metadata.Release.DefaultKey),
};
return release;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="Rom"/>
/// </summary>
private static Rom ConvertFromInternalModel(Data.Models.Metadata.Rom item)
{
var rom = new Rom
{
Name = item.ReadString(Data.Models.Metadata.Rom.NameKey),
Size = item.ReadString(Data.Models.Metadata.Rom.SizeKey),
CRC16 = item.ReadString(Data.Models.Metadata.Rom.CRC16Key),
CRC = item.ReadString(Data.Models.Metadata.Rom.CRCKey),
CRC64 = item.ReadString(Data.Models.Metadata.Rom.CRC64Key),
MD2 = item.ReadString(Data.Models.Metadata.Rom.MD2Key),
MD4 = item.ReadString(Data.Models.Metadata.Rom.MD4Key),
MD5 = item.ReadString(Data.Models.Metadata.Rom.MD5Key),
RIPEMD128 = item.ReadString(Data.Models.Metadata.Rom.RIPEMD128Key),
RIPEMD160 = item.ReadString(Data.Models.Metadata.Rom.RIPEMD160Key),
SHA1 = item.ReadString(Data.Models.Metadata.Rom.SHA1Key),
SHA256 = item.ReadString(Data.Models.Metadata.Rom.SHA256Key),
SHA384 = item.ReadString(Data.Models.Metadata.Rom.SHA384Key),
SHA512 = item.ReadString(Data.Models.Metadata.Rom.SHA512Key),
SpamSum = item.ReadString(Data.Models.Metadata.Rom.SpamSumKey),
xxHash364 = item.ReadString(Data.Models.Metadata.Rom.xxHash364Key),
xxHash3128 = item.ReadString(Data.Models.Metadata.Rom.xxHash3128Key),
Merge = item.ReadString(Data.Models.Metadata.Rom.MergeKey),
Status = item.ReadString(Data.Models.Metadata.Rom.StatusKey),
Region = item.ReadString(Data.Models.Metadata.Rom.RegionKey),
Flags = item.ReadString(Data.Models.Metadata.Rom.FlagsKey),
Offs = item.ReadString(Data.Models.Metadata.Rom.OffsetKey),
Serial = item.ReadString(Data.Models.Metadata.Rom.SerialKey),
Header = item.ReadString(Data.Models.Metadata.Rom.HeaderKey),
Date = item.ReadString(Data.Models.Metadata.Rom.DateKey),
Inverted = item.ReadString(Data.Models.Metadata.Rom.InvertedKey),
MIA = item.ReadString(Data.Models.Metadata.Rom.MIAKey),
};
return rom;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Sample"/> to <see cref="Sample"/>
/// </summary>
private static Sample ConvertFromInternalModel(Data.Models.Metadata.Sample item)
{
var sample = new Sample
{
Name = item.ReadString(Data.Models.Metadata.Sample.NameKey),
};
return sample;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Sound"/> to <see cref="Sound"/>
/// </summary>
private static Sound ConvertFromInternalModel(Data.Models.Metadata.Sound item)
{
var sound = new Sound
{
Channels = item.ReadString(Data.Models.Metadata.Sound.ChannelsKey),
};
return sound;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Video"/> to <see cref="Video"/>
/// </summary>
private static Video ConvertFromInternalModel(Data.Models.Metadata.Video item)
{
var video = new Video
{
Screen = item.ReadString(Data.Models.Metadata.Video.ScreenKey),
Orientation = item.ReadString(Data.Models.Metadata.Video.OrientationKey),
X = item.ReadString(Data.Models.Metadata.Video.WidthKey),
Y = item.ReadString(Data.Models.Metadata.Video.HeightKey),
AspectX = item.ReadString(Data.Models.Metadata.Video.AspectXKey),
AspectY = item.ReadString(Data.Models.Metadata.Video.AspectYKey),
Freq = item.ReadString(Data.Models.Metadata.Video.RefreshKey),
};
return video;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.InfoSource"/> to <see cref="Models.ClrMamePro.Info"/>
/// </summary>
private static Info ConvertInfoSourceFromInternalModel(Data.Models.Metadata.InfoSource item)
{
var info = new Info();
var sources = item.Read<string[]>(Data.Models.Metadata.InfoSource.SourceKey);
if (sources is not null && sources.Length > 0)
info.Source = [.. sources];
return info;
}
}
}

View File

@@ -0,0 +1,384 @@
using System;
using SabreTools.Data.Models.ClrMamePro;
namespace SabreTools.Serialization.CrossModel
{
public partial class ClrMamePro : BaseMetadataSerializer<MetadataFile>
{
/// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
{
if (obj is null)
return null;
var metadataFile = new Data.Models.Metadata.MetadataFile();
if (obj?.ClrMamePro is not null)
metadataFile[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(obj.ClrMamePro);
if (obj?.Game is not null && obj.Game.Length > 0)
{
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(obj.Game, ConvertMachineToInternalModel);
}
if (obj?.Info is not null)
metadataFile[Data.Models.Metadata.MetadataFile.InfoSourceKey] = ConvertInfoSourceToInternalModel(obj.Info);
return metadataFile;
}
/// <summary>
/// Convert from <see cref="Models.ClrMamePro.ClrMamePro"/> to <see cref="Models.Metadata.Header"/>
/// </summary>
private static Data.Models.Metadata.Header ConvertHeaderToInternalModel(Data.Models.ClrMamePro.ClrMamePro item)
{
var header = new Data.Models.Metadata.Header
{
[Data.Models.Metadata.Header.NameKey] = item.Name,
[Data.Models.Metadata.Header.DescriptionKey] = item.Description,
[Data.Models.Metadata.Header.RootDirKey] = item.RootDir,
[Data.Models.Metadata.Header.CategoryKey] = item.Category,
[Data.Models.Metadata.Header.VersionKey] = item.Version,
[Data.Models.Metadata.Header.DateKey] = item.Date,
[Data.Models.Metadata.Header.AuthorKey] = item.Author,
[Data.Models.Metadata.Header.HomepageKey] = item.Homepage,
[Data.Models.Metadata.Header.UrlKey] = item.Url,
[Data.Models.Metadata.Header.CommentKey] = item.Comment,
[Data.Models.Metadata.Header.HeaderKey] = item.Header,
[Data.Models.Metadata.Header.TypeKey] = item.Type,
[Data.Models.Metadata.Header.ForceMergingKey] = item.ForceMerging,
[Data.Models.Metadata.Header.ForceZippingKey] = item.ForceZipping,
[Data.Models.Metadata.Header.ForcePackingKey] = item.ForcePacking,
};
return header;
}
/// <summary>
/// Convert from <see cref="GameBase"/> to <see cref="Models.Metadata.Machine"/>
/// </summary>
private static Data.Models.Metadata.Machine? ConvertMachineToInternalModel(GameBase? item)
{
if (item is null)
return null;
var machine = new Data.Models.Metadata.Machine
{
[Data.Models.Metadata.Machine.NameKey] = item.Name,
[Data.Models.Metadata.Machine.DescriptionKey] = item.Description,
// [Data.Models.Metadata.Machine.DriverKey] = item.DriverStatus, // TODO: Needs metadata mapping
[Data.Models.Metadata.Machine.YearKey] = item.Year,
[Data.Models.Metadata.Machine.ManufacturerKey] = item.Manufacturer,
[Data.Models.Metadata.Machine.CategoryKey] = item.Category,
[Data.Models.Metadata.Machine.CloneOfKey] = item.CloneOf,
[Data.Models.Metadata.Machine.RomOfKey] = item.RomOf,
[Data.Models.Metadata.Machine.SampleOfKey] = item.SampleOf,
};
if (item.Release is not null && item.Release.Length > 0)
{
machine[Data.Models.Metadata.Machine.ReleaseKey]
= Array.ConvertAll(item.Release, ConvertToInternalModel);
}
if (item.BiosSet is not null && item.BiosSet.Length > 0)
{
machine[Data.Models.Metadata.Machine.BiosSetKey]
= Array.ConvertAll(item.BiosSet, ConvertToInternalModel);
}
if (item.Rom is not null && item.Rom.Length > 0)
{
machine[Data.Models.Metadata.Machine.RomKey]
= Array.ConvertAll(item.Rom, ConvertToInternalModel);
}
if (item.Disk is not null && item.Disk.Length > 0)
{
machine[Data.Models.Metadata.Machine.DiskKey]
= Array.ConvertAll(item.Disk, ConvertToInternalModel);
}
if (item.Media is not null && item.Media.Length > 0)
{
machine[Data.Models.Metadata.Machine.MediaKey]
= Array.ConvertAll(item.Media, ConvertToInternalModel);
}
if (item.Sample is not null && item.Sample.Length > 0)
{
machine[Data.Models.Metadata.Machine.SampleKey]
= Array.ConvertAll(item.Sample, ConvertToInternalModel);
}
if (item.Archive is not null && item.Archive.Length > 0)
{
machine[Data.Models.Metadata.Machine.ArchiveKey]
= Array.ConvertAll(item.Archive, ConvertToInternalModel);
}
if (item.Chip is not null && item.Chip.Length > 0)
{
machine[Data.Models.Metadata.Machine.ChipKey]
= Array.ConvertAll(item.Chip, ConvertToInternalModel);
}
if (item.Video is not null)
{
machine[Data.Models.Metadata.Machine.VideoKey]
= Array.ConvertAll(item.Video, ConvertToInternalModel);
}
if (item.Sound is not null)
machine[Data.Models.Metadata.Machine.SoundKey] = ConvertToInternalModel(item.Sound);
if (item.Input is not null)
machine[Data.Models.Metadata.Machine.InputKey] = ConvertToInternalModel(item.Input);
if (item.DipSwitch is not null && item.DipSwitch.Length > 0)
{
machine[Data.Models.Metadata.Machine.DipSwitchKey]
= Array.ConvertAll(item.DipSwitch, ConvertToInternalModel);
}
if (item.Driver is not null)
machine[Data.Models.Metadata.Machine.DriverKey] = ConvertToInternalModel(item.Driver);
return machine;
}
/// <summary>
/// Convert from <see cref="Archive"/> to <see cref="Models.Metadata.Archive"/>
/// </summary>
private static Data.Models.Metadata.Archive ConvertToInternalModel(Archive item)
{
var archive = new Data.Models.Metadata.Archive
{
[Data.Models.Metadata.Archive.NameKey] = item.Name,
};
return archive;
}
/// <summary>
/// Convert from <see cref="BiosSet"/> to <see cref="Models.Metadata.BiosSet"/>
/// </summary>
private static Data.Models.Metadata.BiosSet ConvertToInternalModel(BiosSet item)
{
var biosset = new Data.Models.Metadata.BiosSet
{
[Data.Models.Metadata.BiosSet.NameKey] = item.Name,
[Data.Models.Metadata.BiosSet.DescriptionKey] = item.Description,
[Data.Models.Metadata.BiosSet.DefaultKey] = item.Default,
};
return biosset;
}
/// <summary>
/// Convert from <see cref="Chip"/> to <see cref="Models.Metadata.Chip"/>
/// </summary>
private static Data.Models.Metadata.Chip ConvertToInternalModel(Chip item)
{
var chip = new Data.Models.Metadata.Chip
{
[Data.Models.Metadata.Chip.ChipTypeKey] = item.Type,
[Data.Models.Metadata.Chip.NameKey] = item.Name,
[Data.Models.Metadata.Chip.FlagsKey] = item.Flags,
[Data.Models.Metadata.Chip.ClockKey] = item.Clock,
};
return chip;
}
/// <summary>
/// Convert from <see cref="DipSwitch"/> to <see cref="Models.Metadata.DipSwitch"/>
/// </summary>
private static Data.Models.Metadata.DipSwitch ConvertToInternalModel(DipSwitch item)
{
var dipswitch = new Data.Models.Metadata.DipSwitch
{
[Data.Models.Metadata.DipSwitch.NameKey] = item.Name,
[Data.Models.Metadata.DipSwitch.EntryKey] = item.Entry,
[Data.Models.Metadata.DipSwitch.DefaultKey] = item.Default,
};
return dipswitch;
}
/// <summary>
/// Convert from <see cref="Disk"/> to <see cref="Models.Metadata.Disk"/>
/// </summary>
private static Data.Models.Metadata.Disk ConvertToInternalModel(Disk item)
{
var disk = new Data.Models.Metadata.Disk
{
[Data.Models.Metadata.Disk.NameKey] = item.Name,
[Data.Models.Metadata.Disk.MD5Key] = item.MD5,
[Data.Models.Metadata.Disk.SHA1Key] = item.SHA1,
[Data.Models.Metadata.Disk.MergeKey] = item.Merge,
[Data.Models.Metadata.Disk.StatusKey] = item.Status,
[Data.Models.Metadata.Disk.FlagsKey] = item.Flags,
};
return disk;
}
/// <summary>
/// Convert from <see cref="Driver"/> to <see cref="Models.Metadata.Driver"/>
/// </summary>
private static Data.Models.Metadata.Driver ConvertToInternalModel(Driver item)
{
var driver = new Data.Models.Metadata.Driver
{
[Data.Models.Metadata.Driver.StatusKey] = item.Status,
[Data.Models.Metadata.Driver.ColorKey] = item.Color,
[Data.Models.Metadata.Driver.SoundKey] = item.Sound,
[Data.Models.Metadata.Driver.PaletteSizeKey] = item.PaletteSize,
[Data.Models.Metadata.Driver.BlitKey] = item.Blit,
};
return driver;
}
/// <summary>
/// Convert from <see cref="Input"/> to <see cref="Models.Metadata.Input"/>
/// </summary>
private static Data.Models.Metadata.Input ConvertToInternalModel(Input item)
{
var input = new Data.Models.Metadata.Input
{
[Data.Models.Metadata.Input.PlayersKey] = item.Players,
[Data.Models.Metadata.Input.ControlKey] = item.Control,
[Data.Models.Metadata.Input.ButtonsKey] = item.Buttons,
[Data.Models.Metadata.Input.CoinsKey] = item.Coins,
[Data.Models.Metadata.Input.TiltKey] = item.Tilt,
[Data.Models.Metadata.Input.ServiceKey] = item.Service,
};
return input;
}
/// <summary>
/// Convert from <see cref="Media"/> to <see cref="Models.Metadata.Media"/>
/// </summary>
private static Data.Models.Metadata.Media ConvertToInternalModel(Media item)
{
var media = new Data.Models.Metadata.Media
{
[Data.Models.Metadata.Media.NameKey] = item.Name,
[Data.Models.Metadata.Media.MD5Key] = item.MD5,
[Data.Models.Metadata.Media.SHA1Key] = item.SHA1,
[Data.Models.Metadata.Media.SHA256Key] = item.SHA256,
[Data.Models.Metadata.Media.SpamSumKey] = item.SpamSum,
};
return media;
}
/// <summary>
/// Convert from <see cref="Release"/> to <see cref="Models.Metadata.Release"/>
/// </summary>
private static Data.Models.Metadata.Release ConvertToInternalModel(Release item)
{
var release = new Data.Models.Metadata.Release
{
[Data.Models.Metadata.Release.NameKey] = item.Name,
[Data.Models.Metadata.Release.RegionKey] = item.Region,
[Data.Models.Metadata.Release.LanguageKey] = item.Language,
[Data.Models.Metadata.Release.DateKey] = item.Date,
[Data.Models.Metadata.Release.DefaultKey] = item.Default,
};
return release;
}
/// <summary>
/// Convert from <see cref="Rom"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
private static Data.Models.Metadata.Rom ConvertToInternalModel(Rom item)
{
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.NameKey] = item.Name,
[Data.Models.Metadata.Rom.SizeKey] = item.Size,
[Data.Models.Metadata.Rom.CRC16Key] = item.CRC16,
[Data.Models.Metadata.Rom.CRCKey] = item.CRC,
[Data.Models.Metadata.Rom.CRC64Key] = item.CRC64,
[Data.Models.Metadata.Rom.MD2Key] = item.MD2,
[Data.Models.Metadata.Rom.MD4Key] = item.MD4,
[Data.Models.Metadata.Rom.MD5Key] = item.MD5,
[Data.Models.Metadata.Rom.RIPEMD128Key] = item.RIPEMD128,
[Data.Models.Metadata.Rom.RIPEMD160Key] = item.RIPEMD160,
[Data.Models.Metadata.Rom.SHA1Key] = item.SHA1,
[Data.Models.Metadata.Rom.SHA256Key] = item.SHA256,
[Data.Models.Metadata.Rom.SHA384Key] = item.SHA384,
[Data.Models.Metadata.Rom.SHA512Key] = item.SHA512,
[Data.Models.Metadata.Rom.SpamSumKey] = item.SpamSum,
[Data.Models.Metadata.Rom.xxHash364Key] = item.xxHash364,
[Data.Models.Metadata.Rom.xxHash3128Key] = item.xxHash3128,
[Data.Models.Metadata.Rom.MergeKey] = item.Merge,
[Data.Models.Metadata.Rom.StatusKey] = item.Status,
[Data.Models.Metadata.Rom.RegionKey] = item.Region,
[Data.Models.Metadata.Rom.FlagsKey] = item.Flags,
[Data.Models.Metadata.Rom.OffsetKey] = item.Offs,
[Data.Models.Metadata.Rom.SerialKey] = item.Serial,
[Data.Models.Metadata.Rom.HeaderKey] = item.Header,
[Data.Models.Metadata.Rom.DateKey] = item.Date,
[Data.Models.Metadata.Rom.InvertedKey] = item.Inverted,
[Data.Models.Metadata.Rom.MIAKey] = item.MIA,
};
return rom;
}
/// <summary>
/// Convert from <see cref="Sample"/> to <see cref="Models.Metadata.Sample"/>
/// </summary>
private static Data.Models.Metadata.Sample ConvertToInternalModel(Sample item)
{
var sample = new Data.Models.Metadata.Sample
{
[Data.Models.Metadata.Sample.NameKey] = item.Name,
};
return sample;
}
/// <summary>
/// Convert from <see cref="Sound"/> to <see cref="Models.Metadata.Sound"/>
/// </summary>
private static Data.Models.Metadata.Sound ConvertToInternalModel(Sound item)
{
var sound = new Data.Models.Metadata.Sound
{
[Data.Models.Metadata.Sound.ChannelsKey] = item.Channels,
};
return sound;
}
/// <summary>
/// Convert from <see cref="Video"/> to <see cref="Models.Metadata.Video"/>
/// </summary>
private static Data.Models.Metadata.Video ConvertToInternalModel(Video item)
{
var video = new Data.Models.Metadata.Video
{
[Data.Models.Metadata.Video.ScreenKey] = item.Screen,
[Data.Models.Metadata.Video.OrientationKey] = item.Orientation,
[Data.Models.Metadata.Video.WidthKey] = item.X,
[Data.Models.Metadata.Video.HeightKey] = item.Y,
[Data.Models.Metadata.Video.AspectXKey] = item.AspectX,
[Data.Models.Metadata.Video.AspectYKey] = item.AspectY,
[Data.Models.Metadata.Video.RefreshKey] = item.Freq,
};
return video;
}
/// <summary>
/// Convert from <see cref="Models.ClrMamePro.Info"/> to <see cref="Models.Metadata.InfoSource"/>
/// </summary>
private static Data.Models.Metadata.InfoSource ConvertInfoSourceToInternalModel(Info item)
{
var infoSource = new Data.Models.Metadata.InfoSource();
var sources = item.Source;
if (sources is not null && sources.Length > 0)
{
string[] sourcesCopy = [.. sources];
infoSource[Data.Models.Metadata.InfoSource.SourceKey] = sourcesCopy;
}
return infoSource;
}
}
}

View File

@@ -0,0 +1,78 @@
using System;
using SabreTools.Data.Models.DosCenter;
namespace SabreTools.Serialization.CrossModel
{
public partial class DosCenter : BaseMetadataSerializer<MetadataFile>
{
/// <inheritdoc/>
public override MetadataFile? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{
if (obj is null)
return null;
var metadataFile = new MetadataFile();
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
if (header is not null)
metadataFile.DosCenter = ConvertHeaderFromInternalModel(header);
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
if (machines is not null && machines.Length > 0)
metadataFile.Game = Array.ConvertAll(machines, ConvertMachineFromInternalModel);
return metadataFile;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Header"/> to <see cref="Models.DosCenter.DosCenter"/>
/// </summary>
private static Data.Models.DosCenter.DosCenter ConvertHeaderFromInternalModel(Data.Models.Metadata.Header item)
{
var dosCenter = new Data.Models.DosCenter.DosCenter
{
Name = item.ReadString(Data.Models.Metadata.Header.NameKey),
Description = item.ReadString(Data.Models.Metadata.Header.DescriptionKey),
Version = item.ReadString(Data.Models.Metadata.Header.VersionKey),
Date = item.ReadString(Data.Models.Metadata.Header.DateKey),
Author = item.ReadString(Data.Models.Metadata.Header.AuthorKey),
Homepage = item.ReadString(Data.Models.Metadata.Header.HomepageKey),
Comment = item.ReadString(Data.Models.Metadata.Header.CommentKey),
};
return dosCenter;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Machine"/> to <see cref="Game"/>
/// </summary>
private static Game ConvertMachineFromInternalModel(Data.Models.Metadata.Machine item)
{
var game = new Game
{
Name = item.ReadString(Data.Models.Metadata.Machine.NameKey),
};
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms is not null && roms.Length > 0)
game.File = Array.ConvertAll(roms, ConvertFromInternalModel);
return game;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="File"/>
/// </summary>
private static File ConvertFromInternalModel(Data.Models.Metadata.Rom item)
{
var file = new File
{
Name = item.ReadString(Data.Models.Metadata.Rom.NameKey),
Size = item.ReadString(Data.Models.Metadata.Rom.SizeKey),
CRC = item.ReadString(Data.Models.Metadata.Rom.CRCKey),
SHA1 = item.ReadString(Data.Models.Metadata.Rom.SHA1Key),
Date = item.ReadString(Data.Models.Metadata.Rom.DateKey),
};
return file;
}
}
}

View File

@@ -0,0 +1,81 @@
using System;
using SabreTools.Data.Models.DosCenter;
namespace SabreTools.Serialization.CrossModel
{
public partial class DosCenter : BaseMetadataSerializer<MetadataFile>
{
/// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
{
if (obj is null)
return null;
var metadataFile = new Data.Models.Metadata.MetadataFile();
if (obj?.DosCenter is not null)
metadataFile[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(obj.DosCenter);
if (obj?.Game is not null && obj.Game.Length > 0)
{
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(obj.Game, ConvertMachineToInternalModel);
}
return metadataFile;
}
/// <summary>
/// Convert from <see cref="Models.DosCenter.DosCenter"/> to <see cref="Models.Metadata.Header"/>
/// </summary>
private static Data.Models.Metadata.Header ConvertHeaderToInternalModel(Data.Models.DosCenter.DosCenter item)
{
var header = new Data.Models.Metadata.Header
{
[Data.Models.Metadata.Header.NameKey] = item.Name,
[Data.Models.Metadata.Header.DescriptionKey] = item.Description,
[Data.Models.Metadata.Header.VersionKey] = item.Version,
[Data.Models.Metadata.Header.DateKey] = item.Date,
[Data.Models.Metadata.Header.AuthorKey] = item.Author,
[Data.Models.Metadata.Header.HomepageKey] = item.Homepage,
[Data.Models.Metadata.Header.CommentKey] = item.Comment,
};
return header;
}
/// <summary>
/// Convert from <see cref="Game"/> to <see cref="Models.Metadata.Machine"/>
/// </summary>
private static Data.Models.Metadata.Machine ConvertMachineToInternalModel(Game item)
{
var machine = new Data.Models.Metadata.Machine
{
[Data.Models.Metadata.Machine.NameKey] = item.Name,
};
if (item.File is not null && item.File.Length > 0)
{
machine[Data.Models.Metadata.Machine.RomKey]
= Array.ConvertAll(item.File, ConvertToInternalModel);
}
return machine;
}
/// <summary>
/// Convert from <see cref="File"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
private static Data.Models.Metadata.Rom ConvertToInternalModel(File item)
{
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.NameKey] = item.Name,
[Data.Models.Metadata.Rom.SizeKey] = item.Size,
[Data.Models.Metadata.Rom.CRCKey] = item.CRC,
[Data.Models.Metadata.Rom.SHA1Key] = item.SHA1,
[Data.Models.Metadata.Rom.DateKey] = item.Date,
};
return rom;
}
}
}

View File

@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using SabreTools.Data.Models.EverdriveSMDB;
namespace SabreTools.Serialization.CrossModel
{
public partial class EverdriveSMDB : BaseMetadataSerializer<MetadataFile>
{
/// <inheritdoc/>
public override MetadataFile? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{
if (obj is null)
return null;
var metadataFile = new MetadataFile();
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
var items = new List<Row>();
foreach (var machine in machines ?? [])
{
items.AddRange(ConvertMachineFromInternalModel(machine));
}
metadataFile.Row = [.. items];
return metadataFile;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Machine"/> to an array of <see cref="Row"/>
/// </summary>
private static Row[] ConvertMachineFromInternalModel(Data.Models.Metadata.Machine item)
{
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms is null || roms.Length == 0)
return [];
return Array.ConvertAll(roms, ConvertFromInternalModel);
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="Row"/>
/// </summary>
private static Row ConvertFromInternalModel(Data.Models.Metadata.Rom item)
{
var row = new Row
{
SHA256 = item.ReadString(Data.Models.Metadata.Rom.SHA256Key),
Name = item.ReadString(Data.Models.Metadata.Rom.NameKey),
SHA1 = item.ReadString(Data.Models.Metadata.Rom.SHA1Key),
MD5 = item.ReadString(Data.Models.Metadata.Rom.MD5Key),
CRC32 = item.ReadString(Data.Models.Metadata.Rom.CRCKey),
Size = item.ReadString(Data.Models.Metadata.Rom.SizeKey),
};
return row;
}
}
}

View File

@@ -0,0 +1,69 @@
using System;
using SabreTools.Data.Models.EverdriveSMDB;
namespace SabreTools.Serialization.CrossModel
{
public partial class EverdriveSMDB : BaseMetadataSerializer<MetadataFile>
{
/// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
{
if (obj is null)
return null;
var metadataFile = new Data.Models.Metadata.MetadataFile
{
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(),
};
if (obj?.Row is not null && obj.Row.Length > 0)
{
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(obj.Row, ConvertMachineToInternalModel);
}
return metadataFile;
}
/// <summary>
/// Convert from <see cref="MetadataFile"/> to <see cref="Models.Metadata.Header"/>
/// </summary>
private static Data.Models.Metadata.Header ConvertHeaderToInternalModel()
{
var header = new Data.Models.Metadata.Header
{
[Data.Models.Metadata.Header.NameKey] = "Everdrive SMDB",
};
return header;
}
/// <summary>
/// Convert from <see cref="Row"/> to <see cref="Models.Metadata.Machine"/>
/// </summary>
private static Data.Models.Metadata.Machine ConvertMachineToInternalModel(Row item)
{
var machine = new Data.Models.Metadata.Machine
{
[Data.Models.Metadata.Machine.RomKey] = new Data.Models.Metadata.Rom[] { ConvertToInternalModel(item) },
};
return machine;
}
/// <summary>
/// Convert from <see cref="Row"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
private static Data.Models.Metadata.Rom ConvertToInternalModel(Row item)
{
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.SHA256Key] = item.SHA256,
[Data.Models.Metadata.Rom.NameKey] = item.Name,
[Data.Models.Metadata.Rom.SHA1Key] = item.SHA1,
[Data.Models.Metadata.Rom.MD5Key] = item.MD5,
[Data.Models.Metadata.Rom.CRCKey] = item.CRC32,
[Data.Models.Metadata.Rom.SizeKey] = item.Size,
};
return rom;
}
}
}

View File

@@ -0,0 +1,9 @@
#if NET20
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
internal sealed class ExtensionAttribute : Attribute {}
}
#endif

View File

@@ -0,0 +1,84 @@
using System.Collections.Generic;
using SabreTools.Data.Models.NES;
namespace SabreTools.Serialization.CrossModel
{
/// <see href="https://www.nesdev.org/wiki/FDS_disk_format"/>
/// <see href="https://gist.github.com/einstein95/6545066905680466cdf200c4cc8ca4f0"/>
public partial class FamicomDiskSystem : ICrossModel<FDS, QD>
{
/// <inheritdoc/>
public bool Debug { get; set; } = false;
/// <inheritdoc/>
public FDS? Deserialize(QD? obj)
{
// Ignore invalid data
if (obj?.Data is null || obj.Data.Length == 0)
return null;
// Ignore incomplete data
if ((obj.Data.Length % 65536) != 0)
return null;
// Determine the number of sides
byte sides = (byte)(obj.Data.Length / 65536);
if (sides < 1)
return null;
// Create the FDS for output
var fds = new FDS
{
Header = new FDSHeader
{
IdentificationString = Constants.FDSSignatureBytes,
DiskSides = sides,
}
};
// Loop over the sides and convert
List<byte> converted = [];
for (int i = 0; i < sides; i++)
{
// Convert the data to manipulate
List<byte> data = [.. obj.Data];
// Delete block 01 checksum
data.RemoveRange(0x38, 2);
// Delete block 02 checksum
int pos = 0x3A;
data.RemoveRange(pos, 2);
// Loop while there are more files
while (data[pos] == 3)
{
// Get the filesize
ushort filesize = (ushort)((data[pos + 0x0E] << 8) | data[pos + 0x0D]);
// Delete block 03 checksum
data.RemoveRange(pos + 0x10, 2);
// Skip the file data
pos = pos + 0x10 + 1 + filesize;
// Delete block 04 checksum
data.RemoveRange(pos, 2);
}
// Ensure the data is correctly sized
if (data.Count > 65500)
data = data.GetRange(0, 65500);
else if (data.Count < 65500)
data.AddRange(new byte[65500 - data.Count]);
// Add the data to the output
converted.AddRange(data);
}
// Assign the converted data and return
fds.Data = [.. converted];
return fds;
}
}
}

View File

@@ -0,0 +1,131 @@
using System.Collections.Generic;
using SabreTools.Data.Models.NES;
namespace SabreTools.Serialization.CrossModel
{
/// <see href="https://www.nesdev.org/wiki/FDS_disk_format"/>
/// <see href="https://gist.github.com/einstein95/6545066905680466cdf200c4cc8ca4f0"/>
public partial class FamicomDiskSystem : ICrossModel<FDS, QD>
{
/// <inheritdoc/>
public QD? Serialize(FDS? obj)
=> Serialize(obj, false);
/// <inheritdoc/>
/// <param name="nul">True to insert null checksums on conversion, false otherwise</param>
public QD? Serialize(FDS? obj, bool nul)
{
// Ignore invalid data
if (obj?.Data is null || obj.Data.Length == 0)
return null;
// Ignore incomplete data
if ((obj.Data.Length % 65500) != 0)
return null;
// Determine the number of sides
byte sides = obj.Header != null
? obj.Header.DiskSides
: (byte)(obj.Data.Length / 65500);
if (sides < 1)
return null;
// Create the QD for output
var qd = new QD();
// Loop over the sides and convert
List<byte> converted = [];
for (int i = 0; i < sides; i++)
{
// Convert the data to manipulate
List<byte> data = [.. obj.Data];
// If the data is unexpected
if (data[0] != 0x01)
break;
// Insert block 01 checksum
InsertCrc(data, 0, 0x38, nul);
// Insert block 02 checksum
int pos = 0x3A;
InsertCrc(data, pos, pos + 2, nul);
// Loop while there are more files
pos = 0x3E;
while (data[pos] == 3)
{
// Get the filesize
ushort filesize = (ushort)((data[pos + 0x0E] << 8) | data[pos + 0x0D]);
// Insert block 03 checksum
InsertCrc(data, pos, pos + 0x10, nul);
// Skip the file data
pos += 0x10 + 2;
// Insert block 04 checksum
InsertCrc(data, pos, pos + 1 + filesize, nul);
pos += 1 + filesize + 2;
}
// Ensure the data is correctly sized
if (data.Count > 65536)
data = data.GetRange(0, 65536);
else if (data.Count < 65536)
data.AddRange(new byte[65536 - data.Count]);
// Add the data to the output
converted.AddRange(data);
}
// Assign the converted data and return
qd.Data = [.. converted];
return qd;
}
private void InsertCrc(List<byte> data, int start, int end, bool nul)
{
if (!nul)
{
byte[] temp = new byte[end - start];
data.CopyTo(start, temp, 0, temp.Length);
ushort crc = FdsCrc(temp);
data.Insert(end + 0, (byte)(crc & 0xFF));
data.Insert(end + 1, (byte)(crc >> 0x08));
}
else
{
data.Insert(end + 0, 0);
data.Insert(end + 1, 0);
}
}
// TODO: Replace with CRC-16/KERMIT from Hashing
private ushort FdsCrc(byte[] data)
{
// http://forums.nesdev.com/viewtopic.php?p=194867
// Do not include any existing checksum, not even the blank checksums 00 00 or FF FF.
// The formula will automatically count 2 0x00 bytes without the programmer adding them manually.
// Also, do not include the gap terminator (0x80) in the data.
// If you wish to do so, change sum to 0x0000.
ushort s = 0x8000;
byte[] padded = [.. data, 0x00, 0x00];
foreach (byte b in padded)
{
s |= (ushort)(b << 16);
for (int i = 0; i < 8; i++)
{
if ((s & 1) != 0)
{
unchecked { s ^= (ushort)(0x8408 << 1); }
}
s >>= 1;
}
}
return s;
}
}
}

View File

@@ -0,0 +1,284 @@
using System;
using System.Collections.Generic;
using SabreTools.Data.Models.Hashfile;
using SabreTools.Hashing;
#pragma warning disable CA1822 // Mark members as static
namespace SabreTools.Serialization.CrossModel
{
public partial class Hashfile : BaseMetadataSerializer<Data.Models.Hashfile.Hashfile>
{
/// <inheritdoc/>
public override Data.Models.Hashfile.Hashfile? Deserialize(Data.Models.Metadata.MetadataFile? obj)
=> Deserialize(obj, HashType.CRC32);
/// <inheritdoc/>
public Data.Models.Hashfile.Hashfile? Deserialize(Data.Models.Metadata.MetadataFile? obj, HashType hash)
{
if (obj is null)
return null;
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
if (machines is null || machines.Length == 0)
return null;
var hashfiles = Array.ConvertAll(machines,
m => ConvertMachineFromInternalModel(m, hash));
var sfvs = new List<SFV>();
var md2s = new List<MD2>();
var md4s = new List<MD4>();
var md5s = new List<MD5>();
var ripemd128s = new List<RIPEMD128>();
var ripemd160s = new List<RIPEMD160>();
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 is not null && hashfile.SFV.Length > 0)
sfvs.AddRange(hashfile.SFV);
if (hashfile.MD2 is not null && hashfile.MD2.Length > 0)
md2s.AddRange(hashfile.MD2);
if (hashfile.MD4 is not null && hashfile.MD4.Length > 0)
md4s.AddRange(hashfile.MD4);
if (hashfile.MD5 is not null && hashfile.MD5.Length > 0)
md5s.AddRange(hashfile.MD5);
if (hashfile.RIPEMD128 is not null && hashfile.RIPEMD128.Length > 0)
ripemd128s.AddRange(hashfile.RIPEMD128);
if (hashfile.RIPEMD160 is not null && hashfile.RIPEMD160.Length > 0)
ripemd160s.AddRange(hashfile.RIPEMD160);
if (hashfile.SHA1 is not null && hashfile.SHA1.Length > 0)
sha1s.AddRange(hashfile.SHA1);
if (hashfile.SHA256 is not null && hashfile.SHA256.Length > 0)
sha256s.AddRange(hashfile.SHA256);
if (hashfile.SHA384 is not null && hashfile.SHA384.Length > 0)
sha384s.AddRange(hashfile.SHA384);
if (hashfile.SHA512 is not null && hashfile.SHA512.Length > 0)
sha512s.AddRange(hashfile.SHA512);
if (hashfile.SpamSum is not null && hashfile.SpamSum.Length > 0)
spamsums.AddRange(hashfile.SpamSum);
}
var hashfileItem = new Data.Models.Hashfile.Hashfile();
if (sfvs.Count > 0)
hashfileItem.SFV = [.. sfvs];
if (md2s.Count > 0)
hashfileItem.MD2 = [.. md2s];
if (md4s.Count > 0)
hashfileItem.MD4 = [.. md4s];
if (md5s.Count > 0)
hashfileItem.MD5 = [.. md5s];
if (ripemd128s.Count > 0)
hashfileItem.RIPEMD128 = [.. ripemd128s];
if (ripemd160s.Count > 0)
hashfileItem.RIPEMD160 = [.. ripemd160s];
if (sha1s.Count > 0)
hashfileItem.SHA1 = [.. sha1s];
if (sha256s.Count > 0)
hashfileItem.SHA256 = [.. sha256s];
if (sha384s.Count > 0)
hashfileItem.SHA384 = [.. sha384s];
if (sha512s.Count > 0)
hashfileItem.SHA512 = [.. sha512s];
if (spamsums.Count > 0)
hashfileItem.SpamSum = [.. spamsums];
return hashfileItem;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Machine"/> to <see cref="Models.Hashfile.Hashfile"/>
/// </summary>
private static Data.Models.Hashfile.Hashfile ConvertMachineFromInternalModel(Data.Models.Metadata.Machine item, HashType hash)
{
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms is null)
return new Data.Models.Hashfile.Hashfile();
return new Data.Models.Hashfile.Hashfile
{
SFV = hash == HashType.CRC32
? Array.ConvertAll(roms, ConvertToSFV)
: null,
MD2 = hash == HashType.MD2
? Array.ConvertAll(roms, ConvertToMD2)
: null,
MD4 = hash == HashType.MD4
? Array.ConvertAll(roms, ConvertToMD4)
: null,
MD5 = hash == HashType.MD5
? Array.ConvertAll(roms, ConvertToMD5)
: null,
RIPEMD128 = hash == HashType.RIPEMD128
? Array.ConvertAll(roms, ConvertToRIPEMD128)
: null,
RIPEMD160 = hash == HashType.RIPEMD160
? Array.ConvertAll(roms, ConvertToRIPEMD160)
: null,
SHA1 = hash == HashType.SHA1
? Array.ConvertAll(roms, ConvertToSHA1)
: null,
SHA256 = hash == HashType.SHA256
? Array.ConvertAll(roms, ConvertToSHA256)
: null,
SHA384 = hash == HashType.SHA384
? Array.ConvertAll(roms, ConvertToSHA384)
: null,
SHA512 = hash == HashType.SHA512
? Array.ConvertAll(roms, ConvertToSHA512)
: null,
SpamSum = hash == HashType.SpamSum
? Array.ConvertAll(roms, ConvertToSpamSum)
: null,
};
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="MD2"/>
/// </summary>
private static MD2 ConvertToMD2(Data.Models.Metadata.Rom item)
{
var md2 = new MD2
{
Hash = item.ReadString(Data.Models.Metadata.Rom.MD2Key),
File = item.ReadString(Data.Models.Metadata.Rom.NameKey),
};
return md2;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="MD4"/>
/// </summary>
private static MD4 ConvertToMD4(Data.Models.Metadata.Rom item)
{
var md4 = new MD4
{
Hash = item.ReadString(Data.Models.Metadata.Rom.MD4Key),
File = item.ReadString(Data.Models.Metadata.Rom.NameKey),
};
return md4;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="MD5"/>
/// </summary>
private static MD5 ConvertToMD5(Data.Models.Metadata.Rom item)
{
var md5 = new MD5
{
Hash = item.ReadString(Data.Models.Metadata.Rom.MD5Key),
File = item.ReadString(Data.Models.Metadata.Rom.NameKey),
};
return md5;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="RIPEMD128"/>
/// </summary>
private static RIPEMD128 ConvertToRIPEMD128(Data.Models.Metadata.Rom item)
{
var ripemd128 = new RIPEMD128
{
Hash = item.ReadString(Data.Models.Metadata.Rom.RIPEMD128Key),
File = item.ReadString(Data.Models.Metadata.Rom.NameKey),
};
return ripemd128;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="RIPEMD160"/>
/// </summary>
private static RIPEMD160 ConvertToRIPEMD160(Data.Models.Metadata.Rom item)
{
var ripemd160 = new RIPEMD160
{
Hash = item.ReadString(Data.Models.Metadata.Rom.RIPEMD160Key),
File = item.ReadString(Data.Models.Metadata.Rom.NameKey),
};
return ripemd160;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="SFV"/>
/// </summary>
private static SFV ConvertToSFV(Data.Models.Metadata.Rom item)
{
var sfv = new SFV
{
File = item.ReadString(Data.Models.Metadata.Rom.NameKey),
Hash = item.ReadString(Data.Models.Metadata.Rom.CRCKey),
};
return sfv;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="SHA1"/>
/// </summary>
private static SHA1 ConvertToSHA1(Data.Models.Metadata.Rom item)
{
var sha1 = new SHA1
{
Hash = item.ReadString(Data.Models.Metadata.Rom.SHA1Key),
File = item.ReadString(Data.Models.Metadata.Rom.NameKey),
};
return sha1;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="SHA256"/>
/// </summary>
private static SHA256 ConvertToSHA256(Data.Models.Metadata.Rom item)
{
var sha256 = new SHA256
{
Hash = item.ReadString(Data.Models.Metadata.Rom.SHA256Key),
File = item.ReadString(Data.Models.Metadata.Rom.NameKey),
};
return sha256;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="SHA384"/>
/// </summary>
private static SHA384 ConvertToSHA384(Data.Models.Metadata.Rom item)
{
var sha384 = new SHA384
{
Hash = item.ReadString(Data.Models.Metadata.Rom.SHA384Key),
File = item.ReadString(Data.Models.Metadata.Rom.NameKey),
};
return sha384;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="SHA512"/>
/// </summary>
private static SHA512 ConvertToSHA512(Data.Models.Metadata.Rom item)
{
var sha512 = new SHA512
{
Hash = item.ReadString(Data.Models.Metadata.Rom.SHA512Key),
File = item.ReadString(Data.Models.Metadata.Rom.NameKey),
};
return sha512;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="SpamSum"/>
/// </summary>
private static SpamSum ConvertToSpamSum(Data.Models.Metadata.Rom item)
{
var spamsum = new SpamSum
{
Hash = item.ReadString(Data.Models.Metadata.Rom.SpamSumKey),
File = item.ReadString(Data.Models.Metadata.Rom.NameKey),
};
return spamsum;
}
}
}

View File

@@ -0,0 +1,213 @@
using System;
using SabreTools.Data.Models.Hashfile;
namespace SabreTools.Serialization.CrossModel
{
public partial class Hashfile : BaseMetadataSerializer<Data.Models.Hashfile.Hashfile>
{
/// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(Data.Models.Hashfile.Hashfile? obj)
{
if (obj is null)
return null;
var metadataFile = new Data.Models.Metadata.MetadataFile
{
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(),
};
var machine = ConvertMachineToInternalModel(obj);
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey] = new Data.Models.Metadata.Machine[] { machine };
return metadataFile;
}
/// <summary>
/// Convert from <see cref="Models.Hashfile.Hashfile"/> to <see cref="Models.Metadata.Header"/>
/// </summary>
private static Data.Models.Metadata.Header ConvertHeaderToInternalModel()
{
var header = new Data.Models.Metadata.Header
{
[Data.Models.Metadata.Header.NameKey] = "Hashfile",
};
return header;
}
/// <summary>
/// Convert from <see cref="Models.Hashfile.Hashfile"/> to <see cref="Models.Metadata.Machine"/>
/// </summary>
private static Data.Models.Metadata.Machine ConvertMachineToInternalModel(Data.Models.Hashfile.Hashfile item)
{
var machine = new Data.Models.Metadata.Machine();
if (item.SFV is not null && item.SFV.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.SFV, ConvertToInternalModel);
else if (item.MD2 is not null && item.MD2.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.MD2, ConvertToInternalModel);
else if (item.MD4 is not null && item.MD4.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.MD4, ConvertToInternalModel);
else if (item.MD5 is not null && item.MD5.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.MD5, ConvertToInternalModel);
else if (item.RIPEMD128 is not null && item.RIPEMD128.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.RIPEMD128, ConvertToInternalModel);
else if (item.RIPEMD160 is not null && item.RIPEMD160.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.RIPEMD160, ConvertToInternalModel);
else if (item.SHA1 is not null && item.SHA1.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.SHA1, ConvertToInternalModel);
else if (item.SHA256 is not null && item.SHA256.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.SHA256, ConvertToInternalModel);
else if (item.SHA384 is not null && item.SHA384.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.SHA384, ConvertToInternalModel);
else if (item.SHA512 is not null && item.SHA512.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.SHA512, ConvertToInternalModel);
else if (item.SpamSum is not null && item.SpamSum.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.SpamSum, ConvertToInternalModel);
return machine;
}
/// <summary>
/// Convert from <see cref="MD2"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
private static Data.Models.Metadata.Rom ConvertToInternalModel(MD2 item)
{
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.MD2Key] = item.Hash,
[Data.Models.Metadata.Rom.NameKey] = item.File,
};
return rom;
}
/// <summary>
/// Convert from <see cref="MD4"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
private static Data.Models.Metadata.Rom ConvertToInternalModel(MD4 item)
{
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.MD4Key] = item.Hash,
[Data.Models.Metadata.Rom.NameKey] = item.File,
};
return rom;
}
/// <summary>
/// Convert from <see cref="MD5"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
private static Data.Models.Metadata.Rom ConvertToInternalModel(MD5 item)
{
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.MD5Key] = item.Hash,
[Data.Models.Metadata.Rom.NameKey] = item.File,
};
return rom;
}
/// <summary>
/// Convert from <see cref="RIPEMD128"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
private static Data.Models.Metadata.Rom ConvertToInternalModel(RIPEMD128 item)
{
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.RIPEMD128Key] = item.Hash,
[Data.Models.Metadata.Rom.NameKey] = item.File,
};
return rom;
}
/// <summary>
/// Convert from <see cref="RIPEMD160"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
private static Data.Models.Metadata.Rom ConvertToInternalModel(RIPEMD160 item)
{
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.RIPEMD160Key] = item.Hash,
[Data.Models.Metadata.Rom.NameKey] = item.File,
};
return rom;
}
/// <summary>
/// Convert from <see cref="SFV"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
private static Data.Models.Metadata.Rom ConvertToInternalModel(SFV item)
{
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.NameKey] = item.File,
[Data.Models.Metadata.Rom.CRCKey] = item.Hash,
};
return rom;
}
/// <summary>
/// Convert from <see cref="SHA1"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
private static Data.Models.Metadata.Rom ConvertToInternalModel(SHA1 item)
{
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.SHA1Key] = item.Hash,
[Data.Models.Metadata.Rom.NameKey] = item.File,
};
return rom;
}
/// <summary>
/// Convert from <see cref="SHA256"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
private static Data.Models.Metadata.Rom ConvertToInternalModel(SHA256 item)
{
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.SHA256Key] = item.Hash,
[Data.Models.Metadata.Rom.NameKey] = item.File,
};
return rom;
}
/// <summary>
/// Convert from <see cref="SHA384"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
private static Data.Models.Metadata.Rom ConvertToInternalModel(SHA384 item)
{
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.SHA384Key] = item.Hash,
[Data.Models.Metadata.Rom.NameKey] = item.File,
};
return rom;
}
/// <summary>
/// Convert from <see cref="SHA512"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
private static Data.Models.Metadata.Rom ConvertToInternalModel(SHA512 item)
{
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.SHA512Key] = item.Hash,
[Data.Models.Metadata.Rom.NameKey] = item.File,
};
return rom;
}
/// <summary>
/// Convert from <see cref="SpamSum"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
private static Data.Models.Metadata.Rom ConvertToInternalModel(SpamSum item)
{
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.SpamSumKey] = item.Hash,
[Data.Models.Metadata.Rom.NameKey] = item.File,
};
return rom;
}
}
}

View File

@@ -0,0 +1,31 @@
namespace SabreTools.Serialization.CrossModel
{
/// <summary>
/// Defines how to convert between two model types
/// </summary>
public interface ICrossModel<TSource, TDest>
{
/// <summary>
/// Enable outputting debug information
/// </summary>
public bool Debug { get; set; }
/// <summary>
/// Deserialize a <typeparamref name="TDest"/> into <typeparamref name="TSource"/>
/// </summary>
/// <typeparam name="T">Type of object to deserialize to</typeparam>
/// <typeparam name="U">Type of object to deserialize from</typeparam>
/// <param name="obj">Object to deserialize from</param>
/// <returns>Filled object on success, null on error</returns>
public TSource? Deserialize(TDest? obj);
/// <summary>
/// Serialize a <typeparamref name="TSource"/> into <typeparamref name="TDest"/>
/// </summary>
/// <typeparam name="T">Type of object to serialize from</typeparam>
/// <typeparam name="U">Type of object to serialize to</typeparam>
/// <param name="obj">Object to serialize from</param>
/// <returns>Filled object on success, null on error</returns>
public TDest? Serialize(TSource? obj);
}
}

View File

@@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using SabreTools.Data.Models.Listrom;
namespace SabreTools.Serialization.CrossModel
{
public partial class Listrom : BaseMetadataSerializer<MetadataFile>
{
/// <inheritdoc/>
public override MetadataFile? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{
if (obj is null)
return null;
var metadataFile = new MetadataFile();
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
if (machines is not null && machines.Length > 0)
metadataFile.Set = Array.ConvertAll(machines, ConvertMachineFromInternalModel);
return metadataFile;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Machine"/> to <see cref="Set"/>
/// </summary>
private static Set ConvertMachineFromInternalModel(Data.Models.Metadata.Machine item)
{
var set = new Set();
if (item.ReadString(Data.Models.Metadata.Machine.IsDeviceKey) == "yes")
set.Device = item.ReadString(Data.Models.Metadata.Machine.NameKey);
else
set.Driver = item.ReadString(Data.Models.Metadata.Machine.NameKey);
var rowItems = new List<Row>();
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms is not null)
{
rowItems.AddRange(Array.ConvertAll(roms, ConvertFromInternalModel));
}
var disks = item.Read<Data.Models.Metadata.Disk[]>(Data.Models.Metadata.Machine.DiskKey);
if (disks is not null)
rowItems.AddRange(Array.ConvertAll(disks, ConvertFromInternalModel));
set.Row = [.. rowItems];
return set;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Disk"/> to <see cref="Row"/>
/// </summary>
private static Row ConvertFromInternalModel(Data.Models.Metadata.Disk item)
{
var row = new Row
{
Name = item.ReadString(Data.Models.Metadata.Disk.NameKey),
MD5 = item.ReadString(Data.Models.Metadata.Disk.MD5Key),
SHA1 = item.ReadString(Data.Models.Metadata.Disk.SHA1Key),
};
if ((item[Data.Models.Metadata.Disk.StatusKey] as string) == "nodump")
row.NoGoodDumpKnown = true;
else if ((item[Data.Models.Metadata.Disk.StatusKey] as string) == "baddump")
row.Bad = true;
return row;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="Row"/>
/// </summary>
private static Row ConvertFromInternalModel(Data.Models.Metadata.Rom item)
{
var row = new Row
{
Name = item.ReadString(Data.Models.Metadata.Rom.NameKey),
Size = item.ReadString(Data.Models.Metadata.Rom.SizeKey),
CRC = item.ReadString(Data.Models.Metadata.Rom.CRCKey),
SHA1 = item.ReadString(Data.Models.Metadata.Rom.SHA1Key),
};
if ((item[Data.Models.Metadata.Rom.StatusKey] as string) == "nodump")
row.NoGoodDumpKnown = true;
else if ((item[Data.Models.Metadata.Rom.StatusKey] as string) == "baddump")
row.Bad = true;
return row;
}
}
}

View File

@@ -0,0 +1,119 @@
using System;
using System.Collections.Generic;
using SabreTools.Data.Models.Listrom;
namespace SabreTools.Serialization.CrossModel
{
public partial class Listrom : BaseMetadataSerializer<MetadataFile>
{
/// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
{
if (obj is null)
return null;
var metadataFile = new Data.Models.Metadata.MetadataFile
{
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(),
};
if (obj?.Set is not null && obj.Set.Length > 0)
{
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(obj.Set, ConvertMachineToInternalModel);
}
return metadataFile;
}
/// <summary>
/// Convert from <see cref="MetadataFile"/> to <see cref="Header"/>
/// </summary>
private static Data.Models.Metadata.Header ConvertHeaderToInternalModel()
{
var header = new Data.Models.Metadata.Header
{
[Data.Models.Metadata.Header.NameKey] = "MAME Listrom",
};
return header;
}
/// <summary>
/// Convert from <see cref="Set"/> to <see cref="Models.Metadata.Machine"/>
/// </summary>
private static Data.Models.Metadata.Machine ConvertMachineToInternalModel(Set item)
{
var machine = new Data.Models.Metadata.Machine();
if (!string.IsNullOrEmpty(item.Device))
{
machine[Data.Models.Metadata.Machine.NameKey] = item.Device;
machine[Data.Models.Metadata.Machine.IsDeviceKey] = "yes";
}
else
{
machine[Data.Models.Metadata.Machine.NameKey] = item.Driver;
}
if (item.Row is not null && item.Row.Length > 0)
{
var disks = new List<Data.Models.Metadata.Disk>();
var roms = new List<Data.Models.Metadata.Rom>();
foreach (var file in item.Row)
{
var datItem = ConvertToInternalModel(file);
if (datItem is Data.Models.Metadata.Disk disk)
disks.Add(disk);
else if (datItem is Data.Models.Metadata.Rom rom)
roms.Add(rom);
}
machine[Data.Models.Metadata.Machine.DiskKey] = disks.ToArray();
machine[Data.Models.Metadata.Machine.RomKey] = roms.ToArray();
}
return machine;
}
/// <summary>
/// Convert from <see cref="Row"/> to <see cref="Models.Metadata.DatItem"/>
/// </summary>
private static Data.Models.Metadata.DatItem ConvertToInternalModel(Row item)
{
if (item.Size is null)
{
var disk = new Data.Models.Metadata.Disk
{
[Data.Models.Metadata.DatItem.TypeKey] = "disk",
[Data.Models.Metadata.Disk.NameKey] = item.Name,
[Data.Models.Metadata.Disk.MD5Key] = item.MD5,
[Data.Models.Metadata.Disk.SHA1Key] = item.SHA1,
};
if (item.NoGoodDumpKnown)
disk[Data.Models.Metadata.Disk.StatusKey] = "nodump";
else if (item.Bad)
disk[Data.Models.Metadata.Disk.StatusKey] = "baddump";
return disk;
}
else
{
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.DatItem.TypeKey] = "rom",
[Data.Models.Metadata.Rom.NameKey] = item.Name,
[Data.Models.Metadata.Rom.SizeKey] = item.Size,
[Data.Models.Metadata.Rom.CRCKey] = item.CRC,
[Data.Models.Metadata.Rom.SHA1Key] = item.SHA1,
};
if (item.NoGoodDumpKnown)
rom[Data.Models.Metadata.Rom.StatusKey] = "nodump";
else if (item.Bad)
rom[Data.Models.Metadata.Rom.StatusKey] = "baddump";
return rom;
}
}
}
}

View File

@@ -0,0 +1,672 @@
using System;
using SabreTools.Data.Models.Listxml;
namespace SabreTools.Serialization.CrossModel
{
public partial class Listxml : BaseMetadataSerializer<Mame>
{
/// <inheritdoc/>
public override Mame? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{
if (obj is null)
return null;
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
var mame = header is not null ? ConvertMameFromInternalModel(header) : new Mame();
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
if (machines is not null && machines.Length > 0)
mame.Game = Array.ConvertAll(machines, ConvertMachineFromInternalModel);
return mame;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Header"/> to <see cref="Mame"/>
/// </summary>
private static Mame ConvertMameFromInternalModel(Data.Models.Metadata.Header item)
{
var mame = new Mame
{
Build = item.ReadString(Data.Models.Metadata.Header.BuildKey),
Debug = item.ReadString(Data.Models.Metadata.Header.DebugKey),
MameConfig = item.ReadString(Data.Models.Metadata.Header.MameConfigKey),
};
return mame;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Machine"/> to <see cref="GameBase"/>
/// </summary>
internal static GameBase ConvertMachineFromInternalModel(Data.Models.Metadata.Machine item)
{
var machine = new Machine
{
Name = item.ReadString(Data.Models.Metadata.Machine.NameKey),
SourceFile = item.ReadString(Data.Models.Metadata.Machine.SourceFileKey),
IsBios = item.ReadString(Data.Models.Metadata.Machine.IsBiosKey),
IsDevice = item.ReadString(Data.Models.Metadata.Machine.IsDeviceKey),
IsMechanical = item.ReadString(Data.Models.Metadata.Machine.IsMechanicalKey),
Runnable = item.ReadString(Data.Models.Metadata.Machine.RunnableKey),
CloneOf = item.ReadString(Data.Models.Metadata.Machine.CloneOfKey),
RomOf = item.ReadString(Data.Models.Metadata.Machine.RomOfKey),
SampleOf = item.ReadString(Data.Models.Metadata.Machine.SampleOfKey),
Description = item.ReadString(Data.Models.Metadata.Machine.DescriptionKey),
Year = item.ReadString(Data.Models.Metadata.Machine.YearKey),
Manufacturer = item.ReadString(Data.Models.Metadata.Machine.ManufacturerKey),
History = item.ReadString(Data.Models.Metadata.Machine.HistoryKey),
};
var biosSets = item.Read<Data.Models.Metadata.BiosSet[]>(Data.Models.Metadata.Machine.BiosSetKey);
if (biosSets is not null && biosSets.Length > 0)
machine.BiosSet = Array.ConvertAll(biosSets, ConvertFromInternalModel);
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms is not null && roms.Length > 0)
machine.Rom = Array.ConvertAll(roms, ConvertFromInternalModel);
var disks = item.Read<Data.Models.Metadata.Disk[]>(Data.Models.Metadata.Machine.DiskKey);
if (disks is not null && disks.Length > 0)
machine.Disk = Array.ConvertAll(disks, ConvertFromInternalModel);
var deviceRefs = item.Read<Data.Models.Metadata.DeviceRef[]>(Data.Models.Metadata.Machine.DeviceRefKey);
if (deviceRefs is not null && deviceRefs.Length > 0)
machine.DeviceRef = Array.ConvertAll(deviceRefs, ConvertFromInternalModel);
var samples = item.Read<Data.Models.Metadata.Sample[]>(Data.Models.Metadata.Machine.SampleKey);
if (samples is not null && samples.Length > 0)
machine.Sample = Array.ConvertAll(samples, ConvertFromInternalModel);
var chips = item.Read<Data.Models.Metadata.Chip[]>(Data.Models.Metadata.Machine.ChipKey);
if (chips is not null && chips.Length > 0)
machine.Chip = Array.ConvertAll(chips, ConvertFromInternalModel);
var displays = item.Read<Data.Models.Metadata.Display[]>(Data.Models.Metadata.Machine.DisplayKey);
if (displays is not null && displays.Length > 0)
machine.Display = Array.ConvertAll(displays, ConvertFromInternalModel);
var videos = item.Read<Data.Models.Metadata.Video[]>(Data.Models.Metadata.Machine.VideoKey);
if (videos is not null && videos.Length > 0)
machine.Video = Array.ConvertAll(videos, ConvertFromInternalModel);
var sound = item.Read<Data.Models.Metadata.Sound>(Data.Models.Metadata.Machine.SoundKey);
if (sound is not null)
machine.Sound = ConvertFromInternalModel(sound);
var input = item.Read<Data.Models.Metadata.Input>(Data.Models.Metadata.Machine.InputKey);
if (input is not null)
machine.Input = ConvertFromInternalModel(input);
var dipSwitches = item.Read<Data.Models.Metadata.DipSwitch[]>(Data.Models.Metadata.Machine.DipSwitchKey);
if (dipSwitches is not null && dipSwitches.Length > 0)
machine.DipSwitch = Array.ConvertAll(dipSwitches, ConvertFromInternalModel);
var configurations = item.Read<Data.Models.Metadata.Configuration[]>(Data.Models.Metadata.Machine.ConfigurationKey);
if (configurations is not null && configurations.Length > 0)
machine.Configuration = Array.ConvertAll(configurations, ConvertFromInternalModel);
var ports = item.Read<Data.Models.Metadata.Port[]>(Data.Models.Metadata.Machine.PortKey);
if (ports is not null && ports.Length > 0)
machine.Port = Array.ConvertAll(ports, ConvertFromInternalModel);
var adjusters = item.Read<Data.Models.Metadata.Adjuster[]>(Data.Models.Metadata.Machine.AdjusterKey);
if (adjusters is not null && adjusters.Length > 0)
machine.Adjuster = Array.ConvertAll(adjusters, ConvertFromInternalModel);
var driver = item.Read<Data.Models.Metadata.Driver>(Data.Models.Metadata.Machine.DriverKey);
if (driver is not null)
machine.Driver = ConvertFromInternalModel(driver);
var features = item.Read<Data.Models.Metadata.Feature[]>(Data.Models.Metadata.Machine.FeatureKey);
if (features is not null && features.Length > 0)
machine.Feature = Array.ConvertAll(features, ConvertFromInternalModel);
var devices = item.Read<Data.Models.Metadata.Device[]>(Data.Models.Metadata.Machine.DeviceKey);
if (devices is not null && devices.Length > 0)
machine.Device = Array.ConvertAll(devices, ConvertFromInternalModel);
var slots = item.Read<Data.Models.Metadata.Slot[]>(Data.Models.Metadata.Machine.SlotKey);
if (slots is not null && slots.Length > 0)
machine.Slot = Array.ConvertAll(slots, ConvertFromInternalModel);
var softwareLists = item.Read<Data.Models.Metadata.SoftwareList[]>(Data.Models.Metadata.Machine.SoftwareListKey);
if (softwareLists is not null && softwareLists.Length > 0)
machine.SoftwareList = Array.ConvertAll(softwareLists, ConvertFromInternalModel);
var ramOptions = item.Read<Data.Models.Metadata.RamOption[]>(Data.Models.Metadata.Machine.RamOptionKey);
if (ramOptions is not null && ramOptions.Length > 0)
machine.RamOption = Array.ConvertAll(ramOptions, ConvertFromInternalModel);
return machine;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Adjuster"/> to <see cref="Adjuster"/>
/// </summary>
private static Adjuster ConvertFromInternalModel(Data.Models.Metadata.Adjuster item)
{
var adjuster = new Adjuster
{
Name = item.ReadString(Data.Models.Metadata.Adjuster.NameKey),
Default = item.ReadString(Data.Models.Metadata.Adjuster.DefaultKey),
};
var condition = item.Read<Data.Models.Metadata.Condition>(Data.Models.Metadata.Adjuster.ConditionKey);
if (condition is not null)
adjuster.Condition = ConvertFromInternalModel(condition);
return adjuster;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Analog"/> to <see cref="Analog"/>
/// </summary>
private static Analog ConvertFromInternalModel(Data.Models.Metadata.Analog item)
{
var analog = new Analog
{
Mask = item.ReadString(Data.Models.Metadata.Analog.MaskKey),
};
return analog;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.BiosSet"/> to <see cref="BiosSet"/>
/// </summary>
private static BiosSet ConvertFromInternalModel(Data.Models.Metadata.BiosSet item)
{
var biosset = new BiosSet
{
Name = item.ReadString(Data.Models.Metadata.BiosSet.NameKey),
Description = item.ReadString(Data.Models.Metadata.BiosSet.DescriptionKey),
Default = item.ReadString(Data.Models.Metadata.BiosSet.DefaultKey),
};
return biosset;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Chip"/> to <see cref="Chip"/>
/// </summary>
private static Chip ConvertFromInternalModel(Data.Models.Metadata.Chip item)
{
var chip = new Chip
{
Name = item.ReadString(Data.Models.Metadata.Chip.NameKey),
Tag = item.ReadString(Data.Models.Metadata.Chip.TagKey),
Type = item.ReadString(Data.Models.Metadata.Chip.ChipTypeKey),
SoundOnly = item.ReadString(Data.Models.Metadata.Chip.SoundOnlyKey),
Clock = item.ReadString(Data.Models.Metadata.Chip.ClockKey),
};
return chip;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Condition"/> to <see cref="Condition"/>
/// </summary>
private static Condition ConvertFromInternalModel(Data.Models.Metadata.Condition item)
{
var condition = new Condition
{
Tag = item.ReadString(Data.Models.Metadata.Condition.TagKey),
Mask = item.ReadString(Data.Models.Metadata.Condition.MaskKey),
Relation = item.ReadString(Data.Models.Metadata.Condition.RelationKey),
Value = item.ReadString(Data.Models.Metadata.Condition.ValueKey),
};
return condition;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Configuration"/> to <see cref="Configuration"/>
/// </summary>
private static Configuration ConvertFromInternalModel(Data.Models.Metadata.Configuration item)
{
var configuration = new Configuration
{
Name = item.ReadString(Data.Models.Metadata.Configuration.NameKey),
Tag = item.ReadString(Data.Models.Metadata.Configuration.TagKey),
Mask = item.ReadString(Data.Models.Metadata.Configuration.MaskKey),
};
var condition = item.Read<Data.Models.Metadata.Condition>(Data.Models.Metadata.Configuration.ConditionKey);
if (condition is not null)
configuration.Condition = ConvertFromInternalModel(condition);
var confLocations = item.Read<Data.Models.Metadata.ConfLocation[]>(Data.Models.Metadata.Configuration.ConfLocationKey);
if (confLocations is not null && confLocations.Length > 0)
configuration.ConfLocation = Array.ConvertAll(confLocations, ConvertFromInternalModel);
var confSettings = item.Read<Data.Models.Metadata.ConfSetting[]>(Data.Models.Metadata.Configuration.ConfSettingKey);
if (confSettings is not null && confSettings.Length > 0)
configuration.ConfSetting = Array.ConvertAll(confSettings, ConvertFromInternalModel);
return configuration;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.ConfLocation"/> to <see cref="ConfLocation"/>
/// </summary>
private static ConfLocation ConvertFromInternalModel(Data.Models.Metadata.ConfLocation item)
{
var confLocation = new ConfLocation
{
Name = item.ReadString(Data.Models.Metadata.ConfLocation.NameKey),
Number = item.ReadString(Data.Models.Metadata.ConfLocation.NumberKey),
Inverted = item.ReadString(Data.Models.Metadata.ConfLocation.InvertedKey),
};
return confLocation;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.ConfSetting"/> to <see cref="ConfSetting"/>
/// </summary>
private static ConfSetting ConvertFromInternalModel(Data.Models.Metadata.ConfSetting item)
{
var confSetting = new ConfSetting
{
Name = item.ReadString(Data.Models.Metadata.ConfSetting.NameKey),
Value = item.ReadString(Data.Models.Metadata.ConfSetting.ValueKey),
Default = item.ReadString(Data.Models.Metadata.ConfSetting.DefaultKey),
};
var condition = item.Read<Data.Models.Metadata.Condition>(Data.Models.Metadata.ConfSetting.ConditionKey);
if (condition is not null)
confSetting.Condition = ConvertFromInternalModel(condition);
return confSetting;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Control"/> to <see cref="Control"/>
/// </summary>
private static Control ConvertFromInternalModel(Data.Models.Metadata.Control item)
{
var control = new Control
{
Type = item.ReadString(Data.Models.Metadata.Control.ControlTypeKey),
Player = item.ReadString(Data.Models.Metadata.Control.PlayerKey),
Buttons = item.ReadString(Data.Models.Metadata.Control.ButtonsKey),
ReqButtons = item.ReadString(Data.Models.Metadata.Control.ReqButtonsKey),
Minimum = item.ReadString(Data.Models.Metadata.Control.MinimumKey),
Maximum = item.ReadString(Data.Models.Metadata.Control.MaximumKey),
Sensitivity = item.ReadString(Data.Models.Metadata.Control.SensitivityKey),
KeyDelta = item.ReadString(Data.Models.Metadata.Control.KeyDeltaKey),
Reverse = item.ReadString(Data.Models.Metadata.Control.ReverseKey),
Ways = item.ReadString(Data.Models.Metadata.Control.WaysKey),
Ways2 = item.ReadString(Data.Models.Metadata.Control.Ways2Key),
Ways3 = item.ReadString(Data.Models.Metadata.Control.Ways3Key),
};
return control;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Device"/> to <see cref="Device"/>
/// </summary>
private static Device ConvertFromInternalModel(Data.Models.Metadata.Device item)
{
var device = new Device
{
Type = item.ReadString(Data.Models.Metadata.Device.DeviceTypeKey),
Tag = item.ReadString(Data.Models.Metadata.Device.TagKey),
FixedImage = item.ReadString(Data.Models.Metadata.Device.FixedImageKey),
Mandatory = item.ReadString(Data.Models.Metadata.Device.MandatoryKey),
Interface = item.ReadString(Data.Models.Metadata.Device.InterfaceKey),
};
var instance = item.Read<Data.Models.Metadata.Instance>(Data.Models.Metadata.Device.InstanceKey);
if (instance is not null)
device.Instance = ConvertFromInternalModel(instance);
var extensions = item.Read<Data.Models.Metadata.Extension[]>(Data.Models.Metadata.Device.ExtensionKey);
if (extensions is not null && extensions.Length > 0)
device.Extension = Array.ConvertAll(extensions, ConvertFromInternalModel);
return device;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.DeviceRef"/> to <see cref="DeviceRef"/>
/// </summary>
private static DeviceRef ConvertFromInternalModel(Data.Models.Metadata.DeviceRef item)
{
var deviceRef = new DeviceRef
{
Name = item.ReadString(Data.Models.Metadata.DeviceRef.NameKey),
};
return deviceRef;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.DipLocation"/> to <see cref="DipLocation"/>
/// </summary>
private static DipLocation ConvertFromInternalModel(Data.Models.Metadata.DipLocation item)
{
var dipLocation = new DipLocation
{
Name = item.ReadString(Data.Models.Metadata.DipLocation.NameKey),
Number = item.ReadString(Data.Models.Metadata.DipLocation.NumberKey),
Inverted = item.ReadString(Data.Models.Metadata.DipLocation.InvertedKey),
};
return dipLocation;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.DipSwitch"/> to <see cref="DipSwitch"/>
/// </summary>
private static DipSwitch ConvertFromInternalModel(Data.Models.Metadata.DipSwitch item)
{
var dipSwitch = new DipSwitch
{
Name = item.ReadString(Data.Models.Metadata.DipSwitch.NameKey),
Tag = item.ReadString(Data.Models.Metadata.DipSwitch.TagKey),
Mask = item.ReadString(Data.Models.Metadata.DipSwitch.MaskKey),
};
var condition = item.Read<Data.Models.Metadata.Condition>(Data.Models.Metadata.DipSwitch.ConditionKey);
if (condition is not null)
dipSwitch.Condition = ConvertFromInternalModel(condition);
var dipLocations = item.Read<Data.Models.Metadata.DipLocation[]>(Data.Models.Metadata.DipSwitch.DipLocationKey);
if (dipLocations is not null && dipLocations.Length > 0)
dipSwitch.DipLocation = Array.ConvertAll(dipLocations, ConvertFromInternalModel);
var dipValues = item.Read<Data.Models.Metadata.DipValue[]>(Data.Models.Metadata.DipSwitch.DipValueKey);
if (dipValues is not null && dipValues.Length > 0)
dipSwitch.DipValue = Array.ConvertAll(dipValues, ConvertFromInternalModel);
return dipSwitch;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.DipValue"/> to <see cref="DipValue"/>
/// </summary>
private static DipValue ConvertFromInternalModel(Data.Models.Metadata.DipValue item)
{
var dipValue = new DipValue
{
Name = item.ReadString(Data.Models.Metadata.DipValue.NameKey),
Value = item.ReadString(Data.Models.Metadata.DipValue.ValueKey),
Default = item.ReadString(Data.Models.Metadata.DipValue.DefaultKey),
};
var condition = item.Read<Data.Models.Metadata.Condition>(Data.Models.Metadata.DipValue.ConditionKey);
if (condition is not null)
dipValue.Condition = ConvertFromInternalModel(condition);
return dipValue;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Disk"/> to <see cref="Disk"/>
/// </summary>
private static Disk ConvertFromInternalModel(Data.Models.Metadata.Disk item)
{
var disk = new Disk
{
Name = item.ReadString(Data.Models.Metadata.Disk.NameKey),
MD5 = item.ReadString(Data.Models.Metadata.Disk.MD5Key),
SHA1 = item.ReadString(Data.Models.Metadata.Disk.SHA1Key),
Merge = item.ReadString(Data.Models.Metadata.Disk.MergeKey),
Region = item.ReadString(Data.Models.Metadata.Disk.RegionKey),
Index = item.ReadString(Data.Models.Metadata.Disk.IndexKey),
Writable = item.ReadString(Data.Models.Metadata.Disk.WritableKey),
Status = item.ReadString(Data.Models.Metadata.Disk.StatusKey),
Optional = item.ReadString(Data.Models.Metadata.Disk.OptionalKey),
};
return disk;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Display"/> to <see cref="Display"/>
/// </summary>
private static Display ConvertFromInternalModel(Data.Models.Metadata.Display item)
{
var display = new Display
{
Tag = item.ReadString(Data.Models.Metadata.Display.TagKey),
Type = item.ReadString(Data.Models.Metadata.Display.DisplayTypeKey),
Rotate = item.ReadString(Data.Models.Metadata.Display.RotateKey),
FlipX = item.ReadString(Data.Models.Metadata.Display.FlipXKey),
Width = item.ReadString(Data.Models.Metadata.Display.WidthKey),
Height = item.ReadString(Data.Models.Metadata.Display.HeightKey),
Refresh = item.ReadString(Data.Models.Metadata.Display.RefreshKey),
PixClock = item.ReadString(Data.Models.Metadata.Display.PixClockKey),
HTotal = item.ReadString(Data.Models.Metadata.Display.HTotalKey),
HBEnd = item.ReadString(Data.Models.Metadata.Display.HBEndKey),
HBStart = item.ReadString(Data.Models.Metadata.Display.HBStartKey),
VTotal = item.ReadString(Data.Models.Metadata.Display.VTotalKey),
VBEnd = item.ReadString(Data.Models.Metadata.Display.VBEndKey),
VBStart = item.ReadString(Data.Models.Metadata.Display.VBStartKey),
};
return display;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Driver"/> to <see cref="Driver"/>
/// </summary>
private static Driver ConvertFromInternalModel(Data.Models.Metadata.Driver item)
{
var driver = new Driver
{
Status = item.ReadString(Data.Models.Metadata.Driver.StatusKey),
Color = item.ReadString(Data.Models.Metadata.Driver.ColorKey),
Sound = item.ReadString(Data.Models.Metadata.Driver.SoundKey),
PaletteSize = item.ReadString(Data.Models.Metadata.Driver.PaletteSizeKey),
Emulation = item.ReadString(Data.Models.Metadata.Driver.EmulationKey),
Cocktail = item.ReadString(Data.Models.Metadata.Driver.CocktailKey),
SaveState = item.ReadString(Data.Models.Metadata.Driver.SaveStateKey),
RequiresArtwork = item.ReadString(Data.Models.Metadata.Driver.RequiresArtworkKey),
Unofficial = item.ReadString(Data.Models.Metadata.Driver.UnofficialKey),
NoSoundHardware = item.ReadString(Data.Models.Metadata.Driver.NoSoundHardwareKey),
Incomplete = item.ReadString(Data.Models.Metadata.Driver.IncompleteKey),
};
return driver;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Extension"/> to <see cref="Extension"/>
/// </summary>
private static Extension ConvertFromInternalModel(Data.Models.Metadata.Extension item)
{
var extension = new Extension
{
Name = item.ReadString(Data.Models.Metadata.Extension.NameKey),
};
return extension;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Feature"/> to <see cref="Feature"/>
/// </summary>
private static Feature ConvertFromInternalModel(Data.Models.Metadata.Feature item)
{
var feature = new Feature
{
Type = item.ReadString(Data.Models.Metadata.Feature.FeatureTypeKey),
Status = item.ReadString(Data.Models.Metadata.Feature.StatusKey),
Overall = item.ReadString(Data.Models.Metadata.Feature.OverallKey),
};
return feature;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Input"/> to <see cref="Input"/>
/// </summary>
private static Input ConvertFromInternalModel(Data.Models.Metadata.Input item)
{
var input = new Input
{
Service = item.ReadString(Data.Models.Metadata.Input.ServiceKey),
Tilt = item.ReadString(Data.Models.Metadata.Input.TiltKey),
Players = item.ReadString(Data.Models.Metadata.Input.PlayersKey),
Buttons = item.ReadString(Data.Models.Metadata.Input.ButtonsKey),
Coins = item.ReadString(Data.Models.Metadata.Input.CoinsKey),
};
var controlAttr = item.ReadString(Data.Models.Metadata.Input.ControlKey);
if (controlAttr is not null)
input.ControlAttr = controlAttr;
var controls = item.Read<Data.Models.Metadata.Control[]>(Data.Models.Metadata.Input.ControlKey);
if (controls is not null && controls.Length > 0)
input.Control = Array.ConvertAll(controls, ConvertFromInternalModel);
return input;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Instance"/> to <see cref="Instance"/>
/// </summary>
private static Instance ConvertFromInternalModel(Data.Models.Metadata.Instance item)
{
var instance = new Instance
{
Name = item.ReadString(Data.Models.Metadata.Instance.NameKey),
BriefName = item.ReadString(Data.Models.Metadata.Instance.BriefNameKey),
};
return instance;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Port"/> to <see cref="Port"/>
/// </summary>
private static Port ConvertFromInternalModel(Data.Models.Metadata.Port item)
{
var port = new Port
{
Tag = item.ReadString(Data.Models.Metadata.Port.TagKey),
};
var analogs = item.Read<Data.Models.Metadata.Analog[]>(Data.Models.Metadata.Port.AnalogKey);
if (analogs is not null && analogs.Length > 0)
port.Analog = Array.ConvertAll(analogs, ConvertFromInternalModel);
return port;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.RamOption"/> to <see cref="RamOption"/>
/// </summary>
private static RamOption ConvertFromInternalModel(Data.Models.Metadata.RamOption item)
{
var ramOption = new RamOption
{
Name = item.ReadString(Data.Models.Metadata.RamOption.NameKey),
Default = item.ReadString(Data.Models.Metadata.RamOption.DefaultKey),
Content = item.ReadString(Data.Models.Metadata.RamOption.ContentKey),
};
return ramOption;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="Rom"/>
/// </summary>
private static Rom ConvertFromInternalModel(Data.Models.Metadata.Rom item)
{
var rom = new Rom
{
Name = item.ReadString(Data.Models.Metadata.Rom.NameKey),
Bios = item.ReadString(Data.Models.Metadata.Rom.BiosKey),
Size = item.ReadString(Data.Models.Metadata.Rom.SizeKey),
CRC = item.ReadString(Data.Models.Metadata.Rom.CRCKey),
SHA1 = item.ReadString(Data.Models.Metadata.Rom.SHA1Key),
Merge = item.ReadString(Data.Models.Metadata.Rom.MergeKey),
Region = item.ReadString(Data.Models.Metadata.Rom.RegionKey),
Offset = item.ReadString(Data.Models.Metadata.Rom.OffsetKey),
Status = item.ReadString(Data.Models.Metadata.Rom.StatusKey),
Optional = item.ReadString(Data.Models.Metadata.Rom.OptionalKey),
Dispose = item.ReadString(Data.Models.Metadata.Rom.DisposeKey),
SoundOnly = item.ReadString(Data.Models.Metadata.Rom.SoundOnlyKey),
};
return rom;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Sample"/> to <see cref="Sample"/>
/// </summary>
private static Sample ConvertFromInternalModel(Data.Models.Metadata.Sample item)
{
var sample = new Sample
{
Name = item.ReadString(Data.Models.Metadata.Sample.NameKey),
};
return sample;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Slot"/> to <see cref="Slot"/>
/// </summary>
private static Slot ConvertFromInternalModel(Data.Models.Metadata.Slot item)
{
var slot = new Slot
{
Name = item.ReadString(Data.Models.Metadata.Slot.NameKey),
};
var slotOptions = item.Read<Data.Models.Metadata.SlotOption[]>(Data.Models.Metadata.Slot.SlotOptionKey);
if (slotOptions is not null && slotOptions.Length > 0)
slot.SlotOption = Array.ConvertAll(slotOptions, ConvertFromInternalModel);
return slot;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.SlotOption"/> to <see cref="SlotOption"/>
/// </summary>
private static SlotOption ConvertFromInternalModel(Data.Models.Metadata.SlotOption item)
{
var slotOption = new SlotOption
{
Name = item.ReadString(Data.Models.Metadata.SlotOption.NameKey),
DevName = item.ReadString(Data.Models.Metadata.SlotOption.DevNameKey),
Default = item.ReadString(Data.Models.Metadata.SlotOption.DefaultKey),
};
return slotOption;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.SoftwareList"/> to <see cref="Models.Listxml.SoftwareList"/>
/// </summary>
private static Data.Models.Listxml.SoftwareList ConvertFromInternalModel(Data.Models.Metadata.SoftwareList item)
{
var softwareList = new Data.Models.Listxml.SoftwareList
{
Tag = item.ReadString(Data.Models.Metadata.SoftwareList.TagKey),
Name = item.ReadString(Data.Models.Metadata.SoftwareList.NameKey),
Status = item.ReadString(Data.Models.Metadata.SoftwareList.StatusKey),
Filter = item.ReadString(Data.Models.Metadata.SoftwareList.FilterKey),
};
return softwareList;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Sound"/> to <see cref="Sound"/>
/// </summary>
private static Sound ConvertFromInternalModel(Data.Models.Metadata.Sound item)
{
var sound = new Sound
{
Channels = item.ReadString(Data.Models.Metadata.Sound.ChannelsKey),
};
return sound;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Video"/> to <see cref="Video"/>
/// </summary>
private static Video ConvertFromInternalModel(Data.Models.Metadata.Video item)
{
var video = new Video
{
Screen = item.ReadString(Data.Models.Metadata.Video.ScreenKey),
Orientation = item.ReadString(Data.Models.Metadata.Video.OrientationKey),
Width = item.ReadString(Data.Models.Metadata.Video.WidthKey),
Height = item.ReadString(Data.Models.Metadata.Video.HeightKey),
AspectX = item.ReadString(Data.Models.Metadata.Video.AspectXKey),
AspectY = item.ReadString(Data.Models.Metadata.Video.AspectYKey),
Refresh = item.ReadString(Data.Models.Metadata.Video.RefreshKey),
};
return video;
}
}
}

View File

@@ -0,0 +1,713 @@
using System;
using SabreTools.Data.Models.Listxml;
namespace SabreTools.Serialization.CrossModel
{
public partial class Listxml : BaseMetadataSerializer<Mame>
{
/// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(Mame? item)
{
if (item is null)
return null;
var metadataFile = new Data.Models.Metadata.MetadataFile
{
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
};
if (item?.Game is not null && item.Game.Length > 0)
{
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(item.Game, ConvertMachineToInternalModel);
}
return metadataFile;
}
/// <summary>
/// Convert from <see cref="Mame"/> to <see cref="Models.Metadata.Header"/>
/// </summary>
private static Data.Models.Metadata.Header ConvertHeaderToInternalModel(Mame item)
{
var header = new Data.Models.Metadata.Header
{
[Data.Models.Metadata.Header.BuildKey] = item.Build,
[Data.Models.Metadata.Header.DebugKey] = item.Debug,
[Data.Models.Metadata.Header.MameConfigKey] = item.MameConfig,
};
return header;
}
/// <summary>
/// Convert from <see cref="GameBase"/> to <see cref="Models.Metadata.Machine"/>
/// </summary>
internal static Data.Models.Metadata.Machine ConvertMachineToInternalModel(GameBase item)
{
var machine = new Data.Models.Metadata.Machine
{
[Data.Models.Metadata.Machine.NameKey] = item.Name,
[Data.Models.Metadata.Machine.SourceFileKey] = item.SourceFile,
[Data.Models.Metadata.Machine.IsBiosKey] = item.IsBios,
[Data.Models.Metadata.Machine.IsDeviceKey] = item.IsDevice,
[Data.Models.Metadata.Machine.IsMechanicalKey] = item.IsMechanical,
[Data.Models.Metadata.Machine.RunnableKey] = item.Runnable,
[Data.Models.Metadata.Machine.CloneOfKey] = item.CloneOf,
[Data.Models.Metadata.Machine.RomOfKey] = item.RomOf,
[Data.Models.Metadata.Machine.SampleOfKey] = item.SampleOf,
[Data.Models.Metadata.Machine.DescriptionKey] = item.Description,
[Data.Models.Metadata.Machine.YearKey] = item.Year,
[Data.Models.Metadata.Machine.ManufacturerKey] = item.Manufacturer,
[Data.Models.Metadata.Machine.HistoryKey] = item.History,
};
if (item.BiosSet is not null && item.BiosSet.Length > 0)
{
machine[Data.Models.Metadata.Machine.BiosSetKey]
= Array.ConvertAll(item.BiosSet, ConvertToInternalModel);
}
if (item.Rom is not null && item.Rom.Length > 0)
{
machine[Data.Models.Metadata.Machine.RomKey]
= Array.ConvertAll(item.Rom, ConvertToInternalModel);
}
if (item.Disk is not null && item.Disk.Length > 0)
{
machine[Data.Models.Metadata.Machine.DiskKey]
= Array.ConvertAll(item.Disk, ConvertToInternalModel);
}
if (item.DeviceRef is not null && item.DeviceRef.Length > 0)
{
machine[Data.Models.Metadata.Machine.DeviceRefKey]
= Array.ConvertAll(item.DeviceRef, ConvertToInternalModel);
}
if (item.Sample is not null && item.Sample.Length > 0)
{
machine[Data.Models.Metadata.Machine.SampleKey]
= Array.ConvertAll(item.Sample, ConvertToInternalModel);
}
if (item.Chip is not null && item.Chip.Length > 0)
{
machine[Data.Models.Metadata.Machine.ChipKey]
= Array.ConvertAll(item.Chip, ConvertToInternalModel);
}
if (item.Display is not null && item.Display.Length > 0)
{
machine[Data.Models.Metadata.Machine.DisplayKey]
= Array.ConvertAll(item.Display, ConvertToInternalModel);
}
if (item.Video is not null && item.Video.Length > 0)
{
machine[Data.Models.Metadata.Machine.VideoKey]
= Array.ConvertAll(item.Video, ConvertToInternalModel);
}
if (item.Sound is not null)
machine[Data.Models.Metadata.Machine.SoundKey] = ConvertToInternalModel(item.Sound);
if (item.Input is not null)
machine[Data.Models.Metadata.Machine.InputKey] = ConvertToInternalModel(item.Input);
if (item.DipSwitch is not null && item.DipSwitch.Length > 0)
{
machine[Data.Models.Metadata.Machine.DipSwitchKey]
= Array.ConvertAll(item.DipSwitch, ConvertToInternalModel);
}
if (item.Configuration is not null && item.Configuration.Length > 0)
{
machine[Data.Models.Metadata.Machine.ConfigurationKey]
= Array.ConvertAll(item.Configuration, ConvertToInternalModel);
}
if (item.Port is not null && item.Port.Length > 0)
{
machine[Data.Models.Metadata.Machine.PortKey]
= Array.ConvertAll(item.Port, ConvertToInternalModel);
}
if (item.Adjuster is not null && item.Adjuster.Length > 0)
{
machine[Data.Models.Metadata.Machine.AdjusterKey]
= Array.ConvertAll(item.Adjuster, ConvertToInternalModel);
}
if (item.Driver is not null)
machine[Data.Models.Metadata.Machine.DriverKey] = ConvertToInternalModel(item.Driver);
if (item.Feature is not null && item.Feature.Length > 0)
{
machine[Data.Models.Metadata.Machine.FeatureKey]
= Array.ConvertAll(item.Feature, ConvertToInternalModel);
}
if (item.Device is not null && item.Device.Length > 0)
{
machine[Data.Models.Metadata.Machine.DeviceKey]
= Array.ConvertAll(item.Device, ConvertToInternalModel);
}
if (item.Slot is not null && item.Slot.Length > 0)
{
machine[Data.Models.Metadata.Machine.SlotKey]
= Array.ConvertAll(item.Slot, ConvertToInternalModel);
}
if (item.SoftwareList is not null && item.SoftwareList.Length > 0)
{
machine[Data.Models.Metadata.Machine.SoftwareListKey]
= Array.ConvertAll(item.SoftwareList, ConvertToInternalModel);
}
if (item.RamOption is not null && item.RamOption.Length > 0)
{
machine[Data.Models.Metadata.Machine.RamOptionKey]
= Array.ConvertAll(item.RamOption, ConvertToInternalModel);
}
return machine;
}
/// <summary>
/// Convert from <see cref="Adjuster"/> to <see cref="Models.Metadata.Adjuster"/>
/// </summary>
private static Data.Models.Metadata.Adjuster ConvertToInternalModel(Adjuster item)
{
var adjuster = new Data.Models.Metadata.Adjuster
{
[Data.Models.Metadata.Adjuster.NameKey] = item.Name,
[Data.Models.Metadata.Adjuster.DefaultKey] = item.Default,
};
if (item.Condition is not null)
adjuster[Data.Models.Metadata.Adjuster.ConditionKey] = ConvertToInternalModel(item.Condition);
return adjuster;
}
/// <summary>
/// Convert from <see cref="Analog"/> to <see cref="Models.Metadata.Analog"/>
/// </summary>
private static Data.Models.Metadata.Analog ConvertToInternalModel(Analog item)
{
var analog = new Data.Models.Metadata.Analog
{
[Data.Models.Metadata.Analog.MaskKey] = item.Mask,
};
return analog;
}
/// <summary>
/// Convert from <see cref="BiosSet"/> to <see cref="Models.Metadata.BiosSet"/>
/// </summary>
private static Data.Models.Metadata.BiosSet ConvertToInternalModel(BiosSet item)
{
var biosset = new Data.Models.Metadata.BiosSet
{
[Data.Models.Metadata.BiosSet.NameKey] = item.Name,
[Data.Models.Metadata.BiosSet.DescriptionKey] = item.Description,
[Data.Models.Metadata.BiosSet.DefaultKey] = item.Default,
};
return biosset;
}
/// <summary>
/// Convert from <see cref="Chip"/> to <see cref="Models.Metadata.Chip"/>
/// </summary>
private static Data.Models.Metadata.Chip ConvertToInternalModel(Chip item)
{
var chip = new Data.Models.Metadata.Chip
{
[Data.Models.Metadata.Chip.NameKey] = item.Name,
[Data.Models.Metadata.Chip.TagKey] = item.Tag,
[Data.Models.Metadata.Chip.ChipTypeKey] = item.Type,
[Data.Models.Metadata.Chip.SoundOnlyKey] = item.SoundOnly,
[Data.Models.Metadata.Chip.ClockKey] = item.Clock,
};
return chip;
}
/// <summary>
/// Convert from <see cref="Condition"/> to <see cref="Models.Metadata.Condition"/>
/// </summary>
private static Data.Models.Metadata.Condition ConvertToInternalModel(Condition item)
{
var condition = new Data.Models.Metadata.Condition
{
[Data.Models.Metadata.Condition.TagKey] = item.Tag,
[Data.Models.Metadata.Condition.MaskKey] = item.Mask,
[Data.Models.Metadata.Condition.RelationKey] = item.Relation,
[Data.Models.Metadata.Condition.ValueKey] = item.Value,
};
return condition;
}
/// <summary>
/// Convert from <see cref="Configuration"/> to <see cref="Models.Metadata.Configuration"/>
/// </summary>
private static Data.Models.Metadata.Configuration ConvertToInternalModel(Configuration item)
{
var configuration = new Data.Models.Metadata.Configuration
{
[Data.Models.Metadata.Configuration.NameKey] = item.Name,
[Data.Models.Metadata.Configuration.TagKey] = item.Tag,
[Data.Models.Metadata.Configuration.MaskKey] = item.Mask,
};
if (item.Condition is not null)
configuration[Data.Models.Metadata.Configuration.ConditionKey] = ConvertToInternalModel(item.Condition);
if (item.ConfLocation is not null && item.ConfLocation.Length > 0)
{
configuration[Data.Models.Metadata.Configuration.ConfLocationKey]
= Array.ConvertAll(item.ConfLocation, ConvertToInternalModel);
}
if (item.ConfSetting is not null && item.ConfSetting.Length > 0)
{
configuration[Data.Models.Metadata.Configuration.ConfSettingKey]
= Array.ConvertAll(item.ConfSetting, ConvertToInternalModel);
}
return configuration;
}
/// <summary>
/// Convert from <see cref="ConfLocation"/> to <see cref="Models.Metadata.ConfLocation"/>
/// </summary>
private static Data.Models.Metadata.ConfLocation ConvertToInternalModel(ConfLocation item)
{
var confLocation = new Data.Models.Metadata.ConfLocation
{
[Data.Models.Metadata.ConfLocation.NameKey] = item.Name,
[Data.Models.Metadata.ConfLocation.NumberKey] = item.Number,
[Data.Models.Metadata.ConfLocation.InvertedKey] = item.Inverted,
};
return confLocation;
}
/// <summary>
/// Convert from <see cref="ConfSetting"/> to <see cref="Models.Metadata.ConfSetting"/>
/// </summary>
private static Data.Models.Metadata.ConfSetting ConvertToInternalModel(ConfSetting item)
{
var confSetting = new Data.Models.Metadata.ConfSetting
{
[Data.Models.Metadata.ConfSetting.NameKey] = item.Name,
[Data.Models.Metadata.ConfSetting.ValueKey] = item.Value,
[Data.Models.Metadata.ConfSetting.DefaultKey] = item.Default,
};
if (item.Condition is not null)
confSetting[Data.Models.Metadata.ConfSetting.ConditionKey] = ConvertToInternalModel(item.Condition);
return confSetting;
}
/// <summary>
/// Convert from <see cref="Control"/> to <see cref="Models.Metadata.Control"/>
/// </summary>
private static Data.Models.Metadata.Control ConvertToInternalModel(Control item)
{
var control = new Data.Models.Metadata.Control
{
[Data.Models.Metadata.Control.ControlTypeKey] = item.Type,
[Data.Models.Metadata.Control.PlayerKey] = item.Player,
[Data.Models.Metadata.Control.ButtonsKey] = item.Buttons,
[Data.Models.Metadata.Control.ReqButtonsKey] = item.ReqButtons,
[Data.Models.Metadata.Control.MinimumKey] = item.Minimum,
[Data.Models.Metadata.Control.MaximumKey] = item.Maximum,
[Data.Models.Metadata.Control.SensitivityKey] = item.Sensitivity,
[Data.Models.Metadata.Control.KeyDeltaKey] = item.KeyDelta,
[Data.Models.Metadata.Control.ReverseKey] = item.Reverse,
[Data.Models.Metadata.Control.WaysKey] = item.Ways,
[Data.Models.Metadata.Control.Ways2Key] = item.Ways2,
[Data.Models.Metadata.Control.Ways3Key] = item.Ways3,
};
return control;
}
/// <summary>
/// Convert from <see cref="Device"/> to <see cref="Models.Metadata.Device"/>
/// </summary>
private static Data.Models.Metadata.Device ConvertToInternalModel(Device item)
{
var device = new Data.Models.Metadata.Device
{
[Data.Models.Metadata.Device.DeviceTypeKey] = item.Type,
[Data.Models.Metadata.Device.TagKey] = item.Tag,
[Data.Models.Metadata.Device.FixedImageKey] = item.FixedImage,
[Data.Models.Metadata.Device.MandatoryKey] = item.Mandatory,
[Data.Models.Metadata.Device.InterfaceKey] = item.Interface,
};
if (item.Instance is not null)
device[Data.Models.Metadata.Device.InstanceKey] = ConvertToInternalModel(item.Instance);
if (item.Extension is not null && item.Extension.Length > 0)
{
device[Data.Models.Metadata.Device.ExtensionKey]
= Array.ConvertAll(item.Extension, ConvertToInternalModel);
}
return device;
}
/// <summary>
/// Convert from <see cref="DeviceRef"/> to <see cref="Models.Metadata.DeviceRef"/>
/// </summary>
private static Data.Models.Metadata.DeviceRef ConvertToInternalModel(DeviceRef item)
{
var deviceRef = new Data.Models.Metadata.DeviceRef
{
[Data.Models.Metadata.DeviceRef.NameKey] = item.Name,
};
return deviceRef;
}
/// <summary>
/// Convert from <see cref="DipLocation"/> to <see cref="Models.Metadata.DipLocation"/>
/// </summary>
private static Data.Models.Metadata.DipLocation ConvertToInternalModel(DipLocation item)
{
var dipLocation = new Data.Models.Metadata.DipLocation
{
[Data.Models.Metadata.DipLocation.NameKey] = item.Name,
[Data.Models.Metadata.DipLocation.NumberKey] = item.Number,
[Data.Models.Metadata.DipLocation.InvertedKey] = item.Inverted,
};
return dipLocation;
}
/// <summary>
/// Convert from <see cref="DipSwitch"/> to <see cref="Models.Metadata.DipSwitch"/>
/// </summary>
private static Data.Models.Metadata.DipSwitch ConvertToInternalModel(DipSwitch item)
{
var dipSwitch = new Data.Models.Metadata.DipSwitch
{
[Data.Models.Metadata.DipSwitch.NameKey] = item.Name,
[Data.Models.Metadata.DipSwitch.TagKey] = item.Tag,
[Data.Models.Metadata.DipSwitch.MaskKey] = item.Mask,
};
if (item.Condition is not null)
dipSwitch[Data.Models.Metadata.DipSwitch.ConditionKey] = ConvertToInternalModel(item.Condition);
if (item.DipLocation is not null && item.DipLocation.Length > 0)
{
dipSwitch[Data.Models.Metadata.DipSwitch.DipLocationKey]
= Array.ConvertAll(item.DipLocation, ConvertToInternalModel);
}
if (item.DipValue is not null && item.DipValue.Length > 0)
{
dipSwitch[Data.Models.Metadata.DipSwitch.DipValueKey]
= Array.ConvertAll(item.DipValue, ConvertToInternalModel);
}
return dipSwitch;
}
/// <summary>
/// Convert from <see cref="DipValue"/> to <see cref="Models.Metadata.DipValue"/>
/// </summary>
private static Data.Models.Metadata.DipValue ConvertToInternalModel(DipValue item)
{
var dipValue = new Data.Models.Metadata.DipValue
{
[Data.Models.Metadata.DipValue.NameKey] = item.Name,
[Data.Models.Metadata.DipValue.ValueKey] = item.Value,
[Data.Models.Metadata.DipValue.DefaultKey] = item.Default,
};
if (item.Condition is not null)
dipValue[Data.Models.Metadata.DipValue.ConditionKey] = ConvertToInternalModel(item.Condition);
return dipValue;
}
/// <summary>
/// Convert from <see cref="Disk"/> to <see cref="Models.Metadata.Disk"/>
/// </summary>
private static Data.Models.Metadata.Disk ConvertToInternalModel(Disk item)
{
var disk = new Data.Models.Metadata.Disk
{
[Data.Models.Metadata.Disk.NameKey] = item.Name,
[Data.Models.Metadata.Disk.MD5Key] = item.MD5,
[Data.Models.Metadata.Disk.SHA1Key] = item.SHA1,
[Data.Models.Metadata.Disk.MergeKey] = item.Merge,
[Data.Models.Metadata.Disk.RegionKey] = item.Region,
[Data.Models.Metadata.Disk.IndexKey] = item.Index,
[Data.Models.Metadata.Disk.WritableKey] = item.Writable,
[Data.Models.Metadata.Disk.StatusKey] = item.Status,
[Data.Models.Metadata.Disk.OptionalKey] = item.Optional,
};
return disk;
}
/// <summary>
/// Convert from <see cref="Display"/> to <see cref="Models.Metadata.Display"/>
/// </summary>
private static Data.Models.Metadata.Display ConvertToInternalModel(Display item)
{
var display = new Data.Models.Metadata.Display
{
[Data.Models.Metadata.Display.TagKey] = item.Tag,
[Data.Models.Metadata.Display.DisplayTypeKey] = item.Type,
[Data.Models.Metadata.Display.RotateKey] = item.Rotate,
[Data.Models.Metadata.Display.FlipXKey] = item.FlipX,
[Data.Models.Metadata.Display.WidthKey] = item.Width,
[Data.Models.Metadata.Display.HeightKey] = item.Height,
[Data.Models.Metadata.Display.RefreshKey] = item.Refresh,
[Data.Models.Metadata.Display.PixClockKey] = item.PixClock,
[Data.Models.Metadata.Display.HTotalKey] = item.HTotal,
[Data.Models.Metadata.Display.HBEndKey] = item.HBEnd,
[Data.Models.Metadata.Display.HBStartKey] = item.HBStart,
[Data.Models.Metadata.Display.VTotalKey] = item.VTotal,
[Data.Models.Metadata.Display.VBEndKey] = item.VBEnd,
[Data.Models.Metadata.Display.VBStartKey] = item.VBStart,
};
return display;
}
/// <summary>
/// Convert from <see cref="Driver"/> to <see cref="Models.Metadata.Driver"/>
/// </summary>
private static Data.Models.Metadata.Driver ConvertToInternalModel(Driver item)
{
var driver = new Data.Models.Metadata.Driver
{
[Data.Models.Metadata.Driver.StatusKey] = item.Status,
[Data.Models.Metadata.Driver.ColorKey] = item.Color,
[Data.Models.Metadata.Driver.SoundKey] = item.Sound,
[Data.Models.Metadata.Driver.PaletteSizeKey] = item.PaletteSize,
[Data.Models.Metadata.Driver.EmulationKey] = item.Emulation,
[Data.Models.Metadata.Driver.CocktailKey] = item.Cocktail,
[Data.Models.Metadata.Driver.SaveStateKey] = item.SaveState,
[Data.Models.Metadata.Driver.RequiresArtworkKey] = item.RequiresArtwork,
[Data.Models.Metadata.Driver.UnofficialKey] = item.Unofficial,
[Data.Models.Metadata.Driver.NoSoundHardwareKey] = item.NoSoundHardware,
[Data.Models.Metadata.Driver.IncompleteKey] = item.Incomplete,
};
return driver;
}
/// <summary>
/// Convert from <see cref="Extension"/> to <see cref="Models.Metadata.Extension"/>
/// </summary>
private static Data.Models.Metadata.Extension ConvertToInternalModel(Extension item)
{
var extension = new Data.Models.Metadata.Extension
{
[Data.Models.Metadata.Extension.NameKey] = item.Name,
};
return extension;
}
/// <summary>
/// Convert from <see cref="Feature"/> to <see cref="Models.Metadata.Feature"/>
/// </summary>
private static Data.Models.Metadata.Feature ConvertToInternalModel(Feature item)
{
var feature = new Data.Models.Metadata.Feature
{
[Data.Models.Metadata.Feature.FeatureTypeKey] = item.Type,
[Data.Models.Metadata.Feature.StatusKey] = item.Status,
[Data.Models.Metadata.Feature.OverallKey] = item.Overall,
};
return feature;
}
/// <summary>
/// Convert from <see cref="Input"/> to <see cref="Models.Metadata.Input"/>
/// </summary>
private static Data.Models.Metadata.Input ConvertToInternalModel(Input item)
{
var input = new Data.Models.Metadata.Input
{
[Data.Models.Metadata.Input.ServiceKey] = item.Service,
[Data.Models.Metadata.Input.TiltKey] = item.Tilt,
[Data.Models.Metadata.Input.PlayersKey] = item.Players,
[Data.Models.Metadata.Input.ControlKey] = item.ControlAttr,
[Data.Models.Metadata.Input.ButtonsKey] = item.Buttons,
[Data.Models.Metadata.Input.CoinsKey] = item.Coins,
};
if (item.Control is not null && item.Control.Length > 0)
{
input[Data.Models.Metadata.Input.ControlKey]
= Array.ConvertAll(item.Control, ConvertToInternalModel);
}
return input;
}
/// <summary>
/// Convert from <see cref="Instance"/> to <see cref="Models.Metadata.Instance"/>
/// </summary>
private static Data.Models.Metadata.Instance ConvertToInternalModel(Instance item)
{
var instance = new Data.Models.Metadata.Instance
{
[Data.Models.Metadata.Instance.NameKey] = item.Name,
[Data.Models.Metadata.Instance.BriefNameKey] = item.BriefName,
};
return instance;
}
/// <summary>
/// Convert from <see cref="Port"/> to <see cref="Models.Metadata.Port"/>
/// </summary>
private static Data.Models.Metadata.Port ConvertToInternalModel(Port item)
{
var port = new Data.Models.Metadata.Port
{
[Data.Models.Metadata.Port.TagKey] = item.Tag,
};
if (item.Analog is not null && item.Analog.Length > 0)
{
port[Data.Models.Metadata.Port.AnalogKey]
= Array.ConvertAll(item.Analog, ConvertToInternalModel);
}
return port;
}
/// <summary>
/// Convert from <see cref="RamOption"/> to <see cref="Models.Metadata.RamOption"/>
/// </summary>
private static Data.Models.Metadata.RamOption ConvertToInternalModel(RamOption item)
{
var ramOption = new Data.Models.Metadata.RamOption
{
[Data.Models.Metadata.RamOption.NameKey] = item.Name,
[Data.Models.Metadata.RamOption.DefaultKey] = item.Default,
[Data.Models.Metadata.RamOption.ContentKey] = item.Content,
};
return ramOption;
}
/// <summary>
/// Convert from <see cref="Rom"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
private static Data.Models.Metadata.Rom ConvertToInternalModel(Rom item)
{
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.NameKey] = item.Name,
[Data.Models.Metadata.Rom.BiosKey] = item.Bios,
[Data.Models.Metadata.Rom.SizeKey] = item.Size,
[Data.Models.Metadata.Rom.CRCKey] = item.CRC,
[Data.Models.Metadata.Rom.SHA1Key] = item.SHA1,
[Data.Models.Metadata.Rom.MergeKey] = item.Merge,
[Data.Models.Metadata.Rom.RegionKey] = item.Region,
[Data.Models.Metadata.Rom.OffsetKey] = item.Offset,
[Data.Models.Metadata.Rom.StatusKey] = item.Status,
[Data.Models.Metadata.Rom.OptionalKey] = item.Optional,
[Data.Models.Metadata.Rom.DisposeKey] = item.Dispose,
[Data.Models.Metadata.Rom.SoundOnlyKey] = item.SoundOnly,
};
return rom;
}
/// <summary>
/// Convert from <see cref="Sample"/> to <see cref="Models.Metadata.Sample"/>
/// </summary>
private static Data.Models.Metadata.Sample ConvertToInternalModel(Sample item)
{
var sample = new Data.Models.Metadata.Sample
{
[Data.Models.Metadata.Sample.NameKey] = item.Name,
};
return sample;
}
/// <summary>
/// Convert from <see cref="Slot"/> to <see cref="Models.Metadata.Slot"/>
/// </summary>
private static Data.Models.Metadata.Slot ConvertToInternalModel(Slot item)
{
var slot = new Data.Models.Metadata.Slot
{
[Data.Models.Metadata.Slot.NameKey] = item.Name,
};
if (item.SlotOption is not null && item.SlotOption.Length > 0)
{
slot[Data.Models.Metadata.Slot.SlotOptionKey]
= Array.ConvertAll(item.SlotOption, ConvertToInternalModel);
}
return slot;
}
/// <summary>
/// Convert from <see cref="SlotOption"/> to <see cref="Models.Metadata.SlotOption"/>
/// </summary>
private static Data.Models.Metadata.SlotOption ConvertToInternalModel(SlotOption item)
{
var slotOption = new Data.Models.Metadata.SlotOption
{
[Data.Models.Metadata.SlotOption.NameKey] = item.Name,
[Data.Models.Metadata.SlotOption.DevNameKey] = item.DevName,
[Data.Models.Metadata.SlotOption.DefaultKey] = item.Default,
};
return slotOption;
}
/// <summary>
/// Convert from <see cref="Models.Listxml.SoftwareList"/> to <see cref="Models.Metadata.SoftwareList"/>
/// </summary>
private static Data.Models.Metadata.SoftwareList ConvertToInternalModel(Data.Models.Listxml.SoftwareList item)
{
var softwareList = new Data.Models.Metadata.SoftwareList
{
[Data.Models.Metadata.SoftwareList.TagKey] = item.Tag,
[Data.Models.Metadata.SoftwareList.NameKey] = item.Name,
[Data.Models.Metadata.SoftwareList.StatusKey] = item.Status,
[Data.Models.Metadata.SoftwareList.FilterKey] = item.Filter,
};
return softwareList;
}
/// <summary>
/// Convert from <see cref="Sound"/> to <see cref="Models.Metadata.Sound"/>
/// </summary>
private static Data.Models.Metadata.Sound ConvertToInternalModel(Sound item)
{
var sound = new Data.Models.Metadata.Sound
{
[Data.Models.Metadata.Sound.ChannelsKey] = item.Channels,
};
return sound;
}
/// <summary>
/// Convert from <see cref="Video"/> to <see cref="Models.Metadata.Video"/>
/// </summary>
private static Data.Models.Metadata.Video ConvertToInternalModel(Video item)
{
var video = new Data.Models.Metadata.Video
{
[Data.Models.Metadata.Video.ScreenKey] = item.Screen,
[Data.Models.Metadata.Video.OrientationKey] = item.Orientation,
[Data.Models.Metadata.Video.WidthKey] = item.Width,
[Data.Models.Metadata.Video.HeightKey] = item.Height,
[Data.Models.Metadata.Video.AspectXKey] = item.AspectX,
[Data.Models.Metadata.Video.AspectYKey] = item.AspectY,
[Data.Models.Metadata.Video.RefreshKey] = item.Refresh,
};
return video;
}
}
}

View File

@@ -0,0 +1,358 @@
using System;
using SabreTools.Data.Models.Logiqx;
#pragma warning disable CA1822 // Mark members as static
namespace SabreTools.Serialization.CrossModel
{
public partial class Logiqx : BaseMetadataSerializer<Datafile>
{
/// <inheritdoc/>
public override Datafile? Deserialize(Data.Models.Metadata.MetadataFile? obj)
=> Deserialize(obj, false);
/// <inheritdoc/>
public Datafile? Deserialize(Data.Models.Metadata.MetadataFile? obj, bool game)
{
if (obj is null)
return null;
var datafile = new Datafile();
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
if (header is not null)
{
datafile.Build = header.ReadString(Data.Models.Metadata.Header.BuildKey);
datafile.Debug = header.ReadString(Data.Models.Metadata.Header.DebugKey);
datafile.SchemaLocation = header.ReadString(Data.Models.Metadata.Header.SchemaLocationKey);
datafile.Header = ConvertHeaderFromInternalModel(header);
}
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
if (machines is not null && machines.Length > 0)
datafile.Game = Array.ConvertAll(machines, m => ConvertMachineFromInternalModel(m, game));
return datafile;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Header"/> to <see cref="Header"/>
/// </summary>
private static Header ConvertHeaderFromInternalModel(Data.Models.Metadata.Header item)
{
var header = new Header
{
Id = item.ReadString(Data.Models.Metadata.Header.IdKey),
Name = item.ReadString(Data.Models.Metadata.Header.NameKey),
Description = item.ReadString(Data.Models.Metadata.Header.DescriptionKey),
RootDir = item.ReadString(Data.Models.Metadata.Header.RootDirKey),
Category = item.ReadString(Data.Models.Metadata.Header.CategoryKey),
Version = item.ReadString(Data.Models.Metadata.Header.VersionKey),
Date = item.ReadString(Data.Models.Metadata.Header.DateKey),
Author = item.ReadString(Data.Models.Metadata.Header.AuthorKey),
Email = item.ReadString(Data.Models.Metadata.Header.EmailKey),
Homepage = item.ReadString(Data.Models.Metadata.Header.HomepageKey),
Url = item.ReadString(Data.Models.Metadata.Header.UrlKey),
Comment = item.ReadString(Data.Models.Metadata.Header.CommentKey),
Type = item.ReadString(Data.Models.Metadata.Header.TypeKey),
};
string? headerVal = item.ReadString(Data.Models.Metadata.Header.HeaderKey);
string? forceMerging = item.ReadString(Data.Models.Metadata.Header.ForceMergingKey);
string? forceNodump = item.ReadString(Data.Models.Metadata.Header.ForceNodumpKey);
string? forceUnpacking = item.ReadString(Data.Models.Metadata.Header.ForcePackingKey);
if (headerVal is not null
|| forceMerging is not null
|| forceNodump is not null
|| forceUnpacking is not null)
{
header.ClrMamePro = new Data.Models.Logiqx.ClrMamePro();
if (headerVal is not null)
header.ClrMamePro.Header = headerVal;
if (forceMerging is not null)
header.ClrMamePro.ForceMerging = forceMerging;
if (forceNodump is not null)
header.ClrMamePro.ForceNodump = forceNodump;
if (forceUnpacking is not null)
header.ClrMamePro.ForcePacking = forceUnpacking;
}
string? plugin = item.ReadString(Data.Models.Metadata.Header.PluginKey);
string? romMode = item.ReadString(Data.Models.Metadata.Header.RomModeKey);
string? biosMode = item.ReadString(Data.Models.Metadata.Header.BiosModeKey);
string? sampleMode = item.ReadString(Data.Models.Metadata.Header.SampleModeKey);
string? lockRomMode = item.ReadString(Data.Models.Metadata.Header.LockRomModeKey);
string? lockBiosMode = item.ReadString(Data.Models.Metadata.Header.LockBiosModeKey);
string? lockSampleMode = item.ReadString(Data.Models.Metadata.Header.LockSampleModeKey);
if (plugin is not null
|| romMode is not null
|| biosMode is not null
|| sampleMode is not null
|| lockRomMode is not null
|| lockBiosMode is not null
|| lockSampleMode is not null)
{
header.RomCenter = new Data.Models.Logiqx.RomCenter();
if (plugin is not null)
header.RomCenter.Plugin = plugin;
if (romMode is not null)
header.RomCenter.RomMode = romMode;
if (biosMode is not null)
header.RomCenter.BiosMode = biosMode;
if (sampleMode is not null)
header.RomCenter.SampleMode = sampleMode;
if (lockRomMode is not null)
header.RomCenter.LockRomMode = lockRomMode;
if (lockBiosMode is not null)
header.RomCenter.LockBiosMode = lockBiosMode;
if (lockSampleMode is not null)
header.RomCenter.LockSampleMode = lockSampleMode;
}
return header;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Machine"/> to <see cref="GameBase"/>
/// </summary>
private static GameBase ConvertMachineFromInternalModel(Data.Models.Metadata.Machine item, bool game = false)
{
GameBase gameBase = game ? new Game() : new Machine();
gameBase.Name = item.ReadString(Data.Models.Metadata.Machine.NameKey);
gameBase.SourceFile = item.ReadString(Data.Models.Metadata.Machine.SourceFileKey);
gameBase.IsBios = item.ReadString(Data.Models.Metadata.Machine.IsBiosKey);
gameBase.IsDevice = item.ReadString(Data.Models.Metadata.Machine.IsDeviceKey);
gameBase.IsMechanical = item.ReadString(Data.Models.Metadata.Machine.IsMechanicalKey);
gameBase.CloneOf = item.ReadString(Data.Models.Metadata.Machine.CloneOfKey);
gameBase.RomOf = item.ReadString(Data.Models.Metadata.Machine.RomOfKey);
gameBase.SampleOf = item.ReadString(Data.Models.Metadata.Machine.SampleOfKey);
gameBase.Board = item.ReadString(Data.Models.Metadata.Machine.BoardKey);
gameBase.RebuildTo = item.ReadString(Data.Models.Metadata.Machine.RebuildToKey);
gameBase.Id = item.ReadString(Data.Models.Metadata.Machine.IdKey);
gameBase.CloneOfId = item.ReadString(Data.Models.Metadata.Machine.CloneOfIdKey);
gameBase.Runnable = item.ReadString(Data.Models.Metadata.Machine.RunnableKey);
gameBase.Comment = item.ReadStringArray(Data.Models.Metadata.Machine.CommentKey);
gameBase.Description = item.ReadString(Data.Models.Metadata.Machine.DescriptionKey);
gameBase.Year = item.ReadString(Data.Models.Metadata.Machine.YearKey);
gameBase.Manufacturer = item.ReadString(Data.Models.Metadata.Machine.ManufacturerKey);
gameBase.Publisher = item.ReadString(Data.Models.Metadata.Machine.PublisherKey);
gameBase.Category = item.ReadStringArray(Data.Models.Metadata.Machine.CategoryKey);
var trurip = item.Read<Trurip>(Data.Models.Metadata.Machine.TruripKey);
if (trurip is not null)
gameBase.Trurip = trurip;
var releases = item.Read<Data.Models.Metadata.Release[]>(Data.Models.Metadata.Machine.ReleaseKey);
if (releases is not null && releases.Length > 0)
gameBase.Release = Array.ConvertAll(releases, ConvertFromInternalModel);
var biosSets = item.Read<Data.Models.Metadata.BiosSet[]>(Data.Models.Metadata.Machine.BiosSetKey);
if (biosSets is not null && biosSets.Length > 0)
gameBase.BiosSet = Array.ConvertAll(biosSets, ConvertFromInternalModel);
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms is not null && roms.Length > 0)
gameBase.Rom = Array.ConvertAll(roms, ConvertFromInternalModel);
var disks = item.Read<Data.Models.Metadata.Disk[]>(Data.Models.Metadata.Machine.DiskKey);
if (disks is not null && disks.Length > 0)
gameBase.Disk = Array.ConvertAll(disks, ConvertFromInternalModel);
var medias = item.Read<Data.Models.Metadata.Media[]>(Data.Models.Metadata.Machine.MediaKey);
if (medias is not null && medias.Length > 0)
gameBase.Media = Array.ConvertAll(medias, ConvertFromInternalModel);
var deviceRefs = item.Read<Data.Models.Metadata.DeviceRef[]>(Data.Models.Metadata.Machine.DeviceRefKey);
if (deviceRefs is not null && deviceRefs.Length > 0)
gameBase.DeviceRef = Array.ConvertAll(deviceRefs, ConvertFromInternalModel);
var samples = item.Read<Data.Models.Metadata.Sample[]>(Data.Models.Metadata.Machine.SampleKey);
if (samples is not null && samples.Length > 0)
gameBase.Sample = Array.ConvertAll(samples, ConvertFromInternalModel);
var archives = item.Read<Data.Models.Metadata.Archive[]>(Data.Models.Metadata.Machine.ArchiveKey);
if (archives is not null && archives.Length > 0)
gameBase.Archive = Array.ConvertAll(archives, ConvertFromInternalModel);
var driver = item.Read<Data.Models.Metadata.Driver>(Data.Models.Metadata.Machine.DriverKey);
if (driver is not null)
gameBase.Driver = ConvertFromInternalModel(driver);
var softwareLists = item.Read<Data.Models.Metadata.SoftwareList[]>(Data.Models.Metadata.Machine.SoftwareListKey);
if (softwareLists is not null && softwareLists.Length > 0)
gameBase.SoftwareList = Array.ConvertAll(softwareLists, ConvertFromInternalModel);
return gameBase;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Archive"/> to <see cref="Archive"/>
/// </summary>
private static Archive ConvertFromInternalModel(Data.Models.Metadata.Archive item)
{
var archive = new Archive
{
Name = item.ReadString(Data.Models.Metadata.Archive.NameKey),
};
return archive;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.BiosSet"/> to <see cref="BiosSet"/>
/// </summary>
private static BiosSet ConvertFromInternalModel(Data.Models.Metadata.BiosSet item)
{
var biosset = new BiosSet
{
Name = item.ReadString(Data.Models.Metadata.BiosSet.NameKey),
Description = item.ReadString(Data.Models.Metadata.BiosSet.DescriptionKey),
Default = item.ReadString(Data.Models.Metadata.BiosSet.DefaultKey),
};
return biosset;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.DeviceRef"/> to <see cref="DeviceRef"/>
/// </summary>
private static DeviceRef ConvertFromInternalModel(Data.Models.Metadata.DeviceRef item)
{
var deviceRef = new DeviceRef
{
Name = item.ReadString(Data.Models.Metadata.DipSwitch.NameKey),
};
return deviceRef;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Disk"/> to <see cref="Disk"/>
/// </summary>
private static Disk ConvertFromInternalModel(Data.Models.Metadata.Disk item)
{
var disk = new Disk
{
Name = item.ReadString(Data.Models.Metadata.Disk.NameKey),
MD5 = item.ReadString(Data.Models.Metadata.Disk.MD5Key),
SHA1 = item.ReadString(Data.Models.Metadata.Disk.SHA1Key),
Merge = item.ReadString(Data.Models.Metadata.Disk.MergeKey),
Status = item.ReadString(Data.Models.Metadata.Disk.StatusKey),
Region = item.ReadString(Data.Models.Metadata.Disk.RegionKey),
};
return disk;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Driver"/> to <see cref="Driver"/>
/// </summary>
private static Driver ConvertFromInternalModel(Data.Models.Metadata.Driver item)
{
var driver = new Driver
{
Status = item.ReadString(Data.Models.Metadata.Driver.StatusKey),
Emulation = item.ReadString(Data.Models.Metadata.Driver.EmulationKey),
Cocktail = item.ReadString(Data.Models.Metadata.Driver.CocktailKey),
SaveState = item.ReadString(Data.Models.Metadata.Driver.SaveStateKey),
RequiresArtwork = item.ReadString(Data.Models.Metadata.Driver.RequiresArtworkKey),
Unofficial = item.ReadString(Data.Models.Metadata.Driver.UnofficialKey),
NoSoundHardware = item.ReadString(Data.Models.Metadata.Driver.NoSoundHardwareKey),
Incomplete = item.ReadString(Data.Models.Metadata.Driver.IncompleteKey),
};
return driver;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Media"/> to <see cref="Media"/>
/// </summary>
private static Media ConvertFromInternalModel(Data.Models.Metadata.Media item)
{
var media = new Media
{
Name = item.ReadString(Data.Models.Metadata.Media.NameKey),
MD5 = item.ReadString(Data.Models.Metadata.Media.MD5Key),
SHA1 = item.ReadString(Data.Models.Metadata.Media.SHA1Key),
SHA256 = item.ReadString(Data.Models.Metadata.Media.SHA256Key),
SpamSum = item.ReadString(Data.Models.Metadata.Media.SpamSumKey),
};
return media;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Release"/> to <see cref="Release"/>
/// </summary>
private static Release ConvertFromInternalModel(Data.Models.Metadata.Release item)
{
var release = new Release
{
Name = item.ReadString(Data.Models.Metadata.Release.NameKey),
Region = item.ReadString(Data.Models.Metadata.Release.RegionKey),
Language = item.ReadString(Data.Models.Metadata.Release.LanguageKey),
Date = item.ReadString(Data.Models.Metadata.Release.DateKey),
Default = item.ReadString(Data.Models.Metadata.Release.DefaultKey),
};
return release;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="Rom"/>
/// </summary>
private static Rom ConvertFromInternalModel(Data.Models.Metadata.Rom item)
{
var rom = new Rom
{
Name = item.ReadString(Data.Models.Metadata.Rom.NameKey),
Size = item.ReadString(Data.Models.Metadata.Rom.SizeKey),
CRC16 = item.ReadString(Data.Models.Metadata.Rom.CRC16Key),
CRC = item.ReadString(Data.Models.Metadata.Rom.CRCKey),
CRC64 = item.ReadString(Data.Models.Metadata.Rom.CRC64Key),
MD2 = item.ReadString(Data.Models.Metadata.Rom.MD2Key),
MD4 = item.ReadString(Data.Models.Metadata.Rom.MD4Key),
MD5 = item.ReadString(Data.Models.Metadata.Rom.MD5Key),
RIPEMD128 = item.ReadString(Data.Models.Metadata.Rom.RIPEMD128Key),
RIPEMD160 = item.ReadString(Data.Models.Metadata.Rom.RIPEMD160Key),
SHA1 = item.ReadString(Data.Models.Metadata.Rom.SHA1Key),
SHA256 = item.ReadString(Data.Models.Metadata.Rom.SHA256Key),
SHA384 = item.ReadString(Data.Models.Metadata.Rom.SHA384Key),
SHA512 = item.ReadString(Data.Models.Metadata.Rom.SHA512Key),
SpamSum = item.ReadString(Data.Models.Metadata.Rom.SpamSumKey),
xxHash364 = item.ReadString(Data.Models.Metadata.Rom.xxHash364Key),
xxHash3128 = item.ReadString(Data.Models.Metadata.Rom.xxHash3128Key),
Merge = item.ReadString(Data.Models.Metadata.Rom.MergeKey),
Status = item.ReadString(Data.Models.Metadata.Rom.StatusKey),
Serial = item.ReadString(Data.Models.Metadata.Rom.SerialKey),
Header = item.ReadString(Data.Models.Metadata.Rom.HeaderKey),
Date = item.ReadString(Data.Models.Metadata.Rom.DateKey),
Inverted = item.ReadString(Data.Models.Metadata.Rom.InvertedKey),
MIA = item.ReadString(Data.Models.Metadata.Rom.MIAKey),
};
return rom;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Sample"/> to <see cref="Sample"/>
/// </summary>
private static Sample ConvertFromInternalModel(Data.Models.Metadata.Sample item)
{
var sample = new Sample
{
Name = item.ReadString(Data.Models.Metadata.Sample.NameKey),
};
return sample;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.SoftwareList"/> to <see cref="Models.Logiqx.SoftwareList"/>
/// </summary>
private static Data.Models.Logiqx.SoftwareList ConvertFromInternalModel(Data.Models.Metadata.SoftwareList item)
{
var softwareList = new Data.Models.Logiqx.SoftwareList
{
Tag = item.ReadString(Data.Models.Metadata.SoftwareList.TagKey),
Name = item.ReadString(Data.Models.Metadata.SoftwareList.NameKey),
Status = item.ReadString(Data.Models.Metadata.SoftwareList.StatusKey),
Filter = item.ReadString(Data.Models.Metadata.SoftwareList.FilterKey),
};
return softwareList;
}
}
}

View File

@@ -0,0 +1,352 @@
using System;
using System.Collections.Generic;
using SabreTools.Data.Models.Logiqx;
namespace SabreTools.Serialization.CrossModel
{
public partial class Logiqx : BaseMetadataSerializer<Datafile>
{
public override Data.Models.Metadata.MetadataFile? Serialize(Datafile? item)
{
if (item is null)
return null;
var metadataFile = new Data.Models.Metadata.MetadataFile
{
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
};
var machines = new List<Data.Models.Metadata.Machine>();
if (item.Game is not null && item.Game.Length > 0)
machines.AddRange(Array.ConvertAll(item.Game, g => ConvertMachineToInternalModel(g)));
foreach (var dir in item.Dir ?? [])
{
machines.AddRange(ConvertDirToInternalModel(dir));
}
if (machines.Count > 0)
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey] = machines.ToArray();
return metadataFile;
}
/// <summary>
/// Convert from <see cref="Datafile"/> to <see cref="Models.Metadata.Header"/>
/// </summary>
private static Data.Models.Metadata.Header ConvertHeaderToInternalModel(Datafile item)
{
var header = item.Header is not null ? ConvertHeaderToInternalModel(item.Header) : [];
header[Data.Models.Metadata.Header.BuildKey] = item.Build;
header[Data.Models.Metadata.Header.DebugKey] = item.Debug;
header[Data.Models.Metadata.Header.SchemaLocationKey] = item.SchemaLocation;
return header;
}
/// <summary>
/// Convert from <see cref="Header"/> to <see cref="Models.Metadata.Header"/>
/// </summary>
private static Data.Models.Metadata.Header ConvertHeaderToInternalModel(Header item)
{
var header = new Data.Models.Metadata.Header
{
[Data.Models.Metadata.Header.IdKey] = item.Id,
[Data.Models.Metadata.Header.NameKey] = item.Name,
[Data.Models.Metadata.Header.DescriptionKey] = item.Description,
[Data.Models.Metadata.Header.RootDirKey] = item.RootDir,
[Data.Models.Metadata.Header.CategoryKey] = item.Category,
[Data.Models.Metadata.Header.VersionKey] = item.Version,
[Data.Models.Metadata.Header.DateKey] = item.Date,
[Data.Models.Metadata.Header.AuthorKey] = item.Author,
[Data.Models.Metadata.Header.EmailKey] = item.Email,
[Data.Models.Metadata.Header.HomepageKey] = item.Homepage,
[Data.Models.Metadata.Header.UrlKey] = item.Url,
[Data.Models.Metadata.Header.CommentKey] = item.Comment,
[Data.Models.Metadata.Header.TypeKey] = item.Type,
};
if (item.ClrMamePro is not null)
{
header[Data.Models.Metadata.Header.HeaderKey] = item.ClrMamePro.Header;
header[Data.Models.Metadata.Header.ForceMergingKey] = item.ClrMamePro.ForceMerging;
header[Data.Models.Metadata.Header.ForceNodumpKey] = item.ClrMamePro.ForceNodump;
header[Data.Models.Metadata.Header.ForcePackingKey] = item.ClrMamePro.ForcePacking;
}
if (item.RomCenter is not null)
{
header[Data.Models.Metadata.Header.PluginKey] = item.RomCenter.Plugin;
header[Data.Models.Metadata.Header.RomModeKey] = item.RomCenter.RomMode;
header[Data.Models.Metadata.Header.BiosModeKey] = item.RomCenter.BiosMode;
header[Data.Models.Metadata.Header.SampleModeKey] = item.RomCenter.SampleMode;
header[Data.Models.Metadata.Header.LockRomModeKey] = item.RomCenter.LockRomMode;
header[Data.Models.Metadata.Header.LockBiosModeKey] = item.RomCenter.LockBiosMode;
header[Data.Models.Metadata.Header.LockSampleModeKey] = item.RomCenter.LockSampleMode;
}
return header;
}
/// <summary>
/// Convert from <see cref="Dir"/> to an array of <see cref="Models.Metadata.Machine"/>
/// </summary>
private static Data.Models.Metadata.Machine[] ConvertDirToInternalModel(Dir item, string? parent = null)
{
// Get the directory name
string? dirName = item.Name;
if (parent is not null)
dirName = $"{parent}\\{item.Name}";
// Handle machine items
Data.Models.Metadata.Machine[] machines = [];
if (item.Game is not null && item.Game.Length > 0)
machines = Array.ConvertAll(item.Game, g => ConvertMachineToInternalModel(g, dirName));
// Handle dir items
List<Data.Models.Metadata.Machine> dirs = [];
foreach (var subdir in item.Subdir ?? [])
{
dirs.AddRange(ConvertDirToInternalModel(subdir, dirName));
}
return [.. machines, .. dirs];
}
/// <summary>
/// Convert from <see cref="GameBase"/> to <see cref="Models.Metadata.Machine"/>
/// </summary>
private static Data.Models.Metadata.Machine ConvertMachineToInternalModel(GameBase item, string? dir = null)
{
string? machineName = item.Name;
if (machineName is not null && dir is not null)
machineName = $"{dir}\\{machineName}";
var machine = new Data.Models.Metadata.Machine
{
[Data.Models.Metadata.Machine.NameKey] = machineName,
[Data.Models.Metadata.Machine.SourceFileKey] = item.SourceFile,
[Data.Models.Metadata.Machine.IsBiosKey] = item.IsBios,
[Data.Models.Metadata.Machine.IsDeviceKey] = item.IsDevice,
[Data.Models.Metadata.Machine.IsMechanicalKey] = item.IsMechanical,
[Data.Models.Metadata.Machine.CloneOfKey] = item.CloneOf,
[Data.Models.Metadata.Machine.RomOfKey] = item.RomOf,
[Data.Models.Metadata.Machine.SampleOfKey] = item.SampleOf,
[Data.Models.Metadata.Machine.BoardKey] = item.Board,
[Data.Models.Metadata.Machine.RebuildToKey] = item.RebuildTo,
[Data.Models.Metadata.Machine.IdKey] = item.Id,
[Data.Models.Metadata.Machine.CloneOfIdKey] = item.CloneOfId,
[Data.Models.Metadata.Machine.RunnableKey] = item.Runnable,
[Data.Models.Metadata.Machine.CommentKey] = item.Comment,
[Data.Models.Metadata.Machine.DescriptionKey] = item.Description,
[Data.Models.Metadata.Machine.YearKey] = item.Year,
[Data.Models.Metadata.Machine.ManufacturerKey] = item.Manufacturer,
[Data.Models.Metadata.Machine.PublisherKey] = item.Publisher,
[Data.Models.Metadata.Machine.CategoryKey] = item.Category,
[Data.Models.Metadata.Machine.TruripKey] = item.Trurip,
};
if (item.Release is not null && item.Release.Length > 0)
machine[Data.Models.Metadata.Machine.ReleaseKey] = Array.ConvertAll(item.Release, ConvertToInternalModel);
if (item.BiosSet is not null && item.BiosSet.Length > 0)
machine[Data.Models.Metadata.Machine.BiosSetKey] = Array.ConvertAll(item.BiosSet, ConvertToInternalModel);
if (item.Rom is not null && item.Rom.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.Rom, ConvertToInternalModel);
if (item.Disk is not null && item.Disk.Length > 0)
machine[Data.Models.Metadata.Machine.DiskKey] = Array.ConvertAll(item.Disk, ConvertToInternalModel);
if (item.Media is not null && item.Media.Length > 0)
machine[Data.Models.Metadata.Machine.MediaKey] = Array.ConvertAll(item.Media, ConvertToInternalModel);
if (item.DeviceRef is not null && item.DeviceRef.Length > 0)
machine[Data.Models.Metadata.Machine.DeviceRefKey] = Array.ConvertAll(item.DeviceRef, ConvertToInternalModel);
if (item.Sample is not null && item.Sample.Length > 0)
machine[Data.Models.Metadata.Machine.SampleKey] = Array.ConvertAll(item.Sample, ConvertToInternalModel);
if (item.Archive is not null && item.Archive.Length > 0)
machine[Data.Models.Metadata.Machine.ArchiveKey] = Array.ConvertAll(item.Archive, ConvertToInternalModel);
if (item.Driver is not null)
machine[Data.Models.Metadata.Machine.DriverKey] = ConvertToInternalModel(item.Driver);
if (item.SoftwareList is not null && item.SoftwareList.Length > 0)
machine[Data.Models.Metadata.Machine.SoftwareListKey] = Array.ConvertAll(item.SoftwareList, ConvertToInternalModel);
return machine;
}
/// <summary>
/// Convert from <see cref="Archive"/> to <see cref="Models.Metadata.Archive"/>
/// </summary>
private static Data.Models.Metadata.Archive ConvertToInternalModel(Archive item)
{
var archive = new Data.Models.Metadata.Archive
{
[Data.Models.Metadata.Archive.NameKey] = item.Name,
};
return archive;
}
/// <summary>
/// Convert from <see cref="BiosSet"/> to <see cref="Models.Metadata.BiosSet"/>
/// </summary>
private static Data.Models.Metadata.BiosSet ConvertToInternalModel(BiosSet item)
{
var biosset = new Data.Models.Metadata.BiosSet
{
[Data.Models.Metadata.BiosSet.NameKey] = item.Name,
[Data.Models.Metadata.BiosSet.DescriptionKey] = item.Description,
[Data.Models.Metadata.BiosSet.DefaultKey] = item.Default,
};
return biosset;
}
/// <summary>
/// Convert from <see cref="DeviceRef"/> to <see cref="Models.Metadata.DeviceRef"/>
/// </summary>
private static Data.Models.Metadata.DeviceRef ConvertToInternalModel(DeviceRef item)
{
var deviceRef = new Data.Models.Metadata.DeviceRef
{
[Data.Models.Metadata.DeviceRef.NameKey] = item.Name,
};
return deviceRef;
}
/// <summary>
/// Convert from <see cref="Disk"/> to <see cref="Models.Metadata.Disk"/>
/// </summary>
private static Data.Models.Metadata.Disk ConvertToInternalModel(Disk item)
{
var disk = new Data.Models.Metadata.Disk
{
[Data.Models.Metadata.Disk.NameKey] = item.Name,
[Data.Models.Metadata.Disk.MD5Key] = item.MD5,
[Data.Models.Metadata.Disk.SHA1Key] = item.SHA1,
[Data.Models.Metadata.Disk.MergeKey] = item.Merge,
[Data.Models.Metadata.Disk.StatusKey] = item.Status,
[Data.Models.Metadata.Disk.RegionKey] = item.Region,
};
return disk;
}
/// <summary>
/// Convert from <see cref="Driver"/> to <see cref="Models.Metadata.Driver"/>
/// </summary>
private static Data.Models.Metadata.Driver ConvertToInternalModel(Driver item)
{
var driver = new Data.Models.Metadata.Driver
{
[Data.Models.Metadata.Driver.StatusKey] = item.Status,
[Data.Models.Metadata.Driver.EmulationKey] = item.Emulation,
[Data.Models.Metadata.Driver.CocktailKey] = item.Cocktail,
[Data.Models.Metadata.Driver.SaveStateKey] = item.SaveState,
[Data.Models.Metadata.Driver.RequiresArtworkKey] = item.RequiresArtwork,
[Data.Models.Metadata.Driver.UnofficialKey] = item.Unofficial,
[Data.Models.Metadata.Driver.NoSoundHardwareKey] = item.NoSoundHardware,
[Data.Models.Metadata.Driver.IncompleteKey] = item.Incomplete,
};
return driver;
}
/// <summary>
/// Convert from <see cref="Media"/> to <see cref="Models.Metadata.Media"/>
/// </summary>
private static Data.Models.Metadata.Media ConvertToInternalModel(Media item)
{
var media = new Data.Models.Metadata.Media
{
[Data.Models.Metadata.Media.NameKey] = item.Name,
[Data.Models.Metadata.Media.MD5Key] = item.MD5,
[Data.Models.Metadata.Media.SHA1Key] = item.SHA1,
[Data.Models.Metadata.Media.SHA256Key] = item.SHA256,
[Data.Models.Metadata.Media.SpamSumKey] = item.SpamSum,
};
return media;
}
/// <summary>
/// Convert from <see cref="Release"/> to <see cref="Models.Metadata.Release"/>
/// </summary>
private static Data.Models.Metadata.Release ConvertToInternalModel(Release item)
{
var release = new Data.Models.Metadata.Release
{
[Data.Models.Metadata.Release.NameKey] = item.Name,
[Data.Models.Metadata.Release.RegionKey] = item.Region,
[Data.Models.Metadata.Release.LanguageKey] = item.Language,
[Data.Models.Metadata.Release.DateKey] = item.Date,
[Data.Models.Metadata.Release.DefaultKey] = item.Default,
};
return release;
}
/// <summary>
/// Convert from <see cref="Rom"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
private static Data.Models.Metadata.Rom ConvertToInternalModel(Rom item)
{
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.NameKey] = item.Name,
[Data.Models.Metadata.Rom.SizeKey] = item.Size,
[Data.Models.Metadata.Rom.CRC16Key] = item.CRC16,
[Data.Models.Metadata.Rom.CRCKey] = item.CRC,
[Data.Models.Metadata.Rom.CRC64Key] = item.CRC64,
[Data.Models.Metadata.Rom.MD2Key] = item.MD2,
[Data.Models.Metadata.Rom.MD4Key] = item.MD4,
[Data.Models.Metadata.Rom.MD5Key] = item.MD5,
[Data.Models.Metadata.Rom.RIPEMD128Key] = item.RIPEMD128,
[Data.Models.Metadata.Rom.RIPEMD160Key] = item.RIPEMD160,
[Data.Models.Metadata.Rom.SHA1Key] = item.SHA1,
[Data.Models.Metadata.Rom.SHA256Key] = item.SHA256,
[Data.Models.Metadata.Rom.SHA384Key] = item.SHA384,
[Data.Models.Metadata.Rom.SHA512Key] = item.SHA512,
[Data.Models.Metadata.Rom.SpamSumKey] = item.SpamSum,
[Data.Models.Metadata.Rom.xxHash364Key] = item.xxHash364,
[Data.Models.Metadata.Rom.xxHash3128Key] = item.xxHash3128,
[Data.Models.Metadata.Rom.MergeKey] = item.Merge,
[Data.Models.Metadata.Rom.StatusKey] = item.Status,
[Data.Models.Metadata.Rom.SerialKey] = item.Serial,
[Data.Models.Metadata.Rom.HeaderKey] = item.Header,
[Data.Models.Metadata.Rom.DateKey] = item.Date,
[Data.Models.Metadata.Rom.InvertedKey] = item.Inverted,
[Data.Models.Metadata.Rom.MIAKey] = item.MIA,
};
return rom;
}
/// <summary>
/// Convert from <see cref="Sample"/> to <see cref="Models.Metadata.Sample"/>
/// </summary>
private static Data.Models.Metadata.Sample ConvertToInternalModel(Sample item)
{
var sample = new Data.Models.Metadata.Sample
{
[Data.Models.Metadata.Sample.NameKey] = item.Name,
};
return sample;
}
/// <summary>
/// Convert from <see cref="Models.Logiqx.SoftwareList"/> to <see cref="Models.Metadata.SoftwareList"/>
/// </summary>
private static Data.Models.Metadata.SoftwareList ConvertToInternalModel(Data.Models.Logiqx.SoftwareList item)
{
var softwareList = new Data.Models.Metadata.SoftwareList
{
[Data.Models.Metadata.SoftwareList.TagKey] = item.Tag,
[Data.Models.Metadata.SoftwareList.NameKey] = item.Name,
[Data.Models.Metadata.SoftwareList.StatusKey] = item.Status,
[Data.Models.Metadata.SoftwareList.FilterKey] = item.Filter,
};
return softwareList;
}
}
}

View File

@@ -0,0 +1,35 @@
using System;
namespace SabreTools.Serialization.CrossModel
{
public partial class M1 : BaseMetadataSerializer<Data.Models.Listxml.M1>
{
/// <inheritdoc/>
public override Data.Models.Listxml.M1? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{
if (obj is null)
return null;
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
var m1 = header is not null ? ConvertM1FromInternalModel(header) : new Data.Models.Listxml.M1();
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
if (machines is not null && machines.Length > 0)
m1.Game = Array.ConvertAll(machines, Listxml.ConvertMachineFromInternalModel);
return m1;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Header"/> to <see cref="Models.Listxml.M1"/>
/// </summary>
private static Data.Models.Listxml.M1 ConvertM1FromInternalModel(Data.Models.Metadata.Header item)
{
var m1 = new Data.Models.Listxml.M1
{
Version = item.ReadString(Data.Models.Metadata.Header.VersionKey),
};
return m1;
}
}
}

View File

@@ -0,0 +1,39 @@
using System;
namespace SabreTools.Serialization.CrossModel
{
public partial class M1 : BaseMetadataSerializer<Data.Models.Listxml.M1>
{
/// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(Data.Models.Listxml.M1? item)
{
if (item is null)
return null;
var metadataFile = new Data.Models.Metadata.MetadataFile
{
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
};
if (item?.Game is not null && item.Game.Length > 0)
{
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(item.Game, Listxml.ConvertMachineToInternalModel);
}
return metadataFile;
}
/// <summary>
/// Convert from <see cref="Models.Listxml.M1"/> to <see cref="Models.Metadata.Header"/>
/// </summary>
private static Data.Models.Metadata.Header ConvertHeaderToInternalModel(Data.Models.Listxml.M1 item)
{
var header = new Data.Models.Metadata.Header
{
[Data.Models.Metadata.Header.VersionKey] = item.Version,
};
return header;
}
}
}

View File

@@ -0,0 +1,35 @@
using System;
namespace SabreTools.Serialization.CrossModel
{
public partial class Mess : BaseMetadataSerializer<Data.Models.Listxml.Mess>
{
/// <inheritdoc/>
public override Data.Models.Listxml.Mess? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{
if (obj is null)
return null;
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
var m1 = header is not null ? ConvertMessFromInternalModel(header) : new Data.Models.Listxml.Mess();
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
if (machines is not null && machines.Length > 0)
m1.Game = Array.ConvertAll(machines, Listxml.ConvertMachineFromInternalModel);
return m1;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Header"/> to <see cref="Models.Listxml.Mess"/>
/// </summary>
private static Data.Models.Listxml.Mess ConvertMessFromInternalModel(Data.Models.Metadata.Header item)
{
var m1 = new Data.Models.Listxml.Mess
{
Version = item.ReadString(Data.Models.Metadata.Header.VersionKey),
};
return m1;
}
}
}

View File

@@ -0,0 +1,39 @@
using System;
namespace SabreTools.Serialization.CrossModel
{
public partial class Mess : BaseMetadataSerializer<Data.Models.Listxml.Mess>
{
/// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(Data.Models.Listxml.Mess? item)
{
if (item is null)
return null;
var metadataFile = new Data.Models.Metadata.MetadataFile
{
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
};
if (item?.Game is not null && item.Game.Length > 0)
{
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(item.Game, Listxml.ConvertMachineToInternalModel);
}
return metadataFile;
}
/// <summary>
/// Convert from <see cref="Models.Listxml.Mess"/> to <see cref="Models.Metadata.Header"/>
/// </summary>
private static Data.Models.Metadata.Header ConvertHeaderToInternalModel(Data.Models.Listxml.Mess item)
{
var header = new Data.Models.Metadata.Header
{
[Data.Models.Metadata.Header.VersionKey] = item.Version,
};
return header;
}
}
}

View File

@@ -0,0 +1,125 @@
using System;
using SabreTools.Data.Models.OfflineList;
namespace SabreTools.Serialization.CrossModel
{
public partial class OfflineList : BaseMetadataSerializer<Dat>
{
/// <inheritdoc/>
public override Dat? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{
if (obj is null)
return null;
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
var dat = header is not null ? ConvertHeaderFromInternalModel(header) : new Dat();
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
if (machines is not null && machines.Length > 0)
{
dat.Games = new Games
{
Game = Array.ConvertAll(machines, ConvertMachineFromInternalModel),
};
}
return dat;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Header"/> to <see cref="Dat"/>
/// </summary>
private static Dat ConvertHeaderFromInternalModel(Data.Models.Metadata.Header item)
{
var dat = new Dat
{
NoNamespaceSchemaLocation = item.ReadString(Data.Models.Metadata.Header.SchemaLocationKey),
};
if (item.ContainsKey(Data.Models.Metadata.Header.NameKey)
|| item.ContainsKey(Data.Models.Metadata.Header.ImFolderKey)
|| item.ContainsKey(Data.Models.Metadata.Header.DatVersionKey)
|| item.ContainsKey(Data.Models.Metadata.Header.SystemKey)
|| item.ContainsKey(Data.Models.Metadata.Header.ScreenshotsWidthKey)
|| item.ContainsKey(Data.Models.Metadata.Header.ScreenshotsHeightKey)
|| item.ContainsKey(Data.Models.Metadata.Header.InfosKey)
|| item.ContainsKey(Data.Models.Metadata.Header.CanOpenKey)
|| item.ContainsKey(Data.Models.Metadata.Header.NewDatKey)
|| item.ContainsKey(Data.Models.Metadata.Header.SearchKey)
|| item.ContainsKey(Data.Models.Metadata.Header.RomTitleKey))
{
dat.Configuration = new Configuration
{
DatName = item.ReadString(Data.Models.Metadata.Header.NameKey),
ImFolder = item.ReadString(Data.Models.Metadata.Header.ImFolderKey),
DatVersion = item.ReadString(Data.Models.Metadata.Header.DatVersionKey),
System = item.ReadString(Data.Models.Metadata.Header.SystemKey),
ScreenshotsWidth = item.ReadString(Data.Models.Metadata.Header.ScreenshotsWidthKey),
ScreenshotsHeight = item.ReadString(Data.Models.Metadata.Header.ScreenshotsHeightKey),
Infos = item.Read<Infos>(Data.Models.Metadata.Header.InfosKey),
CanOpen = item.Read<CanOpen>(Data.Models.Metadata.Header.CanOpenKey),
NewDat = item.Read<NewDat>(Data.Models.Metadata.Header.NewDatKey),
Search = item.Read<Search>(Data.Models.Metadata.Header.SearchKey),
RomTitle = item.ReadString(Data.Models.Metadata.Header.RomTitleKey),
};
}
if (item.ContainsKey(Data.Models.Metadata.Header.ImagesKey))
{
dat.GUI = new GUI
{
Images = item.Read<Images>(Data.Models.Metadata.Header.ImagesKey),
};
}
return dat;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Machine"/> to <see cref="Game"/>
/// </summary>
private static Game ConvertMachineFromInternalModel(Data.Models.Metadata.Machine item)
{
var game = new Game
{
ImageNumber = item.ReadString(Data.Models.Metadata.Machine.ImageNumberKey),
ReleaseNumber = item.ReadString(Data.Models.Metadata.Machine.ReleaseNumberKey),
Title = item.ReadString(Data.Models.Metadata.Machine.NameKey),
SaveType = item.ReadString(Data.Models.Metadata.Machine.SaveTypeKey),
Publisher = item.ReadString(Data.Models.Metadata.Machine.PublisherKey),
Location = item.ReadString(Data.Models.Metadata.Machine.LocationKey),
SourceRom = item.ReadString(Data.Models.Metadata.Machine.SourceRomKey),
Language = item.ReadString(Data.Models.Metadata.Machine.LanguageKey),
Im1CRC = item.ReadString(Data.Models.Metadata.Machine.Im1CRCKey),
Im2CRC = item.ReadString(Data.Models.Metadata.Machine.Im2CRCKey),
Comment = item.ReadString(Data.Models.Metadata.Machine.CommentKey),
DuplicateID = item.ReadString(Data.Models.Metadata.Machine.DuplicateIDKey),
};
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms is not null && roms.Length > 0)
{
var romSizes = Array.ConvertAll(roms, r => r.ReadLong(Data.Models.Metadata.Rom.SizeKey) ?? -1);
game.RomSize = Array.Find(romSizes, s => s > -1).ToString();
var romCRCs = Array.ConvertAll(roms, ConvertFromInternalModel);
game.Files = new Files { RomCRC = romCRCs };
}
return game;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="FileRomCRC"/>
/// </summary>
private static FileRomCRC ConvertFromInternalModel(Data.Models.Metadata.Rom item)
{
var fileRomCRC = new FileRomCRC
{
Extension = item.ReadString(Data.Models.Metadata.Rom.ExtensionKey),
Content = item.ReadString(Data.Models.Metadata.Rom.CRCKey),
};
return fileRomCRC;
}
}
}

View File

@@ -0,0 +1,109 @@
using System;
using SabreTools.Data.Models.OfflineList;
namespace SabreTools.Serialization.CrossModel
{
public partial class OfflineList : BaseMetadataSerializer<Dat>
{
/// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(Dat? item)
{
if (item is null)
return null;
var metadataFile = new Data.Models.Metadata.MetadataFile
{
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
};
if (item?.Games?.Game is not null && item.Games.Game.Length > 0)
{
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(item.Games.Game, ConvertMachineToInternalModel);
}
return metadataFile;
}
/// <summary>
/// Convert from <see cref="Dat"/> to <see cref="Models.Metadata.Header"/>
/// </summary>
private static Data.Models.Metadata.Header ConvertHeaderToInternalModel(Dat item)
{
var header = new Data.Models.Metadata.Header
{
[Data.Models.Metadata.Header.SchemaLocationKey] = item.NoNamespaceSchemaLocation,
};
if (item.Configuration is not null)
{
header[Data.Models.Metadata.Header.NameKey] = item.Configuration.DatName;
header[Data.Models.Metadata.Header.ImFolderKey] = item.Configuration.ImFolder;
header[Data.Models.Metadata.Header.DatVersionKey] = item.Configuration.DatVersion;
header[Data.Models.Metadata.Header.SystemKey] = item.Configuration.System;
header[Data.Models.Metadata.Header.ScreenshotsWidthKey] = item.Configuration.ScreenshotsWidth;
header[Data.Models.Metadata.Header.ScreenshotsHeightKey] = item.Configuration.ScreenshotsHeight;
header[Data.Models.Metadata.Header.InfosKey] = item.Configuration.Infos;
header[Data.Models.Metadata.Header.CanOpenKey] = item.Configuration.CanOpen;
header[Data.Models.Metadata.Header.NewDatKey] = item.Configuration.NewDat;
header[Data.Models.Metadata.Header.SearchKey] = item.Configuration.Search;
header[Data.Models.Metadata.Header.RomTitleKey] = item.Configuration.RomTitle;
}
if (item.GUI is not null)
{
header[Data.Models.Metadata.Header.ImagesKey] = item.GUI.Images;
}
return header;
}
/// <summary>
/// Convert from <see cref="Game"/> to <see cref="Models.Metadata.Machine"/>
/// </summary>
private static Data.Models.Metadata.Machine ConvertMachineToInternalModel(Game item)
{
var machine = new Data.Models.Metadata.Machine
{
[Data.Models.Metadata.Machine.ImageNumberKey] = item.ImageNumber,
[Data.Models.Metadata.Machine.ReleaseNumberKey] = item.ReleaseNumber,
[Data.Models.Metadata.Machine.NameKey] = item.Title,
[Data.Models.Metadata.Machine.SaveTypeKey] = item.SaveType,
[Data.Models.Metadata.Machine.PublisherKey] = item.Publisher,
[Data.Models.Metadata.Machine.LocationKey] = item.Location,
[Data.Models.Metadata.Machine.SourceRomKey] = item.SourceRom,
[Data.Models.Metadata.Machine.LanguageKey] = item.Language,
[Data.Models.Metadata.Machine.Im1CRCKey] = item.Im1CRC,
[Data.Models.Metadata.Machine.Im2CRCKey] = item.Im2CRC,
[Data.Models.Metadata.Machine.CommentKey] = item.Comment,
[Data.Models.Metadata.Machine.DuplicateIDKey] = item.DuplicateID,
};
if (item.Files?.RomCRC is not null && item.Files.RomCRC.Length > 0)
{
machine[Data.Models.Metadata.Machine.RomKey]
= Array.ConvertAll(item.Files.RomCRC, romCRC =>
{
var rom = ConvertToInternalModel(romCRC);
rom[Data.Models.Metadata.Rom.SizeKey] = item.RomSize;
return rom;
});
}
return machine;
}
/// <summary>
/// Convert from <see cref="FileRomCRC"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
private static Data.Models.Metadata.Rom ConvertToInternalModel(FileRomCRC item)
{
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.ExtensionKey] = item.Extension,
[Data.Models.Metadata.Rom.CRCKey] = item.Content,
};
return rom;
}
}
}

View File

@@ -0,0 +1,50 @@
#if NET20 || NET35
using System;
using System.IO;
namespace SabreTools.Serialization.CrossModel
{
/// <summary>
/// Derived from the mscorlib code from .NET Framework 4.0
/// </summary>
internal static class OldDotNet
{
public static void CopyTo(this Stream source, Stream destination)
{
if (destination is null)
{
throw new ArgumentNullException("destination");
}
if (!source.CanRead && !source.CanWrite)
{
throw new ObjectDisposedException(null);
}
if (!destination.CanRead && !destination.CanWrite)
{
throw new ObjectDisposedException("destination");
}
if (!source.CanRead)
{
throw new NotSupportedException();
}
if (!destination.CanWrite)
{
throw new NotSupportedException();
}
byte[] array = new byte[81920];
int count;
while ((count = source.Read(array, 0, array.Length)) != 0)
{
destination.Write(array, 0, count);
}
}
}
}
#endif

View File

@@ -0,0 +1,142 @@
using System;
using SabreTools.Data.Models.OpenMSX;
namespace SabreTools.Serialization.CrossModel
{
public partial class OpenMSX : BaseMetadataSerializer<SoftwareDb>
{
/// <inheritdoc/>
public override SoftwareDb? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{
if (obj is null)
return null;
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
var softwareDb = header is not null ? ConvertHeaderFromInternalModel(header) : new SoftwareDb();
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
if (machines is not null && machines.Length > 0)
softwareDb.Software = Array.ConvertAll(machines, ConvertMachineFromInternalModel);
return softwareDb;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Header"/> to <see cref="SoftwareDb"/>
/// </summary>
private static SoftwareDb ConvertHeaderFromInternalModel(Data.Models.Metadata.Header item)
{
var softwareDb = new SoftwareDb
{
Timestamp = item.ReadString(Data.Models.Metadata.Header.TimestampKey),
};
return softwareDb;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Machine"/> to <see cref="Software"/>
/// </summary>
private static Software ConvertMachineFromInternalModel(Data.Models.Metadata.Machine item)
{
var game = new Software
{
Title = item.ReadString(Data.Models.Metadata.Machine.NameKey),
GenMSXID = item.ReadString(Data.Models.Metadata.Machine.GenMSXIDKey),
System = item.ReadString(Data.Models.Metadata.Machine.SystemKey),
Company = item.ReadString(Data.Models.Metadata.Machine.CompanyKey),
Year = item.ReadString(Data.Models.Metadata.Machine.YearKey),
Country = item.ReadString(Data.Models.Metadata.Machine.CountryKey),
};
var dumps = item.Read<Data.Models.Metadata.Dump[]>(Data.Models.Metadata.Machine.DumpKey);
if (dumps is not null && dumps.Length > 0)
game.Dump = Array.ConvertAll(dumps, ConvertFromInternalModel);
return game;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Dump"/> to <see cref="Dump"/>
/// </summary>
private static Dump ConvertFromInternalModel(Data.Models.Metadata.Dump item)
{
var dump = new Dump();
var original = item.Read<Data.Models.Metadata.Original>(Data.Models.Metadata.Dump.OriginalKey);
if (original is not null)
dump.Original = ConvertFromInternalModel(original);
var rom = item.Read<Data.Models.Metadata.Rom>(Data.Models.Metadata.Dump.RomKey);
if (rom is not null)
dump.Rom = ConvertRomFromInternalModel(rom);
var megaRom = item.Read<Data.Models.Metadata.Rom>(Data.Models.Metadata.Dump.MegaRomKey);
if (megaRom is not null)
dump.Rom = ConvertMegaRomFromInternalModel(megaRom);
var sccPlusCart = item.Read<Data.Models.Metadata.Rom>(Data.Models.Metadata.Dump.SCCPlusCartKey);
if (sccPlusCart is not null)
dump.Rom = ConvertSCCPlusCartFromInternalModel(sccPlusCart);
return dump;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="MegaRom"/>
/// </summary>
private static MegaRom ConvertMegaRomFromInternalModel(Data.Models.Metadata.Rom item)
{
var megaRom = new MegaRom
{
Start = item.ReadString(Data.Models.Metadata.Rom.StartKey),
Type = item.ReadString(Data.Models.Metadata.Rom.OpenMSXType),
Hash = item.ReadString(Data.Models.Metadata.Rom.SHA1Key),
Remark = item.ReadString(Data.Models.Metadata.Rom.RemarkKey),
};
return megaRom;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Original"/> to <see cref="Original"/>
/// </summary>
private static Original ConvertFromInternalModel(Data.Models.Metadata.Original item)
{
var original = new Original
{
Value = item.ReadString(Data.Models.Metadata.Original.ValueKey),
Content = item.ReadString(Data.Models.Metadata.Original.ContentKey),
};
return original;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="Rom"/>
/// </summary>
private static Rom ConvertRomFromInternalModel(Data.Models.Metadata.Rom item)
{
var rom = new Rom
{
Start = item.ReadString(Data.Models.Metadata.Rom.StartKey),
Type = item.ReadString(Data.Models.Metadata.Rom.OpenMSXType),
Hash = item.ReadString(Data.Models.Metadata.Rom.SHA1Key),
Remark = item.ReadString(Data.Models.Metadata.Rom.RemarkKey),
};
return rom;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="SCCPlusCart"/>
/// </summary>
private static SCCPlusCart ConvertSCCPlusCartFromInternalModel(Data.Models.Metadata.Rom item)
{
var sccPlusCart = new SCCPlusCart
{
Start = item.ReadString(Data.Models.Metadata.Rom.StartKey),
Type = item.ReadString(Data.Models.Metadata.Rom.OpenMSXType),
Hash = item.ReadString(Data.Models.Metadata.Rom.SHA1Key),
Remark = item.ReadString(Data.Models.Metadata.Rom.RemarkKey),
};
return sccPlusCart;
}
}
}

View File

@@ -0,0 +1,127 @@
using System;
using SabreTools.Data.Models.OpenMSX;
namespace SabreTools.Serialization.CrossModel
{
public partial class OpenMSX : BaseMetadataSerializer<SoftwareDb>
{
/// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(SoftwareDb? item)
{
if (item is null)
return null;
var metadataFile = new Data.Models.Metadata.MetadataFile
{
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
};
if (item?.Software is not null && item.Software.Length > 0)
{
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(item.Software, ConvertMachineToInternalModel);
}
return metadataFile;
}
/// <summary>
/// Convert from <see cref="SoftwareDb"/> to <see cref="Models.Metadata.Header"/>
/// </summary>
public static Data.Models.Metadata.Header ConvertHeaderToInternalModel(SoftwareDb item)
{
var header = new Data.Models.Metadata.Header
{
[Data.Models.Metadata.Header.TimestampKey] = item.Timestamp,
};
return header;
}
/// <summary>
/// Convert from <see cref="Software"/> to <see cref="Models.Metadata.Machine"/>
/// </summary>
public static Data.Models.Metadata.Machine ConvertMachineToInternalModel(Software item)
{
var machine = new Data.Models.Metadata.Machine
{
[Data.Models.Metadata.Machine.NameKey] = item.Title,
[Data.Models.Metadata.Machine.GenMSXIDKey] = item.GenMSXID,
[Data.Models.Metadata.Machine.SystemKey] = item.System,
[Data.Models.Metadata.Machine.CompanyKey] = item.Company,
[Data.Models.Metadata.Machine.YearKey] = item.Year,
[Data.Models.Metadata.Machine.CountryKey] = item.Country,
};
if (item.Dump is not null && item.Dump.Length > 0)
{
machine[Data.Models.Metadata.Machine.DumpKey]
= Array.ConvertAll(item.Dump, ConvertToInternalModel);
}
return machine;
}
/// <summary>
/// Convert from <see cref="Dump"/> to <see cref="Models.Metadata.Dump"/>
/// </summary>
public static Data.Models.Metadata.Dump ConvertToInternalModel(Dump item)
{
var dump = new Data.Models.Metadata.Dump();
if (item.Original is not null)
dump[Data.Models.Metadata.Dump.OriginalKey] = ConvertToInternalModel(item.Original);
if (item.Rom is not null)
{
switch (item.Rom)
{
case Rom rom:
dump[Data.Models.Metadata.Dump.RomKey] = ConvertToInternalModel(rom);
break;
case MegaRom megaRom:
dump[Data.Models.Metadata.Dump.MegaRomKey] = ConvertToInternalModel(megaRom);
break;
case SCCPlusCart sccPlusCart:
dump[Data.Models.Metadata.Dump.SCCPlusCartKey] = ConvertToInternalModel(sccPlusCart);
break;
default:
// TODO: Log invalid values
break;
}
}
return dump;
}
/// <summary>
/// Convert from <see cref="Original"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
public static Data.Models.Metadata.Original ConvertToInternalModel(Original item)
{
var original = new Data.Models.Metadata.Original
{
[Data.Models.Metadata.Original.ValueKey] = item.Value,
[Data.Models.Metadata.Original.ContentKey] = item.Content,
};
return original;
}
/// <summary>
/// Convert from <see cref="RomBase"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
public static Data.Models.Metadata.Rom ConvertToInternalModel(RomBase item)
{
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.StartKey] = item.Start,
[Data.Models.Metadata.Rom.OpenMSXType] = item.Type,
[Data.Models.Metadata.Rom.SHA1Key] = item.Hash,
[Data.Models.Metadata.Rom.RemarkKey] = item.Remark,
};
return rom;
}
}
}

View File

@@ -0,0 +1,5 @@
# SabreTools.Serialization.CrossModel
This library contains methods for converting between different model formats. The majority of the implementations convert from specific Datfile/metadata file formats to the unified Metadata internal format.
All cross-model converters implement `SabreTools.Serialization.CrossModel.ICrossModel<TSource, TDest>` which enforces bi-directional conversion.

View File

@@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using SabreTools.Data.Models.RomCenter;
namespace SabreTools.Serialization.CrossModel
{
public partial class RomCenter : BaseMetadataSerializer<MetadataFile>
{
/// <inheritdoc/>
public override MetadataFile? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{
if (obj is null)
return null;
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
var metadataFile = header is not null ? ConvertHeaderFromInternalModel(header) : new MetadataFile();
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
var items = new List<Rom>();
foreach (var machine in machines ?? [])
{
items.AddRange(ConvertMachineFromInternalModel(machine));
}
metadataFile.Games = new Games { Rom = [.. items] };
return metadataFile;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Header"/> to <see cref="MetadataFile"/>
/// </summary>
private static MetadataFile ConvertHeaderFromInternalModel(Data.Models.Metadata.Header item)
{
var metadataFile = new MetadataFile();
if (item.ContainsKey(Data.Models.Metadata.Header.AuthorKey)
|| item.ContainsKey(Data.Models.Metadata.Header.VersionKey)
|| item.ContainsKey(Data.Models.Metadata.Header.EmailKey)
|| item.ContainsKey(Data.Models.Metadata.Header.HomepageKey)
|| item.ContainsKey(Data.Models.Metadata.Header.UrlKey)
|| item.ContainsKey(Data.Models.Metadata.Header.DateKey)
|| item.ContainsKey(Data.Models.Metadata.Header.CommentKey))
{
metadataFile.Credits = new Credits
{
Author = item.ReadString(Data.Models.Metadata.Header.AuthorKey),
Version = item.ReadString(Data.Models.Metadata.Header.VersionKey),
Email = item.ReadString(Data.Models.Metadata.Header.EmailKey),
Homepage = item.ReadString(Data.Models.Metadata.Header.HomepageKey),
Url = item.ReadString(Data.Models.Metadata.Header.UrlKey),
Date = item.ReadString(Data.Models.Metadata.Header.DateKey),
Comment = item.ReadString(Data.Models.Metadata.Header.CommentKey),
};
}
if (item.ContainsKey(Data.Models.Metadata.Header.DatVersionKey)
|| item.ContainsKey(Data.Models.Metadata.Header.PluginKey)
|| item.ContainsKey(Data.Models.Metadata.Header.ForceMergingKey))
{
metadataFile.Dat = new Dat
{
Version = item.ReadString(Data.Models.Metadata.Header.DatVersionKey),
Plugin = item.ReadString(Data.Models.Metadata.Header.PluginKey),
Split = item.ReadString(Data.Models.Metadata.Header.ForceMergingKey) == "split" ? "yes" : "no",
Merge = item.ReadString(Data.Models.Metadata.Header.ForceMergingKey) == "merge" ? "yes" : "no",
};
}
if (item.ContainsKey(Data.Models.Metadata.Header.RefNameKey)
|| item.ContainsKey(Data.Models.Metadata.Header.EmulatorVersionKey))
{
metadataFile.Emulator = new Emulator
{
RefName = item.ReadString(Data.Models.Metadata.Header.RefNameKey),
Version = item.ReadString(Data.Models.Metadata.Header.EmulatorVersionKey),
};
}
return metadataFile;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Machine"/> to an array of <see cref="Rom"/>
/// </summary>
private static Rom[] ConvertMachineFromInternalModel(Data.Models.Metadata.Machine item)
{
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms is null)
return [];
return Array.ConvertAll(roms, r => ConvertFromInternalModel(r, item));
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="Rom"/>
/// </summary>
private static Rom ConvertFromInternalModel(Data.Models.Metadata.Rom item, Data.Models.Metadata.Machine parent)
{
var row = new Rom
{
ParentName = parent.ReadString(Data.Models.Metadata.Machine.CloneOfKey),
//ParentDescription = parent.ReadString(Data.Models.Metadata.Machine.ParentDescriptionKey), // This is unmappable
GameName = parent.ReadString(Data.Models.Metadata.Machine.NameKey),
GameDescription = parent.ReadString(Data.Models.Metadata.Machine.DescriptionKey),
RomName = item.ReadString(Data.Models.Metadata.Rom.NameKey),
RomCRC = item.ReadString(Data.Models.Metadata.Rom.CRCKey),
RomSize = item.ReadString(Data.Models.Metadata.Rom.SizeKey),
RomOf = parent.ReadString(Data.Models.Metadata.Machine.RomOfKey),
MergeName = item.ReadString(Data.Models.Metadata.Rom.MergeKey),
};
return row;
}
}
}

View File

@@ -0,0 +1,99 @@
using System;
using SabreTools.Data.Models.RomCenter;
namespace SabreTools.Serialization.CrossModel
{
public partial class RomCenter : BaseMetadataSerializer<MetadataFile>
{
/// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
{
if (obj is null)
return null;
var metadataFile = new Data.Models.Metadata.MetadataFile
{
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(obj),
};
if (obj?.Games?.Rom is not null && obj.Games.Rom.Length > 0)
{
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(obj.Games.Rom, ConvertMachineToInternalModel);
}
return metadataFile;
}
/// <summary>
/// Convert from <see cref="MetadataFile"/> to <see cref="Models.Metadata.Header"/>
/// </summary>
private static Data.Models.Metadata.Header ConvertHeaderToInternalModel(MetadataFile item)
{
var header = new Data.Models.Metadata.Header();
if (item.Credits is not null)
{
header[Data.Models.Metadata.Header.AuthorKey] = item.Credits.Author;
header[Data.Models.Metadata.Header.VersionKey] = item.Credits.Version;
header[Data.Models.Metadata.Header.EmailKey] = item.Credits.Email;
header[Data.Models.Metadata.Header.HomepageKey] = item.Credits.Homepage;
header[Data.Models.Metadata.Header.UrlKey] = item.Credits.Url;
header[Data.Models.Metadata.Header.DateKey] = item.Credits.Date;
header[Data.Models.Metadata.Header.CommentKey] = item.Credits.Comment;
}
if (item.Dat is not null)
{
header[Data.Models.Metadata.Header.DatVersionKey] = item.Dat.Version;
header[Data.Models.Metadata.Header.PluginKey] = item.Dat.Plugin;
if (item.Dat.Split == "yes" || item.Dat.Split == "1")
header[Data.Models.Metadata.Header.ForceMergingKey] = "split";
else if (item.Dat.Merge == "yes" || item.Dat.Merge == "1")
header[Data.Models.Metadata.Header.ForceMergingKey] = "merge";
}
if (item.Emulator is not null)
{
header[Data.Models.Metadata.Header.RefNameKey] = item.Emulator.RefName;
header[Data.Models.Metadata.Header.EmulatorVersionKey] = item.Emulator.Version;
}
return header;
}
/// <summary>
/// Convert from <see cref="Game"/> to <see cref="Models.Metadata.Machine"/>
/// </summary>
private static Data.Models.Metadata.Machine ConvertMachineToInternalModel(Rom item)
{
var machine = new Data.Models.Metadata.Machine
{
[Data.Models.Metadata.Machine.RomOfKey] = item.RomOf,
[Data.Models.Metadata.Machine.CloneOfKey] = item.ParentName,
//[Data.Models.Metadata.Machine.ParentDescriptionKey] = item.ParentDescription, // This is unmappable
[Data.Models.Metadata.Machine.NameKey] = item.GameName,
[Data.Models.Metadata.Machine.DescriptionKey] = item.GameDescription,
[Data.Models.Metadata.Machine.RomKey] = new Data.Models.Metadata.Rom[] { ConvertToInternalModel(item) },
};
return machine;
}
/// <summary>
/// Convert from <see cref="Rom"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
private static Data.Models.Metadata.Rom ConvertToInternalModel(Rom item)
{
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.NameKey] = item.RomName,
[Data.Models.Metadata.Rom.CRCKey] = item.RomCRC,
[Data.Models.Metadata.Rom.SizeKey] = item.RomSize,
[Data.Models.Metadata.Rom.MergeKey] = item.MergeName,
};
return rom;
}
}
}

View File

@@ -0,0 +1,42 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- Assembly Properties -->
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0;net10.0;netstandard2.0;netstandard2.1</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
<IncludeSymbols>true</IncludeSymbols>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>2.3.0</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
<Description>Convert between models</Description>
<Copyright>Copyright (c) Matt Nadareski 2019-2026</Copyright>
<PackageProjectUrl>https://github.com/SabreTools/</PackageProjectUrl>
<PackageReadmeFile>README.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/SabreTools/SabreTools.Serialization</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>models conversion metadata</PackageTags>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>
<ItemGroup>
<None Include="README.md" Pack="true" PackagePath="" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.Hashing" Version="[1.6.1]" />
<PackageReference Include="SabreTools.IO" Version="[1.9.1]" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SabreTools.Data.Models\SabreTools.Data.Models.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,155 @@
using System;
using System.Collections.Generic;
using SabreTools.Data.Models.SeparatedValue;
namespace SabreTools.Serialization.CrossModel
{
public partial class SeparatedValue : BaseMetadataSerializer<MetadataFile>
{
/// <inheritdoc/>
public override MetadataFile? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{
if (obj is null)
return null;
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
var metadataFile = header is not null ? ConvertHeaderFromInternalModel(header) : new MetadataFile();
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
var items = new List<Row>();
foreach (var machine in machines ?? [])
{
items.AddRange(ConvertMachineFromInternalModel(machine, header));
}
metadataFile.Row = [.. items];
return metadataFile;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Header"/> to <see cref="MetadataFile"/>
/// </summary>
private static MetadataFile ConvertHeaderFromInternalModel(Data.Models.Metadata.Header item)
{
var metadataFile = new MetadataFile
{
Header = item.ReadStringArray(Data.Models.Metadata.Header.HeaderKey),
};
return metadataFile;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Machine"/> to an array of <see cref="Row"/>
/// </summary>
private static Row[] ConvertMachineFromInternalModel(Data.Models.Metadata.Machine item, Data.Models.Metadata.Header? header)
{
var rowItems = new List<Row>();
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms is not null && roms.Length > 0)
{
rowItems.AddRange(
Array.ConvertAll(roms, r => ConvertFromInternalModel(r, item, header)));
}
var disks = item.Read<Data.Models.Metadata.Disk[]>(Data.Models.Metadata.Machine.DiskKey);
if (disks is not null && disks.Length > 0)
{
rowItems.AddRange(
Array.ConvertAll(disks, d => ConvertFromInternalModel(d, item, header)));
}
var media = item.Read<Data.Models.Metadata.Media[]>(Data.Models.Metadata.Machine.MediaKey);
if (media is not null && media.Length > 0)
{
rowItems.AddRange(
Array.ConvertAll(media, m => ConvertFromInternalModel(m, item, header)));
}
return [.. rowItems];
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Disk"/> to <see cref="Row"/>
/// </summary>
private static Row ConvertFromInternalModel(Data.Models.Metadata.Disk item, Data.Models.Metadata.Machine parent, Data.Models.Metadata.Header? header)
{
var row = new Row
{
FileName = header?.ReadString("FILENAME"), // TODO: Make this an actual key to retrieve
InternalName = header?.ReadString(Data.Models.Metadata.Header.NameKey),
Description = header?.ReadString(Data.Models.Metadata.Header.DescriptionKey),
GameName = parent.ReadString(Data.Models.Metadata.Machine.NameKey),
GameDescription = parent.ReadString(Data.Models.Metadata.Machine.DescriptionKey),
Type = "disk",
RomName = null,
DiskName = item.ReadString(Data.Models.Metadata.Disk.NameKey),
Size = null,
CRC = null,
MD5 = item.ReadString(Data.Models.Metadata.Disk.MD5Key),
SHA1 = item.ReadString(Data.Models.Metadata.Disk.SHA1Key),
SHA256 = null,
SHA384 = null,
SHA512 = null,
SpamSum = null,
Status = item.ReadString(Data.Models.Metadata.Disk.StatusKey),
};
return row;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Media"/> to <see cref="Row"/>
/// </summary>
private static Row ConvertFromInternalModel(Data.Models.Metadata.Media item, Data.Models.Metadata.Machine parent, Data.Models.Metadata.Header? header)
{
var row = new Row
{
FileName = header?.ReadString("FILENAME"), // TODO: Make this an actual key to retrieve on an item -- OriginalFilename
InternalName = header?.ReadString(Data.Models.Metadata.Header.NameKey),
Description = header?.ReadString(Data.Models.Metadata.Header.DescriptionKey),
GameName = parent.ReadString(Data.Models.Metadata.Machine.NameKey),
GameDescription = parent.ReadString(Data.Models.Metadata.Machine.DescriptionKey),
Type = "media",
RomName = null,
DiskName = item.ReadString(Data.Models.Metadata.Media.NameKey),
Size = null,
CRC = null,
MD5 = item.ReadString(Data.Models.Metadata.Media.MD5Key),
SHA1 = item.ReadString(Data.Models.Metadata.Media.SHA1Key),
SHA256 = item.ReadString(Data.Models.Metadata.Media.SHA256Key),
SHA384 = null,
SHA512 = null,
SpamSum = item.ReadString(Data.Models.Metadata.Media.SpamSumKey),
};
return row;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="Row"/>
/// </summary>
private static Row ConvertFromInternalModel(Data.Models.Metadata.Rom item, Data.Models.Metadata.Machine parent, Data.Models.Metadata.Header? header)
{
var row = new Row
{
FileName = header?.ReadString("FILENAME"), // TODO: Make this an actual key to retrieve
InternalName = header?.ReadString(Data.Models.Metadata.Header.NameKey),
Description = header?.ReadString(Data.Models.Metadata.Header.DescriptionKey),
GameName = parent.ReadString(Data.Models.Metadata.Machine.NameKey),
GameDescription = parent.ReadString(Data.Models.Metadata.Machine.DescriptionKey),
Type = "rom",
RomName = item.ReadString(Data.Models.Metadata.Rom.NameKey),
DiskName = null,
Size = item.ReadString(Data.Models.Metadata.Rom.SizeKey),
CRC = item.ReadString(Data.Models.Metadata.Rom.CRCKey),
MD5 = item.ReadString(Data.Models.Metadata.Rom.MD5Key),
SHA1 = item.ReadString(Data.Models.Metadata.Rom.SHA1Key),
SHA256 = item.ReadString(Data.Models.Metadata.Rom.SHA256Key),
SHA384 = item.ReadString(Data.Models.Metadata.Rom.SHA384Key),
SHA512 = item.ReadString(Data.Models.Metadata.Rom.SHA512Key),
SpamSum = item.ReadString(Data.Models.Metadata.Rom.SpamSumKey),
Status = item.ReadString(Data.Models.Metadata.Rom.StatusKey),
};
return row;
}
}
}

View File

@@ -0,0 +1,122 @@
using System;
using SabreTools.Data.Models.SeparatedValue;
namespace SabreTools.Serialization.CrossModel
{
public partial class SeparatedValue : BaseMetadataSerializer<MetadataFile>
{
/// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
{
if (obj is null)
return null;
var metadataFile = new Data.Models.Metadata.MetadataFile
{
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(obj),
};
if (obj?.Row is not null && obj.Row.Length > 0)
{
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(obj.Row, ConvertMachineToInternalModel);
}
return metadataFile;
}
/// <summary>
/// Convert from <see cref="MetadataFile"/> to <see cref="Models.Metadata.Header"/>
/// </summary>
private static Data.Models.Metadata.Header ConvertHeaderToInternalModel(MetadataFile item)
{
var header = new Data.Models.Metadata.Header
{
[Data.Models.Metadata.Header.HeaderKey] = item.Header,
};
if (item.Row is not null && item.Row.Length > 0)
{
var first = item.Row[0];
header["FILENAME"] = first.FileName; // TODO: Make this an actual key to retrieve on an item -- OriginalFilename
header[Data.Models.Metadata.Header.NameKey] = first.FileName;
header[Data.Models.Metadata.Header.DescriptionKey] = first.Description;
}
return header;
}
/// <summary>
/// Convert from <see cref="Row"/> to <see cref="Models.Metadata.Machine"/>
/// </summary>
private static Data.Models.Metadata.Machine ConvertMachineToInternalModel(Row item)
{
var machine = new Data.Models.Metadata.Machine
{
[Data.Models.Metadata.Machine.NameKey] = item.GameName,
[Data.Models.Metadata.Machine.DescriptionKey] = item.GameDescription,
};
var datItem = ConvertToInternalModel(item);
switch (datItem)
{
case Data.Models.Metadata.Disk disk:
machine[Data.Models.Metadata.Machine.DiskKey] = new Data.Models.Metadata.Disk[] { disk };
break;
case Data.Models.Metadata.Media media:
machine[Data.Models.Metadata.Machine.MediaKey] = new Data.Models.Metadata.Media[] { media };
break;
case Data.Models.Metadata.Rom rom:
machine[Data.Models.Metadata.Machine.RomKey] = new Data.Models.Metadata.Rom[] { rom };
break;
default:
// TODO: Log invalid values
break;
}
return machine;
}
/// <summary>
/// Convert from <see cref="Row"/> to <see cref="Models.Metadata.DatItem"/>
/// </summary>
private static Data.Models.Metadata.DatItem? ConvertToInternalModel(Row item)
{
return item.Type switch
{
"disk" => new Data.Models.Metadata.Disk
{
[Data.Models.Metadata.Disk.NameKey] = item.DiskName,
[Data.Models.Metadata.Disk.MD5Key] = item.MD5,
[Data.Models.Metadata.Disk.SHA1Key] = item.SHA1,
[Data.Models.Metadata.Disk.StatusKey] = item.Status,
},
"media" => new Data.Models.Metadata.Media
{
[Data.Models.Metadata.Media.NameKey] = item.DiskName,
[Data.Models.Metadata.Media.MD5Key] = item.MD5,
[Data.Models.Metadata.Media.SHA1Key] = item.SHA1,
[Data.Models.Metadata.Media.SHA256Key] = item.SHA256,
[Data.Models.Metadata.Media.SpamSumKey] = item.SpamSum,
},
"rom" => new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.NameKey] = item.RomName,
[Data.Models.Metadata.Rom.SizeKey] = item.Size,
[Data.Models.Metadata.Rom.CRCKey] = item.CRC,
[Data.Models.Metadata.Rom.MD5Key] = item.MD5,
[Data.Models.Metadata.Rom.SHA1Key] = item.SHA1,
[Data.Models.Metadata.Rom.SHA256Key] = item.SHA256,
[Data.Models.Metadata.Rom.SHA384Key] = item.SHA384,
[Data.Models.Metadata.Rom.SHA512Key] = item.SHA512,
[Data.Models.Metadata.Rom.SpamSumKey] = item.SpamSum,
[Data.Models.Metadata.Rom.StatusKey] = item.Status,
},
_ => null,
};
}
}
}

View File

@@ -0,0 +1,244 @@
using System;
using SabreTools.Data.Models.SoftwareList;
namespace SabreTools.Serialization.CrossModel
{
public partial class SoftwareList : BaseMetadataSerializer<Data.Models.SoftwareList.SoftwareList>
{
/// <inheritdoc/>
public override Data.Models.SoftwareList.SoftwareList? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{
if (obj is null)
return null;
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
var metadataFile = header is not null ? ConvertHeaderFromInternalModel(header) : new Data.Models.SoftwareList.SoftwareList();
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
if (machines is not null && machines.Length > 0)
metadataFile.Software = Array.ConvertAll(machines, ConvertMachineFromInternalModel);
return metadataFile;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Header"/> to <see cref="Models.SoftwareList.SoftwareList"/>
/// </summary>
private static Data.Models.SoftwareList.SoftwareList ConvertHeaderFromInternalModel(Data.Models.Metadata.Header item)
{
var softwareList = new Data.Models.SoftwareList.SoftwareList
{
Name = item.ReadString(Data.Models.Metadata.Header.NameKey),
Description = item.ReadString(Data.Models.Metadata.Header.DescriptionKey),
Notes = item.ReadString(Data.Models.Metadata.Header.NotesKey),
};
return softwareList;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Machine"/> to <see cref="SSoftware"/>
/// </summary>
private static Software ConvertMachineFromInternalModel(Data.Models.Metadata.Machine item)
{
var software = new Software
{
Name = item.ReadString(Data.Models.Metadata.Machine.NameKey),
CloneOf = item.ReadString(Data.Models.Metadata.Machine.CloneOfKey),
Supported = item.ReadString(Data.Models.Metadata.Machine.SupportedKey),
Description = item.ReadString(Data.Models.Metadata.Machine.DescriptionKey),
Year = item.ReadString(Data.Models.Metadata.Machine.YearKey),
Publisher = item.ReadString(Data.Models.Metadata.Machine.PublisherKey),
Notes = item.ReadString(Data.Models.Metadata.Machine.NotesKey),
};
var infos = item.Read<Data.Models.Metadata.Info[]>(Data.Models.Metadata.Machine.InfoKey);
if (infos is not null && infos.Length > 0)
software.Info = Array.ConvertAll(infos, ConvertFromInternalModel);
var sharedFeats = item.Read<Data.Models.Metadata.SharedFeat[]>(Data.Models.Metadata.Machine.SharedFeatKey);
if (sharedFeats is not null && sharedFeats.Length > 0)
software.SharedFeat = Array.ConvertAll(sharedFeats, ConvertFromInternalModel);
var parts = item.Read<Data.Models.Metadata.Part[]>(Data.Models.Metadata.Machine.PartKey);
if (parts is not null && parts.Length > 0)
software.Part = Array.ConvertAll(parts, ConvertFromInternalModel);
return software;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.DataArea"/> to <see cref="SDataArea"/>
/// </summary>
private static DataArea ConvertFromInternalModel(Data.Models.Metadata.DataArea item)
{
var dataArea = new DataArea
{
Name = item.ReadString(Data.Models.Metadata.DataArea.NameKey),
Size = item.ReadString(Data.Models.Metadata.DataArea.SizeKey),
Width = item.ReadString(Data.Models.Metadata.DataArea.WidthKey),
Endianness = item.ReadString(Data.Models.Metadata.DataArea.EndiannessKey),
};
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.DataArea.RomKey);
if (roms is not null && roms.Length > 0)
dataArea.Rom = Array.ConvertAll(roms, ConvertFromInternalModel);
return dataArea;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.DipSwitch"/> to <see cref="SDipSwitch"/>
/// </summary>
private static DipSwitch ConvertFromInternalModel(Data.Models.Metadata.DipSwitch item)
{
var dipSwitch = new DipSwitch
{
Name = item.ReadString(Data.Models.Metadata.DipSwitch.NameKey),
Tag = item.ReadString(Data.Models.Metadata.DipSwitch.TagKey),
Mask = item.ReadString(Data.Models.Metadata.DipSwitch.MaskKey),
};
var dipValues = item.Read<Data.Models.Metadata.DipValue[]>(Data.Models.Metadata.DipSwitch.DipValueKey);
if (dipValues is not null && dipValues.Length > 0)
dipSwitch.DipValue = Array.ConvertAll(dipValues, ConvertFromInternalModel);
return dipSwitch;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.DipValue"/> to <see cref="SDipValue"/>
/// </summary>
private static DipValue ConvertFromInternalModel(Data.Models.Metadata.DipValue item)
{
var dipValue = new DipValue
{
Name = item.ReadString(Data.Models.Metadata.DipValue.NameKey),
Value = item.ReadString(Data.Models.Metadata.DipValue.ValueKey),
Default = item.ReadString(Data.Models.Metadata.DipValue.DefaultKey),
};
return dipValue;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Disk"/> to <see cref="SDisk"/>
/// </summary>
private static Disk ConvertFromInternalModel(Data.Models.Metadata.Disk item)
{
var disk = new Disk
{
Name = item.ReadString(Data.Models.Metadata.Disk.NameKey),
MD5 = item.ReadString(Data.Models.Metadata.Disk.MD5Key),
SHA1 = item.ReadString(Data.Models.Metadata.Disk.SHA1Key),
Status = item.ReadString(Data.Models.Metadata.Disk.StatusKey),
Writeable = item.ReadString(Data.Models.Metadata.Disk.WritableKey),
};
return disk;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.DiskArea"/> to <see cref="SDiskArea"/>
/// </summary>
private static DiskArea ConvertFromInternalModel(Data.Models.Metadata.DiskArea item)
{
var diskArea = new DiskArea
{
Name = item.ReadString(Data.Models.Metadata.DiskArea.NameKey),
};
var disks = item.Read<Data.Models.Metadata.Disk[]>(Data.Models.Metadata.DiskArea.DiskKey);
if (disks is not null && disks.Length > 0)
diskArea.Disk = Array.ConvertAll(disks, ConvertFromInternalModel);
return diskArea;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Feature"/> to <see cref="SFeature"/>
/// </summary>
private static Feature ConvertFromInternalModel(Data.Models.Metadata.Feature item)
{
var feature = new Feature
{
Name = item.ReadString(Data.Models.Metadata.Feature.NameKey),
Value = item.ReadString(Data.Models.Metadata.Feature.ValueKey),
};
return feature;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Info"/> to <see cref="SInfo"/>
/// </summary>
private static Info ConvertFromInternalModel(Data.Models.Metadata.Info item)
{
var info = new Info
{
Name = item.ReadString(Data.Models.Metadata.Info.NameKey),
Value = item.ReadString(Data.Models.Metadata.Info.ValueKey),
};
return info;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Part"/> to <see cref="SPart"/>
/// </summary>
private static Part ConvertFromInternalModel(Data.Models.Metadata.Part item)
{
var part = new Part
{
Name = item.ReadString(Data.Models.Metadata.Part.NameKey),
Interface = item.ReadString(Data.Models.Metadata.Part.InterfaceKey),
};
var features = item.Read<Data.Models.Metadata.Feature[]>(Data.Models.Metadata.Part.FeatureKey);
if (features is not null && features.Length > 0)
part.Feature = Array.ConvertAll(features, ConvertFromInternalModel);
var dataAreas = item.Read<Data.Models.Metadata.DataArea[]>(Data.Models.Metadata.Part.DataAreaKey);
if (dataAreas is not null && dataAreas.Length > 0)
part.DataArea = Array.ConvertAll(dataAreas, ConvertFromInternalModel);
var diskAreas = item.Read<Data.Models.Metadata.DiskArea[]>(Data.Models.Metadata.Part.DiskAreaKey);
if (diskAreas is not null && diskAreas.Length > 0)
part.DiskArea = Array.ConvertAll(diskAreas, ConvertFromInternalModel);
var dipSwitches = item.Read<Data.Models.Metadata.DipSwitch[]>(Data.Models.Metadata.Part.DipSwitchKey);
if (dipSwitches is not null && dipSwitches.Length > 0)
part.DipSwitch = Array.ConvertAll(dipSwitches, ConvertFromInternalModel);
return part;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="SRom"/>
/// </summary>
private static Rom ConvertFromInternalModel(Data.Models.Metadata.Rom item)
{
var rom = new Rom
{
Name = item.ReadString(Data.Models.Metadata.Rom.NameKey),
Size = item.ReadString(Data.Models.Metadata.Rom.SizeKey),
Length = item.ReadString(Data.Models.Metadata.Rom.LengthKey),
CRC = item.ReadString(Data.Models.Metadata.Rom.CRCKey),
SHA1 = item.ReadString(Data.Models.Metadata.Rom.SHA1Key),
Offset = item.ReadString(Data.Models.Metadata.Rom.OffsetKey),
Value = item.ReadString(Data.Models.Metadata.Rom.ValueKey),
Status = item.ReadString(Data.Models.Metadata.Rom.StatusKey),
LoadFlag = item.ReadString(Data.Models.Metadata.Rom.LoadFlagKey),
};
return rom;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.SharedFeat"/> to <see cref="SSharedFeat"/>
/// </summary>
private static SharedFeat ConvertFromInternalModel(Data.Models.Metadata.SharedFeat item)
{
var sharedFeat = new SharedFeat
{
Name = item.ReadString(Data.Models.Metadata.SharedFeat.NameKey),
Value = item.ReadString(Data.Models.Metadata.SharedFeat.ValueKey),
};
return sharedFeat;
}
}
}

View File

@@ -0,0 +1,238 @@
using System;
using SabreTools.Data.Models.SoftwareList;
namespace SabreTools.Serialization.CrossModel
{
public partial class SoftwareList : BaseMetadataSerializer<Data.Models.SoftwareList.SoftwareList>
{
/// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(Data.Models.SoftwareList.SoftwareList? item)
{
if (item is null)
return null;
var metadataFile = new Data.Models.Metadata.MetadataFile
{
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
};
if (item?.Software is not null && item.Software.Length > 0)
{
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(item.Software, ConvertMachineToInternalModel);
}
return metadataFile;
}
/// <summary>
/// Convert from <see cref="Models.SoftwareList.SoftwareList"/> to <see cref="Models.Metadata.Header"/>
/// </summary>
private static Data.Models.Metadata.Header ConvertHeaderToInternalModel(Data.Models.SoftwareList.SoftwareList item)
{
var header = new Data.Models.Metadata.Header
{
[Data.Models.Metadata.Header.NameKey] = item.Name,
[Data.Models.Metadata.Header.DescriptionKey] = item.Description,
[Data.Models.Metadata.Header.NotesKey] = item.Notes,
};
return header;
}
/// <summary>
/// Convert from <see cref="Models.SoftwareList.Software"/> to <see cref="Models.Metadata.Machine"/>
/// </summary>
private static Data.Models.Metadata.Machine ConvertMachineToInternalModel(Software item)
{
var machine = new Data.Models.Metadata.Machine
{
[Data.Models.Metadata.Machine.NameKey] = item.Name,
[Data.Models.Metadata.Machine.CloneOfKey] = item.CloneOf,
[Data.Models.Metadata.Machine.SupportedKey] = item.Supported,
[Data.Models.Metadata.Machine.DescriptionKey] = item.Description,
[Data.Models.Metadata.Machine.YearKey] = item.Year,
[Data.Models.Metadata.Machine.PublisherKey] = item.Publisher,
[Data.Models.Metadata.Machine.NotesKey] = item.Notes,
};
if (item.Info is not null && item.Info.Length > 0)
machine[Data.Models.Metadata.Machine.InfoKey] = Array.ConvertAll(item.Info, ConvertToInternalModel);
if (item.SharedFeat is not null && item.SharedFeat.Length > 0)
machine[Data.Models.Metadata.Machine.SharedFeatKey] = Array.ConvertAll(item.SharedFeat, ConvertToInternalModel);
if (item.Part is not null && item.Part.Length > 0)
machine[Data.Models.Metadata.Machine.PartKey] = Array.ConvertAll(item.Part, ConvertToInternalModel);
return machine;
}
/// <summary>
/// Convert from <see cref="DataArea"/> to <see cref="Models.Metadata.DataArea"/>
/// </summary>
private static Data.Models.Metadata.DataArea ConvertToInternalModel(DataArea item)
{
var dataArea = new Data.Models.Metadata.DataArea
{
[Data.Models.Metadata.DataArea.NameKey] = item.Name,
[Data.Models.Metadata.DataArea.SizeKey] = item.Size,
[Data.Models.Metadata.DataArea.WidthKey] = item.Width,
[Data.Models.Metadata.DataArea.EndiannessKey] = item.Endianness,
};
if (item.Rom is not null && item.Rom.Length > 0)
dataArea[Data.Models.Metadata.DataArea.RomKey] = Array.ConvertAll(item.Rom, ConvertToInternalModel);
return dataArea;
}
/// <summary>
/// Convert from <see cref="DipSwitch"/> to <see cref="Models.Metadata.DipSwitch"/>
/// </summary>
private static Data.Models.Metadata.DipSwitch ConvertToInternalModel(DipSwitch item)
{
var dipSwitch = new Data.Models.Metadata.DipSwitch
{
[Data.Models.Metadata.DipSwitch.NameKey] = item.Name,
[Data.Models.Metadata.DipSwitch.TagKey] = item.Tag,
[Data.Models.Metadata.DipSwitch.MaskKey] = item.Mask,
};
if (item.DipValue is not null && item.DipValue.Length > 0)
dipSwitch[Data.Models.Metadata.DipSwitch.DipValueKey] = Array.ConvertAll(item.DipValue, ConvertToInternalModel);
return dipSwitch;
}
/// <summary>
/// Convert from <see cref="DipValue"/> to <see cref="Models.Metadata.DipValue"/>
/// </summary>
private static Data.Models.Metadata.DipValue ConvertToInternalModel(DipValue item)
{
var dipValue = new Data.Models.Metadata.DipValue
{
[Data.Models.Metadata.DipValue.NameKey] = item.Name,
[Data.Models.Metadata.DipValue.ValueKey] = item.Value,
[Data.Models.Metadata.DipValue.DefaultKey] = item.Default,
};
return dipValue;
}
/// <summary>
/// Convert from <see cref="Disk"/> to <see cref="Models.Metadata.Disk"/>
/// </summary>
private static Data.Models.Metadata.Disk ConvertToInternalModel(Disk item)
{
var disk = new Data.Models.Metadata.Disk
{
[Data.Models.Metadata.Disk.NameKey] = item.Name,
[Data.Models.Metadata.Disk.MD5Key] = item.MD5,
[Data.Models.Metadata.Disk.SHA1Key] = item.SHA1,
[Data.Models.Metadata.Disk.StatusKey] = item.Status,
[Data.Models.Metadata.Disk.WritableKey] = item.Writeable,
};
return disk;
}
/// <summary>
/// Convert from <see cref="DiskArea"/> to <see cref="Models.Metadata.DiskArea"/>
/// </summary>
private static Data.Models.Metadata.DiskArea ConvertToInternalModel(DiskArea item)
{
var diskArea = new Data.Models.Metadata.DiskArea
{
[Data.Models.Metadata.DiskArea.NameKey] = item.Name,
};
if (item.Disk is not null && item.Disk.Length > 0)
diskArea[Data.Models.Metadata.DiskArea.DiskKey] = Array.ConvertAll(item.Disk, ConvertToInternalModel);
return diskArea;
}
/// <summary>
/// Convert from <see cref="Feature"/> to <see cref="Models.Metadata.Feature"/>
/// </summary>
private static Data.Models.Metadata.Feature ConvertToInternalModel(Feature item)
{
var feature = new Data.Models.Metadata.Feature
{
[Data.Models.Metadata.Feature.NameKey] = item.Name,
[Data.Models.Metadata.Feature.ValueKey] = item.Value,
};
return feature;
}
/// <summary>
/// Convert from <see cref="Info"/> to <see cref="Models.Metadata.Info"/>
/// </summary>
private static Data.Models.Metadata.Info ConvertToInternalModel(Info item)
{
var info = new Data.Models.Metadata.Info
{
[Data.Models.Metadata.Info.NameKey] = item.Name,
[Data.Models.Metadata.Info.ValueKey] = item.Value,
};
return info;
}
/// <summary>
/// Convert from <see cref="Part"/> to <see cref="Models.Metadata.Part"/>
/// </summary>
private static Data.Models.Metadata.Part ConvertToInternalModel(Part item)
{
var part = new Data.Models.Metadata.Part
{
[Data.Models.Metadata.Part.NameKey] = item.Name,
[Data.Models.Metadata.Part.InterfaceKey] = item.Interface,
};
if (item.Feature is not null && item.Feature.Length > 0)
part[Data.Models.Metadata.Part.FeatureKey] = Array.ConvertAll(item.Feature, ConvertToInternalModel);
if (item.DataArea is not null && item.DataArea.Length > 0)
part[Data.Models.Metadata.Part.DataAreaKey] = Array.ConvertAll(item.DataArea, ConvertToInternalModel);
if (item.DiskArea is not null && item.DiskArea.Length > 0)
part[Data.Models.Metadata.Part.DiskAreaKey] = Array.ConvertAll(item.DiskArea, ConvertToInternalModel);
if (item.DipSwitch is not null && item.DipSwitch.Length > 0)
part[Data.Models.Metadata.Part.DipSwitchKey] = Array.ConvertAll(item.DipSwitch, ConvertToInternalModel);
return part;
}
/// <summary>
/// Convert from <see cref="Rom"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
private static Data.Models.Metadata.Rom ConvertToInternalModel(Rom item)
{
var rom = new Data.Models.Metadata.Rom
{
[Data.Models.Metadata.Rom.NameKey] = item.Name,
[Data.Models.Metadata.Rom.SizeKey] = item.Size,
[Data.Models.Metadata.Rom.LengthKey] = item.Length,
[Data.Models.Metadata.Rom.CRCKey] = item.CRC,
[Data.Models.Metadata.Rom.SHA1Key] = item.SHA1,
[Data.Models.Metadata.Rom.OffsetKey] = item.Offset,
[Data.Models.Metadata.Rom.ValueKey] = item.Value,
[Data.Models.Metadata.Rom.StatusKey] = item.Status,
[Data.Models.Metadata.Rom.LoadFlagKey] = item.LoadFlag,
};
return rom;
}
/// <summary>
/// Convert from <see cref="SharedFeat"/> to <see cref="Models.Metadata.SharedFeat"/>
/// </summary>
private static Data.Models.Metadata.SharedFeat ConvertToInternalModel(SharedFeat item)
{
var sharedFeat = new Data.Models.Metadata.SharedFeat
{
[Data.Models.Metadata.SharedFeat.NameKey] = item.Name,
[Data.Models.Metadata.SharedFeat.ValueKey] = item.Value,
};
return sharedFeat;
}
}
}