Merge pull request #79 from SabreTools/attempt-metadata-overhaul

This commit is contained in:
Matt Nadareski
2026-04-08 10:16:06 -04:00
committed by GitHub
350 changed files with 27114 additions and 18863 deletions

View File

@@ -82,7 +82,6 @@ Below are a list of the included namespaces with links to their README files:
- [SabreTools.Data.Extensions](https://github.com/SabreTools/SabreTools.Serialization/tree/main/SabreTools.Data.Extensions)
- [SabreTools.Data.Models](https://github.com/SabreTools/SabreTools.Serialization/tree/main/SabreTools.Data.Models)
- [SabreTools.Metadata](https://github.com/SabreTools/SabreTools.Serialization/tree/main/SabreTools.Metadata)
- [SabreTools.Metadata.DatFiles](https://github.com/SabreTools/SabreTools.Serialization/tree/main/SabreTools.Metadata.DatFiles)
- [SabreTools.Metadata.DatItems](https://github.com/SabreTools/SabreTools.Serialization/tree/main/SabreTools.Metadata.Datitems)
- [SabreTools.Metadata.Filter](https://github.com/SabreTools/SabreTools.Serialization/tree/main/SabreTools.Metadata.Filter)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -33,7 +33,7 @@ namespace SabreTools.Data.Models.ArchiveDotOrg
public string? SHA1 { get; set; }
[XmlElement("filecount")]
public string? FileCount { get; set; }
public long? FileCount { get; set; }
/// <remarks>Is this a set of defined values?</remarks>
[XmlElement("format")]

View File

@@ -46,6 +46,6 @@ namespace SabreTools.Data.Models.AttractMode
public string? PlayedTime { get; set; }
public string? FileIsAvailable { get; set; }
public bool? FileIsAvailable { get; set; }
}
}

View File

@@ -3,15 +3,15 @@ namespace SabreTools.Data.Models.ClrMamePro
/// <remarks>biosset</remarks>
public class BiosSet
{
/// <remarks>name</remarks>
/// <remarks>"name"</remarks>
[Required]
public string? Name { get; set; }
/// <remarks>description</remarks>
/// <remarks>"description"</remarks>
[Required]
public string? Description { get; set; }
/// <remarks>default</remarks>
public string? Default { get; set; }
/// <remarks>"default", (yes|no) "no"</remarks>
public bool? Default { get; set; }
}
}

View File

@@ -1,4 +1,6 @@
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.ClrMamePro
{
/// <remarks>chip</remarks>
@@ -6,7 +8,7 @@ namespace SabreTools.Data.Models.ClrMamePro
{
/// <remarks>type, (cpu|audio)</remarks>
[Required]
public string? Type { get; set; }
public ChipType? Type { get; set; }
/// <remarks>name</remarks>
[Required]
@@ -15,7 +17,7 @@ namespace SabreTools.Data.Models.ClrMamePro
/// <remarks>flags</remarks>
public string? Flags { get; set; }
/// <remarks>clock, Numeric?</remarks>
public string? Clock { get; set; }
/// <remarks>clock</remarks>
public long? Clock { get; set; }
}
}

View File

@@ -1,3 +1,5 @@
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.ClrMamePro
{
/// <remarks>clrmamepro</remarks>
@@ -40,12 +42,12 @@ namespace SabreTools.Data.Models.ClrMamePro
public string? Type { get; set; }
/// <remarks>forcemerging</remarks>
public string? ForceMerging { get; set; }
public MergingFlag ForceMerging { get; set; }
/// <remarks>forcezipping</remarks>
public string? ForceZipping { get; set; }
/// <remarks>forcezipping, (yes|no) "no"</remarks>
public bool? ForceZipping { get; set; }
/// <remarks>forcepacking</remarks>
public string? ForcePacking { get; set; }
public PackingFlag ForcePacking { get; set; }
}
}

View File

@@ -4,14 +4,14 @@ namespace SabreTools.Data.Models.ClrMamePro
/// <remarks>dipswitch</remarks>
public class DipSwitch
{
/// <remarks>name</remarks>
/// <remarks>"name"</remarks>
[Required]
public string? Name { get; set; }
/// <remarks>entry</remarks>
/// <remarks>"entry"</remarks>
public string[]? Entry { get; set; }
/// <remarks>default, (yes|no) "no"</remarks>
public string? Default { get; set; }
/// <remarks>"default", (yes|no) "no"</remarks>
public bool? Default { get; set; }
}
}

View File

@@ -1,4 +1,6 @@
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.ClrMamePro
{
/// <remarks>disk</remarks>
@@ -18,7 +20,7 @@ namespace SabreTools.Data.Models.ClrMamePro
public string? Merge { get; set; }
/// <remarks>status</remarks>
public string? Status { get; set; }
public ItemStatus? Status { get; set; }
/// <remarks>flags</remarks>
public string? Flags { get; set; }

View File

@@ -1,4 +1,6 @@
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.ClrMamePro
{
/// <remarks>driver</remarks>
@@ -6,18 +8,18 @@ namespace SabreTools.Data.Models.ClrMamePro
{
/// <remarks>status, (good|imperfect|preliminary)</remarks>
[Required]
public string? Status { get; set; }
public SupportStatus? Status { get; set; }
/// <remarks>color, (good|imperfect|preliminary)</remarks>
public string? Color { get; set; }
public SupportStatus? Color { get; set; }
/// <remarks>sound, (good|imperfect|preliminary)</remarks>
public string? Sound { get; set; }
public SupportStatus? Sound { get; set; }
/// <remarks>palettesize, Numeric?</remarks>
public string? PaletteSize { get; set; }
/// <remarks>blit, (plain|dirty)</remarks>
public string? Blit { get; set; }
public Blit? Blit { get; set; }
}
}

View File

@@ -4,24 +4,24 @@ namespace SabreTools.Data.Models.ClrMamePro
/// <remarks>input</remarks>
public class Input
{
/// <remarks>players, Numeric/remarks>
/// <remarks>"players"/remarks>
[Required]
public string? Players { get; set; }
public long? Players { get; set; }
/// <remarks>control</remarks>
/// <remarks>"control"</remarks>
public string? Control { get; set; }
/// <remarks>buttons, Numeric</remarks>
/// <remarks>"buttons"</remarks>
[Required]
public string? Buttons { get; set; }
public long? Buttons { get; set; }
/// <remarks>coins, Numeric</remarks>
public string? Coins { get; set; }
/// <remarks>"coins"</remarks>
public long? Coins { get; set; }
/// <remarks>tilt, (yes|no) "no"</remarks>
public string? Tilt { get; set; }
/// <remarks>"tilt", (yes|no) "no"</remarks>
public bool? Tilt { get; set; }
/// <remarks>service, (yes|no) "no"</remarks>
public string? Service { get; set; }
/// <remarks>"service", (yes|no) "no"</remarks>
public bool? Service { get; set; }
}
}

View File

@@ -4,21 +4,21 @@ namespace SabreTools.Data.Models.ClrMamePro
/// <remarks>release</remarks>
public class Release
{
/// <remarks>name</remarks>
/// <remarks>"name"</remarks>
[Required]
public string? Name { get; set; }
/// <remarks>region</remarks>
/// <remarks>"region"</remarks>
[Required]
public string? Region { get; set; }
/// <remarks>language</remarks>
/// <remarks>"language"</remarks>
public string? Language { get; set; }
/// <remarks>date</remarks>
/// <remarks>"date"</remarks>
public string? Date { get; set; }
/// <remarks>default</remarks>
public string? Default { get; set; }
/// <remarks>"default", (yes|no) "no"</remarks>
public bool? Default { get; set; }
}
}

View File

@@ -1,5 +1,7 @@
#pragma warning disable IDE1006 // Naming Styles
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.ClrMamePro
{
/// <remarks>rom</remarks>
@@ -11,7 +13,7 @@ namespace SabreTools.Data.Models.ClrMamePro
/// <remarks>size, Numeric</remarks>
[Required]
public string? Size { get; set; }
public long? Size { get; set; }
/// <remarks>crc</remarks>
public string? CRC { get; set; }
@@ -26,7 +28,7 @@ namespace SabreTools.Data.Models.ClrMamePro
public string? Merge { get; set; }
/// <remarks>status</remarks>
public string? Status { get; set; }
public ItemStatus? Status { get; set; }
/// <remarks>flags</remarks>
public string? Flags { get; set; }
@@ -101,10 +103,10 @@ namespace SabreTools.Data.Models.ClrMamePro
#region RomVault Extensions
/// <remarks>inverted; Boolean; Appears after Date</remarks>
public string? Inverted { get; set; }
public bool? Inverted { get; set; }
/// <remarks>mia; Boolean; Appears after Inverted</remarks>
public string? MIA { get; set; }
public bool? MIA { get; set; }
#endregion
}

View File

@@ -6,6 +6,6 @@ namespace SabreTools.Data.Models.ClrMamePro
{
/// <remarks>channels, Numeric?</remarks>
[Required]
public string? Channels { get; set; }
public long? Channels { get; set; }
}
}

View File

@@ -1,4 +1,6 @@
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.ClrMamePro
{
/// <remarks>video</remarks>
@@ -6,25 +8,25 @@ namespace SabreTools.Data.Models.ClrMamePro
{
/// <remarks>screen, (raster|vector)</remarks>
[Required]
public string? Screen { get; set; }
public DisplayType? Screen { get; set; }
/// <remarks>orientation, (vertical|horizontal)</remarks>
[Required]
public string? Orientation { get; set; }
public Rotation? Orientation { get; set; }
/// <remarks>x, Numeric?</remarks>
public string? X { get; set; }
/// <remarks>x</remarks>
public long? X { get; set; }
/// <remarks>y, Numeric?</remarks>
public string? Y { get; set; }
/// <remarks>y</remarks>
public long? Y { get; set; }
/// <remarks>aspectx, Numeric?</remarks>
public string? AspectX { get; set; }
/// <remarks>aspectx</remarks>
public long? AspectX { get; set; }
/// <remarks>aspecty, Numeric?</remarks>
public string? AspectY { get; set; }
/// <remarks>aspecty</remarks>
public long? AspectY { get; set; }
/// <remarks>freq, Numeric?</remarks>
public string? Freq { get; set; }
/// <remarks>freq</remarks>
public double? Freq { get; set; }
}
}

View File

@@ -10,7 +10,7 @@ namespace SabreTools.Data.Models.DosCenter
/// <remarks>size, attribute, numeric</remarks>
[Required]
public string? Size { get; set; }
public long? Size { get; set; }
/// <remarks>crc, attribute</remarks>
[Required]

View File

@@ -21,6 +21,6 @@ namespace SabreTools.Data.Models.EverdriveSMDB
[Required]
public string? CRC32 { get; set; }
public string? Size { get; set; }
public long? Size { get; set; }
}
}

View File

@@ -18,7 +18,7 @@ namespace SabreTools.Data.Models.Listrom
[Required]
public string? Name { get; set; }
public string? Size { get; set; }
public long? Size { get; set; }
public bool Bad { get; set; }

View File

@@ -12,7 +12,7 @@ namespace SabreTools.Data.Models.Listxml
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("default")]
public string? Default { get; set; }
public bool? Default { get; set; }
[XmlElement("condition")]
public Condition? Condition { get; set; }

View File

@@ -16,6 +16,6 @@ namespace SabreTools.Data.Models.Listxml
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("default")]
public string? Default { get; set; }
public bool? Default { get; set; }
}
}

View File

@@ -1,5 +1,6 @@
using System.Xml;
using System.Xml.Serialization;
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.Listxml
{
@@ -16,13 +17,13 @@ namespace SabreTools.Data.Models.Listxml
/// <remarks>(cpu|audio)</remarks>
[Required]
[XmlAttribute("type")]
public string? Type { get; set; }
public ChipType? Type { get; set; }
/// <remarks>Only present in older versions</remarks>
[XmlAttribute("soundonly")]
public string? SoundOnly { get; set; }
public bool? SoundOnly { get; set; }
[XmlAttribute("clock")]
public string? Clock { get; set; }
public long? Clock { get; set; }
}
}

View File

@@ -1,5 +1,6 @@
using System.Xml;
using System.Xml.Serialization;
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.Listxml
{
@@ -17,7 +18,7 @@ namespace SabreTools.Data.Models.Listxml
/// <remarks>(eq|ne|gt|le|lt|ge)</remarks>
[Required]
[XmlAttribute("relation")]
public string? Relation { get; set; }
public Relation? Relation { get; set; }
[Required]
[XmlAttribute("value")]

View File

@@ -10,13 +10,12 @@ namespace SabreTools.Data.Models.Listxml
[XmlAttribute("name")]
public string? Name { get; set; }
/// <remarks>Numeric?</remarks>
[Required]
[XmlAttribute("number")]
public string? Number { get; set; }
public long? Number { get; set; }
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("inverted")]
public string? Inverted { get; set; }
public bool? Inverted { get; set; }
}
}

View File

@@ -16,7 +16,7 @@ namespace SabreTools.Data.Models.Listxml
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("default")]
public string? Default { get; set; }
public bool? Default { get; set; }
[XmlElement("condition")]
public Condition? Condition { get; set; }

View File

@@ -1,5 +1,6 @@
using System.Xml;
using System.Xml.Serialization;
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.Listxml
{
@@ -9,49 +10,39 @@ namespace SabreTools.Data.Models.Listxml
/// <remarks>(joy|stick|paddle|pedal|lightgun|positional|dial|trackball|mouse|only_buttons|keypad|keyboard|mahjong|hanafuda|gambling)</remarks>
[Required]
[XmlAttribute("type")]
public string? Type { get; set; }
public ControlType? Type { get; set; }
/// <remarks>Numeric</remarks>
[XmlAttribute("player")]
public string? Player { get; set; }
public long? Player { get; set; }
/// <remarks>Numeric</remarks>
[XmlAttribute("buttons")]
public string? Buttons { get; set; }
public long? Buttons { get; set; }
/// <remarks>Numeric</remarks>
[XmlAttribute("reqbuttons")]
public string? ReqButtons { get; set; }
public long? ReqButtons { get; set; }
/// <remarks>Numeric</remarks>
[XmlAttribute("minimum")]
public string? Minimum { get; set; }
public long? Minimum { get; set; }
/// <remarks>Numeric</remarks>
[XmlAttribute("maximum")]
public string? Maximum { get; set; }
public long? Maximum { get; set; }
/// <remarks>Numeric</remarks>
[XmlAttribute("sensitivity")]
public string? Sensitivity { get; set; }
public long? Sensitivity { get; set; }
/// <remarks>Numeric</remarks>
[XmlAttribute("keydelta")]
public string? KeyDelta { get; set; }
public long? KeyDelta { get; set; }
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("reverse")]
public string? Reverse { get; set; }
public bool? Reverse { get; set; }
/// <remarks>Numeric?</remarks>
[XmlAttribute("ways")]
public string? Ways { get; set; }
/// <remarks>Numeric?</remarks>
[XmlAttribute("ways2")]
public string? Ways2 { get; set; }
/// <remarks>Numeric?</remarks>
[XmlAttribute("ways3")]
public string? Ways3 { get; set; }
}

View File

@@ -1,14 +1,16 @@
using System.Xml;
using System.Xml.Serialization;
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.Listxml
{
[XmlRoot("device")]
public class Device
{
/// <remarks>(unknown|cartridge|floppydisk|harddisk|cylinder|cassette|punchcard|punchtape|printout|serial|parallel|snapshot|quickload|memcard|cdrom|magtape|romimage|midiin|midiout|picture|vidfile)</remarks>
[Required]
[XmlAttribute("type")]
public string? Type { get; set; }
public DeviceType? Type { get; set; }
[XmlAttribute("tag")]
public string? Tag { get; set; }
@@ -16,9 +18,9 @@ namespace SabreTools.Data.Models.Listxml
[XmlAttribute("fixed_image")]
public string? FixedImage { get; set; }
/// <remarks>Numeric boolean</remarks>
/// <remarks>(0|1) "0"</remarks>
[XmlAttribute("mandatory")]
public string? Mandatory { get; set; }
public bool? Mandatory { get; set; }
[XmlAttribute("interface")]
public string? Interface { get; set; }

View File

@@ -10,13 +10,12 @@ namespace SabreTools.Data.Models.Listxml
[XmlAttribute("name")]
public string? Name { get; set; }
/// <remarks>Numeric?</remarks>
[Required]
[XmlAttribute("number")]
public string? Number { get; set; }
public long? Number { get; set; }
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("inverted")]
public string? Inverted { get; set; }
public bool? Inverted { get; set; }
}
}

View File

@@ -16,7 +16,7 @@ namespace SabreTools.Data.Models.Listxml
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("default")]
public string? Default { get; set; }
public bool? Default { get; set; }
[XmlElement("condition")]
public Condition? Condition { get; set; }

View File

@@ -1,5 +1,6 @@
using System.Xml;
using System.Xml.Serialization;
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.Listxml
{
@@ -23,20 +24,19 @@ namespace SabreTools.Data.Models.Listxml
[XmlAttribute("region")]
public string? Region { get; set; }
/// <remarks>Numeric?</remarks>
[XmlAttribute("index")]
public string? Index { get; set; }
public long? Index { get; set; }
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("writable")]
public string? Writable { get; set; }
public bool? Writable { get; set; }
/// <remarks>(baddump|nodump|good) "good"</remarks>
[XmlAttribute("status")]
public string? Status { get; set; }
public ItemStatus? Status { get; set; }
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("optional")]
public string? Optional { get; set; }
public bool? Optional { get; set; }
}
}

View File

@@ -1,5 +1,6 @@
using System.Xml;
using System.Xml.Serialization;
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.Listxml
{
@@ -12,55 +13,45 @@ namespace SabreTools.Data.Models.Listxml
/// <remarks>(raster|vector|lcd|svg|unknown)</remarks>
[Required]
[XmlAttribute("type")]
public string? Type { get; set; }
public DisplayType? Type { get; set; }
/// <remarks>(0|90|180|270)</remarks>
[XmlAttribute("rotate")]
public string? Rotate { get; set; }
public Rotation? Rotate { get; set; }
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("flipx")]
public string? FlipX { get; set; }
public bool? FlipX { get; set; }
/// <remarks>Numeric</remarks>
[XmlAttribute("width")]
public string? Width { get; set; }
public long? Width { get; set; }
/// <remarks>Numeric</remarks>
[XmlAttribute("height")]
public string? Height { get; set; }
public long? Height { get; set; }
/// <remarks>Numeric</remarks>
[Required]
[XmlAttribute("refresh")]
public string? Refresh { get; set; }
public double? Refresh { get; set; }
/// <remarks>Numeric</remarks>
[XmlAttribute("pixclock")]
public string? PixClock { get; set; }
public long? PixClock { get; set; }
/// <remarks>Numeric</remarks>
[XmlAttribute("htotal")]
public string? HTotal { get; set; }
public long? HTotal { get; set; }
/// <remarks>Numeric</remarks>
[XmlAttribute("hbend")]
public string? HBEnd { get; set; }
public long? HBEnd { get; set; }
/// <remarks>Numeric</remarks>
[XmlAttribute("hbstart")]
public string? HBStart { get; set; }
public long? HBStart { get; set; }
/// <remarks>Numeric</remarks>
[XmlAttribute("vtotal")]
public string? VTotal { get; set; }
public long? VTotal { get; set; }
/// <remarks>Numeric</remarks>
[XmlAttribute("vbend")]
public string? VBEnd { get; set; }
public long? VBEnd { get; set; }
/// <remarks>Numeric</remarks>
[XmlAttribute("vbstart")]
public string? VBStart { get; set; }
public long? VBStart { get; set; }
}
}

View File

@@ -1,5 +1,6 @@
using System.Xml;
using System.Xml.Serialization;
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.Listxml
{
@@ -9,15 +10,15 @@ namespace SabreTools.Data.Models.Listxml
/// <remarks>(good|imperfect|preliminary), (good|preliminary|test) in older versions</remarks>
[Required]
[XmlAttribute("status")]
public string? Status { get; set; }
public SupportStatus? Status { get; set; }
/// <remarks>(good|imperfect|preliminary), Only present in older versions</remarks>
[XmlAttribute("color")]
public string? Color { get; set; }
public SupportStatus? Color { get; set; }
/// <remarks>(good|imperfect|preliminary), Only present in older versions</remarks>
[XmlAttribute("sound")]
public string? Sound { get; set; }
public SupportStatus? Sound { get; set; }
/// <remarks>Only present in older versions</remarks>
[XmlAttribute("palettesize")]
@@ -26,32 +27,32 @@ namespace SabreTools.Data.Models.Listxml
/// <remarks>(good|imperfect|preliminary)</remarks>
[Required]
[XmlAttribute("emulation")]
public string? Emulation { get; set; }
public SupportStatus? Emulation { get; set; }
/// <remarks>(good|imperfect|preliminary)</remarks>
[Required]
[XmlAttribute("cocktail")]
public string? Cocktail { get; set; }
public SupportStatus? Cocktail { get; set; }
/// <remarks>(supported|unsupported)</remarks>
[Required]
[XmlAttribute("savestate")]
public string? SaveState { get; set; }
public Supported? SaveState { get; set; }
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("requiresartwork")]
public string? RequiresArtwork { get; set; }
public bool? RequiresArtwork { get; set; }
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("unofficial")]
public string? Unofficial { get; set; }
public bool? Unofficial { get; set; }
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("nosoundhardware")]
public string? NoSoundHardware { get; set; }
public bool? NoSoundHardware { get; set; }
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("incomplete")]
public string? Incomplete { get; set; }
public bool? Incomplete { get; set; }
}
}

View File

@@ -1,5 +1,6 @@
using System.Xml;
using System.Xml.Serialization;
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.Listxml
{
@@ -9,14 +10,14 @@ namespace SabreTools.Data.Models.Listxml
/// <remarks>(protection|timing|graphics|palette|sound|capture|camera|microphone|controls|keyboard|mouse|media|disk|printer|tape|punch|drum|rom|comms|lan|wan)</remarks>
[Required]
[XmlAttribute("type")]
public string? Type { get; set; }
public FeatureType? Type { get; set; }
/// <remarks>(unemulated|imperfect)</remarks>
[XmlAttribute("status")]
public string? Status { get; set; }
public FeatureStatus? Status { get; set; }
/// <remarks>(unemulated|imperfect)</remarks>
[XmlAttribute("overall")]
public string? Overall { get; set; }
public FeatureStatus? Overall { get; set; }
}
}

View File

@@ -1,5 +1,6 @@
using System.Xml;
using System.Xml.Serialization;
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.Listxml
{
@@ -18,19 +19,19 @@ namespace SabreTools.Data.Models.Listxml
/// <remarks>(yes|no) "no", Machine only</remarks>
[XmlAttribute("isbios")]
public string? IsBios { get; set; }
public bool? IsBios { get; set; }
/// <remarks>(yes|no) "no", Machine only</remarks>
[XmlAttribute("isdevice")]
public string? IsDevice { get; set; }
public bool? IsDevice { get; set; }
/// <remarks>(yes|no) "no", Machine only</remarks>
[XmlAttribute("ismechanical")]
public string? IsMechanical { get; set; }
public bool? IsMechanical { get; set; }
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("runnable")]
public string? Runnable { get; set; }
public Runnable? Runnable { get; set; }
[XmlAttribute("cloneof")]
public string? CloneOf { get; set; }

View File

@@ -8,28 +8,26 @@ namespace SabreTools.Data.Models.Listxml
{
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("service")]
public string? Service { get; set; }
public bool? Service { get; set; }
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("tilt")]
public string? Tilt { get; set; }
public bool? Tilt { get; set; }
/// <remarks>Numeric</remarks>
[Required]
[XmlAttribute("players")]
public string? Players { get; set; }
public long? Players { get; set; }
/// <remarks>Only present in older versions</remarks>
[XmlAttribute("control")]
public string? ControlAttr { get; set; }
/// <remarks>Only present in older versions, Numeric?</remarks>
/// <remarks>Only present in older versions</remarks>
[XmlAttribute("buttons")]
public string? Buttons { get; set; }
public long? Buttons { get; set; }
/// <remarks>Numeric?</remarks>
[XmlAttribute("coins")]
public string? Coins { get; set; }
public long? Coins { get; set; }
[XmlElement("control")]
public Control[]? Control { get; set; }

View File

@@ -11,7 +11,7 @@ namespace SabreTools.Data.Models.Listxml
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("debug")]
public string? Debug { get; set; }
public bool? Debug { get; set; }
[Required]
[XmlAttribute("mameconfig")]

View File

@@ -10,8 +10,9 @@ namespace SabreTools.Data.Models.Listxml
[XmlAttribute("name")]
public string? Name { get; set; }
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("default")]
public string? Default { get; set; }
public bool? Default { get; set; }
[XmlText]
public string? Content { get; set; }

View File

@@ -1,5 +1,6 @@
using System.Xml;
using System.Xml.Serialization;
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.Listxml
{
@@ -13,10 +14,9 @@ namespace SabreTools.Data.Models.Listxml
[XmlAttribute("bios")]
public string? Bios { get; set; }
/// <remarks>Numeric</remarks>
[Required]
[XmlAttribute("size")]
public string? Size { get; set; }
public long? Size { get; set; }
[XmlAttribute("crc")]
public string? CRC { get; set; }
@@ -36,18 +36,18 @@ namespace SabreTools.Data.Models.Listxml
/// <remarks>(baddump|nodump|good) "good"</remarks>
[XmlAttribute("status")]
public string? Status { get; set; }
public ItemStatus? Status { get; set; }
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("optional")]
public string? Optional { get; set; }
public bool? Optional { get; set; }
/// <remarks>(yes|no) "no", Only present in older versions</remarks>
[XmlAttribute("dispose")]
public string? Dispose { get; set; }
public bool? Dispose { get; set; }
/// <remarks>(yes|no) "no", Only present in older versions</remarks>
[XmlAttribute("soundonly")]
public string? SoundOnly { get; set; }
public bool? SoundOnly { get; set; }
}
}

View File

@@ -16,6 +16,6 @@ namespace SabreTools.Data.Models.Listxml
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("default")]
public string? Default { get; set; }
public bool? Default { get; set; }
}
}

View File

@@ -1,5 +1,6 @@
using System.Xml;
using System.Xml.Serialization;
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.Listxml
{
@@ -17,7 +18,7 @@ namespace SabreTools.Data.Models.Listxml
/// <remarks>(original|compatible)</remarks>
[Required]
[XmlAttribute("status")]
public string? Status { get; set; }
public SoftwareListStatus? Status { get; set; }
[XmlAttribute("filter")]
public string? Filter { get; set; }

View File

@@ -9,6 +9,6 @@ namespace SabreTools.Data.Models.Listxml
/// <remarks>Numeric</remarks>
[Required]
[XmlAttribute("channels")]
public string? Channels { get; set; }
public long? Channels { get; set; }
}
}

View File

@@ -1,5 +1,6 @@
using System.Xml;
using System.Xml.Serialization;
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.Listxml
{
@@ -9,31 +10,26 @@ namespace SabreTools.Data.Models.Listxml
/// <remarks>(raster|vector)</remarks>
[Required]
[XmlAttribute("screen")]
public string? Screen { get; set; }
public DisplayType? Screen { get; set; }
/// <remarks>(vertical|horizontal)</remarks>
[Required]
[XmlAttribute("orientation")]
public string? Orientation { get; set; }
public Rotation? Orientation { get; set; }
/// <remarks>Numeric</remarks>
[XmlAttribute("width")]
public string? Width { get; set; }
public long? Width { get; set; }
/// <remarks>Numeric</remarks>
[XmlAttribute("height")]
public string? Height { get; set; }
public long? Height { get; set; }
/// <remarks>Numeric</remarks>
[XmlAttribute("aspectx")]
public string? AspectX { get; set; }
public long? AspectX { get; set; }
/// <remarks>Numeric</remarks>
[XmlAttribute("aspecty")]
public string? AspectY { get; set; }
public long? AspectY { get; set; }
/// <remarks>Numeric</remarks>
[XmlAttribute("refresh")]
public string? Refresh { get; set; }
public double? Refresh { get; set; }
}
}

View File

@@ -16,6 +16,6 @@ namespace SabreTools.Data.Models.Logiqx
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("default")]
public string? Default { get; set; }
public bool? Default { get; set; }
}
}

View File

@@ -1,5 +1,6 @@
using System.Xml;
using System.Xml.Serialization;
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.Logiqx
{
@@ -11,14 +12,14 @@ namespace SabreTools.Data.Models.Logiqx
/// <remarks>(none|split|merged|nonmerged|fullmerged|device|full) "split"</remarks>
[XmlAttribute("forcemerging")]
public string? ForceMerging { get; set; }
public MergingFlag ForceMerging { get; set; }
/// <remarks>(obsolete|required|ignore) "obsolete"</remarks>
[XmlAttribute("forcenodump")]
public string? ForceNodump { get; set; }
public NodumpFlag ForceNodump { get; set; }
/// <remarks>(zip|unzip) "zip"</remarks>
[XmlAttribute("forcepacking")]
public string? ForcePacking { get; set; }
public PackingFlag ForcePacking { get; set; }
}
}

View File

@@ -11,7 +11,7 @@ namespace SabreTools.Data.Models.Logiqx
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("debug")]
public string? Debug { get; set; }
public bool? Debug { get; set; }
/// <remarks>No-Intro extension</remarks>
[XmlAttribute(Namespace = "http://www.w3.org/2001/XMLSchema-instance", AttributeName = "schemaLocation")]

View File

@@ -1,5 +1,6 @@
using System.Xml;
using System.Xml.Serialization;
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.Logiqx
{
@@ -21,7 +22,7 @@ namespace SabreTools.Data.Models.Logiqx
/// <remarks>(baddump|nodump|good|verified) "good"</remarks>
[XmlAttribute("status")]
public string? Status { get; set; }
public ItemStatus? Status { get; set; }
/// <remarks>MAME extension</remarks>
[XmlAttribute("region")]

View File

@@ -1,5 +1,6 @@
using System.Xml;
using System.Xml.Serialization;
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.Logiqx
{
@@ -9,37 +10,37 @@ namespace SabreTools.Data.Models.Logiqx
/// <remarks>(good|imperfect|preliminary)</remarks>
[Required]
[XmlAttribute("status")]
public string? Status { get; set; }
public SupportStatus? Status { get; set; }
/// <remarks>(good|imperfect|preliminary)</remarks>
[Required]
[XmlAttribute("emulation")]
public string? Emulation { get; set; }
public SupportStatus? Emulation { get; set; }
/// <remarks>(good|imperfect|preliminary)</remarks>
[Required]
[XmlAttribute("cocktail")]
public string? Cocktail { get; set; }
public SupportStatus? Cocktail { get; set; }
/// <remarks>(supported|unsupported)</remarks>
[Required]
[XmlAttribute("savestate")]
public string? SaveState { get; set; }
public Supported? SaveState { get; set; }
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("requiresartwork")]
public string? RequiresArtwork { get; set; }
public bool? RequiresArtwork { get; set; }
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("unofficial")]
public string? Unofficial { get; set; }
public bool? Unofficial { get; set; }
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("nosoundhardware")]
public string? NoSoundHardware { get; set; }
public bool? NoSoundHardware { get; set; }
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("incomplete")]
public string? Incomplete { get; set; }
public bool? Incomplete { get; set; }
}
}

View File

@@ -1,5 +1,6 @@
using System.Xml;
using System.Xml.Serialization;
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.Logiqx
{
@@ -17,15 +18,15 @@ namespace SabreTools.Data.Models.Logiqx
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("isbios")]
public string? IsBios { get; set; }
public bool? IsBios { get; set; }
/// <remarks>(yes|no) "no", MAME extension</remarks>
[XmlAttribute("isdevice")]
public string? IsDevice { get; set; }
public bool? IsDevice { get; set; }
/// <remarks>(yes|no) "no", MAME extension</remarks>
[XmlAttribute("ismechanical")]
public string? IsMechanical { get; set; }
public bool? IsMechanical { get; set; }
[XmlAttribute("cloneof")]
public string? CloneOf { get; set; }
@@ -52,7 +53,7 @@ namespace SabreTools.Data.Models.Logiqx
/// <remarks>(no|partial|yes) "no"</remarks>
[XmlAttribute("runnable")]
public string? Runnable { get; set; }
public Runnable? Runnable { get; set; }
[XmlElement("comment")]
public string[]? Comment { get; set; }

View File

@@ -52,6 +52,9 @@ namespace SabreTools.Data.Models.Logiqx
[XmlElement("type")]
public string? Type { get; set; }
[XmlElement("romvault")]
public RomVault? RomVault { get; set; }
[XmlElement("clrmamepro")]
public ClrMamePro? ClrMamePro { get; set; }

View File

@@ -22,6 +22,6 @@ namespace SabreTools.Data.Models.Logiqx
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("default")]
public string? Default { get; set; }
public bool? Default { get; set; }
}
}

View File

@@ -1,5 +1,6 @@
using System.Xml;
using System.Xml.Serialization;
using SabreTools.Data.Models.Metadata;
#pragma warning disable IDE1006 // Naming Styles
namespace SabreTools.Data.Models.Logiqx
@@ -13,7 +14,7 @@ namespace SabreTools.Data.Models.Logiqx
[Required]
[XmlAttribute("size")]
public string? Size { get; set; }
public long? Size { get; set; }
/// <remarks>Hash extension</remarks>
[XmlAttribute("crc16")]
@@ -77,7 +78,7 @@ namespace SabreTools.Data.Models.Logiqx
/// <remarks>(baddump|nodump|good|verified) "good"</remarks>
[XmlAttribute("status")]
public string? Status { get; set; }
public ItemStatus? Status { get; set; }
/// <remarks>No-Intro extension</remarks>
[XmlAttribute("serial")]
@@ -92,10 +93,10 @@ namespace SabreTools.Data.Models.Logiqx
/// <remarks>Boolean; RomVault extension</remarks>
[XmlAttribute("inverted")]
public string? Inverted { get; set; }
public bool? Inverted { get; set; }
/// <remarks>Boolean; RomVault extension</remarks>
[XmlAttribute("mia")]
public string? MIA { get; set; }
public bool? MIA { get; set; }
}
}

View File

@@ -1,5 +1,6 @@
using System.Xml;
using System.Xml.Serialization;
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.Logiqx
{
@@ -11,26 +12,26 @@ namespace SabreTools.Data.Models.Logiqx
/// <remarks>(none|split|merged|unmerged|fullmerged|device|full) "split"</remarks>
[XmlAttribute("rommode")]
public string? RomMode { get; set; }
public MergingFlag RomMode { get; set; }
/// <remarks>(none|split|merged|unmerged|fullmerged|device|full) "split"</remarks>
[XmlAttribute("biosmode")]
public string? BiosMode { get; set; }
public MergingFlag BiosMode { get; set; }
/// <remarks>(none|split|merged|unmerged|fullmerged|device|full) "merged"</remarks>
[XmlAttribute("samplemode")]
public string? SampleMode { get; set; }
public MergingFlag SampleMode { get; set; }
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("lockrommode")]
public string? LockRomMode { get; set; }
public bool? LockRomMode { get; set; }
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("lockbiosmode")]
public string? LockBiosMode { get; set; }
public bool? LockBiosMode { get; set; }
/// <remarks>(yes|no) "no"</remarks>
[XmlAttribute("locksamplemode")]
public string? LockSampleMode { get; set; }
public bool? LockSampleMode { get; set; }
}
}

View File

@@ -0,0 +1,25 @@
using System.Xml;
using System.Xml.Serialization;
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.Logiqx
{
[XmlRoot("romvault")]
public class RomVault
{
[XmlAttribute("header")]
public string? Header { get; set; }
/// <remarks>(none|split|merged|nonmerged|fullmerged|device|full) "split"</remarks>
[XmlAttribute("forcemerging")]
public MergingFlag ForceMerging { get; set; }
/// <remarks>(obsolete|required|ignore) "obsolete"</remarks>
[XmlAttribute("forcenodump")]
public NodumpFlag ForceNodump { get; set; }
/// <remarks>(zip|unzip) "zip"</remarks>
[XmlAttribute("forcepacking")]
public PackingFlag ForcePacking { get; set; }
}
}

View File

@@ -1,5 +1,6 @@
using System.Xml;
using System.Xml.Serialization;
using SabreTools.Data.Models.Metadata;
namespace SabreTools.Data.Models.Logiqx
{
@@ -17,7 +18,7 @@ namespace SabreTools.Data.Models.Logiqx
/// <remarks>(original|compatible)</remarks>
[Required]
[XmlAttribute("status")]
public string? Status { get; set; }
public SoftwareListStatus? Status { get; set; }
[XmlAttribute("filter")]
public string? Filter { get; set; }

View File

@@ -1,25 +1,60 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("adjuster"), XmlRoot("adjuster")]
public class Adjuster : DatItem
public class Adjuster : DatItem, ICloneable, IEquatable<Adjuster>
{
#region Keys
#region Properties
// <remarks>Condition</remarks>
[NoFilter]
public const string ConditionKey = "condition";
public Condition? Condition { get; set; }
/// <remarks>bool</remarks>
public const string DefaultKey = "default";
/// <remarks>(yes|no) "no"</remarks>
public bool? Default { get; set; }
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
#endregion
public Adjuster() => Type = ItemType.Adjuster;
public Adjuster() => ItemType = ItemType.Adjuster;
/// <inheritdoc/>
public object Clone()
{
var obj = new Adjuster();
obj.Condition = Condition?.Clone() as Condition;
obj.Default = Default;
obj.Name = Name;
return obj;
}
/// <inheritdoc/>
public bool Equals(Adjuster? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if (Default != other.Default)
return false;
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
// Sub-items
if ((Condition is null) ^ (other.Condition is null))
return false;
else if (Condition is not null && other.Condition is not null && Condition.Equals(other.Condition))
return false;
return true;
}
}
}

View File

@@ -1,18 +1,44 @@
using System.Xml.Serialization;
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("analog"), XmlRoot("analog")]
public class Analog : DatItem
public class Analog : DatItem, ICloneable, IEquatable<Analog>
{
#region Keys
#region Properties
/// <remarks>string</remarks>
public const string MaskKey = "mask";
public string? Mask { get; set; }
#endregion
public Analog() => Type = ItemType.Analog;
public Analog() => ItemType = ItemType.Analog;
/// <inheritdoc/>
public object Clone()
{
var obj = new Analog();
obj.Mask = Mask;
return obj;
}
/// <inheritdoc/>
public bool Equals(Analog? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((Mask is null) ^ (other.Mask is null))
return false;
else if (Mask is not null && !Mask.Equals(other.Mask, StringComparison.OrdinalIgnoreCase))
return false;
return true;
}
}
}

View File

@@ -1,114 +1,310 @@
using System.Xml.Serialization;
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("archive"), XmlRoot("archive")]
public class Archive : DatItem
public class Archive : DatItem, ICloneable, IEquatable<Archive>
{
#region Keys
#region Properties
/// <remarks>string, No-Intro DB extension</remarks>
public const string NumberKey = "number";
/// <remarks>No-Intro DB extension</remarks>
public string? Additional { get; set; }
/// <remarks>string, No-Intro DB extension</remarks>
public const string CloneKey = "clone";
/// <remarks>(0|1) "0", No-Intro DB extension</remarks>
public bool? Adult { get; set; }
/// <remarks>string, No-Intro DB extension</remarks>
public const string RegParentKey = "regparent";
/// <remarks>(0|1) "0", No-Intro DB extension</remarks>
public bool? Alt { get; set; }
/// <remarks>string, No-Intro DB extension</remarks>
public const string MergeOfKey = "mergeof";
/// <remarks>(0|1) "0", No-Intro DB extension</remarks>
public bool? Bios { get; set; }
/// <remarks>string, No-Intro DB extension</remarks>
public const string MergeNameKey = "mergename";
/// <remarks>No-Intro DB extension</remarks>
public string? Categories { get; set; }
/// <remarks>string</remarks>
public const string NameKey = "name";
/// <remarks>No-Intro DB extension</remarks>
public string? CloneTag { get; set; }
/// <remarks>string, No-Intro DB extension</remarks>
public const string NameAltKey = "name_alt";
/// <remarks>(0|1) "0", No-Intro DB extension</remarks>
public bool? Complete { get; set; }
/// <remarks>string, No-Intro DB extension</remarks>
public const string RegionKey = "region";
/// <remarks>(0|1) "0", No-Intro DB extension</remarks>
public bool? Dat { get; set; }
/// <remarks>string, No-Intro DB extension</remarks>
public const string LanguagesKey = "languages";
/// <remarks>No-Intro DB extension</remarks>
public string? DatterNote { get; set; }
/// <remarks>byte, No-Intro DB extension</remarks>
public const string ShowLangKey = "showlang";
/// <remarks>No-Intro DB extension</remarks>
public string? Description { get; set; }
/// <remarks>string, No-Intro DB extension</remarks>
public const string LangCheckedKey = "langchecked";
/// <remarks>No-Intro DB extension</remarks>
public string? DevStatus { get; set; }
/// <remarks>string, No-Intro DB extension</remarks>
public const string Version1Key = "version1";
/// <remarks>No-Intro DB extension</remarks>
public string? GameId1 { get; set; }
/// <remarks>string, No-Intro DB extension</remarks>
public const string Version2Key = "version2";
/// <remarks>No-Intro DB extension</remarks>
public string? GameId2 { get; set; }
/// <remarks>string, No-Intro DB extension</remarks>
public const string DevStatusKey = "devstatus";
/// <remarks>No-Intro DB extension</remarks>
public string? LangChecked { get; set; }
/// <remarks>string, No-Intro DB extension</remarks>
public const string AdditionalKey = "additional";
/// <remarks>No-Intro DB extension</remarks>
public string? Languages { get; set; }
/// <remarks>string, No-Intro DB extension</remarks>
public const string Special1Key = "special1";
/// <remarks>(0|1) "0", No-Intro DB extension</remarks>
public bool? Licensed { get; set; }
/// <remarks>string, No-Intro DB extension</remarks>
public const string Special2Key = "special2";
/// <remarks>(0|1) "0", No-Intro DB extension</remarks>
public bool? Listed { get; set; }
/// <remarks>byte, No-Intro DB extension</remarks>
public const string AltKey = "alt";
/// <remarks>No-Intro DB extension</remarks>
public string? MergeOf { get; set; }
/// <remarks>string, No-Intro DB extension</remarks>
public const string GameId1Key = "gameid1";
/// <remarks>No-Intro DB extension</remarks>
public string? MergeName { get; set; }
/// <remarks>string, No-Intro DB extension</remarks>
public const string GameId2Key = "gameid2";
public string? Name { get; set; }
/// <remarks>string, No-Intro DB extension</remarks>
public const string DescriptionKey = "description";
/// <remarks>No-Intro DB extension</remarks>
public string? NameAlt { get; set; }
/// <remarks>byte, No-Intro DB extension</remarks>
public const string BiosKey = "bios";
/// <remarks>No-Intro DB extension</remarks>
public string? Number { get; set; }
/// <remarks>byte, No-Intro DB extension</remarks>
public const string LicensedKey = "licensed";
/// <remarks>(0|1) "0", No-Intro DB extension</remarks>
public bool? Physical { get; set; }
/// <remarks>byte, No-Intro DB extension</remarks>
public const string PirateKey = "pirate";
/// <remarks>(0|1) "0", No-Intro DB extension</remarks>
public bool? Pirate { get; set; }
/// <remarks>byte, No-Intro DB extension</remarks>
public const string PhysicalKey = "physical";
/// <remarks>(0|1) "0", No-Intro DB extension</remarks>
public bool? Private { get; set; }
/// <remarks>byte, No-Intro DB extension</remarks>
public const string CompleteKey = "complete";
/// <remarks>No-Intro DB extension</remarks>
public string? Region { get; set; }
/// <remarks>byte, No-Intro DB extension</remarks>
public const string AdultKey = "adult";
/// <remarks>No-Intro DB extension</remarks>
public string? RegParent { get; set; }
/// <remarks>byte, No-Intro DB extension</remarks>
public const string DatKey = "dat";
/// <remarks>(0|1) "0", No-Intro DB extension</remarks>
public bool? ShowLang { get; set; }
/// <remarks>byte, No-Intro DB extension</remarks>
public const string ListedKey = "listed";
/// <remarks>No-Intro DB extension</remarks>
public string? Special1 { get; set; }
/// <remarks>byte, No-Intro DB extension</remarks>
public const string PrivateKey = "private";
/// <remarks>No-Intro DB extension</remarks>
public string? Special2 { get; set; }
/// <remarks>string, No-Intro DB extension</remarks>
public const string StickyNoteKey = "stickynote";
/// <remarks>No-Intro DB extension</remarks>
public string? StickyNote { get; set; }
/// <remarks>string, No-Intro DB extension</remarks>
public const string DatterNoteKey = "datternote";
/// <remarks>No-Intro DB extension</remarks>
public string? Version1 { get; set; }
/// <remarks>string, No-Intro DB extension</remarks>
public const string CategoriesKey = "categories";
/// <remarks>No-Intro DB extension</remarks>
public string? Version2 { get; set; }
#endregion
public Archive() => Type = ItemType.Archive;
public Archive() => ItemType = ItemType.Archive;
/// <inheritdoc/>
public object Clone()
{
var obj = new Archive();
obj.Additional = Additional;
obj.Adult = Adult;
obj.Alt = Alt;
obj.Bios = Bios;
obj.Categories = Categories;
obj.CloneTag = CloneTag;
obj.Complete = Complete;
obj.Dat = Dat;
obj.DatterNote = DatterNote;
obj.Description = Description;
obj.DevStatus = DevStatus;
obj.GameId1 = GameId1;
obj.GameId2 = GameId2;
obj.LangChecked = LangChecked;
obj.Languages = Languages;
obj.Licensed = Licensed;
obj.Listed = Listed;
obj.MergeOf = MergeOf;
obj.MergeName = MergeName;
obj.Name = Name;
obj.NameAlt = NameAlt;
obj.Number = Number;
obj.Physical = Physical;
obj.Pirate = Pirate;
obj.Private = Private;
obj.Region = Region;
obj.RegParent = RegParent;
obj.ShowLang = ShowLang;
obj.Special1 = Special1;
obj.Special2 = Special2;
obj.StickyNote = StickyNote;
obj.Version1 = Version1;
obj.Version2 = Version2;
return obj;
}
/// <inheritdoc/>
public bool Equals(Archive? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((Additional is null) ^ (other.Additional is null))
return false;
else if (Additional is not null && !Additional.Equals(other.Additional, StringComparison.OrdinalIgnoreCase))
return false;
if (Adult != other.Adult)
return false;
if (Alt != other.Alt)
return false;
if (Bios != other.Bios)
return false;
if ((Categories is null) ^ (other.Categories is null))
return false;
else if (Categories is not null && !Categories.Equals(other.Categories, StringComparison.OrdinalIgnoreCase))
return false;
if ((CloneTag is null) ^ (other.CloneTag is null))
return false;
else if (CloneTag is not null && !CloneTag.Equals(other.CloneTag, StringComparison.OrdinalIgnoreCase))
return false;
if (Complete != other.Complete)
return false;
if (Dat != other.Dat)
return false;
if ((DatterNote is null) ^ (other.DatterNote is null))
return false;
else if (DatterNote is not null && !DatterNote.Equals(other.DatterNote, StringComparison.OrdinalIgnoreCase))
return false;
if ((Description is null) ^ (other.Description is null))
return false;
else if (Description is not null && !Description.Equals(other.Description, StringComparison.OrdinalIgnoreCase))
return false;
if ((DevStatus is null) ^ (other.DevStatus is null))
return false;
else if (DevStatus is not null && !DevStatus.Equals(other.DevStatus, StringComparison.OrdinalIgnoreCase))
return false;
if ((GameId1 is null) ^ (other.GameId1 is null))
return false;
else if (GameId1 is not null && !GameId1.Equals(other.GameId1, StringComparison.OrdinalIgnoreCase))
return false;
if ((GameId2 is null) ^ (other.GameId2 is null))
return false;
else if (GameId2 is not null && !GameId2.Equals(other.GameId2, StringComparison.OrdinalIgnoreCase))
return false;
if ((LangChecked is null) ^ (other.LangChecked is null))
return false;
else if (LangChecked is not null && !LangChecked.Equals(other.LangChecked, StringComparison.OrdinalIgnoreCase))
return false;
if ((Languages is null) ^ (other.Languages is null))
return false;
else if (Languages is not null && !Languages.Equals(other.Languages, StringComparison.OrdinalIgnoreCase))
return false;
if (Licensed != other.Licensed)
return false;
if (Listed != other.Listed)
return false;
if ((MergeOf is null) ^ (other.MergeOf is null))
return false;
else if (MergeOf is not null && !MergeOf.Equals(other.MergeOf, StringComparison.OrdinalIgnoreCase))
return false;
if ((MergeName is null) ^ (other.MergeName is null))
return false;
else if (MergeName is not null && !MergeName.Equals(other.MergeName, StringComparison.OrdinalIgnoreCase))
return false;
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
if ((NameAlt is null) ^ (other.NameAlt is null))
return false;
else if (NameAlt is not null && !NameAlt.Equals(other.NameAlt, StringComparison.OrdinalIgnoreCase))
return false;
if ((Number is null) ^ (other.Number is null))
return false;
else if (Number is not null && !Number.Equals(other.Number, StringComparison.OrdinalIgnoreCase))
return false;
if (Physical != other.Physical)
return false;
if (Pirate != other.Pirate)
return false;
if (Private != other.Private)
return false;
if ((Region is null) ^ (other.Region is null))
return false;
else if (Region is not null && !Region.Equals(other.Region, StringComparison.OrdinalIgnoreCase))
return false;
if ((RegParent is null) ^ (other.RegParent is null))
return false;
else if (RegParent is not null && !RegParent.Equals(other.RegParent, StringComparison.OrdinalIgnoreCase))
return false;
if (ShowLang != other.ShowLang)
return false;
if ((Special1 is null) ^ (other.Special1 is null))
return false;
else if (Special1 is not null && !Special1.Equals(other.Special1, StringComparison.OrdinalIgnoreCase))
return false;
if ((Special2 is null) ^ (other.Special2 is null))
return false;
else if (Special2 is not null && !Special2.Equals(other.Special2, StringComparison.OrdinalIgnoreCase))
return false;
if ((StickyNote is null) ^ (other.StickyNote is null))
return false;
else if (StickyNote is not null && !StickyNote.Equals(other.StickyNote, StringComparison.OrdinalIgnoreCase))
return false;
if ((Version1 is null) ^ (other.Version1 is null))
return false;
else if (Version1 is not null && !Version1.Equals(other.Version1, StringComparison.OrdinalIgnoreCase))
return false;
if ((Version2 is null) ^ (other.Version2 is null))
return false;
else if (Version2 is not null && !Version2.Equals(other.Version2, StringComparison.OrdinalIgnoreCase))
return false;
return true;
}
}
}

View File

@@ -1,24 +1,59 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("biosset"), XmlRoot("biosset")]
public class BiosSet : DatItem
public class BiosSet : DatItem, ICloneable, IEquatable<BiosSet>
{
#region Keys
#region Properties
/// <remarks>bool</remarks>
public const string DefaultKey = "default";
/// <remarks>(yes|no) "no"</remarks>
public bool? Default { get; set; }
/// <remarks>string</remarks>
public const string DescriptionKey = "description";
public string? Description { get; set; }
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
#endregion
public BiosSet() => Type = ItemType.BiosSet;
public BiosSet() => ItemType = ItemType.BiosSet;
/// <inheritdoc/>
public object Clone()
{
var obj = new BiosSet();
obj.Default = Default;
obj.Description = Description;
obj.Name = Name;
return obj;
}
/// <inheritdoc/>
public bool Equals(BiosSet? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if (Default != other.Default)
return false;
if ((Description is null) ^ (other.Description is null))
return false;
else if (Description is not null && !Description.Equals(other.Description, StringComparison.OrdinalIgnoreCase))
return false;
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
return true;
}
}
}

View File

@@ -1,11 +1,18 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("blank"), XmlRoot("blank")]
public class Blank : DatItem
public class Blank : DatItem, ICloneable, IEquatable<Blank>
{
public Blank() => Type = ItemType.Blank;
public Blank() => ItemType = ItemType.Blank;
/// <inheritdoc/>
public object Clone() => new Blank();
/// <inheritdoc/>
public bool Equals(Blank? other) => other is not null;
}
}

View File

@@ -1,33 +1,80 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("chip"), XmlRoot("chip")]
public class Chip : DatItem
public class Chip : DatItem, ICloneable, IEquatable<Chip>
{
#region Keys
/// <remarks>long</remarks>
public const string ClockKey = "clock";
/// <remarks>string</remarks>
public const string FlagsKey = "flags";
/// <remarks>string</remarks>
public const string NameKey = "name";
/// <remarks>(yes|no) "no"</remarks>
public const string SoundOnlyKey = "soundonly";
/// <remarks>string</remarks>
public const string TagKey = "tag";
#region Properties
/// <remarks>(cpu|audio)</remarks>
public const string ChipTypeKey = "type";
public ChipType? ChipType { get; set; }
public long? Clock { get; set; }
public string? Flags { get; set; }
public string? Name { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public bool? SoundOnly { get; set; }
public string? Tag { get; set; }
#endregion
public Chip() => Type = ItemType.Chip;
public Chip() => ItemType = ItemType.Chip;
/// <inheritdoc/>
public object Clone()
{
var obj = new Chip();
obj.ChipType = ChipType;
obj.Clock = Clock;
obj.Flags = Flags;
obj.Name = Name;
obj.SoundOnly = SoundOnly;
obj.Tag = Tag;
return obj;
}
/// <inheritdoc/>
public bool Equals(Chip? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if (ChipType != other.ChipType)
return false;
if (Clock != other.Clock)
return false;
if ((Flags is null) ^ (other.Flags is null))
return false;
else if (Flags is not null && !Flags.Equals(other.Flags, StringComparison.OrdinalIgnoreCase))
return false;
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
if (SoundOnly != other.SoundOnly)
return false;
if ((Tag is null) ^ (other.Tag is null))
return false;
else if (Tag is not null && !Tag.Equals(other.Tag, StringComparison.OrdinalIgnoreCase))
return false;
return true;
}
}
}

View File

@@ -1,27 +1,67 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("condition"), XmlRoot("condition")]
public class Condition : DatItem
public class Condition : DatItem, ICloneable, IEquatable<Condition>
{
#region Keys
#region Properties
/// <remarks>string</remarks>
public const string ValueKey = "clock";
/// <remarks>string</remarks>
public const string MaskKey = "mask";
public string? Mask { get; set; }
/// <remarks>(eq|ne|gt|le|lt|ge)</remarks>
public const string RelationKey = "relation";
public Relation? Relation { get; set; }
/// <remarks>string</remarks>
public const string TagKey = "tag";
public string? Tag { get; set; }
public string? Value { get; set; }
#endregion
public Condition() => Type = ItemType.Condition;
public Condition() => ItemType = ItemType.Condition;
/// <inheritdoc/>
public object Clone()
{
var obj = new Condition();
obj.Mask = Mask;
obj.Relation = Relation;
obj.Tag = Tag;
obj.Value = Value;
return obj;
}
/// <inheritdoc/>
public bool Equals(Condition? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((Mask is null) ^ (other.Mask is null))
return false;
else if (Mask is not null && !Mask.Equals(other.Mask, StringComparison.OrdinalIgnoreCase))
return false;
if (Relation != other.Relation)
return false;
if ((Tag is null) ^ (other.Tag is null))
return false;
else if (Tag is not null && !Tag.Equals(other.Tag, StringComparison.OrdinalIgnoreCase))
return false;
if ((Value is null) ^ (other.Value is null))
return false;
else if (Value is not null && !Value.Equals(other.Value, StringComparison.OrdinalIgnoreCase))
return false;
return true;
}
}
}

View File

@@ -1,24 +1,57 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("conflocation"), XmlRoot("conflocation")]
public class ConfLocation : DatItem
public class ConfLocation : DatItem, ICloneable, IEquatable<ConfLocation>
{
#region Keys
#region Properties
/// <remarks>(yes|no) "no"</remarks>
public const string InvertedKey = "inverted";
public bool? Inverted { get; set; }
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
/// <remarks>string, possibly long</remarks>
public const string NumberKey = "number";
public long? Number { get; set; }
#endregion
public ConfLocation() => Type = ItemType.ConfLocation;
public ConfLocation() => ItemType = ItemType.ConfLocation;
/// <inheritdoc/>
public object Clone()
{
var obj = new ConfLocation();
obj.Inverted = Inverted;
obj.Name = Name;
obj.Number = Number;
return obj;
}
/// <inheritdoc/>
public bool Equals(ConfLocation? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if (Inverted != other.Inverted)
return false;
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
if (Number != other.Number)
return false;
return true;
}
}
}

View File

@@ -1,28 +1,68 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("confsetting"), XmlRoot("confsetting")]
public class ConfSetting : DatItem
public class ConfSetting : DatItem, ICloneable, IEquatable<ConfSetting>
{
#region Keys
#region Properties
/// <remarks>Condition</remarks>
[NoFilter]
public const string ConditionKey = "condition";
public Condition? Condition { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string DefaultKey = "default";
public bool? Default { get; set; }
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
/// <remarks>string</remarks>
public const string ValueKey = "value";
public string? Value { get; set; }
#endregion
public ConfSetting() => Type = ItemType.ConfSetting;
public ConfSetting() => ItemType = ItemType.ConfSetting;
/// <inheritdoc/>
public object Clone()
{
var obj = new ConfSetting();
obj.Condition = Condition?.Clone() as Condition;
obj.Default = Default;
obj.Name = Name;
obj.Value = Value;
return obj;
}
/// <inheritdoc/>
public bool Equals(ConfSetting? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if (Default != other.Default)
return false;
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
if ((Value is null) ^ (other.Value is null))
return false;
else if (Value is not null && !Value.Equals(other.Value, StringComparison.OrdinalIgnoreCase))
return false;
// Sub-items
if ((Condition is null) ^ (other.Condition is null))
return false;
else if (Condition is not null && other.Condition is not null && Condition.Equals(other.Condition))
return false;
return true;
}
}
}

View File

@@ -1,36 +1,79 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("configuration"), XmlRoot("configuration")]
public class Configuration : DatItem
public class Configuration : DatItem, ICloneable, IEquatable<Configuration>
{
#region Keys
#region Properties
/// <remarks>Condition</remarks>
[NoFilter]
public const string ConditionKey = "condition";
public Condition? Condition { get; set; }
/// <remarks>ConfLocation[]</remarks>
[NoFilter]
public const string ConfLocationKey = "conflocation";
public ConfLocation[]? ConfLocation { get; set; }
/// <remarks>ConfSetting[]</remarks>
[NoFilter]
public const string ConfSettingKey = "confsetting";
public ConfSetting[]? ConfSetting { get; set; }
/// <remarks>string</remarks>
public const string MaskKey = "mask";
public string? Mask { get; set; }
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
/// <remarks>string</remarks>
public const string TagKey = "tag";
public string? Tag { get; set; }
#endregion
public Configuration() => Type = ItemType.Configuration;
public Configuration() => ItemType = ItemType.Configuration;
/// <inheritdoc/>
public object Clone()
{
var obj = new Configuration();
obj.Condition = Condition?.Clone() as Condition;
if (ConfLocation is not null)
obj.ConfLocation = Array.ConvertAll(ConfLocation, i => (ConfLocation)i.Clone());
if (ConfSetting is not null)
obj.ConfSetting = Array.ConvertAll(ConfSetting, i => (ConfSetting)i.Clone());
obj.Mask = Mask;
obj.Name = Name;
obj.Tag = Tag;
return obj;
}
/// <inheritdoc/>
public bool Equals(Configuration? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((Mask is null) ^ (other.Mask is null))
return false;
else if (Mask is not null && !Mask.Equals(other.Mask, StringComparison.OrdinalIgnoreCase))
return false;
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
if ((Tag is null) ^ (other.Tag is null))
return false;
else if (Tag is not null && !Tag.Equals(other.Tag, StringComparison.OrdinalIgnoreCase))
return false;
// Sub-items
if ((Condition is null) ^ (other.Condition is null))
return false;
else if (Condition is not null && other.Condition is not null && Condition.Equals(other.Condition))
return false;
// TODO: Figure out how to properly check arrays
return true;
}
}
}

View File

@@ -1,51 +1,116 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("control"), XmlRoot("control")]
public class Control : DatItem
public class Control : DatItem, ICloneable, IEquatable<Control>
{
#region Keys
#region Properties
/// <remarks>long</remarks>
public const string ButtonsKey = "buttons";
/// <remarks>long</remarks>
public const string KeyDeltaKey = "keydelta";
/// <remarks>long</remarks>
public const string MaximumKey = "maximum";
/// <remarks>long</remarks>
public const string MinimumKey = "minimum";
/// <remarks>long</remarks>
public const string PlayerKey = "player";
/// <remarks>long</remarks>
public const string ReqButtonsKey = "reqbuttons";
/// <remarks>(yes|no) "no"</remarks>
public const string ReverseKey = "reverse";
/// <remarks>long</remarks>
public const string SensitivityKey = "sensitivity";
public long? Buttons { get; set; }
/// <remarks>(joy|stick|paddle|pedal|lightgun|positional|dial|trackball|mouse|only_buttons|keypad|keyboard|mahjong|hanafuda|gambling)</remarks>
public const string ControlTypeKey = "type";
public ControlType? ControlType { get; set; }
/// <remarks>string, possibly long</remarks>
public const string WaysKey = "ways";
public long? KeyDelta { get; set; }
/// <remarks>string, possibly long</remarks>
public const string Ways2Key = "ways2";
public long? Maximum { get; set; }
/// <remarks>string, possibly long</remarks>
public const string Ways3Key = "ways3";
public long? Minimum { get; set; }
public long? Player { get; set; }
public long? ReqButtons { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public bool? Reverse { get; set; }
public long? Sensitivity { get; set; }
public string? Ways { get; set; }
public string? Ways2 { get; set; }
public string? Ways3 { get; set; }
#endregion
public Control() => Type = ItemType.Control;
public Control() => ItemType = ItemType.Control;
/// <inheritdoc/>
public object Clone()
{
var obj = new Control();
obj.Buttons = Buttons;
obj.ControlType = ControlType;
obj.KeyDelta = KeyDelta;
obj.Maximum = Maximum;
obj.Minimum = Minimum;
obj.Player = Player;
obj.ReqButtons = ReqButtons;
obj.Reverse = Reverse;
obj.Sensitivity = Sensitivity;
obj.Ways = Ways;
obj.Ways2 = Ways2;
obj.Ways3 = Ways3;
return obj;
}
/// <inheritdoc/>
public bool Equals(Control? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if (Buttons != other.Buttons)
return false;
if (ControlType != other.ControlType)
return false;
if (KeyDelta != other.KeyDelta)
return false;
if (Maximum != other.Maximum)
return false;
if (Minimum != other.Minimum)
return false;
if (Player != other.Player)
return false;
if (ReqButtons != other.ReqButtons)
return false;
if (Reverse != other.Reverse)
return false;
if (Sensitivity != other.Sensitivity)
return false;
if ((Ways is null) ^ (other.Ways is null))
return false;
else if (Ways is not null && !Ways.Equals(other.Ways, StringComparison.OrdinalIgnoreCase))
return false;
if ((Ways2 is null) ^ (other.Ways2 is null))
return false;
else if (Ways2 is not null && !Ways2.Equals(other.Ways2, StringComparison.OrdinalIgnoreCase))
return false;
if ((Ways3 is null) ^ (other.Ways3 is null))
return false;
else if (Ways3 is not null && !Ways3.Equals(other.Ways3, StringComparison.OrdinalIgnoreCase))
return false;
return true;
}
}
}

View File

@@ -6,22 +6,12 @@ namespace SabreTools.Data.Models.Metadata
/// <summary>
/// Format-agnostic representation of item data
/// </summary>
public class DatItem : DictionaryBase
public abstract class DatItem
{
#region Common Keys
public const string TypeKey = "_type";
#endregion
/// <summary>
/// Quick accessor to item type, if it exists
/// Quick accessor to item type
/// </summary>
[JsonProperty("itemtype", DefaultValueHandling = DefaultValueHandling.Ignore), XmlElement("itemtype")]
public ItemType? Type
{
get => ContainsKey(TypeKey) ? this[TypeKey] as ItemType? : null;
set => this[TypeKey] = value;
}
public ItemType ItemType { get; protected set; }
}
}

View File

@@ -1,31 +1,71 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("dataarea"), XmlRoot("dataarea")]
public class DataArea : DatItem
public class DataArea : DatItem, ICloneable, IEquatable<DataArea>
{
#region Keys
#region Properties
/// <remarks>(big|little) "little"</remarks>
public const string EndiannessKey = "endianness";
public Endianness? Endianness { get; set; }
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
/// <remarks>Rom[]</remarks>
[NoFilter]
public const string RomKey = "rom";
public Rom[]? Rom { get; set; }
/// <remarks>long</remarks>
public const string SizeKey = "size";
public long? Size { get; set; }
/// <remarks>(8|16|32|64) "8"</remarks>
public const string WidthKey = "width";
public Width? Width { get; set; }
#endregion
public DataArea() => Type = ItemType.DataArea;
public DataArea() => ItemType = ItemType.DataArea;
/// <inheritdoc/>
public object Clone()
{
var obj = new DataArea();
obj.Endianness = Endianness;
obj.Name = Name;
if (Rom is not null)
obj.Rom = Array.ConvertAll(Rom, i => (Rom)i.Clone());
obj.Size = Size;
obj.Width = Width;
return obj;
}
/// <inheritdoc/>
public bool Equals(DataArea? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if (Endianness != other.Endianness)
return false;
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
if (Size != other.Size)
return false;
if (Width != other.Width)
return false;
// Sub-items
// TODO: Figure out how to properly check arrays
return true;
}
}
}

View File

@@ -1,38 +1,89 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("device"), XmlRoot("device")]
public class Device : DatItem
public class Device : DatItem, ICloneable, IEquatable<Device>
{
#region Keys
/// <remarks>Extension[]</remarks>
[NoFilter]
public const string ExtensionKey = "extension";
/// <remarks>string</remarks>
public const string FixedImageKey = "fixed_image";
/// <remarks>Instance</remarks>
[NoFilter]
public const string InstanceKey = "instance";
/// <remarks>string</remarks>
public const string InterfaceKey = "interface";
/// <remarks>(0|1) "0"</remarks>
public const string MandatoryKey = "mandatory";
/// <remarks>string</remarks>
public const string TagKey = "tag";
#region Properties
/// <remarks>(unknown|cartridge|floppydisk|harddisk|cylinder|cassette|punchcard|punchtape|printout|serial|parallel|snapshot|quickload|memcard|cdrom|magtape|romimage|midiin|midiout|picture|vidfile)</remarks>
public const string DeviceTypeKey = "type";
public DeviceType? DeviceType { get; set; }
public Extension[]? Extension { get; set; }
public string? FixedImage { get; set; }
public Instance? Instance { get; set; }
public string? Interface { get; set; }
/// <remarks>(0|1) "0"</remarks>
public bool? Mandatory { get; set; }
public string? Tag { get; set; }
#endregion
public Device() => Type = ItemType.Device;
public Device() => ItemType = ItemType.Device;
/// <inheritdoc/>
public object Clone()
{
var obj = new Device();
obj.DeviceType = DeviceType;
if (Extension is not null)
obj.Extension = Array.ConvertAll(Extension, i => (Extension)i.Clone());
obj.FixedImage = FixedImage;
obj.Instance = Instance?.Clone() as Instance;
obj.Interface = Interface;
obj.Mandatory = Mandatory;
obj.Tag = Tag;
return obj;
}
/// <inheritdoc/>
public bool Equals(Device? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if (DeviceType != other.DeviceType)
return false;
if ((FixedImage is null) ^ (other.FixedImage is null))
return false;
else if (FixedImage is not null && !FixedImage.Equals(other.FixedImage, StringComparison.OrdinalIgnoreCase))
return false;
if ((Interface is null) ^ (other.Interface is null))
return false;
else if (Interface is not null && !Interface.Equals(other.Interface, StringComparison.OrdinalIgnoreCase))
return false;
if (Mandatory != other.Mandatory)
return false;
if ((Tag is null) ^ (other.Tag is null))
return false;
else if (Tag is not null && !Tag.Equals(other.Tag, StringComparison.OrdinalIgnoreCase))
return false;
// Sub-items
if ((Instance is null) ^ (other.Instance is null))
return false;
else if (Instance is not null && other.Instance is not null && Instance.Equals(other.Instance))
return false;
// TODO: Figure out how to properly check arrays
return true;
}
}
}

View File

@@ -1,18 +1,44 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("device_ref"), XmlRoot("device_ref")]
public class DeviceRef : DatItem
public class DeviceRef : DatItem, ICloneable, IEquatable<DeviceRef>
{
#region Keys
#region Properties
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
#endregion
public DeviceRef() => Type = ItemType.DeviceRef;
public DeviceRef() => ItemType = ItemType.DeviceRef;
/// <inheritdoc/>
public object Clone()
{
var obj = new DeviceRef();
obj.Name = Name;
return obj;
}
/// <inheritdoc/>
public bool Equals(DeviceRef? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
return true;
}
}
}

View File

@@ -1,259 +0,0 @@
using System.Collections.Generic;
namespace SabreTools.Data.Models.Metadata
{
/// <summary>
/// Specialized dictionary base for item types
/// </summary>
public abstract class DictionaryBase : Dictionary<string, object?>
{
#region Read
/// <summary>
/// Read a key as the specified type, returning null on error
/// </summary>
public T? Read<T>(string key)
{
try
{
if (!ValidateReadKey(key))
return default;
if (this[key] is not T)
return default;
return (T?)this[key];
}
catch
{
return default;
}
}
/// <summary>
/// Read a key as a bool, returning null on error
/// </summary>
public bool? ReadBool(string key)
{
if (!ValidateReadKey(key))
return null;
bool? asBool = Read<bool?>(key);
if (asBool is not null)
return asBool;
string? asString = Read<string>(key);
return asString?.ToLowerInvariant() switch
{
"true" or "yes" => true,
"false" or "no" => false,
_ => null,
};
}
/// <summary>
/// Read a key as a double, returning null on error
/// </summary>
public double? ReadDouble(string key)
{
if (!ValidateReadKey(key))
return null;
double? asDouble = Read<double?>(key);
if (asDouble is not null)
return asDouble;
float? asFloat = Read<float?>(key);
if (asFloat is not null)
return asFloat;
#if NET5_0_OR_GREATER
System.Half? asHalf = Read<System.Half?>(key);
if (asHalf is not null)
return (double?)asHalf;
#endif
string? asString = Read<string>(key);
if (asString is not null && double.TryParse(asString, out double asStringDouble))
return asStringDouble;
return null;
}
/// <summary>
/// Read a key as a long, returning null on error
/// </summary>
/// <remarks>TODO: Add logic to convert SI suffixes and hex</remarks>
public long? ReadLong(string key)
{
if (!ValidateReadKey(key))
return null;
long? asLong = Read<long?>(key);
if (asLong is not null)
return asLong;
int? asInt = Read<int?>(key);
if (asInt is not null)
return asInt;
short? asShort = Read<short?>(key);
if (asShort is not null)
return asShort;
string? asString = Read<string>(key);
if (asString is not null && long.TryParse(asString, out long asStringLong))
return asStringLong;
return null;
}
/// <summary>
/// Read a key as a string, returning null on error
/// </summary>
public string? ReadString(string key)
{
if (!ValidateReadKey(key))
return null;
string? asString = Read<string>(key);
if (asString is not null)
return asString;
string[]? asArray = Read<string[]>(key);
if (asArray is not null)
#if NETFRAMEWORK || NETSTANDARD2_0
return string.Join(",", asArray);
#else
return string.Join(',', asArray);
#endif
// TODO: Add byte array conversion here
// TODO: Add byte array read helper
return this[key]!.ToString();
}
/// <summary>
/// Read a key as a T[], returning null on error
/// </summary>
public T[]? ReadArray<T>(string key)
{
if (!ValidateReadKey(key))
return null;
var items = Read<T[]>(key);
if (items is not null)
return items;
var single = Read<T>(key);
if (single is not null)
return [single];
return null;
}
/// <summary>
/// Read a key as a string[], returning null on error
/// </summary>
public string[]? ReadStringArray(string key)
{
if (!ValidateReadKey(key))
return null;
string[]? asArray = Read<string[]>(key);
if (asArray is not null)
return asArray;
string? asString = Read<string>(key);
if (asString is not null)
return [asString];
asString = this[key]!.ToString();
if (asString is not null)
return [asString];
return null;
}
/// <summary>
/// Check if a key is valid for read
/// </summary>
private bool ValidateReadKey(string key)
{
if (string.IsNullOrEmpty(key))
return false;
else if (!ContainsKey(key))
return false;
else if (this[key] is null)
return false;
return true;
}
#endregion
#region Write
/// <summary>
/// Remove a key, if possible
/// </summary>
public new bool Remove(string? fieldName)
{
// If the item or field name are missing, we can't do anything
if (string.IsNullOrEmpty(fieldName))
return false;
// If the key doesn't exist, then it's already removed
if (!ContainsKey(fieldName!))
return true;
// Remove the key
base.Remove(fieldName!);
return true;
}
/// <summary>
/// Replace a field from another item
/// </summary>
public bool Replace(DictionaryBase? from, string fieldName)
{
// If the source item is invalid
if (from is null)
return false;
// If the field name is missing, we can't do anything
if (string.IsNullOrEmpty(fieldName))
return false;
// If the types of the items are not the same, we can't do anything
if (from.GetType() != GetType())
return false;
// If the key doesn't exist in the source, we can't do anything
if (!from.TryGetValue(fieldName!, out var value))
return false;
// Set the key
this[fieldName!] = value;
return true;
}
/// <summary>
/// Write a key as the specified type, returning false on error
/// </summary>
/// <param name="fieldName">Field to set</param>
/// <param name="value">Value to set</param>
/// <returns>True if the value was set, false otherwise</returns>
public bool Write<T>(string fieldName, T? value)
{
// Invalid field cannot be processed
if (fieldName is null)
return false;
// Set the value based on the type
this[fieldName] = value;
return true;
}
#endregion
}
}

View File

@@ -1,24 +1,57 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("diplocation"), XmlRoot("diplocation")]
public class DipLocation : DatItem
public class DipLocation : DatItem, ICloneable, IEquatable<DipLocation>
{
#region Keys
#region Properties
/// <remarks>(yes|no) "no"</remarks>
public const string InvertedKey = "inverted";
public bool? Inverted { get; set; }
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
/// <remarks>string, possibly long</remarks>
public const string NumberKey = "number";
public long? Number { get; set; }
#endregion
public DipLocation() => Type = ItemType.DipLocation;
public DipLocation() => ItemType = ItemType.DipLocation;
/// <inheritdoc/>
public object Clone()
{
var obj = new DipLocation();
obj.Inverted = Inverted;
obj.Name = Name;
obj.Number = Number;
return obj;
}
/// <inheritdoc/>
public bool Equals(DipLocation? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if (Inverted != other.Inverted)
return false;
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
if (Number != other.Number)
return false;
return true;
}
}
}

View File

@@ -1,42 +1,87 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("dipswitch"), XmlRoot("dipswitch")]
public class DipSwitch : DatItem
public class DipSwitch : DatItem, ICloneable, IEquatable<DipSwitch>
{
#region Keys
#region Properties
/// <remarks>Condition</remarks>
[NoFilter]
public const string ConditionKey = "condition";
public Condition? Condition { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string DefaultKey = "default";
public bool? Default { get; set; }
/// <remarks>DipLocation[]</remarks>
[NoFilter]
public const string DipLocationKey = "diplocation";
public DipLocation[]? DipLocation { get; set; }
/// <remarks>DipValue[]</remarks>
[NoFilter]
public const string DipValueKey = "dipvalue";
public DipValue[]? DipValue { get; set; }
/// <remarks>string[]</remarks>
public const string EntryKey = "entry";
public string[]? Entry { get; set; }
/// <remarks>string</remarks>
public const string MaskKey = "mask";
public string? Mask { get; set; }
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
/// <remarks>string</remarks>
public const string TagKey = "tag";
public string? Tag { get; set; }
#endregion
public DipSwitch() => Type = ItemType.DipSwitch;
public DipSwitch() => ItemType = ItemType.DipSwitch;
/// <inheritdoc/>
public object Clone()
{
var obj = new DipSwitch();
obj.Condition = Condition?.Clone() as Condition;
obj.Default = Default;
if (DipLocation is not null)
obj.DipLocation = Array.ConvertAll(DipLocation, i => (DipLocation)i.Clone());
if (DipValue is not null)
obj.DipValue = Array.ConvertAll(DipValue, i => (DipValue)i.Clone());
if (Entry is not null)
obj.Entry = Array.ConvertAll(Entry, i => i);
obj.Mask = Mask;
obj.Name = Name;
obj.Tag = Tag;
return obj;
}
/// <inheritdoc/>
public bool Equals(DipSwitch? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((Mask is null) ^ (other.Mask is null))
return false;
else if (Mask is not null && !Mask.Equals(other.Mask, StringComparison.OrdinalIgnoreCase))
return false;
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
if ((Tag is null) ^ (other.Tag is null))
return false;
else if (Tag is not null && !Tag.Equals(other.Tag, StringComparison.OrdinalIgnoreCase))
return false;
// Sub-items
if ((Condition is null) ^ (other.Condition is null))
return false;
else if (Condition is not null && other.Condition is not null && Condition.Equals(other.Condition))
return false;
// TODO: Figure out how to properly check arrays
return true;
}
}
}

View File

@@ -1,28 +1,68 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("dipvalue"), XmlRoot("dipvalue")]
public class DipValue : DatItem
public class DipValue : DatItem, ICloneable, IEquatable<DipValue>
{
#region Keys
#region Properties
/// <remarks>Condition</remarks>
[NoFilter]
public const string ConditionKey = "condition";
public Condition? Condition { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string DefaultKey = "default";
public bool? Default { get; set; }
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
/// <remarks>string</remarks>
public const string ValueKey = "value";
public string? Value { get; set; }
#endregion
public DipValue() => Type = ItemType.DipValue;
public DipValue() => ItemType = ItemType.DipValue;
/// <inheritdoc/>
public object Clone()
{
var obj = new DipValue();
obj.Condition = Condition?.Clone() as Condition;
obj.Default = Default;
obj.Name = Name;
obj.Value = Value;
return obj;
}
/// <inheritdoc/>
public bool Equals(DipValue? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if (Default != other.Default)
return false;
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
if ((Value is null) ^ (other.Value is null))
return false;
else if (Value is not null && !Value.Equals(other.Value, StringComparison.OrdinalIgnoreCase))
return false;
// Sub-items
if ((Condition is null) ^ (other.Condition is null))
return false;
else if (Condition is not null && other.Condition is not null && Condition.Equals(other.Condition))
return false;
return true;
}
}
}

View File

@@ -1,45 +1,59 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
// TODO: IEquatable<Disk>
[JsonObject("disk"), XmlRoot(elementName: "disk")]
public class Disk : DatItem
public class Disk : DatItem, ICloneable
{
#region Keys
#region Properties
/// <remarks>string</remarks>
public const string FlagsKey = "flags";
public string? Flags { get; set; }
/// <remarks>string, possibly long</remarks>
public const string IndexKey = "index";
public long? Index { get; set; }
/// <remarks>string</remarks>
public const string MD5Key = "md5";
public string? MD5 { get; set; }
/// <remarks>string</remarks>
public const string MergeKey = "merge";
public string? Merge { get; set; }
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string OptionalKey = "optional";
public bool? Optional { get; set; }
/// <remarks>string</remarks>
public const string RegionKey = "region";
public string? Region { get; set; }
/// <remarks>string</remarks>
public const string SHA1Key = "sha1";
public string? SHA1 { get; set; }
/// <remarks>(baddump|nodump|good|verified) "good"</remarks>
public const string StatusKey = "status";
public ItemStatus? Status { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string WritableKey = "writable";
public bool? Writable { get; set; }
#endregion
public Disk() => Type = ItemType.Disk;
public Disk() => ItemType = ItemType.Disk;
/// <inheritdoc/>
public object Clone()
{
var obj = new Disk();
obj.Flags = Flags;
obj.Index = Index;
obj.MD5 = MD5;
obj.Merge = Merge;
obj.Name = Name;
obj.Optional = Optional;
obj.Region = Region;
obj.SHA1 = SHA1;
obj.Status = Status;
obj.Writable = Writable;
return obj;
}
}
}

View File

@@ -1,22 +1,51 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("diskarea"), XmlRoot("diskarea")]
public class DiskArea : DatItem
public class DiskArea : DatItem, ICloneable, IEquatable<DiskArea>
{
#region Keys
#region Properties
/// <remarks>Disk[]</remarks>
[NoFilter]
public const string DiskKey = "disk";
public Disk[]? Disk { get; set; }
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
#endregion
public DiskArea() => Type = ItemType.DiskArea;
public DiskArea() => ItemType = ItemType.DiskArea;
/// <inheritdoc/>
public object Clone()
{
var obj = new DiskArea();
if (Disk is not null)
obj.Disk = Array.ConvertAll(Disk, i => (Disk)i.Clone());
obj.Name = Name;
return obj;
}
/// <inheritdoc/>
public bool Equals(DiskArea? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
// Sub-items
// TODO: Figure out how to properly check arrays
return true;
}
}
}

View File

@@ -1,57 +1,165 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("display"), XmlRoot("display")]
public class Display : DatItem
public class Display : DatItem, ICloneable, IEquatable<Display>, IEquatable<Video>
{
#region Keys
#region Properties
/// <remarks>(yes|no) "no"</remarks>
public const string FlipXKey = "flipx";
/// <remarks>Only found in Video</remarks>
public long? AspectX { get; set; }
/// <remarks>long</remarks>
public const string HBEndKey = "hbend";
/// <remarks>long</remarks>
public const string HBStartKey = "hbstart";
/// <remarks>long</remarks>
public const string HeightKey = "height";
/// <remarks>long</remarks>
public const string HTotalKey = "htotal";
/// <remarks>long</remarks>
public const string PixClockKey = "pixclock";
/// <remarks>double</remarks>
public const string RefreshKey = "refresh";
/// <remarks>(0|90|180|270)</remarks>
public const string RotateKey = "rotate";
/// <remarks>string</remarks>
public const string TagKey = "tag";
/// <remarks>Only found in Video</remarks>
public long? AspectY { get; set; }
/// <remarks>(raster|vector|lcd|svg|unknown)</remarks>
public const string DisplayTypeKey = "type";
public DisplayType? DisplayType { get; set; }
/// <remarks>long</remarks>
public const string VBEndKey = "vbend";
/// <remarks>(yes|no) "no"</remarks>
public bool? FlipX { get; set; }
/// <remarks>long</remarks>
public const string VBStartKey = "vbstart";
public long? HBEnd { get; set; }
/// <remarks>long</remarks>
public const string VTotalKey = "vtotal";
public long? HBStart { get; set; }
/// <remarks>long</remarks>
public const string WidthKey = "width";
public long? Height { get; set; }
public long? HTotal { get; set; }
public long? PixClock { get; set; }
public double? Refresh { get; set; }
/// <remarks>(0|90|180|270)</remarks>
public Rotation? Rotate { get; set; }
public string? Tag { get; set; }
public long? VBEnd { get; set; }
public long? VBStart { get; set; }
public long? VTotal { get; set; }
public long? Width { get; set; }
#endregion
public Display() => Type = ItemType.Display;
public Display() => ItemType = ItemType.Display;
/// <inheritdoc/>
public object Clone()
{
var obj = new Display();
obj.AspectX = AspectX;
obj.AspectY = AspectY;
obj.DisplayType = DisplayType;
obj.FlipX = FlipX;
obj.HBEnd = HBEnd;
obj.HBStart = HBStart;
obj.Height = Height;
obj.HTotal = HTotal;
obj.PixClock = PixClock;
obj.Refresh = Refresh;
obj.Rotate = Rotate;
obj.Tag = Tag;
obj.VBEnd = VBEnd;
obj.VBStart = VBStart;
obj.VTotal = VTotal;
obj.Width = Width;
return obj;
}
/// <inheritdoc/>
public bool Equals(Display? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if (DisplayType != other.DisplayType)
return false;
if (FlipX != other.FlipX)
return false;
if (HBEnd != other.HBEnd)
return false;
if (HBStart != other.HBStart)
return false;
if (Height != other.Height)
return false;
if (HTotal != other.HTotal)
return false;
if (PixClock != other.PixClock)
return false;
if (Refresh != other.Refresh)
return false;
if (Rotate != other.Rotate)
return false;
if ((Tag is null) ^ (other.Tag is null))
return false;
else if (Tag is not null && !Tag.Equals(other.Tag, StringComparison.OrdinalIgnoreCase))
return false;
if (VBEnd != other.VBEnd)
return false;
if (VBStart != other.VBStart)
return false;
if (VTotal != other.VTotal)
return false;
if (Width != other.Width)
return false;
return true;
}
/// <inheritdoc/>
public bool Equals(Video? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if (AspectX != other.AspectX)
return false;
if (AspectY != other.AspectY)
return false;
if (DisplayType != other.Screen)
return false;
if (Height != other.Height)
return false;
if (Refresh != other.Refresh)
return false;
if (Rotate != other.Orientation)
return false;
if (Width != other.Width)
return false;
return true;
}
}
}

View File

@@ -1,51 +1,122 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("driver"), XmlRoot("driver")]
public class Driver : DatItem
public class Driver : DatItem, ICloneable, IEquatable<Driver>
{
#region Keys
#region Properties
/// <remarks>(plain|dirty)</remarks>
public const string BlitKey = "blit";
public Blit? Blit { get; set; }
/// <remarks>(good|imperfect|preliminary)</remarks>
public const string CocktailKey = "cocktail";
public SupportStatus? Cocktail { get; set; }
/// <remarks>(good|imperfect|preliminary)</remarks>
public const string ColorKey = "color";
public SupportStatus? Color { get; set; }
/// <remarks>(good|imperfect|preliminary)</remarks>
public const string EmulationKey = "emulation";
public SupportStatus? Emulation { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string IncompleteKey = "incomplete";
public bool? Incomplete { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string NoSoundHardwareKey = "nosoundhardware";
public bool? NoSoundHardware { get; set; }
/// <remarks>string, possibly long</remarks>
public const string PaletteSizeKey = "palettesize";
/// <remarks>Possibly long</remarks>
public string? PaletteSize { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string RequiresArtworkKey = "requiresartwork";
public bool? RequiresArtwork { get; set; }
/// <remarks>(supported|unsupported)</remarks>
public const string SaveStateKey = "savestate";
public Supported? SaveState { get; set; }
/// <remarks>(good|imperfect|preliminary)</remarks>
public const string SoundKey = "sound";
public SupportStatus? Sound { get; set; }
/// <remarks>(good|imperfect|preliminary|test)</remarks>
public const string StatusKey = "status";
public SupportStatus? Status { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string UnofficialKey = "unofficial";
public bool? Unofficial { get; set; }
#endregion
public Driver() => Type = ItemType.Driver;
public Driver() => ItemType = ItemType.Driver;
/// <inheritdoc/>
public object Clone()
{
var obj = new Driver();
obj.Blit = Blit;
obj.Cocktail = Cocktail;
obj.Color = Color;
obj.Emulation = Emulation;
obj.Incomplete = Incomplete;
obj.NoSoundHardware = NoSoundHardware;
obj.PaletteSize = PaletteSize;
obj.RequiresArtwork = RequiresArtwork;
obj.SaveState = SaveState;
obj.Sound = Sound;
obj.Status = Status;
obj.Unofficial = Unofficial;
return obj;
}
/// <inheritdoc/>
public bool Equals(Driver? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if (Blit != other.Blit)
return false;
if (Cocktail != other.Cocktail)
return false;
if (Color != other.Color)
return false;
if (Emulation != other.Emulation)
return false;
if (Incomplete != other.Incomplete)
return false;
if (NoSoundHardware != other.NoSoundHardware)
return false;
if ((PaletteSize is null) ^ (other.PaletteSize is null))
return false;
else if (PaletteSize is not null && !PaletteSize.Equals(other.PaletteSize, StringComparison.OrdinalIgnoreCase))
return false;
if (RequiresArtwork != other.RequiresArtwork)
return false;
if (SaveState != other.SaveState)
return false;
if (Sound != other.Sound)
return false;
if (Status != other.Status)
return false;
if (Unofficial != other.Unofficial)
return false;
return true;
}
}
}

View File

@@ -1,31 +1,72 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("dump"), XmlRoot("dump")]
public class Dump : DatItem
public class Dump : DatItem, ICloneable, IEquatable<Dump>
{
#region Keys
#region Properties
/// <remarks>Rom</remarks>
[NoFilter]
public const string MegaRomKey = "megarom";
public Rom? MegaRom { get; set; }
/// <remarks>Original</remarks>
[NoFilter]
public const string OriginalKey = "original";
public Original? Original { get; set; }
/// <remarks>Rom</remarks>
[NoFilter]
public const string RomKey = "rom";
public Rom? Rom { get; set; }
/// <remarks>Rom</remarks>
[NoFilter]
public const string SCCPlusCartKey = "sccpluscart";
public Rom? SCCPlusCart { get; set; }
#endregion
public Dump() => Type = ItemType.Dump;
public Dump() => ItemType = ItemType.Dump;
/// <inheritdoc/>
public object Clone()
{
var obj = new Dump();
if (MegaRom is not null)
obj.MegaRom = MegaRom.Clone() as Rom;
if (Original is not null)
obj.Original = Original.Clone() as Original;
if (Rom is not null)
obj.Rom = Rom.Clone() as Rom;
if (SCCPlusCart is not null)
obj.SCCPlusCart = SCCPlusCart.Clone() as Rom;
return obj;
}
/// <inheritdoc/>
public bool Equals(Dump? other)
{
// Null never matches
if (other is null)
return false;
// Sub-items
if ((MegaRom is null) ^ (other.MegaRom is null))
return false;
else if (MegaRom is not null && other.MegaRom is not null && MegaRom.Equals(other.MegaRom))
return false;
if ((Original is null) ^ (other.Original is null))
return false;
else if (Original is not null && other.Original is not null && Original.Equals(other.Original))
return false;
if ((Rom is null) ^ (other.Rom is null))
return false;
else if (Rom is not null && other.Rom is not null && Rom.Equals(other.Rom))
return false;
if ((SCCPlusCart is null) ^ (other.SCCPlusCart is null))
return false;
else if (SCCPlusCart is not null && other.SCCPlusCart is not null && SCCPlusCart.Equals(other.SCCPlusCart))
return false;
return true;
}
}
}

View File

@@ -1,5 +1,17 @@
namespace SabreTools.Data.Models.Metadata
{
/// <summary>
/// Determine the blit type
/// </summary>
public enum Blit
{
/// <summary>"plain"</summary>
Plain,
/// <summary>"dirty"</summary>
Dirty,
}
/// <summary>
/// Determine the chip type
/// </summary>
@@ -244,6 +256,9 @@ namespace SabreTools.Data.Models.Metadata
/// <summary>"verified"</summary>
Verified,
/// <summary>"deduped", RomVault extensions</summary>
Deduped,
}
/// <summary>
@@ -279,12 +294,14 @@ namespace SabreTools.Data.Models.Metadata
Dump,
Extension,
Feature,
File, // TODO: This should be merged with Rom?
Info,
Input,
Instance,
Media,
Original,
Part,
PartFeature,
Port,
RamOption,
Release,
@@ -295,7 +312,6 @@ namespace SabreTools.Data.Models.Metadata
SharedFeat,
Slot,
SlotOption,
Software,
SoftwareList,
Sound,
SourceDetails,
@@ -481,6 +497,24 @@ namespace SabreTools.Data.Models.Metadata
GreaterThanOrEqual,
}
/// <summary>
/// Determine display rotation
/// </summary>
public enum Rotation
{
/// <summary>0</summary>
North = 0,
/// <summary>90</summary>
East = 90,
/// <summary>180</summary>
South = 180,
/// <summary>270</summary>
West = 270,
}
/// <summary>
/// Determine machine runnable status
/// </summary>
@@ -539,5 +573,26 @@ namespace SabreTools.Data.Models.Metadata
/// <summary>"preliminary"</summary>
Preliminary,
/// <summary>"test"</summary>
Test,
}
/// <summary>
/// Determine area width
/// </summary>
public enum Width
{
/// <summary>8</summary>
Byte = 8,
/// <summary>16</summary>
Short = 16,
/// <summary>32</summary>
Int = 32,
/// <summary>64</summary>
Long = 64,
}
}

View File

@@ -1,18 +1,44 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("extension"), XmlRoot("extension")]
public class Extension : DatItem
public class Extension : DatItem, ICloneable, IEquatable<Extension>
{
#region Keys
#region Properties
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
#endregion
public Extension() => Type = ItemType.Extension;
public Extension() => ItemType = ItemType.Extension;
/// <inheritdoc/>
public object Clone()
{
var obj = new Extension();
obj.Name = Name;
return obj;
}
/// <inheritdoc/>
public bool Equals(Extension? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
return true;
}
}
}

View File

@@ -1,30 +1,73 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("feature"), XmlRoot("feature")]
public class Feature : DatItem
public class Feature : DatItem, ICloneable, IEquatable<Feature>
{
#region Keys
/// <remarks>string</remarks>
public const string NameKey = "name";
/// <remarks>(unemulated|imperfect)</remarks>
public const string OverallKey = "overall";
/// <remarks>(unemulated|imperfect)</remarks>
public const string StatusKey = "status";
#region Properties
/// <remarks>(protection|timing|graphics|palette|sound|capture|camera|microphone|controls|keyboard|mouse|media|disk|printer|tape|punch|drum|rom|comms|lan|wan)</remarks>
public const string FeatureTypeKey = "type";
public FeatureType? FeatureType { get; set; }
/// <remarks>string</remarks>
public const string ValueKey = "value";
public string? Name { get; set; }
/// <remarks>(unemulated|imperfect)</remarks>
public FeatureStatus? Overall { get; set; }
/// <remarks>(unemulated|imperfect)</remarks>
public FeatureStatus? Status { get; set; }
public string? Value { get; set; }
#endregion
public Feature() => Type = ItemType.Feature;
public Feature() => ItemType = ItemType.Feature;
/// <inheritdoc/>
public object Clone()
{
var obj = new Feature();
obj.FeatureType = FeatureType;
obj.Name = Name;
obj.Overall = Overall;
obj.Status = Status;
obj.Value = Value;
return obj;
}
/// <inheritdoc/>
public bool Equals(Feature? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if (FeatureType != other.FeatureType)
return false;
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
if (Overall != other.Overall)
return false;
if (Status != other.Status)
return false;
if ((Value is null) ^ (other.Value is null))
return false;
else if (Value is not null && !Value.Equals(other.Value, StringComparison.OrdinalIgnoreCase))
return false;
return true;
}
}
}

View File

@@ -1,155 +1,376 @@
using System;
namespace SabreTools.Data.Models.Metadata
{
/// <summary>
/// Format-agnostic representation of metadata header data
/// </summary>
public class Header : DictionaryBase
public class Header : ICloneable, IEquatable<Header>
{
#region Keys
#region Properties
/// <remarks>string</remarks>
public const string AuthorKey = "author";
public string? Author { get; set; }
/// <remarks>(none|split|merged|nonmerged|fullmerged|device|full) "split"</remarks>
public const string BiosModeKey = "biosmode";
public MergingFlag BiosMode { get; set; }
/// <remarks>string</remarks>
public const string BuildKey = "build";
public string? Build { get; set; }
/// TODO: This needs an internal model OR mapping to fields
/// <remarks>CanOpen</remarks>
[NoFilter]
public const string CanOpenKey = "canOpen";
public OfflineList.CanOpen? CanOpen { get; set; }
/// <remarks>string</remarks>
public const string CategoryKey = "category";
public string? Category { get; set; }
/// <remarks>string</remarks>
public const string CommentKey = "comment";
public string? Comment { get; set; }
/// <remarks>string</remarks>
public const string DateKey = "date";
public string? Date { get; set; }
/// <remarks>string</remarks>
public const string DatVersionKey = "datversion";
public string? DatVersion { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string DebugKey = "debug";
public bool? Debug { get; set; }
/// <remarks>string</remarks>
public const string DescriptionKey = "description";
public string? Description { get; set; }
/// <remarks>string</remarks>
public const string EmailKey = "email";
public string? Email { get; set; }
/// <remarks>string</remarks>
public const string EmulatorVersionKey = "emulatorversion";
public string? EmulatorVersion { get; set; }
public string? FileName { get; set; }
/// <remarks>(none|split|merged|nonmerged|fullmerged|device|full) "split"</remarks>
public const string ForceMergingKey = "forcemerging";
public MergingFlag ForceMerging { get; set; }
/// <remarks>(obsolete|required|ignore) "obsolete"</remarks>
public const string ForceNodumpKey = "forcenodump";
public NodumpFlag ForceNodump { get; set; }
/// <remarks>(zip|unzip) "zip"</remarks>
public const string ForcePackingKey = "forcepacking";
public PackingFlag ForcePacking { get; set; }
/// <remarks>(yes|no) "yes"</remarks>
public const string ForceZippingKey = "forcezipping";
public bool? ForceZipping { get; set; }
/// <remarks>string, string[]</remarks>
public const string HeaderKey = "header";
public string[]? HeaderRow { get; set; }
/// <remarks>string</remarks>
public const string HomepageKey = "homepage";
public string? HeaderSkipper { get; set; }
/// <remarks>string</remarks>
public const string IdKey = "id";
public string? Homepage { get; set; }
public string? Id { get; set; }
/// TODO: This needs an internal model OR mapping to fields
/// <remarks>Search</remarks>
[NoFilter]
public const string ImagesKey = "images";
public OfflineList.Images? Images { get; set; }
/// <remarks>string</remarks>
public const string ImFolderKey = "imFolder";
public string? ImFolder { get; set; }
/// TODO: This needs an internal model OR mapping to fields
/// <remarks>Infos</remarks>
[NoFilter]
public const string InfosKey = "infos";
public OfflineList.Infos? Infos { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string LockBiosModeKey = "lockbiosmode";
public bool? LockBiosMode { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string LockRomModeKey = "lockrommode";
public bool? LockRomMode { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string LockSampleModeKey = "locksamplemode";
public bool? LockSampleMode { get; set; }
/// <remarks>string</remarks>
public const string MameConfigKey = "mameconfig";
public string? MameConfig { get; set; }
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
/// TODO: This needs an internal model OR mapping to fields
/// <remarks>NewDat</remarks>
[NoFilter]
public const string NewDatKey = "newDat";
public OfflineList.NewDat? NewDat { get; set; }
/// <remarks>string</remarks>
public const string NotesKey = "notes";
public string? Notes { get; set; }
/// <remarks>string</remarks>
public const string PluginKey = "plugin";
public string? Plugin { get; set; }
/// <remarks>string</remarks>
public const string RefNameKey = "refname";
public string? RefName { get; set; }
/// <remarks>(none|split|merged|nonmerged|fullmerged|device|full) "split"</remarks>
public const string RomModeKey = "rommode";
public MergingFlag RomMode { get; set; }
/// <remarks>string</remarks>
public const string RomTitleKey = "romTitle";
public string? RomTitle { get; set; }
/// <remarks>string</remarks>
public const string RootDirKey = "rootdir";
public string? RootDir { get; set; }
/// <remarks>(none|split|merged|nonmerged|fullmerged|device|full) "split"</remarks>
public const string SampleModeKey = "samplemode";
public MergingFlag SampleMode { get; set; }
/// <remarks>string</remarks>
public const string SchemaLocationKey = "schemaLocation";
public string? SchemaLocation { get; set; }
/// <remarks>string</remarks>
public const string ScreenshotsHeightKey = "screenshotsHeight";
public string? ScreenshotsHeight { get; set; }
/// <remarks>string</remarks>
public const string ScreenshotsWidthKey = "screenshotsWidth";
public string? ScreenshotsWidth { get; set; }
/// TODO: This needs an internal model OR mapping to fields
/// <remarks>Search</remarks>
[NoFilter]
public const string SearchKey = "search";
public OfflineList.Search? Search { get; set; }
/// <remarks>string</remarks>
public const string SystemKey = "system";
public string? System { get; set; }
/// <remarks>string</remarks>
public const string TimestampKey = "timestamp";
public string? Timestamp { get; set; }
/// <remarks>string</remarks>
public const string TypeKey = "type";
public string? Type { get; set; }
/// <remarks>string</remarks>
public const string UrlKey = "url";
public string? Url { get; set; }
/// <remarks>string</remarks>
public const string VersionKey = "version";
public string? Version { get; set; }
#endregion
/// <inheritdoc/>
public object Clone()
{
var obj = new Header();
obj.Author = Author;
obj.BiosMode = BiosMode;
obj.Build = Build;
obj.CanOpen = CanOpen;
obj.Category = Category;
obj.Comment = Comment;
obj.Date = Date;
obj.DatVersion = DatVersion;
obj.Debug = Debug;
obj.Description = Description;
obj.Email = Email;
obj.EmulatorVersion = EmulatorVersion;
obj.FileName = FileName;
obj.ForceMerging = ForceMerging;
obj.ForceNodump = ForceNodump;
obj.ForcePacking = ForcePacking;
obj.ForceZipping = ForceZipping;
obj.HeaderRow = HeaderRow;
obj.HeaderSkipper = HeaderSkipper;
obj.Homepage = Homepage;
obj.Id = Id;
obj.Images = Images;
obj.ImFolder = ImFolder;
obj.Infos = Infos;
obj.LockBiosMode = LockBiosMode;
obj.LockRomMode = LockRomMode;
obj.LockSampleMode = LockSampleMode;
obj.MameConfig = MameConfig;
obj.Name = Name;
obj.NewDat = NewDat;
obj.Notes = Notes;
obj.Plugin = Plugin;
obj.RefName = RefName;
obj.RomMode = RomMode;
obj.RomTitle = RomTitle;
obj.RootDir = RootDir;
obj.SampleMode = SampleMode;
obj.SchemaLocation = SchemaLocation;
obj.ScreenshotsHeight = ScreenshotsHeight;
obj.ScreenshotsWidth = ScreenshotsWidth;
obj.Search = Search;
obj.System = System;
obj.Timestamp = Timestamp;
obj.Type = Type;
obj.Url = Url;
obj.Version = Version;
return obj;
}
/// <inheritdoc/>
public bool Equals(Header? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((Author is null) ^ (other.Author is null))
return false;
else if (Author is not null && !Author.Equals(other.Author, StringComparison.OrdinalIgnoreCase))
return false;
if (BiosMode != other.BiosMode)
return false;
if ((Build is null) ^ (other.Build is null))
return false;
else if (Build is not null && !Build.Equals(other.Build, StringComparison.OrdinalIgnoreCase))
return false;
if ((Category is null) ^ (other.Category is null))
return false;
else if (Category is not null && !Category.Equals(other.Category, StringComparison.OrdinalIgnoreCase))
return false;
if ((Comment is null) ^ (other.Comment is null))
return false;
else if (Comment is not null && !Comment.Equals(other.Comment, StringComparison.OrdinalIgnoreCase))
return false;
if ((Date is null) ^ (other.Date is null))
return false;
else if (Date is not null && !Date.Equals(other.Date, StringComparison.OrdinalIgnoreCase))
return false;
if ((DatVersion is null) ^ (other.DatVersion is null))
return false;
else if (DatVersion is not null && !DatVersion.Equals(other.DatVersion, StringComparison.OrdinalIgnoreCase))
return false;
if (Debug != other.Debug)
return false;
if ((Description is null) ^ (other.Description is null))
return false;
else if (Description is not null && !Description.Equals(other.Description, StringComparison.OrdinalIgnoreCase))
return false;
if ((Email is null) ^ (other.Email is null))
return false;
else if (Email is not null && !Email.Equals(other.Email, StringComparison.OrdinalIgnoreCase))
return false;
if ((EmulatorVersion is null) ^ (other.EmulatorVersion is null))
return false;
else if (EmulatorVersion is not null && !EmulatorVersion.Equals(other.EmulatorVersion, StringComparison.OrdinalIgnoreCase))
return false;
if ((FileName is null) ^ (other.FileName is null))
return false;
else if (FileName is not null && !FileName.Equals(other.FileName, StringComparison.OrdinalIgnoreCase))
return false;
if (ForceMerging != other.ForceMerging)
return false;
if (ForceNodump != other.ForceNodump)
return false;
if (ForcePacking != other.ForcePacking)
return false;
if (ForceZipping != other.ForceZipping)
return false;
if ((HeaderSkipper is null) ^ (other.HeaderSkipper is null))
return false;
else if (HeaderSkipper is not null && !HeaderSkipper.Equals(other.HeaderSkipper, StringComparison.OrdinalIgnoreCase))
return false;
if ((Homepage is null) ^ (other.Homepage is null))
return false;
else if (Homepage is not null && !Homepage.Equals(other.Homepage, StringComparison.OrdinalIgnoreCase))
return false;
if ((Id is null) ^ (other.Id is null))
return false;
else if (Id is not null && !Id.Equals(other.Id, StringComparison.OrdinalIgnoreCase))
return false;
if ((ImFolder is null) ^ (other.ImFolder is null))
return false;
else if (ImFolder is not null && !ImFolder.Equals(other.ImFolder, StringComparison.OrdinalIgnoreCase))
return false;
if (LockBiosMode != other.ForceZipping)
return false;
if (LockRomMode != other.LockRomMode)
return false;
if (LockSampleMode != other.LockSampleMode)
return false;
if ((MameConfig is null) ^ (other.MameConfig is null))
return false;
else if (MameConfig is not null && !MameConfig.Equals(other.MameConfig, StringComparison.OrdinalIgnoreCase))
return false;
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
if ((Notes is null) ^ (other.Notes is null))
return false;
else if (Notes is not null && !Notes.Equals(other.Notes, StringComparison.OrdinalIgnoreCase))
return false;
if ((Plugin is null) ^ (other.Plugin is null))
return false;
else if (Plugin is not null && !Plugin.Equals(other.Plugin, StringComparison.OrdinalIgnoreCase))
return false;
if ((RefName is null) ^ (other.RefName is null))
return false;
else if (RefName is not null && !RefName.Equals(other.RefName, StringComparison.OrdinalIgnoreCase))
return false;
if (RomMode != other.RomMode)
return false;
if ((RomTitle is null) ^ (other.RomTitle is null))
return false;
else if (RomTitle is not null && !RomTitle.Equals(other.RomTitle, StringComparison.OrdinalIgnoreCase))
return false;
if ((RootDir is null) ^ (other.RootDir is null))
return false;
else if (RootDir is not null && !RootDir.Equals(other.RootDir, StringComparison.OrdinalIgnoreCase))
return false;
if (SampleMode != other.SampleMode)
return false;
if ((SchemaLocation is null) ^ (other.SchemaLocation is null))
return false;
else if (SchemaLocation is not null && !SchemaLocation.Equals(other.SchemaLocation, StringComparison.OrdinalIgnoreCase))
return false;
if ((ScreenshotsHeight is null) ^ (other.ScreenshotsHeight is null))
return false;
else if (ScreenshotsHeight is not null && !ScreenshotsHeight.Equals(other.ScreenshotsHeight, StringComparison.OrdinalIgnoreCase))
return false;
if ((ScreenshotsWidth is null) ^ (other.ScreenshotsWidth is null))
return false;
else if (ScreenshotsWidth is not null && !ScreenshotsWidth.Equals(other.ScreenshotsWidth, StringComparison.OrdinalIgnoreCase))
return false;
if ((System is null) ^ (other.System is null))
return false;
else if (System is not null && !System.Equals(other.System, StringComparison.OrdinalIgnoreCase))
return false;
if ((Timestamp is null) ^ (other.Timestamp is null))
return false;
else if (Timestamp is not null && !Timestamp.Equals(other.Timestamp, StringComparison.OrdinalIgnoreCase))
return false;
if ((Type is null) ^ (other.Type is null))
return false;
else if (Type is not null && !Type.Equals(other.Type, StringComparison.OrdinalIgnoreCase))
return false;
if ((Url is null) ^ (other.Url is null))
return false;
else if (Url is not null && !Url.Equals(other.Url, StringComparison.OrdinalIgnoreCase))
return false;
if ((Version is null) ^ (other.Version is null))
return false;
else if (Version is not null && !Version.Equals(other.Version, StringComparison.OrdinalIgnoreCase))
return false;
// Sub-items
// Header.CanOpen is intentionally skipped
// Header.Images is intentionally skipped
// Header.Infos is intentionally skipped
// Header.NewDat is intentionally skipped
// Header.Search is intentionally skipped
// TODO: Figure out how to properly check arrays
return true;
}
}
}

View File

@@ -1,21 +1,52 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("info"), XmlRoot("info")]
public class Info : DatItem
public class Info : DatItem, ICloneable, IEquatable<Info>
{
#region Keys
#region Properties
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
/// <remarks>string</remarks>
public const string ValueKey = "value";
public string? Value { get; set; }
#endregion
public Info() => Type = ItemType.Info;
public Info() => ItemType = ItemType.Info;
/// <inheritdoc/>
public object Clone()
{
var obj = new Info();
obj.Name = Name;
obj.Value = Value;
return obj;
}
/// <inheritdoc/>
public bool Equals(Info? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
if ((Value is null) ^ (other.Value is null))
return false;
else if (Value is not null && !Value.Equals(other.Value, StringComparison.OrdinalIgnoreCase))
return false;
return true;
}
}
}

View File

@@ -4,13 +4,8 @@ using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("infosource"), XmlRoot("infosource")]
public class InfoSource : DictionaryBase
public class InfoSource
{
#region Keys
/// <remarks>string[]</remarks>
public const string SourceKey = "source";
#endregion
public string[]? Source { get; set; }
}
}

View File

@@ -1,33 +1,84 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("input"), XmlRoot("input")]
public class Input : DatItem
public class Input : DatItem, ICloneable, IEquatable<Input>
{
#region Keys
#region Properties
/// <remarks>long</remarks>
public const string ButtonsKey = "buttons";
public long? Buttons { get; set; }
/// <remarks>long</remarks>
public const string CoinsKey = "coins";
public long? Coins { get; set; }
/// <remarks>string / Control[]</remarks>
public const string ControlKey = "control";
public Control[]? Control { get; set; }
/// <remarks>long</remarks>
public const string PlayersKey = "players";
/// <remarks>Attribute also named Control</remarks>
public string? ControlAttr { get; set; }
public long? Players { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string ServiceKey = "service";
public bool? Service { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string TiltKey = "tilt";
public bool? Tilt { get; set; }
#endregion
public Input() => Type = ItemType.Input;
public Input() => ItemType = ItemType.Input;
/// <inheritdoc/>
public object Clone()
{
var obj = new Input();
obj.Buttons = Buttons;
obj.Coins = Coins;
if (Control is not null)
obj.Control = Array.ConvertAll(Control, i => (Control)i.Clone());
obj.ControlAttr = ControlAttr;
obj.Players = Players;
obj.Service = Service;
obj.Tilt = Tilt;
return obj;
}
/// <inheritdoc/>
public bool Equals(Input? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if (Buttons != other.Buttons)
return false;
if (Coins != other.Coins)
return false;
if ((ControlAttr is null) ^ (other.ControlAttr is null))
return false;
else if (ControlAttr is not null && !ControlAttr.Equals(other.ControlAttr, StringComparison.OrdinalIgnoreCase))
return false;
if (Players != other.Players)
return false;
if (Service != other.Service)
return false;
if (Tilt != other.Tilt)
return false;
// Sub-items
// TODO: Figure out how to properly check arrays
return true;
}
}
}

View File

@@ -1,21 +1,52 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("instance"), XmlRoot("instance")]
public class Instance : DatItem
public class Instance : DatItem, ICloneable, IEquatable<Instance>
{
#region Keys
#region Properties
/// <remarks>string</remarks>
public const string BriefNameKey = "briefname";
public string? BriefName { get; set; }
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
#endregion
public Instance() => Type = ItemType.Instance;
public Instance() => ItemType = ItemType.Instance;
/// <inheritdoc/>
public object Clone()
{
var obj = new Instance();
obj.BriefName = BriefName;
obj.Name = Name;
return obj;
}
/// <inheritdoc/>
public bool Equals(Instance? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((BriefName is null) ^ (other.BriefName is null))
return false;
else if (BriefName is not null && !BriefName.Equals(other.BriefName, StringComparison.OrdinalIgnoreCase))
return false;
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
return true;
}
}
}

View File

@@ -1,279 +1,635 @@
using System;
namespace SabreTools.Data.Models.Metadata
{
/// <summary>
/// Format-agnostic representation of game, machine, and set data
/// </summary>
public class Machine : DictionaryBase
public class Machine : ICloneable, IEquatable<Machine>
{
#region Keys
#region Properties
/// <remarks>Adjuster[]</remarks>
[NoFilter]
public const string AdjusterKey = "adjuster";
public Adjuster[]? Adjuster { get; set; }
/// <remarks>Archive[]</remarks>
[NoFilter]
public const string ArchiveKey = "archive";
public Archive[]? Archive { get; set; }
/// <remarks>BiosSet[]</remarks>
[NoFilter]
public const string BiosSetKey = "biosset";
public BiosSet[]? BiosSet { get; set; }
/// <remarks>string</remarks>
public const string BoardKey = "board";
public string? Board { get; set; }
/// <remarks>string</remarks>
public const string ButtonsKey = "buttons";
public string? Buttons { get; set; }
/// <remarks>string, string[]</remarks>
public const string CategoryKey = "category";
public string[]? Category { get; set; }
/// <remarks>Chip[]</remarks>
[NoFilter]
public const string ChipKey = "chip";
public Chip[]? Chip { get; set; }
/// <remarks>string</remarks>
public const string CloneOfKey = "cloneof";
public string? CloneOf { get; set; }
/// <remarks>string</remarks>
public const string CloneOfIdKey = "cloneofid";
public string? CloneOfId { get; set; }
/// <remarks>string, string[]</remarks>
public const string CommentKey = "comment";
public string[]? Comment { get; set; }
/// <remarks>string</remarks>
public const string CompanyKey = "company";
public string? Company { get; set; }
/// <remarks>Configuration[]</remarks>
[NoFilter]
public const string ConfigurationKey = "configuration";
public Configuration[]? Configuration { get; set; }
/// <remarks>string</remarks>
public const string ControlKey = "control";
public string? Control { get; set; }
/// <remarks>string</remarks>
public const string CountryKey = "country";
public string? CRC { get; set; }
/// <remarks>string</remarks>
public const string DescriptionKey = "description";
public string? Country { get; set; }
/// <remarks>Device[]</remarks>
[NoFilter]
public const string DeviceKey = "device";
public string? Description { get; set; }
/// <remarks>DeviceRef[]</remarks>
[NoFilter]
public const string DeviceRefKey = "device_ref";
public string? Developer { get; set; }
/// <remarks>DipSwitch[]</remarks>
[NoFilter]
public const string DipSwitchKey = "dipswitch";
public Device[]? Device { get; set; }
/// <remarks>string</remarks>
public const string DirNameKey = "dirName";
public DeviceRef[]? DeviceRef { get; set; }
/// <remarks>Disk[]</remarks>
[NoFilter]
public const string DiskKey = "disk";
public DipSwitch[]? DipSwitch { get; set; }
/// <remarks>string</remarks>
public const string DisplayCountKey = "displaycount";
public string? DirName { get; set; }
/// <remarks>Display[]</remarks>
[NoFilter]
public const string DisplayKey = "display";
public Disk[]? Disk { get; set; }
/// <remarks>string</remarks>
public const string DisplayTypeKey = "displaytype";
public Display[]? Display { get; set; }
/// <remarks>Driver</remarks>
[NoFilter]
public const string DriverKey = "driver";
public string? DisplayCount { get; set; }
/// <remarks>Dump[]</remarks>
[NoFilter]
public const string DumpKey = "dump";
public string? DisplayType { get; set; }
/// <remarks>string</remarks>
public const string DuplicateIDKey = "duplicateID";
public Driver? Driver { get; set; }
/// <remarks>string</remarks>
public const string EmulatorKey = "emulator";
public Dump[]? Dump { get; set; }
/// <remarks>string</remarks>
public const string ExtraKey = "extra";
public string? DuplicateID { get; set; }
/// <remarks>string</remarks>
public const string FavoriteKey = "favorite";
public string? Emulator { get; set; }
/// <remarks>Feature[]</remarks>
[NoFilter]
public const string FeatureKey = "feature";
public string? Enabled { get; set; }
/// <remarks>string</remarks>
public const string GenMSXIDKey = "genmsxid";
public string? Extra { get; set; }
/// <remarks>string</remarks>
public const string HashKey = "hash";
public string? Favorite { get; set; }
/// <remarks>string</remarks>
public const string HistoryKey = "history";
public Feature[]? Feature { get; set; }
/// <remarks>string</remarks>
public const string IdKey = "id";
public string? GenMSXID { get; set; }
/// <remarks>string</remarks>
public const string Im1CRCKey = "im1CRC";
public string? Genre { get; set; }
/// <remarks>string</remarks>
public const string Im2CRCKey = "im2CRC";
public string? Hash { get; set; }
/// <remarks>string</remarks>
public const string ImageNumberKey = "imageNumber";
public string? History { get; set; }
/// <remarks>Info[]</remarks>
[NoFilter]
public const string InfoKey = "info";
public string? Id { get; set; }
/// <remarks>Input</remarks>
[NoFilter]
public const string InputKey = "input";
public string? Im1CRC { get; set; }
public string? Im2CRC { get; set; }
public string? ImageNumber { get; set; }
public Info[]? Info { get; set; }
public Input? Input { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string IsBiosKey = "isbios";
public bool? IsBios { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string IsDeviceKey = "isdevice";
public bool? IsDevice { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string IsMechanicalKey = "ismechanical";
public bool? IsMechanical { get; set; }
/// <remarks>string</remarks>
public const string LanguageKey = "language";
public string? Language { get; set; }
/// <remarks>string</remarks>
public const string LocationKey = "location";
public string? Location { get; set; }
/// <remarks>string</remarks>
public const string ManufacturerKey = "manufacturer";
public string? Manufacturer { get; set; }
/// <remarks>Media[]</remarks>
[NoFilter]
public const string MediaKey = "media";
public Media[]? Media { get; set; }
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
/// <remarks>string</remarks>
public const string NotesKey = "notes";
public string? Notes { get; set; }
/// <remarks>Part[]</remarks>
[NoFilter]
public const string PartKey = "part";
public Part[]? Part { get; set; }
/// <remarks>string</remarks>
public const string PlayedCountKey = "playedcount";
public string? PlayedCount { get; set; }
/// <remarks>string</remarks>
public const string PlayedTimeKey = "playedtime";
public string? PlayedTime { get; set; }
/// <remarks>string</remarks>
public const string PlayersKey = "players";
public string? Players { get; set; }
/// <remarks>Port[]</remarks>
[NoFilter]
public const string PortKey = "port";
public Port[]? Port { get; set; }
/// <remarks>string</remarks>
public const string PublisherKey = "publisher";
public string? Publisher { get; set; }
/// <remarks>RamOption[]</remarks>
[NoFilter]
public const string RamOptionKey = "ramoption";
public RamOption[]? RamOption { get; set; }
/// <remarks>string</remarks>
public const string RebuildToKey = "rebuildto";
public string? Ratings { get; set; }
/// <remarks>Release[]</remarks>
[NoFilter]
public const string ReleaseKey = "release";
public string? RebuildTo { get; set; }
/// <remarks>string</remarks>
public const string ReleaseNumberKey = "releaseNumber";
public string? RelatedTo { get; set; }
/// <remarks>Rom[]</remarks>
[NoFilter]
public const string RomKey = "rom";
public Release[]? Release { get; set; }
/// <remarks>string</remarks>
public const string RomOfKey = "romof";
public string? ReleaseNumber { get; set; }
/// <remarks>string</remarks>
public const string RotationKey = "rotation";
public Rom[]? Rom { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string RunnableKey = "runnable";
public string? RomOf { get; set; }
/// <remarks>Sample[]</remarks>
[NoFilter]
public const string SampleKey = "sample";
public string? Rotation { get; set; }
/// <remarks>string</remarks>
public const string SampleOfKey = "sampleof";
/// <remarks>(yes|partial|no) "no"</remarks>
public Runnable? Runnable { get; set; }
/// <remarks>string</remarks>
public const string SaveTypeKey = "saveType";
public Sample[]? Sample { get; set; }
/// <remarks>SharedFeat[]</remarks>
[NoFilter]
public const string SharedFeatKey = "sharedfeat";
public string? SampleOf { get; set; }
/// <remarks>Slot[]</remarks>
[NoFilter]
public const string SlotKey = "slot";
public string? SaveType { get; set; }
/// <remarks>SoftwareList[]</remarks>
[NoFilter]
public const string SoftwareListKey = "softwarelist";
public string? Score { get; set; }
/// <remarks>Sound</remarks>
[NoFilter]
public const string SoundKey = "sound";
public SharedFeat[]? SharedFeat { get; set; }
/// <remarks>string</remarks>
public const string SourceFileKey = "sourcefile";
public Slot[]? Slot { get; set; }
/// <remarks>string</remarks>
public const string SourceRomKey = "sourceRom";
public SoftwareList[]? SoftwareList { get; set; }
/// <remarks>string</remarks>
public const string StatusKey = "status";
public Sound? Sound { get; set; }
public string? Source { get; set; }
public string? SourceFile { get; set; }
public string? SourceRom { get; set; }
public string? Status { get; set; }
public string? Subgenre { get; set; }
/// <remarks>(yes|partial|no) "yes"</remarks>
public const string SupportedKey = "supported";
public Supported? Supported { get; set; }
/// <remarks>string</remarks>
public const string SystemKey = "system";
public string? System { get; set; }
/// <remarks>string</remarks>
public const string TagsKey = "tags";
public string? Tags { get; set; }
/// TODO: This needs an internal model OR mapping to fields
/// <remarks>Trurip</remarks>
[NoFilter]
public const string TruripKey = "trurip";
public string? TitleID { get; set; }
/// <remarks>string</remarks>
public const string UrlKey = "url";
public string? Url { get; set; }
/// <remarks>Video[]</remarks>
[NoFilter]
public const string VideoKey = "video";
public Video[]? Video { get; set; }
/// <remarks>string</remarks>
public const string YearKey = "year";
public string? Year { get; set; }
#endregion
/// <inheritdoc/>
public object Clone()
{
var obj = new Machine();
if (Adjuster is not null)
obj.Adjuster = Array.ConvertAll(Adjuster, i => (Adjuster)i.Clone());
if (Archive is not null)
obj.Archive = Array.ConvertAll(Archive, i => (Archive)i.Clone());
if (BiosSet is not null)
obj.BiosSet = Array.ConvertAll(BiosSet, i => (BiosSet)i.Clone());
obj.Board = Board;
obj.Buttons = Buttons;
if (Category is not null)
obj.Category = Array.ConvertAll(Category, i => i);
if (Chip is not null)
obj.Chip = Array.ConvertAll(Chip, i => (Chip)i.Clone());
obj.CloneOf = CloneOf;
obj.CloneOfId = CloneOfId;
if (Comment is not null)
obj.Comment = Array.ConvertAll(Comment, i => i);
obj.Company = Company;
if (Configuration is not null)
obj.Configuration = Array.ConvertAll(Configuration, i => (Configuration)i.Clone());
obj.Control = Control;
obj.CRC = CRC;
obj.Country = Country;
obj.Description = Description;
obj.Developer = Developer;
if (Device is not null)
obj.Device = Array.ConvertAll(Device, i => (Device)i.Clone());
if (DeviceRef is not null)
obj.DeviceRef = Array.ConvertAll(DeviceRef, i => (DeviceRef)i.Clone());
if (DipSwitch is not null)
obj.DipSwitch = Array.ConvertAll(DipSwitch, i => (DipSwitch)i.Clone());
obj.DirName = DirName;
if (Disk is not null)
obj.Disk = Array.ConvertAll(Disk, i => (Disk)i.Clone());
if (Display is not null)
obj.Display = Array.ConvertAll(Display, i => (Display)i.Clone());
obj.DisplayCount = DisplayCount;
obj.DisplayType = DisplayType;
if (Driver is not null)
obj.Driver = (Driver)Driver.Clone();
if (Dump is not null)
obj.Dump = Array.ConvertAll(Dump, i => (Dump)i.Clone());
obj.DuplicateID = DuplicateID;
obj.Emulator = Emulator;
obj.Enabled = Enabled;
obj.Extra = Extra;
obj.Favorite = Favorite;
if (Feature is not null)
obj.Feature = Array.ConvertAll(Feature, i => (Feature)i.Clone());
obj.GenMSXID = GenMSXID;
obj.Genre = Genre;
obj.Hash = Hash;
obj.History = History;
obj.Id = Id;
obj.Im1CRC = Im1CRC;
obj.Im2CRC = Im2CRC;
obj.ImageNumber = ImageNumber;
if (Info is not null)
obj.Info = Array.ConvertAll(Info, i => (Info)i.Clone());
if (Input is not null)
obj.Input = (Input)Input.Clone();
obj.IsBios = IsBios;
obj.IsDevice = IsDevice;
obj.IsMechanical = IsMechanical;
obj.Language = Language;
obj.Location = Location;
obj.Manufacturer = Manufacturer;
if (Media is not null)
obj.Media = Array.ConvertAll(Media, i => (Media)i.Clone());
obj.Name = Name;
obj.Notes = Notes;
if (Part is not null)
obj.Part = Array.ConvertAll(Part, i => (Part)i.Clone());
obj.PlayedCount = PlayedCount;
obj.PlayedTime = PlayedTime;
obj.Players = Players;
if (Port is not null)
obj.Port = Array.ConvertAll(Port, i => (Port)i.Clone());
obj.Publisher = Publisher;
if (RamOption is not null)
obj.RamOption = Array.ConvertAll(RamOption, i => (RamOption)i.Clone());
obj.Ratings = Ratings;
obj.RebuildTo = RebuildTo;
obj.RelatedTo = RelatedTo;
if (Release is not null)
obj.Release = Array.ConvertAll(Release, i => (Release)i.Clone());
obj.ReleaseNumber = ReleaseNumber;
if (Rom is not null)
obj.Rom = Array.ConvertAll(Rom, i => (Rom)i.Clone());
obj.RomOf = RomOf;
obj.Rotation = Rotation;
obj.Runnable = Runnable;
if (Sample is not null)
obj.Sample = Array.ConvertAll(Sample, i => (Sample)i.Clone());
obj.SampleOf = SampleOf;
obj.SaveType = SaveType;
obj.Score = Score;
if (SharedFeat is not null)
obj.SharedFeat = Array.ConvertAll(SharedFeat, i => (SharedFeat)i.Clone());
if (Slot is not null)
obj.Slot = Array.ConvertAll(Slot, i => (Slot)i.Clone());
if (SoftwareList is not null)
obj.SoftwareList = Array.ConvertAll(SoftwareList, i => (SoftwareList)i.Clone());
if (Sound is not null)
obj.Sound = (Sound)Sound.Clone();
obj.Source = Source;
obj.SourceFile = SourceFile;
obj.SourceRom = SourceRom;
obj.Status = Status;
obj.Subgenre = Subgenre;
obj.Supported = Supported;
obj.System = System;
obj.Tags = Tags;
obj.TitleID = TitleID;
obj.Url = Url;
if (Video is not null)
obj.Video = Array.ConvertAll(Video, i => (Video)i.Clone());
obj.Year = Year;
return obj;
}
/// <inheritdoc/>
public bool Equals(Machine? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((Board is null) ^ (other.Board is null))
return false;
else if (Board is not null && !Board.Equals(other.Board, StringComparison.OrdinalIgnoreCase))
return false;
if ((Buttons is null) ^ (other.Buttons is null))
return false;
else if (Buttons is not null && !Buttons.Equals(other.Buttons, StringComparison.OrdinalIgnoreCase))
return false;
if ((CloneOf is null) ^ (other.CloneOf is null))
return false;
else if (CloneOf is not null && !CloneOf.Equals(other.CloneOf, StringComparison.OrdinalIgnoreCase))
return false;
if ((CloneOfId is null) ^ (other.CloneOfId is null))
return false;
else if (CloneOfId is not null && !CloneOfId.Equals(other.CloneOfId, StringComparison.OrdinalIgnoreCase))
return false;
if ((Company is null) ^ (other.Company is null))
return false;
else if (Company is not null && !Company.Equals(other.Company, StringComparison.OrdinalIgnoreCase))
return false;
if ((Control is null) ^ (other.Control is null))
return false;
else if (Control is not null && !Control.Equals(other.Control, StringComparison.OrdinalIgnoreCase))
return false;
if ((CRC is null) ^ (other.CRC is null))
return false;
else if (CRC is not null && !CRC.Equals(other.CRC, StringComparison.OrdinalIgnoreCase))
return false;
if ((Country is null) ^ (other.Country is null))
return false;
else if (Country is not null && !Country.Equals(other.Country, StringComparison.OrdinalIgnoreCase))
return false;
if ((Description is null) ^ (other.Description is null))
return false;
else if (Description is not null && !Description.Equals(other.Description, StringComparison.OrdinalIgnoreCase))
return false;
if ((Developer is null) ^ (other.Developer is null))
return false;
else if (Developer is not null && !Developer.Equals(other.Developer, StringComparison.OrdinalIgnoreCase))
return false;
if ((DirName is null) ^ (other.DirName is null))
return false;
else if (DirName is not null && !DirName.Equals(other.DirName, StringComparison.OrdinalIgnoreCase))
return false;
if ((DisplayCount is null) ^ (other.DisplayCount is null))
return false;
else if (DisplayCount is not null && !DisplayCount.Equals(other.DisplayCount, StringComparison.OrdinalIgnoreCase))
return false;
if ((DisplayType is null) ^ (other.DisplayType is null))
return false;
else if (DisplayType is not null && !DisplayType.Equals(other.DisplayType, StringComparison.OrdinalIgnoreCase))
return false;
if ((DuplicateID is null) ^ (other.DuplicateID is null))
return false;
else if (DuplicateID is not null && !DuplicateID.Equals(other.DuplicateID, StringComparison.OrdinalIgnoreCase))
return false;
if ((Emulator is null) ^ (other.Emulator is null))
return false;
else if (Emulator is not null && !Emulator.Equals(other.Emulator, StringComparison.OrdinalIgnoreCase))
return false;
if ((Enabled is null) ^ (other.Enabled is null))
return false;
else if (Enabled is not null && !Enabled.Equals(other.Enabled, StringComparison.OrdinalIgnoreCase))
return false;
if ((Extra is null) ^ (other.Extra is null))
return false;
else if (Extra is not null && !Extra.Equals(other.Extra, StringComparison.OrdinalIgnoreCase))
return false;
if ((Favorite is null) ^ (other.Favorite is null))
return false;
else if (Favorite is not null && !Favorite.Equals(other.Favorite, StringComparison.OrdinalIgnoreCase))
return false;
if ((GenMSXID is null) ^ (other.GenMSXID is null))
return false;
else if (GenMSXID is not null && !GenMSXID.Equals(other.GenMSXID, StringComparison.OrdinalIgnoreCase))
return false;
if ((Genre is null) ^ (other.Genre is null))
return false;
else if (Genre is not null && !Genre.Equals(other.Genre, StringComparison.OrdinalIgnoreCase))
return false;
if ((Hash is null) ^ (other.Hash is null))
return false;
else if (Hash is not null && !Hash.Equals(other.Hash, StringComparison.OrdinalIgnoreCase))
return false;
if ((History is null) ^ (other.History is null))
return false;
else if (History is not null && !History.Equals(other.History, StringComparison.OrdinalIgnoreCase))
return false;
if ((Id is null) ^ (other.Id is null))
return false;
else if (Id is not null && !Id.Equals(other.Id, StringComparison.OrdinalIgnoreCase))
return false;
if ((Im1CRC is null) ^ (other.Im1CRC is null))
return false;
else if (Im1CRC is not null && !Im1CRC.Equals(other.Im1CRC, StringComparison.OrdinalIgnoreCase))
return false;
if ((Im2CRC is null) ^ (other.Im2CRC is null))
return false;
else if (Im2CRC is not null && !Im2CRC.Equals(other.Im2CRC, StringComparison.OrdinalIgnoreCase))
return false;
if ((ImageNumber is null) ^ (other.ImageNumber is null))
return false;
else if (ImageNumber is not null && !ImageNumber.Equals(other.ImageNumber, StringComparison.OrdinalIgnoreCase))
return false;
if (IsBios != other.IsBios)
return false;
if (IsDevice != other.IsDevice)
return false;
if (IsMechanical != other.IsMechanical)
return false;
if ((Language is null) ^ (other.Language is null))
return false;
else if (Language is not null && !Language.Equals(other.Language, StringComparison.OrdinalIgnoreCase))
return false;
if ((Location is null) ^ (other.Location is null))
return false;
else if (Location is not null && !Location.Equals(other.Location, StringComparison.OrdinalIgnoreCase))
return false;
if ((Manufacturer is null) ^ (other.Manufacturer is null))
return false;
else if (Manufacturer is not null && !Manufacturer.Equals(other.Manufacturer, StringComparison.OrdinalIgnoreCase))
return false;
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
if ((Notes is null) ^ (other.Notes is null))
return false;
else if (Notes is not null && !Notes.Equals(other.Notes, StringComparison.OrdinalIgnoreCase))
return false;
if ((PlayedCount is null) ^ (other.PlayedCount is null))
return false;
else if (PlayedCount is not null && !PlayedCount.Equals(other.PlayedCount, StringComparison.OrdinalIgnoreCase))
return false;
if ((PlayedTime is null) ^ (other.PlayedTime is null))
return false;
else if (PlayedTime is not null && !PlayedTime.Equals(other.PlayedTime, StringComparison.OrdinalIgnoreCase))
return false;
if ((Players is null) ^ (other.Players is null))
return false;
else if (Players is not null && !Players.Equals(other.Players, StringComparison.OrdinalIgnoreCase))
return false;
if ((Publisher is null) ^ (other.Publisher is null))
return false;
else if (Publisher is not null && !Publisher.Equals(other.Publisher, StringComparison.OrdinalIgnoreCase))
return false;
if ((Ratings is null) ^ (other.Ratings is null))
return false;
else if (Ratings is not null && !Ratings.Equals(other.Ratings, StringComparison.OrdinalIgnoreCase))
return false;
if ((RebuildTo is null) ^ (other.RebuildTo is null))
return false;
else if (RebuildTo is not null && !RebuildTo.Equals(other.RebuildTo, StringComparison.OrdinalIgnoreCase))
return false;
if ((RelatedTo is null) ^ (other.RelatedTo is null))
return false;
else if (RelatedTo is not null && !RelatedTo.Equals(other.RelatedTo, StringComparison.OrdinalIgnoreCase))
return false;
if ((ReleaseNumber is null) ^ (other.ReleaseNumber is null))
return false;
else if (ReleaseNumber is not null && !ReleaseNumber.Equals(other.ReleaseNumber, StringComparison.OrdinalIgnoreCase))
return false;
if ((RomOf is null) ^ (other.RomOf is null))
return false;
else if (RomOf is not null && !RomOf.Equals(other.RomOf, StringComparison.OrdinalIgnoreCase))
return false;
if ((Rotation is null) ^ (other.Rotation is null))
return false;
else if (Rotation is not null && !Rotation.Equals(other.Rotation, StringComparison.OrdinalIgnoreCase))
return false;
if (Runnable != other.Runnable)
return false;
if ((SampleOf is null) ^ (other.SampleOf is null))
return false;
else if (SampleOf is not null && !SampleOf.Equals(other.SampleOf, StringComparison.OrdinalIgnoreCase))
return false;
if ((SaveType is null) ^ (other.SaveType is null))
return false;
else if (SaveType is not null && !SaveType.Equals(other.SaveType, StringComparison.OrdinalIgnoreCase))
return false;
if ((Score is null) ^ (other.Score is null))
return false;
else if (Score is not null && !Score.Equals(other.Score, StringComparison.OrdinalIgnoreCase))
return false;
if ((Source is null) ^ (other.Source is null))
return false;
else if (Source is not null && !Source.Equals(other.Source, StringComparison.OrdinalIgnoreCase))
return false;
if ((SourceFile is null) ^ (other.SourceFile is null))
return false;
else if (SourceFile is not null && !SourceFile.Equals(other.SourceFile, StringComparison.OrdinalIgnoreCase))
return false;
if ((SourceRom is null) ^ (other.SourceRom is null))
return false;
else if (SourceRom is not null && !SourceRom.Equals(other.SourceRom, StringComparison.OrdinalIgnoreCase))
return false;
if ((Status is null) ^ (other.Status is null))
return false;
else if (Status is not null && !Status.Equals(other.Status, StringComparison.OrdinalIgnoreCase))
return false;
if ((Subgenre is null) ^ (other.Subgenre is null))
return false;
else if (Subgenre is not null && !Subgenre.Equals(other.Subgenre, StringComparison.OrdinalIgnoreCase))
return false;
if (Supported != other.Supported)
return false;
if ((System is null) ^ (other.System is null))
return false;
else if (System is not null && !System.Equals(other.System, StringComparison.OrdinalIgnoreCase))
return false;
if ((Tags is null) ^ (other.Tags is null))
return false;
else if (Tags is not null && !Tags.Equals(other.Tags, StringComparison.OrdinalIgnoreCase))
return false;
if ((TitleID is null) ^ (other.TitleID is null))
return false;
else if (TitleID is not null && !TitleID.Equals(other.TitleID, StringComparison.OrdinalIgnoreCase))
return false;
if ((Url is null) ^ (other.Url is null))
return false;
else if (Url is not null && !Url.Equals(other.Url, StringComparison.OrdinalIgnoreCase))
return false;
if ((Year is null) ^ (other.Year is null))
return false;
else if (Year is not null && !Year.Equals(other.Year, StringComparison.OrdinalIgnoreCase))
return false;
// Sub-items
if ((Driver is null) ^ (other.Driver is null))
return false;
else if (Driver is not null && other.Driver is not null && Driver.Equals(other.Driver))
return false;
if ((Input is null) ^ (other.Input is null))
return false;
else if (Input is not null && other.Input is not null && Input.Equals(other.Input))
return false;
if ((Sound is null) ^ (other.Sound is null))
return false;
else if (Sound is not null && other.Sound is not null && Sound.Equals(other.Sound))
return false;
// TODO: Figure out how to properly check arrays
return true;
}
}
}

View File

@@ -1,30 +1,41 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
// TODO: IEquatable<Media>
[JsonObject("media"), XmlRoot("media")]
public class Media : DatItem
public class Media : DatItem, ICloneable
{
#region Keys
#region Properties
/// <remarks>string</remarks>
public const string MD5Key = "md5";
public string? MD5 { get; set; }
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
/// <remarks>string</remarks>
public const string SHA1Key = "sha1";
public string? SHA1 { get; set; }
/// <remarks>string</remarks>
public const string SHA256Key = "sha256";
public string? SHA256 { get; set; }
/// <remarks>string</remarks>
public const string SpamSumKey = "spamsum";
public string? SpamSum { get; set; }
#endregion
public Media() => Type = ItemType.Media;
public Media() => ItemType = ItemType.Media;
/// <inheritdoc/>
public object Clone()
{
var obj = new Media();
obj.MD5 = MD5;
obj.Name = Name;
obj.SHA1 = SHA1;
obj.SHA256 = SHA256;
obj.SpamSum = SpamSum;
return obj;
}
}
}

View File

@@ -4,22 +4,14 @@ namespace SabreTools.Data.Models.Metadata
/// <summary>
/// Format-agnostic representation of a full metadata file
/// </summary>
public class MetadataFile : DictionaryBase
/// TODO: ICloneable
/// TODO: IComparable<MetadataFile>
public class MetadataFile
{
#region Keys
public Header? Header { get; set; }
/// <remarks>Machine[]</remarks>
[NoFilter]
public const string MachineKey = "machine";
public InfoSource? InfoSource { get; set; }
/// <remarks>Header</remarks>
[NoFilter]
public const string HeaderKey = "header";
/// <remarks>InfoSource</remarks>
[NoFilter]
public const string InfoSourceKey = "infosource";
#endregion
public Machine[]? Machine { get; set; }
}
}

View File

@@ -1,21 +1,50 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("original"), XmlRoot("original")]
public class Original : DatItem
public class Original : DatItem, ICloneable, IEquatable<Original>
{
#region Keys
#region Properties
/// <remarks>string</remarks>
public const string ContentKey = "content";
public string? Content { get; set; }
/// <remarks>bool</remarks>
public const string ValueKey = "value";
public bool? Value { get; set; }
#endregion
public Original() => Type = ItemType.Original;
public Original() => ItemType = ItemType.Original;
/// <inheritdoc/>
public object Clone()
{
var obj = new Original();
obj.Content = Content;
obj.Value = Value;
return obj;
}
/// <inheritdoc/>
public bool Equals(Original? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((Content is null) ^ (other.Content is null))
return false;
else if (Content is not null && !Content.Equals(other.Content, StringComparison.OrdinalIgnoreCase))
return false;
if (Value != other.Value)
return false;
return true;
}
}
}

View File

@@ -1,37 +1,71 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("part"), XmlRoot("part")]
public class Part : DatItem
public class Part : DatItem, ICloneable, IEquatable<Part>
{
#region Keys
#region Properties
/// <remarks>DataArea[]</remarks>
[NoFilter]
public const string DataAreaKey = "dataarea";
public DataArea[]? DataArea { get; set; }
/// <remarks>DiskArea[]</remarks>
[NoFilter]
public const string DiskAreaKey = "diskarea";
public DiskArea[]? DiskArea { get; set; }
/// <remarks>DipSwitch[]</remarks>
[NoFilter]
public const string DipSwitchKey = "dipswitch";
public DipSwitch[]? DipSwitch { get; set; }
/// <remarks>Feature[]</remarks>
[NoFilter]
public const string FeatureKey = "feature";
public Feature[]? Feature { get; set; }
/// <remarks>string</remarks>
public const string InterfaceKey = "interface";
public string? Interface { get; set; }
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
#endregion
public Part() => Type = ItemType.Part;
public Part() => ItemType = ItemType.Part;
/// <inheritdoc/>
public object Clone()
{
var obj = new Part();
if (DataArea is not null)
obj.DataArea = Array.ConvertAll(DataArea, i => (DataArea)i.Clone());
if (DiskArea is not null)
obj.DiskArea = Array.ConvertAll(DiskArea, i => (DiskArea)i.Clone());
if (DipSwitch is not null)
obj.DipSwitch = Array.ConvertAll(DipSwitch, i => (DipSwitch)i.Clone());
if (Feature is not null)
obj.Feature = Array.ConvertAll(Feature, i => (Feature)i.Clone());
obj.Interface = Interface;
obj.Name = Name;
return obj;
}
/// <inheritdoc/>
public bool Equals(Part? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((Interface is null) ^ (other.Interface is null))
return false;
else if (Interface is not null && !Interface.Equals(other.Interface, StringComparison.OrdinalIgnoreCase))
return false;
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
// Sub-items
// TODO: Figure out how to properly check arrays
return true;
}
}
}

View File

@@ -1,22 +1,51 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("port"), XmlRoot("port")]
public class Port : DatItem
public class Port : DatItem, ICloneable, IEquatable<Port>
{
#region Keys
#region Properties
/// <remarks>Analog[]</remarks>
[NoFilter]
public const string AnalogKey = "analog";
public Analog[]? Analog { get; set; }
/// <remarks>string</remarks>
public const string TagKey = "tag";
public string? Tag { get; set; }
#endregion
public Port() => Type = ItemType.Port;
public Port() => ItemType = ItemType.Port;
/// <inheritdoc/>
public object Clone()
{
var obj = new Port();
if (Analog is not null)
obj.Analog = Array.ConvertAll(Analog, i => (Analog)i.Clone());
obj.Tag = Tag;
return obj;
}
/// <inheritdoc/>
public bool Equals(Port? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((Tag is null) ^ (other.Tag is null))
return false;
else if (Tag is not null && !Tag.Equals(other.Tag, StringComparison.OrdinalIgnoreCase))
return false;
// Sub-items
// TODO: Figure out how to properly check arrays
return true;
}
}
}

View File

@@ -1,24 +1,59 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("ramoption"), XmlRoot("ramoption")]
public class RamOption : DatItem
public class RamOption : DatItem, ICloneable, IEquatable<RamOption>
{
#region Keys
#region Properties
/// <remarks>string</remarks>
public const string ContentKey = "content";
public string? Content { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string DefaultKey = "default";
public bool? Default { get; set; }
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
#endregion
public RamOption() => Type = ItemType.RamOption;
public RamOption() => ItemType = ItemType.RamOption;
/// <inheritdoc/>
public object Clone()
{
var obj = new RamOption();
obj.Content = Content;
obj.Default = Default;
obj.Name = Name;
return obj;
}
/// <inheritdoc/>
public bool Equals(RamOption? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((Content is null) ^ (other.Content is null))
return false;
else if (Content is not null && !Content.Equals(other.Content, StringComparison.OrdinalIgnoreCase))
return false;
if (Default != other.Default)
return false;
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
return true;
}
}
}

View File

@@ -1,30 +1,75 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("release"), XmlRoot("release")]
public class Release : DatItem
public class Release : DatItem, ICloneable, IEquatable<Release>
{
#region Keys
#region Properties
/// <remarks>string</remarks>
public const string DateKey = "date";
public string? Date { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string DefaultKey = "default";
public bool? Default { get; set; }
/// <remarks>string</remarks>
public const string LanguageKey = "language";
public string? Language { get; set; }
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
/// <remarks>string</remarks>
public const string RegionKey = "region";
public string? Region { get; set; }
#endregion
public Release() => Type = ItemType.Release;
public Release() => ItemType = ItemType.Release;
/// <inheritdoc/>
public object Clone()
{
var obj = new Release();
obj.Date = Date;
obj.Default = Default;
obj.Language = Language;
obj.Name = Name;
obj.Region = Region;
return obj;
}
/// <inheritdoc/>
public bool Equals(Release? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((Date is null) ^ (other.Date is null))
return false;
else if (Date is not null && !Date.Equals(other.Date, StringComparison.OrdinalIgnoreCase))
return false;
if (Default != other.Default)
return false;
if ((Language is null) ^ (other.Language is null))
return false;
else if (Language is not null && !Language.Equals(other.Language, StringComparison.OrdinalIgnoreCase))
return false;
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
if ((Region is null) ^ (other.Region is null))
return false;
else if (Region is not null && !Region.Equals(other.Region, StringComparison.OrdinalIgnoreCase))
return false;
return true;
}
}
}

View File

@@ -1,63 +1,164 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("release_details"), XmlRoot("release_details")]
public class ReleaseDetails : DatItem
public class ReleaseDetails : DatItem, ICloneable, IEquatable<ReleaseDetails>
{
#region Keys
#region Properties
/// <remarks>string</remarks>
public const string IdKey = "id";
public string? AppendToNumber { get; set; }
/// <remarks>string</remarks>
public const string AppendToNumberKey = "appendtonumber";
public string? ArchiveName { get; set; }
/// <remarks>string</remarks>
public const string DateKey = "date";
public string? Category { get; set; }
/// <remarks>string</remarks>
public const string OriginalFormatKey = "originalformat";
public string? Comment { get; set; }
/// <remarks>string</remarks>
public const string GroupKey = "group";
public string? Date { get; set; }
/// <remarks>string</remarks>
public const string DirNameKey = "dirname";
public string? DirName { get; set; }
/// <remarks>string</remarks>
public const string NfoNameKey = "nfoname";
public string? Group { get; set; }
/// <remarks>string</remarks>
public const string NfoSizeKey = "nfosize";
public string? Id { get; set; }
/// <remarks>string</remarks>
public const string NfoCRCKey = "nfocrc";
public string? NfoCRC { get; set; }
/// <remarks>string</remarks>
public const string ArchiveNameKey = "archivename";
public string? NfoName { get; set; }
/// <remarks>string</remarks>
public const string RomInfoKey = "rominfo";
public string? NfoSize { get; set; }
/// <remarks>string</remarks>
public const string CategoryKey = "category";
public string? Origin { get; set; }
/// <remarks>string</remarks>
public const string CommentKey = "comment";
public string? OriginalFormat { get; set; }
/// <remarks>string</remarks>
public const string ToolKey = "tool";
public string? Region { get; set; }
/// <remarks>string</remarks>
public const string RegionKey = "region";
public string? RomInfo { get; set; }
/// <remarks>string</remarks>
public const string OriginKey = "origin";
public string? Tool { get; set; }
#endregion
public ReleaseDetails() => Type = ItemType.ReleaseDetails;
public ReleaseDetails() => ItemType = ItemType.ReleaseDetails;
/// <inheritdoc/>
public object Clone()
{
var obj = new ReleaseDetails();
obj.AppendToNumber = AppendToNumber;
obj.ArchiveName = ArchiveName;
obj.Category = Category;
obj.Comment = Comment;
obj.Date = Date;
obj.DirName = DirName;
obj.Group = Group;
obj.Id = Id;
obj.NfoCRC = NfoCRC;
obj.NfoName = NfoName;
obj.NfoSize = NfoSize;
obj.Origin = Origin;
obj.OriginalFormat = OriginalFormat;
obj.Region = Region;
obj.RomInfo = RomInfo;
obj.Tool = Tool;
return obj;
}
/// <inheritdoc/>
public bool Equals(ReleaseDetails? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((AppendToNumber is null) ^ (other.AppendToNumber is null))
return false;
else if (AppendToNumber is not null && !AppendToNumber.Equals(other.AppendToNumber, StringComparison.OrdinalIgnoreCase))
return false;
if ((ArchiveName is null) ^ (other.ArchiveName is null))
return false;
else if (ArchiveName is not null && !ArchiveName.Equals(other.ArchiveName, StringComparison.OrdinalIgnoreCase))
return false;
if ((Category is null) ^ (other.Category is null))
return false;
else if (Category is not null && !Category.Equals(other.Category, StringComparison.OrdinalIgnoreCase))
return false;
if ((Comment is null) ^ (other.Comment is null))
return false;
else if (Comment is not null && !Comment.Equals(other.Comment, StringComparison.OrdinalIgnoreCase))
return false;
if ((Date is null) ^ (other.Date is null))
return false;
else if (Date is not null && !Date.Equals(other.Date, StringComparison.OrdinalIgnoreCase))
return false;
if ((DirName is null) ^ (other.DirName is null))
return false;
else if (DirName is not null && !DirName.Equals(other.DirName, StringComparison.OrdinalIgnoreCase))
return false;
if ((Group is null) ^ (other.Group is null))
return false;
else if (Group is not null && !Group.Equals(other.Group, StringComparison.OrdinalIgnoreCase))
return false;
if ((Id is null) ^ (other.Id is null))
return false;
else if (Id is not null && !Id.Equals(other.Id, StringComparison.OrdinalIgnoreCase))
return false;
if ((NfoCRC is null) ^ (other.NfoCRC is null))
return false;
else if (NfoCRC is not null && !NfoCRC.Equals(other.NfoCRC, StringComparison.OrdinalIgnoreCase))
return false;
if ((NfoName is null) ^ (other.NfoName is null))
return false;
else if (NfoName is not null && !NfoName.Equals(other.NfoName, StringComparison.OrdinalIgnoreCase))
return false;
if ((NfoSize is null) ^ (other.NfoSize is null))
return false;
else if (NfoSize is not null && !NfoSize.Equals(other.NfoSize, StringComparison.OrdinalIgnoreCase))
return false;
if ((Origin is null) ^ (other.Origin is null))
return false;
else if (Origin is not null && !Origin.Equals(other.Origin, StringComparison.OrdinalIgnoreCase))
return false;
if ((OriginalFormat is null) ^ (other.OriginalFormat is null))
return false;
else if (OriginalFormat is not null && !OriginalFormat.Equals(other.OriginalFormat, StringComparison.OrdinalIgnoreCase))
return false;
if ((Region is null) ^ (other.Region is null))
return false;
else if (Region is not null && !Region.Equals(other.Region, StringComparison.OrdinalIgnoreCase))
return false;
if ((RomInfo is null) ^ (other.RomInfo is null))
return false;
else if (RomInfo is not null && !RomInfo.Equals(other.RomInfo, StringComparison.OrdinalIgnoreCase))
return false;
if ((Tool is null) ^ (other.Tool is null))
return false;
else if (Tool is not null && !Tool.Equals(other.Tool, StringComparison.OrdinalIgnoreCase))
return false;
return true;
}
}
}

View File

@@ -1,303 +1,390 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
// TODO: IEquatable<Rom>
[JsonObject("rom"), XmlRoot("rom")]
public class Rom : DatItem
public class Rom : DatItem, ICloneable
{
#region Keys
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string AlbumKey = "album";
/// <remarks>string; AttractMode.Row</remarks>
public const string AltRomnameKey = "alt_romname";
/// <remarks>string; AttractMode.Row</remarks>
public const string AltTitleKey = "alt_title";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string ArtistKey = "artist";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string ASRDetectedLangKey = "asr_detected_lang";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string ASRDetectedLangConfKey = "asr_detected_lang_conf";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string ASRTranscribedLangKey = "asr_transcribed_lang";
/// <remarks>string</remarks>
public const string BiosKey = "bios";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string BitrateKey = "bitrate";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string BitTorrentMagnetHashKey = "btih";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string ClothCoverDetectionModuleVersionKey = "cloth_cover_detection_module_version";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string CollectionCatalogNumberKey = "collection-catalog-number";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string CommentKey = "comment";
/// <remarks>string; Also "crc32" in ArchiveDotOrg.File</remarks>
public const string CRCKey = "crc";
/// <remarks>string</remarks>
public const string CRC16Key = "crc16";
/// <remarks>string</remarks>
public const string CRC64Key = "crc64";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string CreatorKey = "creator";
/// <remarks>string</remarks>
public const string DateKey = "date";
#region Properties
/// <remarks>(yes|no) "no"</remarks>
public const string DisposeKey = "dispose";
public bool? Dispose { get; set; }
/// <remarks>string; OfflineList.FileRomCRC</remarks>
public const string ExtensionKey = "extension";
/// <remarks>long; ArchiveDotOrg.File</remarks>
public const string FileCountKey = "filecount";
/// <remarks>ArchiveDotOrg.File</remarks>
public long? FileCount { get; set; }
/// <remarks>bool; AttractMode.Row</remarks>
public const string FileIsAvailableKey = "file_is_available";
/// <remarks>string</remarks>
public const string FlagsKey = "flags";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string FormatKey = "format";
/// <remarks>string</remarks>
public const string HeaderKey = "header";
/// <remarks>string, possibly long; ArchiveDotOrg.File</remarks>
public const string HeightKey = "height";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string hOCRCharToWordhOCRVersionKey = "hocr_char_to_word_hocr_version";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string hOCRCharToWordModuleVersionKey = "hocr_char_to_word_module_version";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string hOCRFtsTexthOCRVersionKey = "hocr_fts_text_hocr_version";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string hOCRFtsTextModuleVersionKey = "hocr_fts_text_module_version";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string hOCRPageIndexhOCRVersionKey = "hocr_pageindex_hocr_version";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string hOCRPageIndexModuleVersionKey = "hocr_pageindex_module_version";
public bool? FileIsAvailable { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string InvertedKey = "inverted";
/// <remarks>long; ArchiveDotOrg.File</remarks>
public const string LastModifiedTimeKey = "mtime";
/// <remarks>string, possibly long; Also in ArchiveDotOrg.File</remarks>
public const string LengthKey = "length";
public bool? Inverted { get; set; }
/// <remarks>(load16_byte|load16_word|load16_word_swap|load32_byte|load32_word|load32_word_swap|load32_dword|load64_word|load64_word_swap|reload|fill|continue|reload_plain|ignore)</remarks>
public const string LoadFlagKey = "loadflag";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string MatrixNumberKey = "matrix_number";
/// <remarks>string</remarks>
public const string MD2Key = "md2";
/// <remarks>string</remarks>
public const string MD4Key = "md4";
/// <remarks>string</remarks>
public const string MD5Key = "md5";
/// <remarks>string; OpenMSX.RomBase</remarks>
public const string OpenMSXMediaType = "mediatype";
/// <remarks>string</remarks>
public const string MergeKey = "merge";
public LoadFlag? LoadFlag { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string MIAKey = "mia";
public bool? MIA { get; set; }
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string TesseractOCRKey = "ocr";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string TesseractOCRConvertedKey = "ocr_converted";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string TesseractOCRDetectedLangKey = "ocr_detected_lang";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string TesseractOCRDetectedLangConfKey = "ocr_detected_lang_conf";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string TesseractOCRDetectedScriptKey = "ocr_detected_script";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string TesseractOCRDetectedScriptConfKey = "ocr_detected_script_conf";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string TesseractOCRModuleVersionKey = "ocr_module_version";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string TesseractOCRParametersKey = "ocr_parameters";
/// <remarks>string, possibly long; Originally "offs"</remarks>
public const string OffsetKey = "offset";
/// <remarks>OpenMSX.RomBase</remarks>
public OpenMSXSubType? OpenMSXMediaType { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string OptionalKey = "optional";
public bool? Optional { get; set; }
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string OriginalKey = "original";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string PDFModuleVersionKey = "pdf_module_version";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string PreviewImageKey = "preview-image";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string PublisherKey = "publisher";
/// <remarks>string</remarks>
public const string RegionKey = "region";
/// <remarks>string; OpenMSX.RomBase</remarks>
public const string RemarkKey = "remark";
/// <remarks>string</remarks>
public const string RIPEMD128Key = "ripemd128";
/// <remarks>string</remarks>
public const string RIPEMD160Key = "ripemd160";
/// <remarks>string, possibly long; ArchiveDotOrg.File</remarks>
public const string RotationKey = "rotation";
/// <remarks>string</remarks>
public const string SerialKey = "serial";
/// <remarks>string</remarks>
public const string SHA1Key = "sha1";
/// <remarks>string</remarks>
public const string SHA256Key = "sha256";
/// <remarks>string</remarks>
public const string SHA384Key = "sha384";
/// <remarks>string</remarks>
public const string SHA512Key = "sha512";
/// <remarks>long</remarks>
public const string SizeKey = "size";
public long? Size { get; set; }
/// <remarks>(yes|no) "no"</remarks>
public const string SoundOnlyKey = "soundonly";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string SourceKey = "source";
/// <remarks>string</remarks>
public const string SpamSumKey = "spamsum";
/// <remarks>string, possibly long; OpenMSX.RomBase</remarks>
public const string StartKey = "start";
public bool? SoundOnly { get; set; }
/// <remarks>(baddump|nodump|good|verified) "good"</remarks>
public const string StatusKey = "status";
public ItemStatus? Status { get; set; }
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string SummationKey = "summation";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string TitleKey = "title";
/// <remarks>string, possibly long; ArchiveDotOrg.File</remarks>
public const string TrackKey = "track";
/// <remarks>string; OpenMSX.RomBase</remarks>
public const string OpenMSXType = "type";
/// <remarks>string</remarks>
public const string ValueKey = "value";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string WhisperASRModuleVersionKey = "whisper_asr_module_version";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string WhisperModelHashKey = "whisper_model_hash";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string WhisperModelNameKey = "whisper_model_name";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string WhisperVersionKey = "whisper_version";
/// <remarks>string, possibly long; ArchiveDotOrg.File</remarks>
public const string WidthKey = "width";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string WordConfidenceInterval0To10Key = "word_conf_0_10";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string WordConfidenceInterval11To20Key = "word_conf_11_20";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string WordConfidenceInterval21To30Key = "word_conf_21_30";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string WordConfidenceInterval31To40Key = "word_conf_31_40";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string WordConfidenceInterval41To50Key = "word_conf_41_50";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string WordConfidenceInterval51To60Key = "word_conf_51_60";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string WordConfidenceInterval61To70Key = "word_conf_61_70";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string WordConfidenceInterval71To80Key = "word_conf_71_80";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string WordConfidenceInterval81To90Key = "word_conf_81_90";
/// <remarks>string; ArchiveDotOrg.File</remarks>
public const string WordConfidenceInterval91To100Key = "word_conf_91_100";
/// <remarks>string</remarks>
public const string xxHash364Key = "xxh3_64";
/// <remarks>string</remarks>
public const string xxHash3128Key = "xxh3_128";
public string? Value { get; set; }
#endregion
public Rom() => Type = ItemType.Rom;
#region Keys
/// <remarks>ArchiveDotOrg.File</remarks>
public string? Album { get; set; }
/// <remarks>AttractMode.Row</remarks>
public string? AltRomname { get; set; }
/// <remarks>AttractMode.Row</remarks>
public string? AltTitle { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? Artist { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? ASRDetectedLang { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? ASRDetectedLangConf { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? ASRTranscribedLang { get; set; }
public string? Bios { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? Bitrate { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? BitTorrentMagnetHash { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? ClothCoverDetectionModuleVersion { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? CollectionCatalogNumber { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? Comment { get; set; }
public string? CRC16 { get; set; }
/// <remarks>Mainly "crc", named here for clarity</remarks>
public string? CRC32 { get; set; }
public string? CRC64 { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? Creator { get; set; }
public string? Date { get; set; }
/// <remarks>OfflineList.FileRomCRC</remarks>
public string? Extension { get; set; }
public string? Flags { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? Format { get; set; }
public string? Header { get; set; }
/// <remarks>Possibly long; ArchiveDotOrg.File</remarks>
public string? Height { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? hOCRCharToWordhOCRVersion { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? hOCRCharToWordModuleVersion { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? hOCRFtsTexthOCRVersion { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? hOCRFtsTextModuleVersion { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? hOCRPageIndexhOCRVersion { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? hOCRPageIndexModuleVersion { get; set; }
/// <remarks>Possibly long; ArchiveDotOrg.File</remarks>
public string? LastModifiedTime { get; set; }
/// <remarks>Possibly long; Also in ArchiveDotOrg.File</remarks>
public string? Length { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? MatrixNumber { get; set; }
public string? MD2 { get; set; }
public string? MD4 { get; set; }
public string? MD5 { get; set; }
public string? Merge { get; set; }
/// <remarks>Possibly long; Originally "offs"</remarks>
public string? Offset { get; set; }
/// <remarks>OpenMSX.RomBase</remarks>
public string? OpenMSXType { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? Original { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? PDFModuleVersion { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? PreviewImage { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? Publisher { get; set; }
public string? Region { get; set; }
/// <remarks>OpenMSX.RomBase</remarks>
public string? Remark { get; set; }
public string? RIPEMD128 { get; set; }
public string? RIPEMD160 { get; set; }
/// <remarks>Possibly long; ArchiveDotOrg.File</remarks>
public string? Rotation { get; set; }
public string? Serial { get; set; }
public string? SHA1 { get; set; }
public string? SHA256 { get; set; }
public string? SHA384 { get; set; }
public string? SHA512 { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? Source { get; set; }
public string? SpamSum { get; set; }
/// <remarks>Possibly long; OpenMSX.RomBase</remarks>
public string? Start { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? Summation { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? TesseractOCR { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? TesseractOCRConverted { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? TesseractOCRDetectedLang { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? TesseractOCRDetectedLangConf { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? TesseractOCRDetectedScript { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? TesseractOCRDetectedScriptConf { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? TesseractOCRModuleVersion { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? TesseractOCRParameters { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? Title { get; set; }
/// <remarks>Possibly long; ArchiveDotOrg.File</remarks>
public string? Track { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? WhisperASRModuleVersion { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? WhisperModelHash { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? WhisperModelName { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? WhisperVersion { get; set; }
/// <remarks>Possibly long; ArchiveDotOrg.File</remarks>
public string? Width { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? WordConfidenceInterval0To10 { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? WordConfidenceInterval11To20 { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? WordConfidenceInterval21To30 { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? WordConfidenceInterval31To40 { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? WordConfidenceInterval41To50 { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? WordConfidenceInterval51To60 { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? WordConfidenceInterval61To70 { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? WordConfidenceInterval71To80 { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? WordConfidenceInterval81To90 { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? WordConfidenceInterval91To100 { get; set; }
public string? xxHash364 { get; set; }
public string? xxHash3128 { get; set; }
#endregion
public Rom() => ItemType = ItemType.Rom;
/// <inheritdoc/>
public object Clone()
{
var obj = new Rom();
obj.Album = Album;
obj.AltRomname = AltRomname;
obj.AltTitle = AltTitle;
obj.Artist = Artist;
obj.ASRDetectedLang = ASRDetectedLang;
obj.ASRDetectedLangConf = ASRDetectedLangConf;
obj.ASRTranscribedLang = ASRTranscribedLang;
obj.Bios = Bios;
obj.Bitrate = Bitrate;
obj.BitTorrentMagnetHash = BitTorrentMagnetHash;
obj.ClothCoverDetectionModuleVersion = ClothCoverDetectionModuleVersion;
obj.CollectionCatalogNumber = CollectionCatalogNumber;
obj.Comment = Comment;
obj.CRC16 = CRC16;
obj.CRC32 = CRC32;
obj.CRC64 = CRC64;
obj.Creator = Creator;
obj.Date = Date;
obj.Dispose = Dispose;
obj.Extension = Extension;
obj.FileCount = FileCount;
obj.FileIsAvailable = FileIsAvailable;
obj.Flags = Flags;
obj.Format = Format;
obj.Header = Header;
obj.Height = Height;
obj.hOCRCharToWordhOCRVersion = hOCRCharToWordhOCRVersion;
obj.hOCRCharToWordModuleVersion = hOCRCharToWordModuleVersion;
obj.hOCRFtsTexthOCRVersion = hOCRFtsTexthOCRVersion;
obj.hOCRFtsTextModuleVersion = hOCRFtsTextModuleVersion;
obj.hOCRPageIndexhOCRVersion = hOCRPageIndexhOCRVersion;
obj.hOCRPageIndexModuleVersion = hOCRPageIndexModuleVersion;
obj.Inverted = Inverted;
obj.LastModifiedTime = LastModifiedTime;
obj.Length = Length;
obj.LoadFlag = LoadFlag;
obj.MatrixNumber = MatrixNumber;
obj.MD2 = MD2;
obj.MD4 = MD4;
obj.MD5 = MD5;
obj.Merge = Merge;
obj.MIA = MIA;
obj.Name = Name;
obj.Offset = Offset;
obj.OpenMSXType = OpenMSXType;
obj.OpenMSXMediaType = OpenMSXMediaType;
obj.Optional = Optional;
obj.Original = Original;
obj.PDFModuleVersion = PDFModuleVersion;
obj.PreviewImage = PreviewImage;
obj.Publisher = Publisher;
obj.Region = Region;
obj.Remark = Remark;
obj.RIPEMD128 = RIPEMD128;
obj.RIPEMD160 = RIPEMD160;
obj.Rotation = Rotation;
obj.Serial = Serial;
obj.SHA1 = SHA1;
obj.SHA256 = SHA256;
obj.SHA384 = SHA384;
obj.SHA512 = SHA512;
obj.Size = Size;
obj.SoundOnly = SoundOnly;
obj.Source = Source;
obj.SpamSum = SpamSum;
obj.Start = Start;
obj.Status = Status;
obj.Summation = Summation;
obj.TesseractOCR = TesseractOCR;
obj.TesseractOCRConverted = TesseractOCRConverted;
obj.TesseractOCRDetectedLang = TesseractOCRDetectedLang;
obj.TesseractOCRDetectedLangConf = TesseractOCRDetectedLangConf;
obj.TesseractOCRDetectedScript = TesseractOCRDetectedScript;
obj.TesseractOCRDetectedScriptConf = TesseractOCRDetectedScriptConf;
obj.TesseractOCRModuleVersion = TesseractOCRModuleVersion;
obj.TesseractOCRParameters = TesseractOCRParameters;
obj.Title = Title;
obj.Track = Track;
obj.Value = Value;
obj.WhisperASRModuleVersion = WhisperASRModuleVersion;
obj.WhisperModelHash = WhisperModelHash;
obj.WhisperModelName = WhisperModelName;
obj.WhisperVersion = WhisperVersion;
obj.Width = Width;
obj.WordConfidenceInterval0To10 = WordConfidenceInterval0To10;
obj.WordConfidenceInterval11To20 = WordConfidenceInterval11To20;
obj.WordConfidenceInterval21To30 = WordConfidenceInterval21To30;
obj.WordConfidenceInterval31To40 = WordConfidenceInterval31To40;
obj.WordConfidenceInterval41To50 = WordConfidenceInterval41To50;
obj.WordConfidenceInterval51To60 = WordConfidenceInterval51To60;
obj.WordConfidenceInterval61To70 = WordConfidenceInterval61To70;
obj.WordConfidenceInterval71To80 = WordConfidenceInterval71To80;
obj.WordConfidenceInterval81To90 = WordConfidenceInterval81To90;
obj.WordConfidenceInterval91To100 = WordConfidenceInterval91To100;
obj.xxHash364 = xxHash364;
obj.xxHash3128 = xxHash3128;
return obj;
}
}
}

View File

@@ -1,18 +1,44 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("sample"), XmlRoot("sample")]
public class Sample : DatItem
public class Sample : DatItem, IEquatable<Sample>
{
#region Keys
#region Properties
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
#endregion
public Sample() => Type = ItemType.Sample;
public Sample() => ItemType = ItemType.Sample;
/// <inheritdoc/>
public object Clone()
{
var obj = new Sample();
obj.Name = Name;
return obj;
}
/// <inheritdoc/>
public bool Equals(Sample? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
return true;
}
}
}

View File

@@ -1,57 +1,148 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("serials"), XmlRoot("serials")]
public class Serials : DatItem
public class Serials : DatItem, ICloneable, IEquatable<Serials>
{
#region Keys
#region Properties
/// <remarks>string</remarks>
public const string MediaSerial1Key = "mediaserial1";
public string? BoxBarcode { get; set; }
/// <remarks>string</remarks>
public const string MediaSerial2Key = "mediaserial2";
public string? BoxSerial { get; set; }
/// <remarks>string</remarks>
public const string MediaSerial3Key = "mediaserial3";
public string? ChipSerial { get; set; }
/// <remarks>string</remarks>
public const string PCBSerialKey = "pcbserial";
public string? DigitalSerial1 { get; set; }
/// <remarks>string</remarks>
public const string RomChipSerial1Key = "romchipserial1";
public string? DigitalSerial2 { get; set; }
/// <remarks>string</remarks>
public const string RomChipSerial2Key = "romchipserial2";
public string? LockoutSerial { get; set; }
/// <remarks>string</remarks>
public const string LockoutSerialKey = "lockoutserial";
public string? MediaSerial1 { get; set; }
/// <remarks>string</remarks>
public const string SaveChipSerialKey = "savechipserial";
public string? MediaSerial2 { get; set; }
/// <remarks>string</remarks>
public const string ChipSerialKey = "chipserial";
public string? MediaSerial3 { get; set; }
/// <remarks>string</remarks>
public const string BoxSerialKey = "boxserial";
public string? MediaStamp { get; set; }
/// <remarks>string</remarks>
public const string MediaStampKey = "mediastamp";
public string? PCBSerial { get; set; }
/// <remarks>string</remarks>
public const string BoxBarcodeKey = "boxbarcode";
public string? RomChipSerial1 { get; set; }
/// <remarks>string</remarks>
public const string DigitalSerial1Key = "digitalserial1";
public string? RomChipSerial2 { get; set; }
/// <remarks>string</remarks>
public const string DigitalSerial2Key = "digitalserial2";
public string? SaveChipSerial { get; set; }
#endregion
public Serials() => Type = ItemType.Serials;
public Serials() => ItemType = ItemType.Serials;
/// <inheritdoc/>
public object Clone()
{
var obj = new Serials();
obj.BoxBarcode = BoxBarcode;
obj.BoxSerial = BoxSerial;
obj.ChipSerial = ChipSerial;
obj.DigitalSerial1 = DigitalSerial1;
obj.DigitalSerial2 = DigitalSerial2;
obj.LockoutSerial = LockoutSerial;
obj.MediaSerial1 = MediaSerial1;
obj.MediaSerial2 = MediaSerial2;
obj.MediaSerial3 = MediaSerial3;
obj.MediaStamp = MediaStamp;
obj.PCBSerial = PCBSerial;
obj.RomChipSerial1 = RomChipSerial1;
obj.RomChipSerial2 = RomChipSerial2;
obj.SaveChipSerial = SaveChipSerial;
return obj;
}
/// <inheritdoc/>
public bool Equals(Serials? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((BoxBarcode is null) ^ (other.BoxBarcode is null))
return false;
else if (BoxBarcode is not null && !BoxBarcode.Equals(other.BoxBarcode, StringComparison.OrdinalIgnoreCase))
return false;
if ((BoxSerial is null) ^ (other.BoxSerial is null))
return false;
else if (BoxSerial is not null && !BoxSerial.Equals(other.BoxSerial, StringComparison.OrdinalIgnoreCase))
return false;
if ((ChipSerial is null) ^ (other.ChipSerial is null))
return false;
else if (ChipSerial is not null && !ChipSerial.Equals(other.ChipSerial, StringComparison.OrdinalIgnoreCase))
return false;
if ((DigitalSerial1 is null) ^ (other.DigitalSerial1 is null))
return false;
else if (DigitalSerial1 is not null && !DigitalSerial1.Equals(other.DigitalSerial1, StringComparison.OrdinalIgnoreCase))
return false;
if ((DigitalSerial2 is null) ^ (other.DigitalSerial2 is null))
return false;
else if (DigitalSerial2 is not null && !DigitalSerial2.Equals(other.DigitalSerial2, StringComparison.OrdinalIgnoreCase))
return false;
if ((LockoutSerial is null) ^ (other.LockoutSerial is null))
return false;
else if (LockoutSerial is not null && !LockoutSerial.Equals(other.LockoutSerial, StringComparison.OrdinalIgnoreCase))
return false;
if ((MediaSerial1 is null) ^ (other.MediaSerial1 is null))
return false;
else if (MediaSerial1 is not null && !MediaSerial1.Equals(other.MediaSerial1, StringComparison.OrdinalIgnoreCase))
return false;
if ((MediaSerial2 is null) ^ (other.MediaSerial2 is null))
return false;
else if (MediaSerial2 is not null && !MediaSerial2.Equals(other.MediaSerial2, StringComparison.OrdinalIgnoreCase))
return false;
if ((MediaSerial3 is null) ^ (other.MediaSerial3 is null))
return false;
else if (MediaSerial3 is not null && !MediaSerial3.Equals(other.MediaSerial3, StringComparison.OrdinalIgnoreCase))
return false;
if ((MediaStamp is null) ^ (other.MediaStamp is null))
return false;
else if (MediaStamp is not null && !MediaStamp.Equals(other.MediaStamp, StringComparison.OrdinalIgnoreCase))
return false;
if ((PCBSerial is null) ^ (other.PCBSerial is null))
return false;
else if (PCBSerial is not null && !PCBSerial.Equals(other.PCBSerial, StringComparison.OrdinalIgnoreCase))
return false;
if ((RomChipSerial1 is null) ^ (other.RomChipSerial1 is null))
return false;
else if (RomChipSerial1 is not null && !RomChipSerial1.Equals(other.RomChipSerial1, StringComparison.OrdinalIgnoreCase))
return false;
if ((RomChipSerial2 is null) ^ (other.RomChipSerial2 is null))
return false;
else if (RomChipSerial2 is not null && !RomChipSerial2.Equals(other.RomChipSerial2, StringComparison.OrdinalIgnoreCase))
return false;
if ((SaveChipSerial is null) ^ (other.SaveChipSerial is null))
return false;
else if (SaveChipSerial is not null && !SaveChipSerial.Equals(other.SaveChipSerial, StringComparison.OrdinalIgnoreCase))
return false;
return true;
}
}
}

View File

@@ -1,21 +1,52 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("sharedfeat"), XmlRoot("sharedfeat")]
public class SharedFeat : DatItem
public class SharedFeat : DatItem, ICloneable, IEquatable<SharedFeat>
{
#region Keys
#region Properties
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
/// <remarks>string</remarks>
public const string ValueKey = "value";
public string? Value { get; set; }
#endregion
public SharedFeat() => Type = ItemType.SharedFeat;
public SharedFeat() => ItemType = ItemType.SharedFeat;
/// <inheritdoc/>
public object Clone()
{
var obj = new SharedFeat();
obj.Name = Name;
obj.Value = Value;
return obj;
}
/// <inheritdoc/>
public bool Equals(SharedFeat? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
if ((Value is null) ^ (other.Value is null))
return false;
else if (Value is not null && !Value.Equals(other.Value, StringComparison.OrdinalIgnoreCase))
return false;
return true;
}
}
}

View File

@@ -1,22 +1,51 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("slot"), XmlRoot("slot")]
public class Slot : DatItem
public class Slot : DatItem, ICloneable, IEquatable<Slot>
{
#region Keys
#region Properties
/// <remarks>string</remarks>
public const string NameKey = "name";
public string? Name { get; set; }
/// <remarks>SlotOption[]</remarks>
[NoFilter]
public const string SlotOptionKey = "slotoption";
public SlotOption[]? SlotOption { get; set; }
#endregion
public Slot() => Type = ItemType.Slot;
public Slot() => ItemType = ItemType.Slot;
/// <inheritdoc/>
public object Clone()
{
var obj = new Slot();
obj.Name = Name;
if (SlotOption is not null)
obj.SlotOption = Array.ConvertAll(SlotOption, i => (SlotOption)i.Clone());
return obj;
}
/// <inheritdoc/>
public bool Equals(Slot? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
// Sub-items
// TODO: Figure out how to properly check arrays
return true;
}
}
}

Some files were not shown because too many files have changed in this diff Show More