using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using SabreTools.IO.Readers; using SabreTools.Models.ClrMamePro; namespace SabreTools.Serialization { /// /// Deserializer for ClrMamePro metadata files /// public partial class ClrMamePro { /// /// Deserializes a ClrMamePro metadata file to the defined type /// /// Path to the file to deserialize /// Enable quotes on read, false otherwise /// Deserialized data on success, null on failure public static MetadataFile? Deserialize(string path, bool quotes) { using var stream = PathProcessor.OpenStream(path); return Deserialize(stream, quotes); } /// /// Deserializes a ClrMamePro metadata file in a stream to the defined type /// /// Stream to deserialize /// Enable quotes on read, false otherwise /// Deserialized data on success, null on failure public static MetadataFile? Deserialize(Stream? stream, bool quotes) { // If the stream is null if (stream == null) return default; // Setup the reader and output var reader = new ClrMameProReader(stream, Encoding.UTF8) { Quotes = quotes }; var dat = new MetadataFile(); // Loop through and parse out the values string lastTopLevel = reader.TopLevel; GameBase? game = null; var games = new List(); var releases = new List(); var biosSets = new List(); var roms = new List(); var disks = new List(); var medias = new List(); var samples = new List(); var archives = new List(); var chips = new List(); var dipSwitches = new List(); var additional = new List(); var headerAdditional = new List(); var gameAdditional = new List(); while (!reader.EndOfStream) { // If we have no next line if (!reader.ReadNextLine()) break; // Ignore certain row types switch (reader.RowType) { case CmpRowType.None: case CmpRowType.Comment: continue; case CmpRowType.EndTopLevel: switch (lastTopLevel) { case "doscenter": dat.ClrMamePro!.ADDITIONAL_ELEMENTS = headerAdditional.ToArray(); headerAdditional.Clear(); break; case "game": case "machine": case "resource": case "set": game!.Release = releases.ToArray(); game.BiosSet = biosSets.ToArray(); game.Rom = roms.ToArray(); game.Disk = disks.ToArray(); game.Media = medias.ToArray(); game.Sample = samples.ToArray(); game.Archive = archives.ToArray(); game.Chip = chips.ToArray(); game.DipSwitch = dipSwitches.ToArray(); game.ADDITIONAL_ELEMENTS = gameAdditional.ToArray(); games.Add(game); game = null; releases.Clear(); biosSets.Clear(); roms.Clear(); disks.Clear(); medias.Clear(); samples.Clear(); archives.Clear(); chips.Clear(); dipSwitches.Clear(); gameAdditional.Clear(); break; default: // No-op break; } continue; } // If we're at the root if (reader.RowType == CmpRowType.TopLevel) { lastTopLevel = reader.TopLevel; switch (reader.TopLevel) { case "clrmamepro": dat.ClrMamePro = new Models.ClrMamePro.ClrMamePro(); break; case "game": game = new Game(); break; case "machine": game = new Machine(); break; case "resource": game = new Resource(); break; case "set": game = new Set(); break; default: additional.Add(reader.CurrentLine); break; } } // If we're in the doscenter block else if (reader.TopLevel == "clrmamepro" && reader.RowType == CmpRowType.Standalone) { // Create the block if we haven't already dat.ClrMamePro ??= new Models.ClrMamePro.ClrMamePro(); switch (reader.Standalone?.Key?.ToLowerInvariant()) { case "name": dat.ClrMamePro.Name = reader.Standalone?.Value; break; case "description": dat.ClrMamePro.Description = reader.Standalone?.Value; break; case "rootdir": dat.ClrMamePro.RootDir = reader.Standalone?.Value; break; case "category": dat.ClrMamePro.Category = reader.Standalone?.Value; break; case "version": dat.ClrMamePro.Version = reader.Standalone?.Value; break; case "date": dat.ClrMamePro.Date = reader.Standalone?.Value; break; case "author": dat.ClrMamePro.Author = reader.Standalone?.Value; break; case "homepage": dat.ClrMamePro.Homepage = reader.Standalone?.Value; break; case "url": dat.ClrMamePro.Url = reader.Standalone?.Value; break; case "comment": dat.ClrMamePro.Comment = reader.Standalone?.Value; break; case "header": dat.ClrMamePro.Header = reader.Standalone?.Value; break; case "type": dat.ClrMamePro.Type = reader.Standalone?.Value; break; case "forcemerging": dat.ClrMamePro.ForceMerging = reader.Standalone?.Value; break; case "forcezipping": dat.ClrMamePro.ForceZipping = reader.Standalone?.Value; break; case "forcepacking": dat.ClrMamePro.ForcePacking = reader.Standalone?.Value; break; default: headerAdditional.Add(reader.CurrentLine); break; } } // If we're in a game, machine, resource, or set block else if ((reader.TopLevel == "game" || reader.TopLevel == "machine" || reader.TopLevel == "resource" || reader.TopLevel == "set") && reader.RowType == CmpRowType.Standalone) { // Create the block if we haven't already game ??= reader.TopLevel switch { "game" => new Game(), "machine" => new Machine(), "resource" => new Resource(), "set" => new Set(), _ => throw new FormatException($"Unknown top-level block: {reader.TopLevel}"), }; switch (reader.Standalone?.Key?.ToLowerInvariant()) { case "name": game.Name = reader.Standalone?.Value; break; case "description": game.Description = reader.Standalone?.Value; break; case "year": game.Year = reader.Standalone?.Value; break; case "manufacturer": game.Manufacturer = reader.Standalone?.Value; break; case "category": game.Category = reader.Standalone?.Value; break; case "cloneof": game.CloneOf = reader.Standalone?.Value; break; case "romof": game.RomOf = reader.Standalone?.Value; break; case "sampleof": game.SampleOf = reader.Standalone?.Value; break; case "sample": var sample = new Sample { Name = reader.Standalone?.Value ?? string.Empty, ADDITIONAL_ELEMENTS = Array.Empty() }; samples.Add(sample); break; default: gameAdditional.Add(reader.CurrentLine); break; } } // If we're in an item block else if ((reader.TopLevel == "game" || reader.TopLevel == "machine" || reader.TopLevel == "resource" || reader.TopLevel == "set") && game != null && reader.RowType == CmpRowType.Internal) { // Create the block switch (reader.InternalName) { case "release": releases.Add(CreateRelease(reader)); break; case "biosset": biosSets.Add(CreateBiosSet(reader)); break; case "rom": roms.Add(CreateRom(reader)); break; case "disk": disks.Add(CreateDisk(reader)); break; case "media": medias.Add(CreateMedia(reader)); break; case "sample": samples.Add(CreateSample(reader)); break; case "archive": archives.Add(CreateArchive(reader)); break; case "chip": chips.Add(CreateChip(reader)); break; case "video": game.Video = CreateVideo(reader); break; case "sound": game.Sound = CreateSound(reader); break; case "input": game.Input = CreateInput(reader); break; case "dipswitch": dipSwitches.Add(CreateDipSwitch(reader)); break; case "driver": game.Driver = CreateDriver(reader); break; default: gameAdditional.Add(reader.CurrentLine); continue; } } else { additional.Add(reader.CurrentLine); } } // Add extra pieces and return dat.Game = games.ToArray(); dat.ADDITIONAL_ELEMENTS = additional.ToArray(); return dat; } /// /// Create a Release object from the current reader context /// /// ClrMameProReader representing the metadata file /// Release object created from the reader context private static Release CreateRelease(ClrMameProReader reader) { var itemAdditional = new List(); var release = new Release(); foreach (var kvp in reader.Internal) { switch (kvp.Key?.ToLowerInvariant()) { case "name": release.Name = kvp.Value; break; case "region": release.Region = kvp.Value; break; case "language": release.Language = kvp.Value; break; case "date": release.Date = kvp.Value; break; case "default": release.Default = kvp.Value; break; default: itemAdditional.Add($"{kvp.Key}: {kvp.Value}"); break; } } release.ADDITIONAL_ELEMENTS = itemAdditional.ToArray(); return release; } /// /// Create a BiosSet object from the current reader context /// /// ClrMameProReader representing the metadata file /// BiosSet object created from the reader context private static BiosSet CreateBiosSet(ClrMameProReader reader) { var itemAdditional = new List(); var biosset = new BiosSet(); foreach (var kvp in reader.Internal) { switch (kvp.Key?.ToLowerInvariant()) { case "name": biosset.Name = kvp.Value; break; case "description": biosset.Description = kvp.Value; break; case "default": biosset.Default = kvp.Value; break; default: itemAdditional.Add($"{kvp.Key}: {kvp.Value}"); break; } } biosset.ADDITIONAL_ELEMENTS = itemAdditional.ToArray(); return biosset; } /// /// Create a Rom object from the current reader context /// /// ClrMameProReader representing the metadata file /// Rom object created from the reader context private static Rom CreateRom(ClrMameProReader reader) { var itemAdditional = new List(); var rom = new Rom(); foreach (var kvp in reader.Internal) { switch (kvp.Key?.ToLowerInvariant()) { case "name": rom.Name = kvp.Value; break; case "size": rom.Size = kvp.Value; break; case "crc": rom.CRC = kvp.Value; break; case "md5": rom.MD5 = kvp.Value; break; case "sha1": rom.SHA1 = kvp.Value; break; case "sha256": rom.SHA256 = kvp.Value; break; case "sha384": rom.SHA384 = kvp.Value; break; case "sha512": rom.SHA512 = kvp.Value; break; case "spamsum": rom.SpamSum = kvp.Value; break; case "xxh3_64": rom.xxHash364 = kvp.Value; break; case "xxh3_128": rom.xxHash3128 = kvp.Value; break; case "merge": rom.Merge = kvp.Value; break; case "status": rom.Status = kvp.Value; break; case "region": rom.Region = kvp.Value; break; case "flags": rom.Flags = kvp.Value; break; case "offs": rom.Offs = kvp.Value; break; case "serial": rom.Serial = kvp.Value; break; case "header": rom.Header = kvp.Value; break; case "date": rom.Date = kvp.Value; break; case "inverted": rom.Inverted = kvp.Value; break; case "mia": rom.MIA = kvp.Value; break; default: itemAdditional.Add($"{kvp.Key}: {kvp.Value}"); break; } } rom.ADDITIONAL_ELEMENTS = itemAdditional.ToArray(); return rom; } /// /// Create a Disk object from the current reader context /// /// ClrMameProReader representing the metadata file /// Disk object created from the reader context private static Disk CreateDisk(ClrMameProReader reader) { var itemAdditional = new List(); var disk = new Disk(); foreach (var kvp in reader.Internal) { switch (kvp.Key?.ToLowerInvariant()) { case "name": disk.Name = kvp.Value; break; case "md5": disk.MD5 = kvp.Value; break; case "sha1": disk.SHA1 = kvp.Value; break; case "merge": disk.Merge = kvp.Value; break; case "status": disk.Status = kvp.Value; break; case "flags": disk.Flags = kvp.Value; break; default: itemAdditional.Add($"{kvp.Key}: {kvp.Value}"); break; } } disk.ADDITIONAL_ELEMENTS = itemAdditional.ToArray(); return disk; } /// /// Create a Media object from the current reader context /// /// ClrMameProReader representing the metadata file /// Media object created from the reader context private static Media CreateMedia(ClrMameProReader reader) { var itemAdditional = new List(); var media = new Media(); foreach (var kvp in reader.Internal) { switch (kvp.Key?.ToLowerInvariant()) { case "name": media.Name = kvp.Value; break; case "md5": media.MD5 = kvp.Value; break; case "sha1": media.SHA1 = kvp.Value; break; case "sha256": media.SHA256 = kvp.Value; break; case "spamsum": media.SpamSum = kvp.Value; break; default: itemAdditional.Add($"{kvp.Key}: {kvp.Value}"); break; } } media.ADDITIONAL_ELEMENTS = itemAdditional.ToArray(); return media; } /// /// Create a Sample object from the current reader context /// /// ClrMameProReader representing the metadata file /// Sample object created from the reader context private static Sample CreateSample(ClrMameProReader reader) { var itemAdditional = new List(); var sample = new Sample(); foreach (var kvp in reader.Internal) { switch (kvp.Key?.ToLowerInvariant()) { case "name": sample.Name = kvp.Value; break; default: itemAdditional.Add($"{kvp.Key}: {kvp.Value}"); break; } } sample.ADDITIONAL_ELEMENTS = itemAdditional.ToArray(); return sample; } /// /// Create a Archive object from the current reader context /// /// ClrMameProReader representing the metadata file /// Archive object created from the reader context private static Archive CreateArchive(ClrMameProReader reader) { var itemAdditional = new List(); var archive = new Archive(); foreach (var kvp in reader.Internal) { switch (kvp.Key?.ToLowerInvariant()) { case "name": archive.Name = kvp.Value; break; default: itemAdditional.Add($"{kvp.Key}: {kvp.Value}"); break; } } archive.ADDITIONAL_ELEMENTS = itemAdditional.ToArray(); return archive; } /// /// Create a Chip object from the current reader context /// /// ClrMameProReader representing the metadata file /// Chip object created from the reader context private static Chip CreateChip(ClrMameProReader reader) { var itemAdditional = new List(); var chip = new Chip(); foreach (var kvp in reader.Internal) { switch (kvp.Key?.ToLowerInvariant()) { case "type": chip.Type = kvp.Value; break; case "name": chip.Name = kvp.Value; break; case "flags": chip.Flags = kvp.Value; break; case "clock": chip.Clock = kvp.Value; break; default: itemAdditional.Add($"{kvp.Key}: {kvp.Value}"); break; } } chip.ADDITIONAL_ELEMENTS = itemAdditional.ToArray(); return chip; } /// /// Create a Video object from the current reader context /// /// ClrMameProReader representing the metadata file /// Video object created from the reader context private static Video CreateVideo(ClrMameProReader reader) { var itemAdditional = new List(); var video = new Video(); foreach (var kvp in reader.Internal) { switch (kvp.Key?.ToLowerInvariant()) { case "screen": video.Screen = kvp.Value; break; case "orientation": video.Orientation = kvp.Value; break; case "x": video.X = kvp.Value; break; case "y": video.Y = kvp.Value; break; case "aspectx": video.AspectX = kvp.Value; break; case "aspecty": video.AspectY = kvp.Value; break; case "freq": video.Freq = kvp.Value; break; default: itemAdditional.Add($"{kvp.Key}: {kvp.Value}"); break; } } video.ADDITIONAL_ELEMENTS = itemAdditional.ToArray(); return video; } /// /// Create a Sound object from the current reader context /// /// ClrMameProReader representing the metadata file /// Sound object created from the reader context private static Sound CreateSound(ClrMameProReader reader) { var itemAdditional = new List(); var sound = new Sound(); foreach (var kvp in reader.Internal) { switch (kvp.Key?.ToLowerInvariant()) { case "channels": sound.Channels = kvp.Value; break; default: itemAdditional.Add($"{kvp.Key}: {kvp.Value}"); break; } } sound.ADDITIONAL_ELEMENTS = itemAdditional.ToArray(); return sound; } /// /// Create a Input object from the current reader context /// /// ClrMameProReader representing the metadata file /// Input object created from the reader context private static Input CreateInput(ClrMameProReader reader) { var itemAdditional = new List(); var input = new Input(); foreach (var kvp in reader.Internal) { switch (kvp.Key?.ToLowerInvariant()) { case "players": input.Players = kvp.Value; break; case "control": input.Control = kvp.Value; break; case "buttons": input.Buttons = kvp.Value; break; case "coins": input.Coins = kvp.Value; break; case "tilt": input.Tilt = kvp.Value; break; case "service": input.Service = kvp.Value; break; default: itemAdditional.Add($"{kvp.Key}: {kvp.Value}"); break; } } input.ADDITIONAL_ELEMENTS = itemAdditional.ToArray(); return input; } /// /// Create a DipSwitch object from the current reader context /// /// ClrMameProReader representing the metadata file /// DipSwitch object created from the reader context private static DipSwitch CreateDipSwitch(ClrMameProReader reader) { var itemAdditional = new List(); var dipswitch = new DipSwitch(); var entries = new List(); foreach (var kvp in reader.Internal) { switch (kvp.Key?.ToLowerInvariant()) { case "name": dipswitch.Name = kvp.Value; break; case "entry": entries.Add(kvp.Value); break; case "default": dipswitch.Default = kvp.Value; break; default: itemAdditional.Add($"{kvp.Key}: {kvp.Value}"); break; } } dipswitch.Entry = entries.ToArray(); dipswitch.ADDITIONAL_ELEMENTS = itemAdditional.ToArray(); return dipswitch; } /// /// Create a Driver object from the current reader context /// /// ClrMameProReader representing the metadata file /// Driver object created from the reader context private static Driver CreateDriver(ClrMameProReader reader) { var itemAdditional = new List(); var driver = new Driver(); foreach (var kvp in reader.Internal) { switch (kvp.Key?.ToLowerInvariant()) { case "status": driver.Status = kvp.Value; break; case "color": driver.Color = kvp.Value; break; case "sound": driver.Sound = kvp.Value; break; case "palettesize": driver.PaletteSize = kvp.Value; break; case "blit": driver.Blit = kvp.Value; break; default: itemAdditional.Add($"{kvp.Key}: {kvp.Value}"); break; } } driver.ADDITIONAL_ELEMENTS = itemAdditional.ToArray(); return driver; } // TODO: Add deserialization of entire MetadataFile #region Internal /// /// Convert from to /// public static Models.ClrMamePro.ClrMamePro? ConvertHeaderFromInternalModel(Models.Internal.Header? item) { if (item == null) return null; var clrMamePro = new Models.ClrMamePro.ClrMamePro { Name = item.ReadString(Models.Internal.Header.NameKey), Description = item.ReadString(Models.Internal.Header.DescriptionKey), RootDir = item.ReadString(Models.Internal.Header.RootDirKey), Category = item.ReadString(Models.Internal.Header.CategoryKey), Version = item.ReadString(Models.Internal.Header.VersionKey), Date = item.ReadString(Models.Internal.Header.DateKey), Author = item.ReadString(Models.Internal.Header.AuthorKey), Homepage = item.ReadString(Models.Internal.Header.HomepageKey), Url = item.ReadString(Models.Internal.Header.UrlKey), Comment = item.ReadString(Models.Internal.Header.CommentKey), Header = item.ReadString(Models.Internal.Header.HeaderKey), Type = item.ReadString(Models.Internal.Header.TypeKey), ForceMerging = item.ReadString(Models.Internal.Header.ForceMergingKey), ForceZipping = item.ReadString(Models.Internal.Header.ForceZippingKey), ForcePacking = item.ReadString(Models.Internal.Header.ForcePackingKey), }; return clrMamePro; } /// /// Convert from to /// public static GameBase? ConvertMachineFromInternalModel(Models.Internal.Machine? item, bool game = false) { if (item == null) return null; GameBase gameBase = game ? new Models.ClrMamePro.Game() : new Models.ClrMamePro.Machine(); gameBase.Name = item.ReadString(Models.Internal.Machine.NameKey); gameBase.Description = item.ReadString(Models.Internal.Machine.DescriptionKey); gameBase.Year = item.ReadString(Models.Internal.Machine.YearKey); gameBase.Manufacturer = item.ReadString(Models.Internal.Machine.ManufacturerKey); gameBase.Category = item.ReadString(Models.Internal.Machine.CategoryKey); gameBase.CloneOf = item.ReadString(Models.Internal.Machine.CloneOfKey); gameBase.RomOf = item.ReadString(Models.Internal.Machine.RomOfKey); gameBase.SampleOf = item.ReadString(Models.Internal.Machine.SampleOfKey); var releases = item.Read(Models.Internal.Machine.ReleaseKey); gameBase.Release = releases?.Select(ConvertFromInternalModel)?.ToArray(); var biosSets = item.Read(Models.Internal.Machine.BiosSetKey); gameBase.BiosSet = biosSets?.Select(ConvertFromInternalModel)?.ToArray(); var roms = item.Read(Models.Internal.Machine.RomKey); gameBase.Rom = roms?.Select(ConvertFromInternalModel)?.ToArray(); var disks = item.Read(Models.Internal.Machine.DiskKey); gameBase.Disk = disks?.Select(ConvertFromInternalModel)?.ToArray(); var medias = item.Read(Models.Internal.Machine.MediaKey); gameBase.Media = medias?.Select(ConvertFromInternalModel)?.ToArray(); var samples = item.Read(Models.Internal.Machine.SampleKey); gameBase.Sample = samples?.Select(ConvertFromInternalModel)?.ToArray(); var archives = item.Read(Models.Internal.Machine.ArchiveKey); gameBase.Archive = archives?.Select(ConvertFromInternalModel)?.ToArray(); var chips = item.Read(Models.Internal.Machine.ChipKey); gameBase.Chip = chips?.Select(ConvertFromInternalModel)?.ToArray(); var video = item.Read(Models.Internal.Machine.VideoKey); gameBase.Video = ConvertFromInternalModel(video); var sound = item.Read(Models.Internal.Machine.SoundKey); gameBase.Sound = ConvertFromInternalModel(sound); var input = item.Read(Models.Internal.Machine.InputKey); gameBase.Input = ConvertFromInternalModel(input); var dipSwitches = item.Read(Models.Internal.Machine.DipSwitchKey); gameBase.DipSwitch = dipSwitches?.Select(ConvertFromInternalModel)?.ToArray(); var driver = item.Read(Models.Internal.Machine.DriverKey); gameBase.Driver = ConvertFromInternalModel(driver); return gameBase; } /// /// Convert from to /// private static Archive? ConvertFromInternalModel(Models.Internal.Archive? item) { if (item == null) return null; var archive = new Archive { Name = item.ReadString(Models.Internal.Archive.NameKey), }; return archive; } /// /// Convert from to /// private static BiosSet? ConvertFromInternalModel(Models.Internal.BiosSet? item) { if (item == null) return null; var biosset = new BiosSet { Name = item.ReadString(Models.Internal.BiosSet.NameKey), Description = item.ReadString(Models.Internal.BiosSet.DescriptionKey), Default = item.ReadString(Models.Internal.BiosSet.DefaultKey), }; return biosset; } /// /// Convert from to /// private static Chip? ConvertFromInternalModel(Models.Internal.Chip? item) { if (item == null) return null; var chip = new Chip { Type = item.ReadString(Models.Internal.Chip.ChipTypeKey), Name = item.ReadString(Models.Internal.Chip.NameKey), Flags = item.ReadString(Models.Internal.Chip.FlagsKey), Clock = item.ReadString(Models.Internal.Chip.ClockKey), }; return chip; } /// /// Convert from to /// private static DipSwitch? ConvertFromInternalModel(Models.Internal.DipSwitch? item) { if (item == null) return null; var dipswitch = new DipSwitch { Name = item.ReadString(Models.Internal.DipSwitch.NameKey), Entry = item[Models.Internal.DipSwitch.EntryKey] as string[], Default = item.ReadString(Models.Internal.DipSwitch.DefaultKey), }; return dipswitch; } /// /// Convert from to /// private static Disk? ConvertFromInternalModel(Models.Internal.Disk? item) { if (item == null) return null; var disk = new Disk { Name = item.ReadString(Models.Internal.Disk.NameKey), MD5 = item.ReadString(Models.Internal.Disk.MD5Key), SHA1 = item.ReadString(Models.Internal.Disk.SHA1Key), Merge = item.ReadString(Models.Internal.Disk.MergeKey), Status = item.ReadString(Models.Internal.Disk.StatusKey), Flags = item.ReadString(Models.Internal.Disk.FlagsKey), }; return disk; } /// /// Convert from to /// private static Driver? ConvertFromInternalModel(Models.Internal.Driver? item) { if (item == null) return null; var driver = new Driver { Status = item.ReadString(Models.Internal.Driver.StatusKey), Color = item.ReadString(Models.Internal.Driver.ColorKey), Sound = item.ReadString(Models.Internal.Driver.SoundKey), PaletteSize = item.ReadString(Models.Internal.Driver.PaletteSizeKey), Blit = item.ReadString(Models.Internal.Driver.BlitKey), }; return driver; } /// /// Convert from to /// private static Input? ConvertFromInternalModel(Models.Internal.Input? item) { if (item == null) return null; var input = new Input { Players = item.ReadString(Models.Internal.Input.PlayersKey), Control = item.ReadString(Models.Internal.Input.ControlKey), Buttons = item.ReadString(Models.Internal.Input.ButtonsKey), Coins = item.ReadString(Models.Internal.Input.CoinsKey), Tilt = item.ReadString(Models.Internal.Input.TiltKey), Service = item.ReadString(Models.Internal.Input.ServiceKey), }; return input; } /// /// Convert from to /// private static Media? ConvertFromInternalModel(Models.Internal.Media? item) { if (item == null) return null; var media = new Media { Name = item.ReadString(Models.Internal.Media.NameKey), MD5 = item.ReadString(Models.Internal.Media.MD5Key), SHA1 = item.ReadString(Models.Internal.Media.SHA1Key), SHA256 = item.ReadString(Models.Internal.Media.SHA256Key), SpamSum = item.ReadString(Models.Internal.Media.SpamSumKey), }; return media; } /// /// Convert from to /// private static Release? ConvertFromInternalModel(Models.Internal.Release? item) { if (item == null) return null; var release = new Release { Name = item.ReadString(Models.Internal.Release.NameKey), Region = item.ReadString(Models.Internal.Release.RegionKey), Language = item.ReadString(Models.Internal.Release.LanguageKey), Date = item.ReadString(Models.Internal.Release.DateKey), Default = item.ReadString(Models.Internal.Release.DefaultKey), }; return release; } /// /// Convert from to /// private static Rom? ConvertFromInternalModel(Models.Internal.Rom? item) { if (item == null) return null; var rom = new Rom { Name = item.ReadString(Models.Internal.Rom.NameKey), Size = item.ReadString(Models.Internal.Rom.SizeKey), CRC = item.ReadString(Models.Internal.Rom.CRCKey), MD5 = item.ReadString(Models.Internal.Rom.MD5Key), SHA1 = item.ReadString(Models.Internal.Rom.SHA1Key), SHA256 = item.ReadString(Models.Internal.Rom.SHA256Key), SHA384 = item.ReadString(Models.Internal.Rom.SHA384Key), SHA512 = item.ReadString(Models.Internal.Rom.SHA512Key), SpamSum = item.ReadString(Models.Internal.Rom.SpamSumKey), xxHash364 = item.ReadString(Models.Internal.Rom.xxHash364Key), xxHash3128 = item.ReadString(Models.Internal.Rom.xxHash3128Key), Merge = item.ReadString(Models.Internal.Rom.MergeKey), Status = item.ReadString(Models.Internal.Rom.StatusKey), Region = item.ReadString(Models.Internal.Rom.RegionKey), Flags = item.ReadString(Models.Internal.Rom.FlagsKey), Offs = item.ReadString(Models.Internal.Rom.OffsetKey), Serial = item.ReadString(Models.Internal.Rom.SerialKey), Header = item.ReadString(Models.Internal.Rom.HeaderKey), Date = item.ReadString(Models.Internal.Rom.DateKey), Inverted = item.ReadString(Models.Internal.Rom.InvertedKey), MIA = item.ReadString(Models.Internal.Rom.MIAKey), }; return rom; } /// /// Convert from to /// private static Sample? ConvertFromInternalModel(Models.Internal.Sample? item) { if (item == null) return null; var sample = new Sample { Name = item.ReadString(Models.Internal.Sample.NameKey), }; return sample; } /// /// Convert from to /// private static Sound? ConvertFromInternalModel(Models.Internal.Sound? item) { if (item == null) return null; var sound = new Sound { Channels = item.ReadString(Models.Internal.Sound.ChannelsKey), }; return sound; } /// /// Convert from to /// private static Video? ConvertFromInternalModel(Models.Internal.Video? item) { if (item == null) return null; var video = new Video { Screen = item.ReadString(Models.Internal.Video.ScreenKey), Orientation = item.ReadString(Models.Internal.Video.OrientationKey), X = item.ReadString(Models.Internal.Video.WidthKey), Y = item.ReadString(Models.Internal.Video.HeightKey), AspectX = item.ReadString(Models.Internal.Video.AspectXKey), AspectY = item.ReadString(Models.Internal.Video.AspectYKey), Freq = item.ReadString(Models.Internal.Video.RefreshKey), }; return video; } #endregion } }