diff --git a/SabreTools.Library/DatFiles/ClrMamePro.cs b/SabreTools.Library/DatFiles/ClrMamePro.cs index 2cc824c6..98a9d037 100644 --- a/SabreTools.Library/DatFiles/ClrMamePro.cs +++ b/SabreTools.Library/DatFiles/ClrMamePro.cs @@ -721,19 +721,19 @@ namespace SabreTools.Library.DatFiles cmpw.WriteStartElement("disk"); cmpw.WriteAttributeString("name", disk.Name); if (!string.IsNullOrWhiteSpace(disk.MD5)) - cmpw.WriteAttributeString("md5", disk.MD5.ToLowerInvariant()); + cmpw.WriteAttributeString("md5", disk.MD5?.ToLowerInvariant()); #if NET_FRAMEWORK if (!string.IsNullOrWhiteSpace(disk.RIPEMD160)) - cmpw.WriteAttributeString("ripemd160", disk.RIPEMD160.ToLowerInvariant()); + cmpw.WriteAttributeString("ripemd160", disk.RIPEMD160?.ToLowerInvariant()); #endif if (!string.IsNullOrWhiteSpace(disk.SHA1)) - cmpw.WriteAttributeString("sha1", disk.SHA1.ToLowerInvariant()); + cmpw.WriteAttributeString("sha1", disk.SHA1?.ToLowerInvariant()); if (!string.IsNullOrWhiteSpace(disk.SHA256)) - cmpw.WriteAttributeString("sha256", disk.SHA256.ToLowerInvariant()); + cmpw.WriteAttributeString("sha256", disk.SHA256?.ToLowerInvariant()); if (!string.IsNullOrWhiteSpace(disk.SHA384)) - cmpw.WriteAttributeString("sha384", disk.SHA384.ToLowerInvariant()); + cmpw.WriteAttributeString("sha384", disk.SHA384?.ToLowerInvariant()); if (!string.IsNullOrWhiteSpace(disk.SHA512)) - cmpw.WriteAttributeString("sha512", disk.SHA512.ToLowerInvariant()); + cmpw.WriteAttributeString("sha512", disk.SHA512?.ToLowerInvariant()); if (disk.ItemStatus != ItemStatus.None) cmpw.WriteAttributeString("flags", disk.ItemStatus.ToString().ToLowerInvariant()); cmpw.WriteEndElement(); @@ -761,21 +761,21 @@ namespace SabreTools.Library.DatFiles if (rom.Size != -1) cmpw.WriteAttributeString("size", rom.Size.ToString()); if (!string.IsNullOrWhiteSpace(rom.CRC)) - cmpw.WriteAttributeString("crc", rom.CRC.ToLowerInvariant()); + cmpw.WriteAttributeString("crc", rom.CRC?.ToLowerInvariant()); if (!string.IsNullOrWhiteSpace(rom.MD5)) - cmpw.WriteAttributeString("md5", rom.MD5.ToLowerInvariant()); + cmpw.WriteAttributeString("md5", rom.MD5?.ToLowerInvariant()); #if NET_FRAMEWORK if (!string.IsNullOrWhiteSpace(rom.RIPEMD160)) - cmpw.WriteAttributeString("ripemd160", rom.RIPEMD160.ToLowerInvariant()); + cmpw.WriteAttributeString("ripemd160", rom.RIPEMD160?.ToLowerInvariant()); #endif if (!string.IsNullOrWhiteSpace(rom.SHA1)) - cmpw.WriteAttributeString("sha1", rom.SHA1.ToLowerInvariant()); + cmpw.WriteAttributeString("sha1", rom.SHA1?.ToLowerInvariant()); if (!string.IsNullOrWhiteSpace(rom.SHA256)) - cmpw.WriteAttributeString("sha256", rom.SHA256.ToLowerInvariant()); + cmpw.WriteAttributeString("sha256", rom.SHA256?.ToLowerInvariant()); if (!string.IsNullOrWhiteSpace(rom.SHA384)) - cmpw.WriteAttributeString("sha384", rom.SHA384.ToLowerInvariant()); + cmpw.WriteAttributeString("sha384", rom.SHA384?.ToLowerInvariant()); if (!string.IsNullOrWhiteSpace(rom.SHA512)) - cmpw.WriteAttributeString("sha512", rom.SHA512.ToLowerInvariant()); + cmpw.WriteAttributeString("sha512", rom.SHA512?.ToLowerInvariant()); if (!string.IsNullOrWhiteSpace(rom.Date)) cmpw.WriteAttributeString("date", rom.Date); if (rom.ItemStatus != ItemStatus.None) diff --git a/SabreTools.Library/DatFiles/DatFile.cs b/SabreTools.Library/DatFiles/DatFile.cs index 4579e9c9..4996f93d 100644 --- a/SabreTools.Library/DatFiles/DatFile.cs +++ b/SabreTools.Library/DatFiles/DatFile.cs @@ -2166,7 +2166,7 @@ namespace SabreTools.Library.DatFiles }); // Now find all folders that are empty, if we are supposed to - if (!Header.OutputDepot.IsActive && addBlanks) + if (!(Header.OutputDepot?.IsActive ?? false) && addBlanks) { List empties = DirectoryExtensions.ListEmpty(basePath); Parallel.ForEach(empties, Globals.ParallelOptions, dir => @@ -2245,7 +2245,7 @@ namespace SabreTools.Library.DatFiles bool copyFiles) { // Special case for if we are in Depot mode (all names are supposed to be SHA-1 hashes) - if (Header.OutputDepot.IsActive) + if (Header.OutputDepot?.IsActive ?? false) { GZipArchive gzarc = new GZipArchive(item); BaseFile baseFile = gzarc.GetTorrentGZFileInfo(); @@ -3841,7 +3841,7 @@ namespace SabreTools.Library.DatFiles string post = CreatePrefixPostfix(item, false); // If we're in Depot mode, take care of that instead - if (Header.OutputDepot.IsActive) + if (Header.OutputDepot?.IsActive ?? false) { if (item.ItemType == ItemType.Rom) { @@ -3928,27 +3928,27 @@ namespace SabreTools.Library.DatFiles // Ensure we have the proper values for replacement if (item.ItemType == ItemType.Rom) { - crc = ((Rom)item).CRC; - md5 = ((Rom)item).MD5; + crc = ((Rom)item).CRC ?? string.Empty; + md5 = ((Rom)item).MD5 ?? string.Empty; #if NET_FRAMEWORK - ripemd160 = ((Rom)item).RIPEMD160; + ripemd160 = ((Rom)item).RIPEMD160 ?? string.Empty; #endif - sha1 = ((Rom)item).SHA1; - sha256 = ((Rom)item).SHA256; - sha384 = ((Rom)item).SHA384; - sha512 = ((Rom)item).SHA512; + sha1 = ((Rom)item).SHA1 ?? string.Empty; + sha256 = ((Rom)item).SHA256 ?? string.Empty; + sha384 = ((Rom)item).SHA384 ?? string.Empty; + sha512 = ((Rom)item).SHA512 ?? string.Empty; size = ((Rom)item).Size.ToString(); } else if (item.ItemType == ItemType.Disk) { - md5 = ((Disk)item).MD5; + md5 = ((Disk)item).MD5 ?? string.Empty; #if NET_FRAMEWORK - ripemd160 = ((Disk)item).RIPEMD160; + ripemd160 = ((Disk)item).RIPEMD160 ?? string.Empty; #endif - sha1 = ((Disk)item).SHA1; - sha256 = ((Disk)item).SHA256; - sha384 = ((Disk)item).SHA384; - sha512 = ((Disk)item).SHA512; + sha1 = ((Disk)item).SHA1 ?? string.Empty; + sha256 = ((Disk)item).SHA256 ?? string.Empty; + sha384 = ((Disk)item).SHA384 ?? string.Empty; + sha512 = ((Disk)item).SHA512 ?? string.Empty; } // Now do bulk replacement where possible @@ -3956,9 +3956,9 @@ namespace SabreTools.Library.DatFiles .Replace("%game%", game) .Replace("%machine%", game) .Replace("%name%", name) - .Replace("%manufacturer%", item.Machine.Manufacturer) - .Replace("%publisher%", item.Machine.Publisher) - .Replace("%category%", item.Machine.Category) + .Replace("%manufacturer%", item.Machine.Manufacturer ?? string.Empty) + .Replace("%publisher%", item.Machine.Publisher ?? string.Empty) + .Replace("%category%", item.Machine.Category ?? string.Empty) .Replace("%crc%", crc) .Replace("%md5%", md5) .Replace("%ripemd160%", ripemd160) diff --git a/SabreTools.Library/DatFiles/DatHeader.cs b/SabreTools.Library/DatFiles/DatHeader.cs index 4ca6a853..d58fdeb5 100644 --- a/SabreTools.Library/DatFiles/DatHeader.cs +++ b/SabreTools.Library/DatFiles/DatHeader.cs @@ -21,106 +21,103 @@ namespace SabreTools.Library.DatFiles /// /// External name of the DAT /// - [JsonProperty("filename")] + [JsonProperty("filename", DefaultValueHandling = DefaultValueHandling.Include)] public string FileName { get; set; } /// /// Internal name of the DAT /// - [JsonProperty("name")] + [JsonProperty("name", DefaultValueHandling = DefaultValueHandling.Include)] public string Name { get; set; } /// /// DAT description /// - [JsonProperty("description")] + [JsonProperty("description", DefaultValueHandling = DefaultValueHandling.Include)] public string Description { get; set; } /// /// Root directory for the files; currently TruRip/EmuARC-exclusive /// - [JsonProperty("rootdir")] + [JsonProperty("rootdir", DefaultValueHandling = DefaultValueHandling.Ignore)] public string RootDir { get; set; } /// /// General category of items found in the DAT /// - [JsonProperty("category")] + [JsonProperty("category", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Category { get; set; } /// /// Version of the DAT /// - [JsonProperty("version")] + [JsonProperty("version", DefaultValueHandling = DefaultValueHandling.Include)] public string Version { get; set; } /// /// Creation or modification date /// - [JsonProperty("date")] + [JsonProperty("date", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Date { get; set; } /// /// List of authors who contributed to the DAT /// - [JsonProperty("author")] + [JsonProperty("author", DefaultValueHandling = DefaultValueHandling.Include)] public string Author { get; set; } /// /// Email address for DAT author(s) /// - [JsonProperty("email")] + [JsonProperty("email", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Email { get; set; } /// /// Author or distribution homepage name /// - [JsonProperty("homepage")] + [JsonProperty("homepage", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Homepage { get; set; } /// /// Author or distribution URL /// - [JsonProperty("url")] + [JsonProperty("url", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Url { get; set; } /// /// Any comment that does not already fit an existing field /// - [JsonProperty("comment")] + [JsonProperty("comment", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Comment { get; set; } /// /// Header skipper to be used when loading the DAT /// - [JsonProperty("header")] + [JsonProperty("header", DefaultValueHandling = DefaultValueHandling.Ignore)] public string HeaderSkipper { get; set; } /// /// Classification of the DAT. Generally only used for SuperDAT /// - [JsonProperty("type")] + [JsonProperty("type", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Type { get; set; } /// /// Force a merging style when loaded /// - /// TODO: Make nullable - [JsonProperty("forcemerging")] + [JsonProperty("forcemerging", DefaultValueHandling = DefaultValueHandling.Ignore)] public MergingFlag ForceMerging { get; set; } /// /// Force nodump handling when loaded /// - /// TODO: Make nullable - [JsonProperty("forcenodump")] + [JsonProperty("forcenodump", DefaultValueHandling = DefaultValueHandling.Ignore)] public NodumpFlag ForceNodump { get; set; } /// /// Force output packing when loaded /// - /// TODO: Make nullable - [JsonProperty("forcepacking")] + [JsonProperty("forcepacking", DefaultValueHandling = DefaultValueHandling.Ignore)] public PackingFlag ForcePacking { get; set; } /// @@ -185,13 +182,13 @@ namespace SabreTools.Library.DatFiles /// Debug build flag /// /// Also in Logiqx - [JsonProperty("debug")] - public bool? Debug { get; set; } = false; + [JsonProperty("debug", DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool? Debug { get; set; } = null; /// /// MAME configuration name /// - [JsonProperty("mameconfig")] + [JsonProperty("mameconfig", DefaultValueHandling = DefaultValueHandling.Ignore)] public string MameConfig { get; set; } #endregion @@ -201,46 +198,46 @@ namespace SabreTools.Library.DatFiles /// /// Build version /// - [JsonProperty("build")] + [JsonProperty("build", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Build { get; set; } /// /// RomCenter rom mode /// /// (merged|split|unmerged) "split" - [JsonProperty("rommode")] + [JsonProperty("rommode", DefaultValueHandling = DefaultValueHandling.Ignore)] public MergingFlag RomMode { get; set; } /// /// RomCenter bios mode /// /// (merged|split|unmerged) "split" - [JsonProperty("biosmode")] + [JsonProperty("biosmode", DefaultValueHandling = DefaultValueHandling.Ignore)] public MergingFlag BiosMode { get; set; } /// /// RomCenter sample mode /// /// (merged|unmerged) "merged" - [JsonProperty("samplemode")] + [JsonProperty("samplemode", DefaultValueHandling = DefaultValueHandling.Ignore)] public MergingFlag SampleMode { get; set; } /// /// RomCenter lock rom mode /// - [JsonProperty("lockrommode")] + [JsonProperty("lockrommode", DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? LockRomMode { get; set; } /// /// RomCenter lock bios mode /// - [JsonProperty("lockbiosmode")] + [JsonProperty("lockbiosmode", DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? LockBiosMode { get; set; } /// /// RomCenter lock sample mode /// - [JsonProperty("locksamplemode")] + [JsonProperty("locksamplemode", DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? LockSampleMode { get; set; } #endregion @@ -261,31 +258,31 @@ namespace SabreTools.Library.DatFiles /// System /// /// Known as "plugin" in Logiqx and RomCenter - [JsonProperty("system")] + [JsonProperty("system", DefaultValueHandling = DefaultValueHandling.Ignore)] public string System { get; set; } /// /// Screenshots width /// - [JsonProperty("screenshotswidth")] + [JsonProperty("screenshotswidth", DefaultValueHandling = DefaultValueHandling.Ignore)] public string ScreenshotsWidth { get; set; } /// /// Screenshots height /// - [JsonProperty("screenshotsheight")] + [JsonProperty("screenshotsheight", DefaultValueHandling = DefaultValueHandling.Ignore)] public string ScreenshotsHeight { get; set; } /// /// OfflineList info list /// - [JsonProperty("infos")] + [JsonProperty("infos", DefaultValueHandling = DefaultValueHandling.Ignore)] public List Infos { get; set; } /// /// OfflineList can-open extensions /// - [JsonProperty("canopen")] + [JsonProperty("canopen", DefaultValueHandling = DefaultValueHandling.Ignore)] public List CanOpen { get; set; } // TODO: Implement the following header values: @@ -299,7 +296,7 @@ namespace SabreTools.Library.DatFiles /// /// Rom title /// - [JsonProperty("romtitle")] + [JsonProperty("romtitle", DefaultValueHandling = DefaultValueHandling.Ignore)] public string RomTitle { get; set; } #endregion @@ -309,7 +306,7 @@ namespace SabreTools.Library.DatFiles /// /// RomCenter DAT format version /// - [JsonProperty("rcversion")] + [JsonProperty("rcversion", DefaultValueHandling = DefaultValueHandling.Ignore)] public string RomCenterVersion { get; set; } #endregion @@ -575,8 +572,8 @@ namespace SabreTools.Library.DatFiles ReplaceExtension = datHeader.ReplaceExtension; RemoveExtension = datHeader.RemoveExtension; - InputDepot = datHeader.InputDepot.Clone() as DepotInformation; - OutputDepot = datHeader.OutputDepot.Clone() as DepotInformation; + InputDepot = datHeader.InputDepot?.Clone() as DepotInformation; + OutputDepot = datHeader.OutputDepot?.Clone() as DepotInformation; GameName = datHeader.GameName; Quotes = datHeader.Quotes; UseRomName = datHeader.UseRomName; diff --git a/SabreTools.Library/DatFiles/DosCenter.cs b/SabreTools.Library/DatFiles/DosCenter.cs index e7a10d2b..738db200 100644 --- a/SabreTools.Library/DatFiles/DosCenter.cs +++ b/SabreTools.Library/DatFiles/DosCenter.cs @@ -477,7 +477,7 @@ namespace SabreTools.Library.DatFiles if (!string.IsNullOrWhiteSpace(rom.Date)) cmpw.WriteAttributeString("date", rom.Date); if (!string.IsNullOrWhiteSpace(rom.CRC)) - cmpw.WriteAttributeString("crc", rom.CRC.ToLowerInvariant()); + cmpw.WriteAttributeString("crc", rom.CRC?.ToLowerInvariant()); cmpw.WriteEndElement(); break; } diff --git a/SabreTools.Library/DatFiles/EverdriveSmdb.cs b/SabreTools.Library/DatFiles/EverdriveSmdb.cs index 0becac3f..2ac594d1 100644 --- a/SabreTools.Library/DatFiles/EverdriveSmdb.cs +++ b/SabreTools.Library/DatFiles/EverdriveSmdb.cs @@ -190,12 +190,12 @@ namespace SabreTools.Library.DatFiles string[] fields = new string[] { - rom.SHA256, - $"{rom.Machine.Name}/", - rom.Name, - rom.SHA1, - rom.MD5, - rom.CRC, + rom.SHA256 ?? string.Empty, + $"{rom.Machine.Name ?? string.Empty}/", + rom.Name ?? string.Empty, + rom.SHA1 ?? string.Empty, + rom.MD5 ?? string.Empty, + rom.CRC ?? string.Empty, }; svw.WriteValues(fields); diff --git a/SabreTools.Library/DatFiles/Json.cs b/SabreTools.Library/DatFiles/Json.cs index 1d1e0885..9165d948 100644 --- a/SabreTools.Library/DatFiles/Json.cs +++ b/SabreTools.Library/DatFiles/Json.cs @@ -8,6 +8,7 @@ using SabreTools.Library.DatItems; using SabreTools.Library.IO; using SabreTools.Library.Tools; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace SabreTools.Library.DatFiles { @@ -64,7 +65,7 @@ namespace SabreTools.Library.DatFiles { // Header value case "header": - ReadHeader(sr, jtr, keep); + ReadHeader(jtr); jtr.Read(); break; @@ -91,288 +92,18 @@ namespace SabreTools.Library.DatFiles /// /// Read header information /// - /// StreamReader to use to parse the header /// JsonTextReader to use to parse the header - /// True if full pathnames are to be kept, false otherwise (default) - private void ReadHeader(StreamReader sr, JsonTextReader jtr, bool keep) + private void ReadHeader(JsonTextReader jtr) { - bool superdat = false; - // If the reader is invalid, skip if (jtr == null) return; + // Read in the header and apply any new fields jtr.Read(); - while (!sr.EndOfStream) - { - // If we hit the end of the header, return - if (jtr.TokenType == JsonToken.EndObject) - return; - - // We don't care about anything except property names - if (jtr.TokenType != JsonToken.PropertyName) - { - jtr.Read(); - continue; - } - - // Get all header items (ONLY OVERWRITE IF THERE'S NO DATA) - string content; - switch (jtr.Value) - { - #region Common - - case "name": - content = jtr.ReadAsString(); - Header.Name = (Header.Name == null ? content : Header.Name); - superdat = superdat || content.Contains(" - SuperDAT"); - if (keep && superdat) - { - Header.Type = (Header.Type == null ? "SuperDAT" : Header.Type); - } - break; - - case "description": - content = jtr.ReadAsString(); - Header.Description = (Header.Description == null ? content : Header.Description); - break; - - case "rootdir": // This is exclusive to TruRip XML - content = jtr.ReadAsString(); - Header.RootDir = (Header.RootDir == null ? content : Header.RootDir); - break; - - case "category": - content = jtr.ReadAsString(); - Header.Category = (Header.Category == null ? content : Header.Category); - break; - - case "version": - content = jtr.ReadAsString(); - Header.Version = (Header.Version == null ? content : Header.Version); - break; - - case "date": - content = jtr.ReadAsString(); - Header.Date = (Header.Date == null ? content.Replace(".", "/") : Header.Date); - break; - - case "author": - content = jtr.ReadAsString(); - Header.Author = (Header.Author == null ? content : Header.Author); - break; - - case "email": - content = jtr.ReadAsString(); - Header.Email = (Header.Email == null ? content : Header.Email); - break; - - case "homepage": - content = jtr.ReadAsString(); - Header.Homepage = (Header.Homepage == null ? content : Header.Homepage); - break; - - case "url": - content = jtr.ReadAsString(); - Header.Url = (Header.Url == null ? content : Header.Url); - break; - - case "comment": - content = jtr.ReadAsString(); - Header.Comment = (Header.Comment == null ? content : Header.Comment); - break; - - case "header": - content = jtr.ReadAsString(); - Header.HeaderSkipper = (Header.HeaderSkipper == null ? content : Header.HeaderSkipper); - break; - - case "type": // This is exclusive to TruRip XML - content = jtr.ReadAsString(); - Header.Type = (Header.Type == null ? content : Header.Type); - superdat = superdat || content.Contains("SuperDAT"); - break; - - case "forcemerging": - if (Header.ForceMerging == MergingFlag.None) - Header.ForceMerging = jtr.ReadAsString().AsMergingFlag(); - - break; - - case "forcenodump": - if (Header.ForceNodump == NodumpFlag.None) - Header.ForceNodump = jtr.ReadAsString().AsNodumpFlag(); - - break; - - case "forcepacking": - if (Header.ForcePacking == PackingFlag.None) - Header.ForcePacking = jtr.ReadAsString().AsPackingFlag(); - - break; - - #endregion - - #region ListXML - - case "debug": - content = jtr.ReadAsString(); - Header.Debug = (Header.Debug == null ? content.AsYesNo() : Header.Debug); - break; - - case "mameconfig": - content = jtr.ReadAsString(); - Header.MameConfig = (Header.MameConfig == null ? content : Header.MameConfig); - break; - - #endregion - - #region Logiqx - - case "build": - content = jtr.ReadAsString(); - Header.Build = (Header.Build == null ? content : Header.Build); - break; - - case "rommode": - content = jtr.ReadAsString(); - Header.RomMode = (Header.RomMode == MergingFlag.None ? content.AsMergingFlag() : Header.RomMode); - break; - - case "biosmode": - content = jtr.ReadAsString(); - Header.BiosMode = (Header.BiosMode == MergingFlag.None ? content.AsMergingFlag() : Header.BiosMode); - break; - - case "samplemode": - content = jtr.ReadAsString(); - Header.SampleMode = (Header.SampleMode == MergingFlag.None ? content.AsMergingFlag() : Header.SampleMode); - break; - - case "lockrommode": - content = jtr.ReadAsString(); - Header.LockRomMode = (Header.LockRomMode == null ? content.AsYesNo() : Header.LockRomMode); - break; - - case "lockbiosmode": - content = jtr.ReadAsString(); - Header.LockBiosMode = (Header.LockBiosMode == null ? content.AsYesNo() : Header.LockBiosMode); - break; - - case "locksamplemode": - content = jtr.ReadAsString(); - Header.LockSampleMode = (Header.LockSampleMode == null ? content.AsYesNo() : Header.LockSampleMode); - break; - - #endregion - - #region OfflineList - - case "system": - content = jtr.ReadAsString(); - Header.System = (Header.System == null ? content : Header.System); - break; - - case "screenshotswidth": - content = jtr.ReadAsString(); - Header.ScreenshotsWidth = (Header.ScreenshotsWidth == null ? content : Header.ScreenshotsWidth); - break; - - case "screenshotsheight": - content = jtr.ReadAsString(); - Header.ScreenshotsHeight = (Header.ScreenshotsHeight == null ? content : Header.ScreenshotsHeight); - break; - - case "infos": - Header.Infos = new List(); - jtr.Read(); // Start Array - while (!sr.EndOfStream) - { - jtr.Read(); // Start object (or end array) - if (jtr.TokenType == JsonToken.EndArray) - break; - - // Get default values - string nameValue = string.Empty; - bool? visibleValue = null; - bool? inNamingOptionValue = null; - bool? defaultValue = null; - - jtr.Read(); - while (!sr.EndOfStream) - { - // If we hit the end of the machine, return - if (jtr.TokenType == JsonToken.EndObject) - return; - - // We don't care about anything except properties - if (jtr.TokenType != JsonToken.PropertyName) - { - jtr.Read(); - continue; - } - - switch (jtr.Value) - { - case "name": - nameValue = jtr.ReadAsString(); - break; - case "visible": - visibleValue = jtr.ReadAsString().AsYesNo(); - break; - case "inNamingOption": - inNamingOptionValue = jtr.ReadAsString().AsYesNo(); - break; - case "default": - defaultValue = jtr.ReadAsString().AsYesNo(); - break; - } - - jtr.Read(); // End object - } - - // Add the new info object - Header.Infos.Add(new OfflineListInfo( - nameValue, - visibleValue, - inNamingOptionValue, - defaultValue)); - } - - break; - - case "canopen": - Header.CanOpen = new List(); - jtr.Read(); // Start Array - while (!sr.EndOfStream && jtr.TokenType != JsonToken.EndArray) - { - Header.CanOpen.Add(jtr.ReadAsString()); - } - - break; - - case "romtitle": - content = jtr.ReadAsString(); - Header.RomTitle = (Header.MameConfig == null ? content : Header.RomTitle); - break; - - #endregion - - #region RomCenter - - case "rcversion": - content = jtr.ReadAsString(); - Header.RomCenterVersion = (Header.RomCenterVersion == null ? content : Header.RomCenterVersion); - break; - - #endregion - - default: - break; - } - - jtr.Read(); - } + JsonSerializer js = new JsonSerializer(); + DatHeader header = js.Deserialize(jtr); + Header.ConditionalCopy(header); } /// @@ -414,7 +145,7 @@ namespace SabreTools.Library.DatFiles } /// - /// Read machine information + /// Read machine object information /// /// StreamReader to use to parse the header /// JsonTextReader to use to parse the machine @@ -433,7 +164,8 @@ namespace SabreTools.Library.DatFiles return; // Prepare internal variables - Machine machine = new Machine(); + JsonSerializer js = new JsonSerializer(); + Machine machine = null; jtr.Read(); while (!sr.EndOfStream) @@ -451,268 +183,15 @@ namespace SabreTools.Library.DatFiles switch (jtr.Value) { - #region Common + case "machine": + jtr.Read(); + machine = js.Deserialize(jtr); + break; - case "name": - machine.Name = jtr.ReadAsString(); - break; - case "comment": - machine.Comment = jtr.ReadAsString(); - break; - case "description": - machine.Description = jtr.ReadAsString(); - break; - case "year": - machine.Year = jtr.ReadAsString(); - break; - case "manufacturer": - machine.Manufacturer = jtr.ReadAsString(); - break; - case "publisher": - machine.Publisher = jtr.ReadAsString(); - break; - case "category": - machine.Category = jtr.ReadAsString(); - break; - case "romof": - machine.RomOf = jtr.ReadAsString(); - break; - case "cloneof": - machine.CloneOf = jtr.ReadAsString(); - break; - case "sampleof": - machine.SampleOf = jtr.ReadAsString(); - break; - case "isbios": - string isbios = jtr.ReadAsString(); - if (string.Equals(isbios, "yes", StringComparison.OrdinalIgnoreCase)) - machine.MachineType &= MachineType.Bios; - - break; - case "isdevice": - string isdevice = jtr.ReadAsString(); - if (string.Equals(isdevice, "yes", StringComparison.OrdinalIgnoreCase)) - machine.MachineType &= MachineType.Device; - - break; - case "ismechanical": - string ismechanical = jtr.ReadAsString(); - if (string.Equals(ismechanical, "yes", StringComparison.OrdinalIgnoreCase)) - machine.MachineType &= MachineType.Mechanical; - - break; case "items": ReadItems(sr, jtr, filename, indexId, machine); break; - #endregion - - #region AttractMode - - case "players": - machine.Players = jtr.ReadAsString(); - break; - case "rotation": - machine.Rotation = jtr.ReadAsString(); - break; - case "control": - machine.Control = jtr.ReadAsString(); - break; - case "status": - machine.Status = jtr.ReadAsString(); - break; - case "displaycount": - machine.DisplayCount = jtr.ReadAsString(); - break; - case "displaytype": - machine.DisplayType = jtr.ReadAsString(); - break; - case "buttons": - machine.Buttons = jtr.ReadAsString(); - break; - - #endregion - - #region ListXML - - case "sourcefile": - machine.SourceFile = jtr.ReadAsString(); - break; - case "runnable": - machine.Runnable = jtr.ReadAsString().AsRunnable(); - break; - case "devices": - machine.DeviceReferences = new List(); - jtr.Read(); // Start Array - while (!sr.EndOfStream && jtr.TokenType != JsonToken.EndArray) - { - machine.DeviceReferences.Add(new ListXmlDeviceReference() { Name = jtr.ReadAsString() }); - } - - break; - - // TODO: Add `slot` - - case "infos": - machine.Infos = new List(); - jtr.Read(); // Start Array - while (!sr.EndOfStream) - { - jtr.Read(); // Start object (or end array) - if (jtr.TokenType == JsonToken.EndArray) - break; - - var info = new ListXmlInfo(); - - jtr.Read(); // Key - info.Name = jtr.Value as string; - info.Value = jtr.ReadAsString(); - jtr.Read(); // End object - - machine.Infos.Add(info); - } - - break; - - #endregion - - #region Logiqx - - case "board": - machine.Board = jtr.ReadAsString(); - break; - case "rebuildto": - machine.RebuildTo = jtr.ReadAsString(); - break; - - #endregion - - #region Logiqx EmuArc - - case "titleid": - machine.TitleID = jtr.ReadAsString(); - break; - case "developer": - machine.Developer = jtr.ReadAsString(); - break; - case "genre": - machine.Genre = jtr.ReadAsString(); - break; - case "subgenre": - machine.Subgenre = jtr.ReadAsString(); - break; - case "ratings": - machine.Ratings = jtr.ReadAsString(); - break; - case "score": - machine.Score = jtr.ReadAsString(); - break; - case "enabled": - machine.Enabled = jtr.ReadAsString(); - break; - case "hascrc": - machine.HasCrc = jtr.ReadAsString().AsYesNo(); - break; - case "relatedto": - machine.RelatedTo = jtr.ReadAsString(); - break; - - #endregion - - #region OpenMSX - - case "genmsxid": - machine.GenMSXID = jtr.ReadAsString(); - break; - case "system": - machine.System = jtr.ReadAsString(); - break; - case "country": - machine.Country = jtr.ReadAsString(); - break; - - #endregion - - #region SoftwareList - - case "supported": - machine.Supported = jtr.ReadAsString().AsSupported(); - break; - - case "sharedfeat": - machine.SharedFeatures = new List(); - jtr.Read(); // Start Array - while (!sr.EndOfStream) - { - jtr.Read(); // Start object (or end array) - if (jtr.TokenType == JsonToken.EndArray) - break; - - var sharedFeature = new SoftwareListSharedFeature(); - - jtr.Read(); // Key - sharedFeature.Name = jtr.Value as string; - sharedFeature.Value = jtr.ReadAsString(); - jtr.Read(); // End object - - machine.SharedFeatures.Add(sharedFeature); - } - - break; - - case "dipswitches": - machine.DipSwitches = new List(); - jtr.Read(); // Start Array - while (!sr.EndOfStream) - { - jtr.Read(); // Start object (or end array) - if (jtr.TokenType == JsonToken.EndArray) - break; - - jtr.Read(); // Name Key - string name = jtr.ReadAsString(); - jtr.Read(); // Tag Key - string tag = jtr.ReadAsString(); - jtr.Read(); // Mask Key - string mask = jtr.ReadAsString(); - - var dipSwitch = new ListXmlDipSwitch(); - dipSwitch.Name = name; - dipSwitch.Tag = tag; - dipSwitch.Mask = mask; - - jtr.Read(); // Start dipvalues object - while (!sr.EndOfStream) - { - jtr.Read(); // Start object (or end array) - if (jtr.TokenType == JsonToken.EndArray) - break; - - jtr.Read(); // Name Key - string valname = jtr.ReadAsString(); - jtr.Read(); // Value Key - string value = jtr.ReadAsString(); - jtr.Read(); // Default Key - bool? def = jtr.ReadAsString().AsYesNo(); - jtr.Read(); // End object - - var dipValue = new ListXmlDipValue(); - dipValue.Name = valname; - dipValue.Value = value; - dipValue.Default = def; - - dipSwitch.Values.Add(dipValue); - } - - jtr.Read(); // End object - - machine.DipSwitches.Add(dipSwitch); - } - - break; - - #endregion - default: break; } @@ -787,45 +266,8 @@ namespace SabreTools.Library.DatFiles return; // Prepare internal variables - bool? def = null, - writable = null, - optional = null, - inverted = null; - long size = -1; - long? areaSize = null; - string name = null, - altName = null, - altTitle = null, - original = null, - msxType = null, - remark = null, - boot = null, - partName = null, - partInterface = null, - areaName = null, - areaWidth = null, - areaEndianness = null, - value = null, - loadFlag = null, - biosDescription = null, - region = null, - language = null, - date = null, - crc = null, - md5 = null, - ripemd160 = null, - sha1 = null, - sha256 = null, - sha384 = null, - sha512 = null, - merge = null, - index = null, - offset = null, - bios = null; - ItemStatus? itemStatus = null; - ItemType? itemType = null; - OpenMSXSubType subType = OpenMSXSubType.NULL; - List features = null; + JsonSerializer js = new JsonSerializer(); + DatItem datItem = null; jtr.Read(); while (!sr.EndOfStream) @@ -834,85 +276,11 @@ namespace SabreTools.Library.DatFiles if (jtr.TokenType == JsonToken.EndObject) { // If we didn't read something valid, just return - if (itemType == null) + if (datItem == null) return; - DatItem datItem = DatItem.Create(itemType.Value); datItem.CopyMachineInformation(machine); datItem.Source = new Source { Index = indexId, Name = filename }; - - datItem.Name = name; - - datItem.AltName = altName; - datItem.AltTitle = altTitle; - - datItem.Original = new OpenMSXOriginal() { Content = original }; - datItem.OpenMSXSubType = subType; - datItem.OpenMSXType = msxType; - datItem.Remark = remark; - datItem.Boot = boot; - - datItem.PartName = partName; - datItem.PartInterface = partInterface; - datItem.Features = features; - datItem.AreaName = areaName; - datItem.AreaSize = areaSize; - datItem.AreaWidth = areaWidth; - datItem.AreaEndianness = areaEndianness; - datItem.Value = value; - datItem.LoadFlag = loadFlag; - - if (itemType == ItemType.BiosSet) - { - (datItem as BiosSet).Description = biosDescription; - (datItem as BiosSet).Default = def; - } - else if (itemType == ItemType.Disk) - { - (datItem as Disk).MD5 = md5; -#if NET_FRAMEWORK - (datItem as Disk).RIPEMD160 = ripemd160; -#endif - (datItem as Disk).SHA1 = sha1; - (datItem as Disk).SHA256 = sha256; - (datItem as Disk).SHA384 = sha384; - (datItem as Disk).SHA512 = sha512; - (datItem as Disk).MergeTag = merge; - (datItem as Disk).Region = region; - (datItem as Disk).Index = index; - (datItem as Disk).Writable = writable; - (datItem as Disk).ItemStatus = itemStatus ?? ItemStatus.None; - (datItem as Disk).Optional = optional; - } - else if (itemType == ItemType.Release) - { - (datItem as Release).Region = region; - (datItem as Release).Language = language; - (datItem as Release).Date = date; - (datItem as Release).Default = def; - } - else if (itemType == ItemType.Rom) - { - (datItem as Rom).Bios = bios; - (datItem as Rom).Size = size; - (datItem as Rom).CRC = crc; - (datItem as Rom).MD5 = md5; -#if NET_FRAMEWORK - (datItem as Rom).RIPEMD160 = ripemd160; -#endif - (datItem as Rom).SHA1 = sha1; - (datItem as Rom).SHA256 = sha256; - (datItem as Rom).SHA384 = sha384; - (datItem as Rom).SHA512 = sha512; - (datItem as Rom).MergeTag = merge; - (datItem as Rom).Region = region; - (datItem as Rom).Offset = offset; - (datItem as Rom).Date = date; - (datItem as Rom).ItemStatus = itemStatus ?? ItemStatus.None; - (datItem as Rom).Optional = optional; - (datItem as Rom).Inverted = inverted; - } - ParseAddHelper(datItem); return; @@ -927,201 +295,36 @@ namespace SabreTools.Library.DatFiles switch (jtr.Value) { - #region Common - - case "type": - itemType = jtr.ReadAsString().AsItemType(); - break; - - case "name": - name = jtr.ReadAsString(); - break; - - #endregion - - #region AttractMode - - case "alt_romname": - altName = jtr.ReadAsString(); - break; - - case "alt_title": - altTitle = jtr.ReadAsString(); - break; - - #endregion - - #region OpenMSX - - case "original": - original = jtr.ReadAsString(); - break; - - case "openmsx_subtype": - subType = jtr.ReadAsString().AsOpenMSXSubType(); - break; - - case "openmsx_type": - msxType = jtr.ReadAsString(); - break; - - case "remark": - remark = jtr.ReadAsString(); - break; - - case "boot": - boot = jtr.ReadAsString(); - break; - - #endregion - - #region SoftwareList - - case "partname": - partName = jtr.ReadAsString(); - break; - - case "partinterface": - partInterface = jtr.ReadAsString(); - break; - - case "features": - features = new List(); - jtr.Read(); // Start Array - while (!sr.EndOfStream) + case "datitem": + jtr.Read(); + JObject datItemObj = js.Deserialize(jtr); + switch (datItemObj.Value("type").AsItemType()) { - jtr.Read(); // Start object (or end array) - if (jtr.TokenType == JsonToken.EndArray) + case ItemType.Archive: + datItem = datItemObj.ToObject(); + break; + case ItemType.BiosSet: + datItem = datItemObj.ToObject(); + break; + case ItemType.Blank: + datItem = datItemObj.ToObject(); + break; + case ItemType.Disk: + datItem = datItemObj.ToObject(); + break; + case ItemType.Release: + datItem = datItemObj.ToObject(); + break; + case ItemType.Rom: + datItem = datItemObj.ToObject(); + break; + case ItemType.Sample: + datItem = datItemObj.ToObject(); break; - - var feature = new SoftwareListFeature(); - - jtr.Read(); // Key - feature.Name = jtr.Value as string; - feature.Value = jtr.ReadAsString(); - jtr.Read(); // End object - - features.Add(feature); } break; - case "areaname": - areaName = jtr.ReadAsString(); - break; - - case "areasize": - if (Int64.TryParse(jtr.ReadAsString(), out long tempAreaSize)) - areaSize = tempAreaSize; - else - areaSize = null; - - break; - - case "areawidth": - areaWidth = jtr.ReadAsString(); - break; - - case "areaendianness": - areaEndianness = jtr.ReadAsString(); - break; - - case "value": - value = jtr.ReadAsString(); - break; - - case "loadflag": - loadFlag = jtr.ReadAsString(); - break; - - #endregion - - case "description": - biosDescription = jtr.ReadAsString(); - break; - - case "default": - def = jtr.ReadAsBoolean(); - break; - - case "region": - region = jtr.ReadAsString(); - break; - - case "language": - language = jtr.ReadAsString(); - break; - - case "date": - date = jtr.ReadAsString(); - break; - - case "size": - if (!Int64.TryParse(jtr.ReadAsString(), out size)) - size = -1; - - break; - - case "crc": - crc = jtr.ReadAsString(); - break; - - case "md5": - md5 = jtr.ReadAsString(); - break; - - case "ripemd160": - ripemd160 = jtr.ReadAsString(); - break; - - case "sha1": - sha1 = jtr.ReadAsString(); - break; - - case "sha256": - sha256 = jtr.ReadAsString(); - break; - - case "sha384": - sha384 = jtr.ReadAsString(); - break; - - case "sha512": - sha512 = jtr.ReadAsString(); - break; - - case "merge": - merge = jtr.ReadAsString(); - break; - - case "index": - index = jtr.ReadAsString(); - break; - - case "writable": - writable = jtr.ReadAsBoolean(); - break; - - case "status": - itemStatus = jtr.ReadAsString().AsItemStatus(); - break; - - case "optional": - optional = jtr.ReadAsBoolean(); - break; - - case "offset": - offset = jtr.ReadAsString(); - break; - - case "bios": - bios = jtr.ReadAsString(); - break; - - case "inverted": - inverted = jtr.ReadAsBoolean(); - break; - default: break; } @@ -1246,315 +449,10 @@ namespace SabreTools.Library.DatFiles { jtw.WriteStartObject(); + // Write the DatHeader jtw.WritePropertyName("header"); - jtw.WriteStartObject(); - - #region Common - - jtw.WritePropertyName("name"); - jtw.WriteValue(Header.Name); - jtw.WritePropertyName("description"); - jtw.WriteValue(Header.Description); - if (!string.IsNullOrWhiteSpace(Header.RootDir)) - { - jtw.WritePropertyName("rootdir"); - jtw.WriteValue(Header.RootDir); - } - if (!string.IsNullOrWhiteSpace(Header.Category)) - { - jtw.WritePropertyName("category"); - jtw.WriteValue(Header.Category); - } - jtw.WritePropertyName("version"); - jtw.WriteValue(Header.Version); - if (!string.IsNullOrWhiteSpace(Header.Date)) - { - jtw.WritePropertyName("date"); - jtw.WriteValue(Header.Date); - } - jtw.WritePropertyName("author"); - jtw.WriteValue(Header.Author); - if (!string.IsNullOrWhiteSpace(Header.Email)) - { - jtw.WritePropertyName("email"); - jtw.WriteValue(Header.Email); - } - if (!string.IsNullOrWhiteSpace(Header.Homepage)) - { - jtw.WritePropertyName("homepage"); - jtw.WriteValue(Header.Homepage); - } - if (!string.IsNullOrWhiteSpace(Header.Url)) - { - jtw.WritePropertyName("date"); - jtw.WriteValue(Header.Url); - } - if (!string.IsNullOrWhiteSpace(Header.Comment)) - { - jtw.WritePropertyName("comment"); - jtw.WriteValue(Header.Comment); - } - if (!string.IsNullOrWhiteSpace(Header.Type)) - { - jtw.WritePropertyName("type"); - jtw.WriteValue(Header.Type); - } - if (Header.ForceMerging != MergingFlag.None) - { - jtw.WritePropertyName("forcemerging"); - switch (Header.ForceMerging) - { - case MergingFlag.Full: - jtw.WriteValue("full"); - break; - case MergingFlag.Split: - jtw.WriteValue("split"); - break; - case MergingFlag.Merged: - jtw.WriteValue("merged"); - break; - case MergingFlag.NonMerged: - jtw.WriteValue("nonmerged"); - break; - } - } - if (Header.ForcePacking != PackingFlag.None) - { - jtw.WritePropertyName("forcepacking"); - switch (Header.ForcePacking) - { - case PackingFlag.Unzip: - jtw.WriteValue("unzip"); - break; - case PackingFlag.Zip: - jtw.WriteValue("zip"); - break; - } - } - if (Header.ForceNodump != NodumpFlag.None) - { - jtw.WritePropertyName("forcenodump"); - switch (Header.ForceNodump) - { - case NodumpFlag.Ignore: - jtw.WriteValue("ignore"); - break; - case NodumpFlag.Obsolete: - jtw.WriteValue("obsolete"); - break; - case NodumpFlag.Required: - jtw.WriteValue("required"); - break; - } - } - if (!string.IsNullOrWhiteSpace(Header.HeaderSkipper)) - { - jtw.WritePropertyName("header"); - jtw.WriteValue(Header.HeaderSkipper); - } - - #endregion - - #region ListXML - - if (Header.Debug != null) - { - jtw.WritePropertyName("debug"); - switch (Header.Debug) - { - case true: - jtw.WriteValue("yes"); - break; - case false: - jtw.WriteValue("no"); - break; - } - } - - if (!string.IsNullOrWhiteSpace(Header.MameConfig)) - { - jtw.WritePropertyName("mameconfig"); - jtw.WriteValue(Header.MameConfig); - } - - #endregion - - #region Logiqx - - if (!string.IsNullOrWhiteSpace(Header.Build)) - { - jtw.WritePropertyName("build"); - jtw.WriteValue(Header.Build); - } - - if (Header.RomMode != MergingFlag.None) - { - jtw.WritePropertyName("rommode"); - switch (Header.RomMode) - { - case MergingFlag.Split: - jtw.WriteValue("split"); - break; - case MergingFlag.Merged: - jtw.WriteValue("merged"); - break; - case MergingFlag.NonMerged: - jtw.WriteValue("unmerged"); - break; - } - } - - if (Header.BiosMode != MergingFlag.None) - { - jtw.WritePropertyName("biosmode"); - switch (Header.BiosMode) - { - case MergingFlag.Split: - jtw.WriteValue("split"); - break; - case MergingFlag.Merged: - jtw.WriteValue("merged"); - break; - case MergingFlag.NonMerged: - jtw.WriteValue("unmerged"); - break; - } - } - - if (Header.SampleMode != MergingFlag.None) - { - jtw.WritePropertyName("samplemode"); - switch (Header.SampleMode) - { - case MergingFlag.Merged: - jtw.WriteValue("merged"); - break; - case MergingFlag.NonMerged: - jtw.WriteValue("unmerged"); - break; - } - } - - if (Header.LockRomMode != null) - { - switch (Header.LockRomMode) - { - case true: - jtw.WritePropertyName("lockrommode"); - jtw.WriteValue("yes"); - break; - case false: - jtw.WritePropertyName("lockrommode"); - jtw.WriteValue("no"); - break; - } - } - - if (Header.LockBiosMode != null) - { - switch (Header.LockBiosMode) - { - case true: - jtw.WritePropertyName("lockbiosmode"); - jtw.WriteValue("yes"); - break; - case false: - jtw.WritePropertyName("lockbiosmode"); - jtw.WriteValue("no"); - break; - } - } - - if (Header.LockSampleMode != null) - { - switch (Header.LockSampleMode) - { - case true: - jtw.WritePropertyName("locksamplemode"); - jtw.WriteValue("yes"); - break; - case false: - jtw.WritePropertyName("locksamplemode"); - jtw.WriteValue("no"); - break; - } - } - - #endregion - - #region OfflineList - - if (!string.IsNullOrWhiteSpace(Header.System)) - { - jtw.WritePropertyName("system"); - jtw.WriteValue(Header.System); - } - - if (!string.IsNullOrWhiteSpace(Header.ScreenshotsWidth)) - { - jtw.WritePropertyName("screenshotswidth"); - jtw.WriteValue(Header.ScreenshotsWidth); - } - - if (!string.IsNullOrWhiteSpace(Header.ScreenshotsHeight)) - { - jtw.WritePropertyName("screenshotsheight"); - jtw.WriteValue(Header.ScreenshotsHeight); - } - - if (Header.Infos != null) - { - jtw.WritePropertyName("infos"); - jtw.WriteStartArray(); - foreach (var info in Header.Infos) - { - jtw.WriteStartObject(); - jtw.WritePropertyName("name"); - jtw.WriteValue(info.Name); - jtw.WritePropertyName("visible"); - jtw.WriteValue(info.Visible.ToString()); - jtw.WritePropertyName("inNamingOption"); - jtw.WriteValue(info.IsNamingOption.ToString()); - jtw.WritePropertyName("default"); - jtw.WriteValue(info.Default.ToString()); - jtw.WriteEndObject(); - } - - jtw.WriteEndArray(); - } - - if (Header.CanOpen != null) - { - jtw.WritePropertyName("canopen"); - jtw.WriteStartArray(); - foreach (string extension in Header.CanOpen) - { - jtw.WriteValue(extension); - } - - jtw.WriteEndArray(); - } - - if (!string.IsNullOrWhiteSpace(Header.RomTitle)) - { - jtw.WritePropertyName("romtitle"); - jtw.WriteValue(Header.RomTitle); - } - - #endregion - - #region RomCenter - - if (!string.IsNullOrWhiteSpace(Header.RomCenterVersion)) - { - jtw.WritePropertyName("rcversion"); - jtw.WriteValue(Header.RomCenterVersion); - } - - #endregion - - // End header - jtw.WriteEndObject(); + JsonSerializer js = new JsonSerializer() { Formatting = Formatting.Indented }; + js.Serialize(jtw, Header); jtw.WritePropertyName("machines"); jtw.WriteStartArray(); @@ -1586,337 +484,10 @@ namespace SabreTools.Library.DatFiles // Build the state jtw.WriteStartObject(); - #region Common - - jtw.WritePropertyName("name"); - jtw.WriteValue(datItem.Machine.Name); - - if (!string.IsNullOrWhiteSpace(datItem.Machine.Comment)) - { - jtw.WritePropertyName("comment"); - jtw.WriteValue(datItem.Machine.Comment); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.Description)) - { - jtw.WritePropertyName("description"); - jtw.WriteValue(datItem.Machine.Description); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.Year)) - { - jtw.WritePropertyName("year"); - jtw.WriteValue(datItem.Machine.Year); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.Manufacturer)) - { - jtw.WritePropertyName("manufacturer"); - jtw.WriteValue(datItem.Machine.Manufacturer); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.Publisher)) - { - jtw.WritePropertyName("publisher"); - jtw.WriteValue(datItem.Machine.Publisher); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.Category)) - { - jtw.WritePropertyName("category"); - jtw.WriteValue(datItem.Machine.Category); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.RomOf) && !string.Equals(datItem.Machine.Name, datItem.Machine.RomOf, StringComparison.OrdinalIgnoreCase)) - { - jtw.WritePropertyName("romof"); - jtw.WriteValue(datItem.Machine.RomOf); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.CloneOf) && !string.Equals(datItem.Machine.Name, datItem.Machine.CloneOf, StringComparison.OrdinalIgnoreCase)) - { - jtw.WritePropertyName("cloneof"); - jtw.WriteValue(datItem.Machine.CloneOf); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.SampleOf) && !string.Equals(datItem.Machine.Name, datItem.Machine.SampleOf, StringComparison.OrdinalIgnoreCase)) - { - jtw.WritePropertyName("sampleof"); - jtw.WriteValue(datItem.Machine.SampleOf); - } - if (datItem.Machine.MachineType != MachineType.NULL) - { - if (datItem.Machine.MachineType.HasFlag(MachineType.Bios)) - { - jtw.WritePropertyName("isbios"); - jtw.WriteValue("yes"); - } - if (datItem.Machine.MachineType.HasFlag(MachineType.Device)) - { - jtw.WritePropertyName("isdevice"); - jtw.WriteValue("yes"); - } - if (datItem.Machine.MachineType.HasFlag(MachineType.Mechanical)) - { - jtw.WritePropertyName("ismechanical"); - jtw.WriteValue("yes"); - } - } - - #endregion - - #region AttractMode - - if (!string.IsNullOrWhiteSpace(datItem.Machine.Players)) - { - jtw.WritePropertyName("players"); - jtw.WriteValue(datItem.Machine.Players); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.Rotation)) - { - jtw.WritePropertyName("rotation"); - jtw.WriteValue(datItem.Machine.Rotation); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.Control)) - { - jtw.WritePropertyName("control"); - jtw.WriteValue(datItem.Machine.Control); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.Status)) - { - jtw.WritePropertyName("status"); - jtw.WriteValue(datItem.Machine.Status); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.DisplayCount)) - { - jtw.WritePropertyName("displaycount"); - jtw.WriteValue(datItem.Machine.DisplayCount); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.DisplayType)) - { - jtw.WritePropertyName("displaytype"); - jtw.WriteValue(datItem.Machine.DisplayType); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.Buttons)) - { - jtw.WritePropertyName("buttons"); - jtw.WriteValue(datItem.Machine.Buttons); - } - - #endregion - - #region ListXML - - if (!string.IsNullOrWhiteSpace(datItem.Machine.SourceFile)) - { - jtw.WritePropertyName("sourcefile"); - jtw.WriteValue(datItem.Machine.SourceFile); - } - if (datItem.Machine.Runnable != Runnable.NULL) - { - switch (datItem.Machine.Runnable) - { - case Runnable.No: - jtw.WritePropertyName("runnable"); - jtw.WriteValue("no"); - break; - case Runnable.Partial: - jtw.WritePropertyName("runnable"); - jtw.WriteValue("partial"); - break; - case Runnable.Yes: - jtw.WritePropertyName("runnable"); - jtw.WriteValue("yes"); - break; - } - } - if (datItem.Machine.DeviceReferences != null) - { - jtw.WritePropertyName("devices"); - jtw.WriteStartArray(); - foreach (ListXmlDeviceReference device in datItem.Machine.DeviceReferences) - { - jtw.WriteValue(device.Name); - } - - jtw.WriteEndArray(); - } - - // TODO: Add Field.Slots - - if (datItem.Machine.Infos != null) - { - jtw.WritePropertyName("infos"); - jtw.WriteStartArray(); - foreach (var info in datItem.Machine.Infos) - { - jtw.WriteStartObject(); - jtw.WritePropertyName(info.Name); - jtw.WriteValue(info.Value); - jtw.WriteEndObject(); - } - - jtw.WriteEndArray(); - } - - #endregion - - #region Logiqx - - if (!string.IsNullOrWhiteSpace(datItem.Machine.Board)) - { - jtw.WritePropertyName("board"); - jtw.WriteValue(datItem.Machine.Board); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.RebuildTo)) - { - jtw.WritePropertyName("rebuildto"); - jtw.WriteValue(datItem.Machine.RebuildTo); - } - - #endregion - - #region Logiqx EmuArc - - if (!string.IsNullOrWhiteSpace(datItem.Machine.TitleID)) - { - jtw.WritePropertyName("titleid"); - jtw.WriteValue(datItem.Machine.TitleID); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.Developer)) - { - jtw.WritePropertyName("developer"); - jtw.WriteValue(datItem.Machine.Developer); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.Genre)) - { - jtw.WritePropertyName("genre"); - jtw.WriteValue(datItem.Machine.Genre); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.Subgenre)) - { - jtw.WritePropertyName("subgenre"); - jtw.WriteValue(datItem.Machine.Subgenre); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.Ratings)) - { - jtw.WritePropertyName("ratings"); - jtw.WriteValue(datItem.Machine.Ratings); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.Score)) - { - jtw.WritePropertyName("score"); - jtw.WriteValue(datItem.Machine.Score); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.Enabled)) - { - jtw.WritePropertyName("enabled"); - jtw.WriteValue(datItem.Machine.Enabled); - } - if (datItem.Machine.HasCrc != null) - { - if (datItem.Machine.HasCrc == true) - { - jtw.WritePropertyName("hascrc"); - jtw.WriteValue("yes"); - } - else if (datItem.Machine.HasCrc == false) - { - jtw.WritePropertyName("hascrc"); - jtw.WriteValue("no"); - } - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.RelatedTo)) - { - jtw.WritePropertyName("relatedto"); - jtw.WriteValue(datItem.Machine.RelatedTo); - } - - #endregion - - #region OpenMSX - - if (!string.IsNullOrWhiteSpace(datItem.Machine.GenMSXID)) - { - jtw.WritePropertyName("genmsxid"); - jtw.WriteValue(datItem.Machine.GenMSXID); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.System)) - { - jtw.WritePropertyName("system"); - jtw.WriteValue(datItem.Machine.System); - } - if (!string.IsNullOrWhiteSpace(datItem.Machine.Country)) - { - jtw.WritePropertyName("country"); - jtw.WriteValue(datItem.Machine.Country); - } - - #endregion - - #region SoftwareList - - if (datItem.Machine.Supported != Supported.NULL) - { - switch (datItem.Machine.Supported) - { - case Supported.No: - jtw.WritePropertyName("supported"); - jtw.WriteValue("yes"); - break; - case Supported.Partial: - jtw.WritePropertyName("supported"); - jtw.WriteValue("partial"); - break; - case Supported.Yes: - jtw.WritePropertyName("supported"); - jtw.WriteValue("no"); - break; - } - } - if (datItem.Machine.SharedFeatures != null) - { - jtw.WritePropertyName("sharedfeat"); - jtw.WriteStartArray(); - foreach (var feature in datItem.Machine.SharedFeatures) - { - jtw.WriteStartObject(); - jtw.WritePropertyName(feature.Name); - jtw.WriteValue(feature.Value); - jtw.WriteEndObject(); - } - - jtw.WriteEndArray(); - } - if (datItem.Machine.DipSwitches != null) - { - jtw.WritePropertyName("dipswitches"); - jtw.WriteStartArray(); - foreach (var dip in datItem.Machine.DipSwitches) - { - jtw.WriteStartObject(); - jtw.WritePropertyName("name"); - jtw.WriteValue(dip.Name); - jtw.WritePropertyName("tag"); - jtw.WriteValue(dip.Tag); - jtw.WritePropertyName("mask"); - jtw.WriteValue(dip.Mask); - jtw.WriteStartArray(); - - foreach (ListXmlDipValue dipval in dip.Values) - { - jtw.WriteStartObject(); - jtw.WritePropertyName("name"); - jtw.WriteValue(dipval.Name); - jtw.WritePropertyName("value"); - jtw.WriteValue(dipval.Value); - jtw.WritePropertyName("default"); - jtw.WriteValue(dipval.Default == true ? "yes" : "no"); - jtw.WriteEndObject(); - } - - jtw.WriteEndArray(); - - // End dipswitch - jtw.WriteEndObject(); - } - - jtw.WriteEndArray(); - } - - #endregion + // Write the Machine + jtw.WritePropertyName("machine"); + JsonSerializer js = new JsonSerializer() { Formatting = Formatting.Indented }; + js.Serialize(jtw, datItem.Machine); jtw.WritePropertyName("items"); jtw.WriteStartArray(); @@ -1982,328 +553,11 @@ namespace SabreTools.Library.DatFiles // Build the state jtw.WriteStartObject(); - jtw.WritePropertyName("type"); - switch (datItem.ItemType) - { - case ItemType.Archive: - jtw.WriteValue("archive"); - jtw.WritePropertyName("name"); - jtw.WriteValue(datItem.Name); - break; - - case ItemType.BiosSet: - var biosSet = datItem as BiosSet; - jtw.WriteValue("biosset"); - jtw.WritePropertyName("name"); - jtw.WriteValue(biosSet.Name); - if (!string.IsNullOrWhiteSpace(biosSet.Description)) - { - jtw.WritePropertyName("description"); - jtw.WriteValue(biosSet.Description); - } - if (biosSet.Default != null) - { - jtw.WritePropertyName("default"); - jtw.WriteValue(biosSet.Default); - } - break; - - case ItemType.Disk: - var disk = datItem as Disk; - jtw.WriteValue("disk"); - jtw.WritePropertyName("name"); - jtw.WriteValue(disk.Name); - if (!string.IsNullOrWhiteSpace(disk.MD5)) - { - jtw.WritePropertyName("md5"); - jtw.WriteValue(disk.MD5.ToLowerInvariant()); - } -#if NET_FRAMEWORK - if (!string.IsNullOrWhiteSpace(disk.RIPEMD160)) - { - jtw.WritePropertyName("ripemd160"); - jtw.WriteValue(disk.RIPEMD160.ToLowerInvariant()); - } -#endif - if (!string.IsNullOrWhiteSpace(disk.SHA1)) - { - jtw.WritePropertyName("sha1"); - jtw.WriteValue(disk.SHA1.ToLowerInvariant()); - } - if (!string.IsNullOrWhiteSpace(disk.SHA256)) - { - jtw.WritePropertyName("sha256"); - jtw.WriteValue(disk.SHA256.ToLowerInvariant()); - } - if (!string.IsNullOrWhiteSpace(disk.SHA384)) - { - jtw.WritePropertyName("sha384"); - jtw.WriteValue(disk.SHA384.ToLowerInvariant()); - } - if (!string.IsNullOrWhiteSpace(disk.SHA512)) - { - jtw.WritePropertyName("sha512"); - jtw.WriteValue(disk.SHA512.ToLowerInvariant()); - } - if (!string.IsNullOrWhiteSpace(disk.MergeTag)) - { - jtw.WritePropertyName("merge"); - jtw.WriteValue(disk.MergeTag); - } - if (!string.IsNullOrWhiteSpace(disk.Region)) - { - jtw.WritePropertyName("region"); - jtw.WriteValue(disk.Region); - } - if (!string.IsNullOrWhiteSpace(disk.Index)) - { - jtw.WritePropertyName("index"); - jtw.WriteValue(disk.Index); - } - if (disk.Writable != null) - { - jtw.WritePropertyName("writable"); - jtw.WriteValue(disk.Writable); - } - if (disk.ItemStatus != ItemStatus.None) - { - jtw.WritePropertyName("status"); - jtw.WriteValue(disk.ItemStatus.ToString().ToLowerInvariant()); - } - if (disk.Optional != null) - { - jtw.WritePropertyName("optional"); - jtw.WriteValue(disk.Optional); - } - break; - - case ItemType.Release: - var release = datItem as Release; - jtw.WriteValue("release"); - jtw.WritePropertyName("name"); - jtw.WriteValue(release.Name); - if (!string.IsNullOrWhiteSpace(release.Region)) - { - jtw.WritePropertyName("region"); - jtw.WriteValue(release.Region); - } - if (!string.IsNullOrWhiteSpace(release.Language)) - { - jtw.WritePropertyName("language"); - jtw.WriteValue(release.Language); - } - if (!string.IsNullOrWhiteSpace(release.Date)) - { - jtw.WritePropertyName("date"); - jtw.WriteValue(release.Date); - } - if (release.Default != null) - { - jtw.WritePropertyName("default"); - jtw.WriteValue(release.Default); - } - break; - - case ItemType.Rom: - var rom = datItem as Rom; - jtw.WriteValue("rom"); - jtw.WritePropertyName("name"); - jtw.WriteValue(rom.Name); - if (rom.Size != -1) - { - jtw.WritePropertyName("size"); - jtw.WriteValue(rom.Size); - } - if (!string.IsNullOrWhiteSpace(rom.Offset)) - { - jtw.WritePropertyName("offset"); - jtw.WriteValue(rom.Offset); - } - if (!string.IsNullOrWhiteSpace(rom.CRC)) - { - jtw.WritePropertyName("crc"); - jtw.WriteValue(rom.CRC.ToLowerInvariant()); - } - if (!string.IsNullOrWhiteSpace(rom.MD5)) - { - jtw.WritePropertyName("md5"); - jtw.WriteValue(rom.MD5.ToLowerInvariant()); - } -#if NET_FRAMEWORK - if (!string.IsNullOrWhiteSpace(rom.RIPEMD160)) - { - jtw.WritePropertyName("ripemd160"); - jtw.WriteValue(rom.RIPEMD160.ToLowerInvariant()); - } -#endif - if (!string.IsNullOrWhiteSpace(rom.SHA1)) - { - jtw.WritePropertyName("sha1"); - jtw.WriteValue(rom.SHA1.ToLowerInvariant()); - } - if (!string.IsNullOrWhiteSpace(rom.SHA256)) - { - jtw.WritePropertyName("sha256"); - jtw.WriteValue(rom.SHA256.ToLowerInvariant()); - } - if (!string.IsNullOrWhiteSpace(rom.SHA384)) - { - jtw.WritePropertyName("sha384"); - jtw.WriteValue(rom.SHA384.ToLowerInvariant()); - } - if (!string.IsNullOrWhiteSpace(rom.SHA512)) - { - jtw.WritePropertyName("sha512"); - jtw.WriteValue(rom.SHA512.ToLowerInvariant()); - } - if (!string.IsNullOrWhiteSpace(rom.Bios)) - { - jtw.WritePropertyName("bios"); - jtw.WriteValue(rom.Bios); - } - if (!string.IsNullOrWhiteSpace(rom.MergeTag)) - { - jtw.WritePropertyName("merge"); - jtw.WriteValue(rom.MergeTag); - } - if (!string.IsNullOrWhiteSpace(rom.Region)) - { - jtw.WritePropertyName("region"); - jtw.WriteValue(rom.Region); - } - if (!string.IsNullOrWhiteSpace(rom.Date)) - { - jtw.WritePropertyName("date"); - jtw.WriteValue(rom.Date); - } - if (rom.ItemStatus != ItemStatus.None) - { - jtw.WritePropertyName("status"); - jtw.WriteValue(rom.ItemStatus.ToString().ToLowerInvariant()); - } - if (rom.Optional != null) - { - jtw.WritePropertyName("optional"); - jtw.WriteValue(rom.Optional); - } - if (rom.Inverted != null) - { - jtw.WritePropertyName("inverted"); - jtw.WriteValue(rom.Inverted); - } - break; - - case ItemType.Sample: - jtw.WriteValue("sample"); - jtw.WritePropertyName("name"); - jtw.WriteValue(datItem.Name); - break; - } - - #region AttractMode - - if (!string.IsNullOrWhiteSpace(datItem.AltName)) - { - jtw.WritePropertyName("alt_romname"); - jtw.WriteValue(datItem.AltName); - } - if (!string.IsNullOrWhiteSpace(datItem.AltTitle)) - { - jtw.WritePropertyName("alt_title"); - jtw.WriteValue(datItem.AltTitle); - } - - #endregion - - #region OpenMSX - - if (!string.IsNullOrWhiteSpace(datItem.Original?.Content ?? string.Empty)) - { - jtw.WritePropertyName("original"); - jtw.WriteValue(datItem.Original.Content); - } - if (datItem.OpenMSXSubType != OpenMSXSubType.NULL) - { - jtw.WritePropertyName("openmsx_subtype"); - jtw.WriteValue(datItem.OpenMSXSubType); - } - if (!string.IsNullOrWhiteSpace(datItem.OpenMSXType)) - { - jtw.WritePropertyName("openmsx_type"); - jtw.WriteValue(datItem.OpenMSXType); - } - if (!string.IsNullOrWhiteSpace(datItem.Remark)) - { - jtw.WritePropertyName("remark"); - jtw.WriteValue(datItem.Remark); - } - if (!string.IsNullOrWhiteSpace(datItem.Boot)) - { - jtw.WritePropertyName("boot"); - jtw.WriteValue(datItem.Boot); - } - - #endregion - - #region SoftwareList - - if (!string.IsNullOrWhiteSpace(datItem.PartName)) - { - jtw.WritePropertyName("partname"); - jtw.WriteValue(datItem.PartName); - } - if (!string.IsNullOrWhiteSpace(datItem.PartInterface)) - { - jtw.WritePropertyName("partinterface"); - jtw.WriteValue(datItem.PartInterface); - } - if (datItem.Features != null) - { - jtw.WritePropertyName("features"); - jtw.WriteStartArray(); - foreach (var feature in datItem.Features) - { - jtw.WriteStartObject(); - jtw.WritePropertyName(feature.Name); - jtw.WriteValue(feature.Value); - jtw.WriteEndObject(); - } - - jtw.WriteEndArray(); - } - if (!string.IsNullOrWhiteSpace(datItem.AreaName)) - { - jtw.WritePropertyName("areaname"); - jtw.WriteValue(datItem.AreaName); - } - if (datItem.AreaSize != null) - { - jtw.WritePropertyName("areasize"); - jtw.WriteValue(datItem.AreaSize); - } - if (!string.IsNullOrWhiteSpace(datItem.AreaWidth)) - { - jtw.WritePropertyName("areawidth"); - jtw.WriteValue(datItem.AreaWidth); - } - if (!string.IsNullOrWhiteSpace(datItem.AreaEndianness)) - { - jtw.WritePropertyName("areaendianness"); - jtw.WriteValue(datItem.AreaEndianness); - } - if (!string.IsNullOrWhiteSpace(datItem.Value)) - { - jtw.WritePropertyName("value"); - jtw.WriteValue(datItem.Value); - } - if (!string.IsNullOrWhiteSpace(datItem.LoadFlag)) - { - jtw.WritePropertyName("loadflag"); - jtw.WriteValue(datItem.LoadFlag); - } - - #endregion + // Write the DatItem + jtw.WritePropertyName("datitem"); + JsonSerializer js = new JsonSerializer() { ContractResolver = new BaseFirstContractResolver(), Formatting = Formatting.Indented }; + js.Serialize(jtw, datItem); // End item jtw.WriteEndObject(); diff --git a/SabreTools.Library/DatFiles/Listrom.cs b/SabreTools.Library/DatFiles/Listrom.cs index 028b3bf9..6b2d832a 100644 --- a/SabreTools.Library/DatFiles/Listrom.cs +++ b/SabreTools.Library/DatFiles/Listrom.cs @@ -445,7 +445,7 @@ namespace SabreTools.Library.DatFiles // Otherwise, write out the SHA-1 hash else if (!string.IsNullOrWhiteSpace(disk.SHA1)) - sw.Write($" SHA1({disk.SHA1})"); + sw.Write($" SHA1({disk.SHA1 ?? string.Empty})"); // If we have a baddump, put the second indicator if (disk.ItemStatus == ItemStatus.BadDump) @@ -480,9 +480,9 @@ namespace SabreTools.Library.DatFiles else { if (!string.IsNullOrWhiteSpace(rom.CRC)) - sw.Write($" CRC({rom.CRC})"); + sw.Write($" CRC({rom.CRC ?? string.Empty})"); if (!string.IsNullOrWhiteSpace(rom.SHA1)) - sw.Write($" SHA1({rom.SHA1})"); + sw.Write($" SHA1({rom.SHA1 ?? string.Empty})"); } // If we have a baddump, put the second indicator diff --git a/SabreTools.Library/DatFiles/Listxml.cs b/SabreTools.Library/DatFiles/Listxml.cs index 64bdf4d9..6a0d8592 100644 --- a/SabreTools.Library/DatFiles/Listxml.cs +++ b/SabreTools.Library/DatFiles/Listxml.cs @@ -1138,14 +1138,14 @@ namespace SabreTools.Library.DatFiles var disk = datItem as Disk; xtw.WriteStartElement("disk"); xtw.WriteRequiredAttributeString("name", disk.Name); - xtw.WriteOptionalAttributeString("md5", disk.MD5.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("md5", disk.MD5?.ToLowerInvariant()); #if NET_FRAMEWORK - xtw.WriteOptionalAttributeString("ripemd160", disk.RIPEMD160.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("ripemd160", disk.RIPEMD160?.ToLowerInvariant()); #endif - xtw.WriteOptionalAttributeString("sha1", disk.SHA1.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha256", disk.SHA256.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha384", disk.SHA384.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha512", disk.SHA512.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha1", disk.SHA1?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha256", disk.SHA256?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha384", disk.SHA384?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha512", disk.SHA512?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("merge", disk.MergeTag); xtw.WriteOptionalAttributeString("region", disk.Region); xtw.WriteOptionalAttributeString("index", disk.Index); @@ -1160,15 +1160,15 @@ namespace SabreTools.Library.DatFiles xtw.WriteStartElement("rom"); xtw.WriteRequiredAttributeString("name", rom.Name); if (rom.Size != -1) xtw.WriteAttributeString("size", rom.Size.ToString()); - xtw.WriteOptionalAttributeString("crc", rom.CRC.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("md5", rom.MD5.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("crc", rom.CRC?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("md5", rom.MD5?.ToLowerInvariant()); #if NET_FRAMEWORK - xtw.WriteOptionalAttributeString("ripemd160", rom.RIPEMD160.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("ripemd160", rom?.RIPEMD160.ToLowerInvariant()); #endif - xtw.WriteOptionalAttributeString("sha1", rom.SHA1.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha256", rom.SHA256.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha384", rom.SHA384.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha512", rom.SHA512.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha1", rom.SHA1?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha256", rom.SHA256?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha384", rom.SHA384?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha512", rom.SHA512?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("bios", rom.Bios); xtw.WriteOptionalAttributeString("merge", rom.MergeTag); xtw.WriteOptionalAttributeString("region", rom.Region); diff --git a/SabreTools.Library/DatFiles/Logiqx.cs b/SabreTools.Library/DatFiles/Logiqx.cs index 89fe30f3..4576b351 100644 --- a/SabreTools.Library/DatFiles/Logiqx.cs +++ b/SabreTools.Library/DatFiles/Logiqx.cs @@ -1057,14 +1057,14 @@ namespace SabreTools.Library.DatFiles var disk = datItem as Disk; xtw.WriteStartElement("disk"); xtw.WriteRequiredAttributeString("name", disk.Name); - xtw.WriteOptionalAttributeString("md5", disk.MD5.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("md5", disk.MD5?.ToLowerInvariant()); #if NET_FRAMEWORK - xtw.WriteOptionalAttributeString("ripemd160", disk.RIPEMD160.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("ripemd160", disk.RIPEMD160?.ToLowerInvariant()); #endif - xtw.WriteOptionalAttributeString("sha1", disk.SHA1.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha256", disk.SHA256.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha384", disk.SHA384.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha512", disk.SHA512.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha1", disk.SHA1?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha256", disk.SHA256?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha384", disk.SHA384?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha512", disk.SHA512?.ToLowerInvariant()); if (disk.ItemStatus != ItemStatus.None) xtw.WriteAttributeString("status", disk.ItemStatus.ToString().ToLowerInvariant()); xtw.WriteEndElement(); break; @@ -1085,15 +1085,15 @@ namespace SabreTools.Library.DatFiles xtw.WriteStartElement("rom"); xtw.WriteRequiredAttributeString("name", rom.Name); if (rom.Size != -1) xtw.WriteAttributeString("size", rom.Size.ToString()); - xtw.WriteOptionalAttributeString("crc", rom.CRC.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("md5", rom.MD5.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("crc", rom.CRC?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("md5", rom.MD5?.ToLowerInvariant()); #if NET_FRAMEWORK - xtw.WriteOptionalAttributeString("ripemd160", rom.RIPEMD160.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("ripemd160", rom.RIPEMD160?.ToLowerInvariant()); #endif - xtw.WriteOptionalAttributeString("sha1", rom.SHA1.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha256", rom.SHA256.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha384", rom.SHA384.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha512", rom.SHA512.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha1", rom.SHA1?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha256", rom.SHA256?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha384", rom.SHA384?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha512", rom.SHA512?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("date", rom.Date); if (rom.ItemStatus != ItemStatus.None) xtw.WriteAttributeString("status", rom.ItemStatus.ToString().ToLowerInvariant()); xtw.WriteOptionalAttributeString("inverted", rom.Inverted.FromYesNo()); diff --git a/SabreTools.Library/DatFiles/Missfile.cs b/SabreTools.Library/DatFiles/Missfile.cs index 2ad377d7..6d06ae65 100644 --- a/SabreTools.Library/DatFiles/Missfile.cs +++ b/SabreTools.Library/DatFiles/Missfile.cs @@ -136,7 +136,7 @@ namespace SabreTools.Library.DatFiles ProcessItemName(datItem, false, forceRomName: false); // Romba mode automatically uses item name - if (Header.OutputDepot.IsActive || Header.UseRomName) + if ((Header.OutputDepot?.IsActive ?? false) || Header.UseRomName) { sw.Write($"{datItem.Name}\n"); } diff --git a/SabreTools.Library/DatFiles/OfflineList.cs b/SabreTools.Library/DatFiles/OfflineList.cs index 0f564b2d..9adbc3c2 100644 --- a/SabreTools.Library/DatFiles/OfflineList.cs +++ b/SabreTools.Library/DatFiles/OfflineList.cs @@ -925,14 +925,14 @@ namespace SabreTools.Library.DatFiles { xtw.WriteStartElement("romMD5"); xtw.WriteAttributeString("extension", ".chd"); - xtw.WriteString(disk.MD5.ToUpperInvariant()); + xtw.WriteString(disk.MD5?.ToUpperInvariant()); xtw.WriteEndElement(); } else if (!string.IsNullOrWhiteSpace(disk.SHA1)) { xtw.WriteStartElement("romSHA1"); xtw.WriteAttributeString("extension", ".chd"); - xtw.WriteString(disk.SHA1.ToUpperInvariant()); + xtw.WriteString(disk.SHA1?.ToUpperInvariant()); xtw.WriteEndElement(); } @@ -949,21 +949,21 @@ namespace SabreTools.Library.DatFiles { xtw.WriteStartElement("romCRC"); xtw.WriteRequiredAttributeString("extension", tempext); - xtw.WriteString(rom.CRC.ToUpperInvariant()); + xtw.WriteString(rom.CRC?.ToUpperInvariant()); xtw.WriteEndElement(); } else if (!string.IsNullOrWhiteSpace(rom.MD5)) { xtw.WriteStartElement("romMD5"); xtw.WriteRequiredAttributeString("extension", tempext); - xtw.WriteString(rom.MD5.ToUpperInvariant()); + xtw.WriteString(rom.MD5?.ToUpperInvariant()); xtw.WriteEndElement(); } else if (!string.IsNullOrWhiteSpace(rom.SHA1)) { xtw.WriteStartElement("romSHA1"); xtw.WriteRequiredAttributeString("extension", tempext); - xtw.WriteString(rom.SHA1.ToUpperInvariant()); + xtw.WriteString(rom.SHA1?.ToUpperInvariant()); xtw.WriteEndElement(); } diff --git a/SabreTools.Library/DatFiles/OpenMSX.cs b/SabreTools.Library/DatFiles/OpenMSX.cs index dc7770f7..b2d6ec3b 100644 --- a/SabreTools.Library/DatFiles/OpenMSX.cs +++ b/SabreTools.Library/DatFiles/OpenMSX.cs @@ -740,7 +740,7 @@ namespace SabreTools.Library.DatFiles case OpenMSXSubType.Rom: case OpenMSXSubType.NULL: xtw.WriteStartElement("rom"); - xtw.WriteRequiredElementString("hash", rom.SHA1.ToLowerInvariant()); + xtw.WriteRequiredElementString("hash", rom.SHA1?.ToLowerInvariant()); xtw.WriteOptionalElementString("start", rom.Offset); xtw.WriteOptionalElementString("type", rom.OpenMSXType); xtw.WriteOptionalElementString("remark", rom.Remark); @@ -749,7 +749,7 @@ namespace SabreTools.Library.DatFiles case OpenMSXSubType.MegaRom: xtw.WriteStartElement("megarom"); - xtw.WriteRequiredElementString("hash", rom.SHA1.ToLowerInvariant()); + xtw.WriteRequiredElementString("hash", rom.SHA1?.ToLowerInvariant()); xtw.WriteOptionalElementString("start", rom.Offset); xtw.WriteOptionalElementString("type", rom.OpenMSXType); xtw.WriteOptionalElementString("remark", rom.Remark); @@ -759,7 +759,7 @@ namespace SabreTools.Library.DatFiles case OpenMSXSubType.SCCPlusCart: xtw.WriteStartElement("sccpluscart"); xtw.WriteOptionalElementString("boot", rom.Boot); - xtw.WriteRequiredElementString("hash", rom.SHA1.ToLowerInvariant()); + xtw.WriteRequiredElementString("hash", rom.SHA1?.ToLowerInvariant()); xtw.WriteOptionalElementString("remark", rom.Remark); xtw.WriteEndElement(); break; diff --git a/SabreTools.Library/DatFiles/RomCenter.cs b/SabreTools.Library/DatFiles/RomCenter.cs index e501f02b..df3a400e 100644 --- a/SabreTools.Library/DatFiles/RomCenter.cs +++ b/SabreTools.Library/DatFiles/RomCenter.cs @@ -532,18 +532,18 @@ namespace SabreTools.Library.DatFiles case ItemType.Rom: var rom = datItem as Rom; - iw.WriteString($"¬{rom.Machine.CloneOf}"); - iw.WriteString($"¬{rom.Machine.CloneOf}"); - iw.WriteString($"¬{rom.Machine.Name}"); - if (string.IsNullOrWhiteSpace(rom.Machine.Description)) - iw.WriteString($"¬{rom.Machine.Name}"); + iw.WriteString($"¬{rom.Machine.CloneOf ?? string.Empty}"); + iw.WriteString($"¬{rom.Machine.CloneOf ?? string.Empty}"); + iw.WriteString($"¬{rom.Machine.Name ?? string.Empty}"); + if (string.IsNullOrWhiteSpace(rom.Machine.Description ?? string.Empty)) + iw.WriteString($"¬{rom.Machine.Name ?? string.Empty}"); else - iw.WriteString($"¬{rom.Machine.Description}"); - iw.WriteString($"¬{rom.Name}"); - iw.WriteString($"¬{rom.CRC}"); + iw.WriteString($"¬{rom.Machine.Description ?? string.Empty}"); + iw.WriteString($"¬{rom.Name ?? string.Empty}"); + iw.WriteString($"¬{rom.CRC ?? string.Empty}"); iw.WriteString($"¬{rom.Size}"); - iw.WriteString($"¬{rom.Machine.RomOf}"); - iw.WriteString($"¬{rom.MergeTag}"); + iw.WriteString($"¬{rom.Machine.RomOf ?? string.Empty}"); + iw.WriteString($"¬{rom.MergeTag ?? string.Empty}"); iw.WriteString("¬"); iw.WriteLine(); diff --git a/SabreTools.Library/DatFiles/SabreDat.cs b/SabreTools.Library/DatFiles/SabreDat.cs index b2824442..1ed83c2a 100644 --- a/SabreTools.Library/DatFiles/SabreDat.cs +++ b/SabreTools.Library/DatFiles/SabreDat.cs @@ -902,14 +902,14 @@ namespace SabreTools.Library.DatFiles xtw.WriteStartElement("file"); xtw.WriteAttributeString("type", "disk"); xtw.WriteRequiredAttributeString("name", disk.Name); - xtw.WriteOptionalAttributeString("md5", disk.MD5.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("md5", disk.MD5?.ToLowerInvariant()); #if NET_FRAMEWORK - xtw.WriteOptionalAttributeString("ripemd160", disk.RIPEMD160.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("ripemd160", disk.RIPEMD160?.ToLowerInvariant()); #endif - xtw.WriteOptionalAttributeString("sha1", disk.SHA1.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha256", disk.SHA256.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha384", disk.SHA384.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha512", disk.SHA512.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha1", disk.SHA1?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha256", disk.SHA256?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha384", disk.SHA384?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha512", disk.SHA512?.ToLowerInvariant()); if (disk.ItemStatus != ItemStatus.None) { xtw.WriteStartElement("flags"); @@ -943,15 +943,15 @@ namespace SabreTools.Library.DatFiles xtw.WriteAttributeString("type", "rom"); xtw.WriteRequiredAttributeString("name", rom.Name); if (rom.Size != -1) xtw.WriteAttributeString("size", rom.Size.ToString()); - xtw.WriteOptionalAttributeString("crc", rom.CRC.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("md5", rom.MD5.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("crc", rom.CRC?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("md5", rom.MD5?.ToLowerInvariant()); #if NET_FRAMEWORK - xtw.WriteOptionalAttributeString("ripemd160", rom.RIPEMD160.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("ripemd160", rom.RIPEMD160?.ToLowerInvariant()); #endif - xtw.WriteOptionalAttributeString("sha1", rom.SHA1.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha256", rom.SHA256.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha384", rom.SHA384.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha512", rom.SHA512.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha1", rom.SHA1?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha256", rom.SHA256?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha384", rom.SHA384?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha512", rom.SHA512?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("date", rom.Date); if (rom.ItemStatus != ItemStatus.None) { diff --git a/SabreTools.Library/DatFiles/SeparatedValue.cs b/SabreTools.Library/DatFiles/SeparatedValue.cs index 4b0a1eee..31cca2fe 100644 --- a/SabreTools.Library/DatFiles/SeparatedValue.cs +++ b/SabreTools.Library/DatFiles/SeparatedValue.cs @@ -1723,11 +1723,11 @@ namespace SabreTools.Library.DatFiles fields[8] = string.Empty; fields[9] = string.Empty; fields[10] = disk.MD5.ToLowerInvariant(); - //fields[11] = disk.GetField(Field.RIPEMD160, DatHeader.ExcludeFields).ToLowerInvariant(); + //fields[11] = disk.RIPEMD160?.ToLowerInvariant(); fields[11] = disk.SHA1.ToLowerInvariant(); fields[12] = disk.SHA256.ToLowerInvariant(); - //fields[13] = disk.GetField(Field.SHA384, DatHeader.ExcludeFields).ToLowerInvariant(); - //fields[14] = disk.GetField(Field.SHA512, DatHeader.ExcludeFields).ToLowerInvariant(); + //fields[13] = disk.SHA384?.ToLowerInvariant(); + //fields[14] = disk.SHA512?.ToLowerInvariant(); fields[13] = disk.ItemStatus.ToString(); break; @@ -1737,13 +1737,13 @@ namespace SabreTools.Library.DatFiles fields[6] = rom.Name; fields[7] = string.Empty; fields[8] = rom.Size.ToString(); - fields[9] = rom.CRC.ToLowerInvariant(); - fields[10] = rom.MD5.ToLowerInvariant(); - //fields[11] = rom.GetField(Field.RIPEMD160, DatHeader.ExcludeFields).ToLowerInvariant(); - fields[11] = rom.SHA1.ToLowerInvariant(); - fields[12] = rom.SHA256.ToLowerInvariant(); - //fields[13] = rom.GetField(Field.SHA384, DatHeader.ExcludeFields).ToLowerInvariant(); - //fields[14] = rom.GetField(Field.SHA512, DatHeader.ExcludeFields).ToLowerInvariant(); + fields[9] = rom.CRC?.ToLowerInvariant(); + fields[10] = rom.MD5?.ToLowerInvariant(); + //fields[11] = rom.RIPEMD160?.ToLowerInvariant(); + fields[11] = rom.SHA1?.ToLowerInvariant(); + fields[12] = rom.SHA256?.ToLowerInvariant(); + //fields[13] = rom.SHA384?.ToLowerInvariant(); + //fields[14] = rom.SHA512?.ToLowerInvariant(); fields[13] = rom.ItemStatus.ToString(); break; } diff --git a/SabreTools.Library/DatFiles/SoftwareList.cs b/SabreTools.Library/DatFiles/SoftwareList.cs index 7dfad60b..e5f8ac73 100644 --- a/SabreTools.Library/DatFiles/SoftwareList.cs +++ b/SabreTools.Library/DatFiles/SoftwareList.cs @@ -952,14 +952,14 @@ namespace SabreTools.Library.DatFiles xtw.WriteStartElement("disk"); xtw.WriteRequiredAttributeString("name", disk.Name); - xtw.WriteOptionalAttributeString("md5", disk.MD5.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("md5", disk.MD5?.ToLowerInvariant()); #if NET_FRAMEWORK - xtw.WriteOptionalAttributeString("ripemd160", disk.RIPEMD160.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("ripemd160", disk.RIPEMD160?.ToLowerInvariant()); #endif - xtw.WriteOptionalAttributeString("sha1", disk.SHA1.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha256", disk.SHA256.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha384", disk.SHA384.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha512", disk.SHA512.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha1", disk.SHA1?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha256", disk.SHA256?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha384", disk.SHA384?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha512", disk.SHA512?.ToLowerInvariant()); if (disk.ItemStatus != ItemStatus.None) xtw.WriteAttributeString("status", disk.ItemStatus.ToString().ToLowerInvariant()); xtw.WriteOptionalAttributeString("writable", disk.Writable.FromYesNo()); xtw.WriteEndElement(); @@ -982,15 +982,15 @@ namespace SabreTools.Library.DatFiles xtw.WriteStartElement("rom"); xtw.WriteRequiredAttributeString("name", rom.Name); if (rom.Size != -1) xtw.WriteAttributeString("size", rom.Size.ToString()); - xtw.WriteOptionalAttributeString("crc", rom.CRC.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("md5", rom.MD5.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("crc", rom.CRC?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("md5", rom.MD5?.ToLowerInvariant()); #if NET_FRAMEWORK - xtw.WriteOptionalAttributeString("ripemd160", rom.RIPEMD160.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("ripemd160", rom.RIPEMD160?.ToLowerInvariant()); #endif - xtw.WriteOptionalAttributeString("sha1", rom.SHA1.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha256", rom.SHA256.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha384", rom.SHA384.ToLowerInvariant()); - xtw.WriteOptionalAttributeString("sha512", rom.SHA512.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha1", rom.SHA1?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha256", rom.SHA256?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha384", rom.SHA384?.ToLowerInvariant()); + xtw.WriteOptionalAttributeString("sha512", rom.SHA512?.ToLowerInvariant()); xtw.WriteOptionalAttributeString("offset", rom.Offset); xtw.WriteOptionalAttributeString("value", rom.Value); if (rom.ItemStatus != ItemStatus.None) xtw.WriteAttributeString("status", rom.ItemStatus.ToString().ToLowerInvariant()); diff --git a/SabreTools.Library/DatItems/BiosSet.cs b/SabreTools.Library/DatItems/BiosSet.cs index 743f2474..4c81a519 100644 --- a/SabreTools.Library/DatItems/BiosSet.cs +++ b/SabreTools.Library/DatItems/BiosSet.cs @@ -18,13 +18,13 @@ namespace SabreTools.Library.DatItems /// /// Description of the BIOS /// - [JsonProperty("description")] + [JsonProperty("description", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Description { get; set; } /// /// Determine whether the BIOS is default /// - [JsonProperty("default")] + [JsonProperty("default", DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? Default { get; set; } #endregion diff --git a/SabreTools.Library/DatItems/DatItem.cs b/SabreTools.Library/DatItems/DatItem.cs index cdea54e8..9faa6cb5 100644 --- a/SabreTools.Library/DatItems/DatItem.cs +++ b/SabreTools.Library/DatItems/DatItem.cs @@ -62,13 +62,13 @@ namespace SabreTools.Library.DatItems /// /// Alternate name for the item /// - [JsonProperty("alt_romname")] + [JsonProperty("alt_romname", DefaultValueHandling = DefaultValueHandling.Ignore)] public string AltName { get; set; } /// /// Alternate title for the item /// - [JsonProperty("alt_title")] + [JsonProperty("alt_title", DefaultValueHandling = DefaultValueHandling.Ignore)] public string AltTitle { get; set; } #endregion @@ -78,13 +78,13 @@ namespace SabreTools.Library.DatItems /// /// OpenMSX sub item type /// - [JsonProperty("original")] + [JsonProperty("original", DefaultValueHandling = DefaultValueHandling.Ignore)] public OpenMSXOriginal Original { get; set; } /// /// OpenMSX sub item type /// - [JsonProperty("openmsx_subtype")] + [JsonProperty("openmsx_subtype", DefaultValueHandling = DefaultValueHandling.Ignore)] [JsonConverter(typeof(StringEnumConverter))] public OpenMSXSubType OpenMSXSubType { get; set; } @@ -92,19 +92,19 @@ namespace SabreTools.Library.DatItems /// OpenMSX sub item type /// /// Not related to the subtype above - [JsonProperty("openmsx_type")] + [JsonProperty("openmsx_type", DefaultValueHandling = DefaultValueHandling.Ignore)] public string OpenMSXType { get; set; } /// /// Item remark (like a comment) /// - [JsonProperty("remark")] + [JsonProperty("remark", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Remark { get; set; } /// /// Boot state /// - [JsonProperty("boot")] + [JsonProperty("boot", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Boot { get; set; } #endregion @@ -114,58 +114,58 @@ namespace SabreTools.Library.DatItems /// /// Original hardware part associated with the item /// - [JsonProperty("partname")] + [JsonProperty("partname", DefaultValueHandling = DefaultValueHandling.Ignore)] public string PartName { get; set; } /// /// Original hardware interface associated with the item /// - [JsonProperty("partinterface")] + [JsonProperty("partinterface", DefaultValueHandling = DefaultValueHandling.Ignore)] public string PartInterface { get; set; } /// /// Features provided to/by the item /// - [JsonProperty("features")] + [JsonProperty("features", DefaultValueHandling = DefaultValueHandling.Ignore)] public List Features { get; set; } /// /// Original hardware part name within an item /// - [JsonProperty("areaname")] + [JsonProperty("areaname", DefaultValueHandling = DefaultValueHandling.Ignore)] public string AreaName { get; set; } /// /// Original hardware size within the part /// - [JsonProperty("areasize")] + [JsonProperty("areasize", DefaultValueHandling = DefaultValueHandling.Ignore)] public long? AreaSize { get; set; } /// /// Width of the data area in bytes /// /// TODO: Convert to Int32 - [JsonProperty("width")] + [JsonProperty("width", DefaultValueHandling = DefaultValueHandling.Ignore)] public string AreaWidth { get; set; } // (8|16|32|64) "8" /// /// Endianness of the data area /// /// TODO: Convert to Enum? - [JsonProperty("endianness")] + [JsonProperty("endianness", DefaultValueHandling = DefaultValueHandling.Ignore)] public string AreaEndianness { get; set; } // (big|little) "little" /// /// SoftwareList value associated with the item /// - [JsonProperty("value")] + [JsonProperty("value", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Value { get; set; } /// /// Loading flag /// /// TODO: Convert to Enum? - [JsonProperty("loadflag")] + [JsonProperty("loadflag", DefaultValueHandling = DefaultValueHandling.Ignore)] public string LoadFlag { get; set; } // (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) #endregion diff --git a/SabreTools.Library/DatItems/Disk.cs b/SabreTools.Library/DatItems/Disk.cs index 064cf895..aef981ae 100644 --- a/SabreTools.Library/DatItems/Disk.cs +++ b/SabreTools.Library/DatItems/Disk.cs @@ -33,7 +33,7 @@ namespace SabreTools.Library.DatItems /// /// Data MD5 hash /// - [JsonProperty("md5")] + [JsonProperty("md5", DefaultValueHandling = DefaultValueHandling.Ignore)] public string MD5 { get { return _md5.IsNullOrEmpty() ? null : Utilities.ByteArrayToString(_md5); } @@ -44,7 +44,7 @@ namespace SabreTools.Library.DatItems /// /// Data RIPEMD160 hash /// - [JsonProperty("ripemd160")] + [JsonProperty("ripemd160", DefaultValueHandling = DefaultValueHandling.Ignore)] public string RIPEMD160 { get { return _ripemd160.IsNullOrEmpty() ? null : Utilities.ByteArrayToString(_ripemd160); } @@ -55,7 +55,7 @@ namespace SabreTools.Library.DatItems /// /// Data SHA-1 hash /// - [JsonProperty("sha1")] + [JsonProperty("sha1", DefaultValueHandling = DefaultValueHandling.Ignore)] public string SHA1 { get { return _sha1.IsNullOrEmpty() ? null : Utilities.ByteArrayToString(_sha1); } @@ -65,7 +65,7 @@ namespace SabreTools.Library.DatItems /// /// Data SHA-256 hash /// - [JsonProperty("sha256")] + [JsonProperty("sha256", DefaultValueHandling = DefaultValueHandling.Ignore)] public string SHA256 { get { return _sha256.IsNullOrEmpty() ? null : Utilities.ByteArrayToString(_sha256); } @@ -75,7 +75,7 @@ namespace SabreTools.Library.DatItems /// /// Data SHA-384 hash /// - [JsonProperty("sha384")] + [JsonProperty("sha384", DefaultValueHandling = DefaultValueHandling.Ignore)] public string SHA384 { get { return _sha384.IsNullOrEmpty() ? null : Utilities.ByteArrayToString(_sha384); } @@ -85,7 +85,7 @@ namespace SabreTools.Library.DatItems /// /// Data SHA-512 hash /// - [JsonProperty("sha512")] + [JsonProperty("sha512", DefaultValueHandling = DefaultValueHandling.Ignore)] public string SHA512 { get { return _sha512.IsNullOrEmpty() ? null : Utilities.ByteArrayToString(_sha512); } @@ -95,38 +95,38 @@ namespace SabreTools.Library.DatItems /// /// Disk name to merge from parent /// - [JsonProperty("merge")] + [JsonProperty("merge", DefaultValueHandling = DefaultValueHandling.Ignore)] public string MergeTag { get; set; } /// /// Disk region /// - [JsonProperty("region")] + [JsonProperty("region", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Region { get; set; } /// /// Disk index /// - [JsonProperty("index")] + [JsonProperty("index", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Index { get; set; } /// /// Disk writable flag /// - [JsonProperty("writable")] + [JsonProperty("writable", DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? Writable { get; set; } /// /// Disk dump status /// - [JsonProperty("status")] + [JsonProperty("status", DefaultValueHandling = DefaultValueHandling.Ignore)] [JsonConverter(typeof(StringEnumConverter))] public ItemStatus ItemStatus { get; set; } /// /// Determine if the disk is optional in the set /// - [JsonProperty("optional")] + [JsonProperty("optional", DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? Optional { get; set; } #endregion diff --git a/SabreTools.Library/DatItems/Machine.cs b/SabreTools.Library/DatItems/Machine.cs index 09a00ffa..8e5b45fa 100644 --- a/SabreTools.Library/DatItems/Machine.cs +++ b/SabreTools.Library/DatItems/Machine.cs @@ -21,68 +21,68 @@ namespace SabreTools.Library.DatItems /// /// Name of the machine /// - [JsonProperty("name")] + [JsonProperty("name", DefaultValueHandling = DefaultValueHandling.Include)] public string Name { get; set; } = null; /// /// Additional notes /// /// Known as "Extra" in AttractMode - [JsonProperty("comment")] + [JsonProperty("comment", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Comment { get; set; } = null; /// /// Extended description /// - [JsonProperty("description")] + [JsonProperty("description", DefaultValueHandling = DefaultValueHandling.Include)] public string Description { get; set; } = null; /// /// Year(s) of release/manufacture /// - [JsonProperty("year")] + [JsonProperty("year", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Year { get; set; } = null; /// /// Manufacturer, if available /// - [JsonProperty("manufacturer")] + [JsonProperty("manufacturer", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Manufacturer { get; set; } = null; /// /// Publisher, if available /// - [JsonProperty("publisher")] + [JsonProperty("publisher", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Publisher { get; set; } = null; /// /// Category, if available /// - [JsonProperty("category")] + [JsonProperty("category", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Category { get; set; } = null; /// /// fomof parent /// - [JsonProperty("romof")] + [JsonProperty("romof", DefaultValueHandling = DefaultValueHandling.Ignore)] public string RomOf { get; set; } = null; /// /// cloneof parent /// - [JsonProperty("cloneof")] + [JsonProperty("cloneof", DefaultValueHandling = DefaultValueHandling.Ignore)] public string CloneOf { get; set; } = null; /// /// sampleof parent /// - [JsonProperty("sampleof")] + [JsonProperty("sampleof", DefaultValueHandling = DefaultValueHandling.Ignore)] public string SampleOf { get; set; } = null; /// /// Type of the machine /// - [JsonProperty("type")] + [JsonProperty("type", DefaultValueHandling = DefaultValueHandling.Ignore)] public MachineType MachineType { get; set; } = MachineType.NULL; #endregion @@ -93,43 +93,43 @@ namespace SabreTools.Library.DatItems /// Player count /// /// Also in Logiqx EmuArc - [JsonProperty("players")] + [JsonProperty("players", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Players { get; set; } = null; /// /// Screen rotation /// - [JsonProperty("rotation")] + [JsonProperty("rotation", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Rotation { get; set; } = null; /// /// Control method /// - [JsonProperty("control")] + [JsonProperty("control", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Control { get; set; } = null; /// /// Support status /// - [JsonProperty("status")] + [JsonProperty("status", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Status { get; set; } = null; /// /// Display count /// - [JsonProperty("displaycount")] + [JsonProperty("displaycount", DefaultValueHandling = DefaultValueHandling.Ignore)] public string DisplayCount { get; set; } = null; /// /// Display type /// - [JsonProperty("displaytype")] + [JsonProperty("displaytype", DefaultValueHandling = DefaultValueHandling.Ignore)] public string DisplayType { get; set; } = null; /// /// Number of input buttons /// - [JsonProperty("buttons")] + [JsonProperty("buttons", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Buttons { get; set; } = null; #endregion @@ -140,50 +140,50 @@ namespace SabreTools.Library.DatItems /// Emulator source file related to the machine /// /// Also in Logiqx - [JsonProperty("sourcefile")] + [JsonProperty("sourcefile", DefaultValueHandling = DefaultValueHandling.Ignore)] public string SourceFile { get; set; } = null; /// /// Machine runnable status /// /// Also in Logiqx - [JsonProperty("runnable")] + [JsonProperty("runnable", DefaultValueHandling = DefaultValueHandling.Ignore)] public Runnable Runnable { get; set; } = Runnable.NULL; /// /// List of associated device names /// - [JsonProperty("devices")] + [JsonProperty("devices", DefaultValueHandling = DefaultValueHandling.Ignore)] public List DeviceReferences { get; set; } = null; /// /// List of associated chips /// - [JsonProperty("chips")] + [JsonProperty("chips", DefaultValueHandling = DefaultValueHandling.Ignore)] public List Chips { get; set; } = null; /// /// List of associated displays /// - [JsonProperty("displays")] + [JsonProperty("displays", DefaultValueHandling = DefaultValueHandling.Ignore)] public List Displays { get; set; } = null; /// /// List of associated sounds /// - [JsonProperty("sounds")] + [JsonProperty("sounds", DefaultValueHandling = DefaultValueHandling.Ignore)] public List Sounds { get; set; } = null; /// /// List of associated conditions /// - [JsonProperty("conditions")] + [JsonProperty("conditions", DefaultValueHandling = DefaultValueHandling.Ignore)] public List Conditions { get; set; } = null; /// /// List of associated inputs /// - [JsonProperty("inputs")] + [JsonProperty("inputs", DefaultValueHandling = DefaultValueHandling.Ignore)] public List Inputs { get; set; } = null; /// @@ -191,26 +191,26 @@ namespace SabreTools.Library.DatItems /// /// Also in SoftwareList /// TODO: Order ListXML and SoftwareList outputs by area names - [JsonProperty("dipswitches")] + [JsonProperty("dipswitches", DefaultValueHandling = DefaultValueHandling.Ignore)] public List DipSwitches { get; set; } = null; /// /// List of associated configurations /// - [JsonProperty("configurations")] + [JsonProperty("configurations", DefaultValueHandling = DefaultValueHandling.Ignore)] public List Configurations { get; set; } = null; /// /// List of slot options /// - [JsonProperty("slots")] + [JsonProperty("slots", DefaultValueHandling = DefaultValueHandling.Ignore)] public List Slots { get; set; } = null; /// /// List of info items /// /// Also in SoftwareList - [JsonProperty("infos")] + [JsonProperty("infos", DefaultValueHandling = DefaultValueHandling.Ignore)] public List Infos { get; set; } = null; #endregion @@ -220,13 +220,13 @@ namespace SabreTools.Library.DatItems /// /// Machine board name /// - [JsonProperty("board")] + [JsonProperty("board", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Board { get; set; } = null; /// /// Rebuild location if different than machine name /// - [JsonProperty("rebuildto")] + [JsonProperty("rebuildto", DefaultValueHandling = DefaultValueHandling.Ignore)] public string RebuildTo { get; set; } = null; #endregion @@ -236,55 +236,55 @@ namespace SabreTools.Library.DatItems /// /// Title ID /// - [JsonProperty("titleid")] + [JsonProperty("titleid", DefaultValueHandling = DefaultValueHandling.Ignore)] public string TitleID { get; set; } = null; /// /// Machine developer /// - [JsonProperty("developer")] + [JsonProperty("developer", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Developer { get; set; } = null; /// /// Game genre /// - [JsonProperty("genre")] + [JsonProperty("genre", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Genre { get; set; } = null; /// /// Game subgenre /// - [JsonProperty("genre")] + [JsonProperty("subgenre", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Subgenre { get; set; } = null; /// /// Game ratings /// - [JsonProperty("ratings")] + [JsonProperty("ratings", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Ratings { get; set; } = null; /// /// Game score /// - [JsonProperty("score")] + [JsonProperty("score", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Score { get; set; } = null; /// /// Is the machine enabled /// - [JsonProperty("enabled")] + [JsonProperty("enabled", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Enabled { get; set; } = null; // bool? /// /// Does the game have a CRC check /// - [JsonProperty("hascrc")] + [JsonProperty("hascrc", DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? HasCrc { get; set; } = null; /// /// Machine relations /// - [JsonProperty("relatedto")] + [JsonProperty("relatedto", DefaultValueHandling = DefaultValueHandling.Ignore)] public string RelatedTo { get; set; } = null; #endregion @@ -294,19 +294,19 @@ namespace SabreTools.Library.DatItems /// /// Generation MSX ID /// - [JsonProperty("genmsxid")] + [JsonProperty("genmsxid", DefaultValueHandling = DefaultValueHandling.Ignore)] public string GenMSXID { get; set; } = null; /// /// MSX System /// - [JsonProperty("system")] + [JsonProperty("system", DefaultValueHandling = DefaultValueHandling.Ignore)] public string System { get; set; } = null; /// /// Machine country of origin /// - [JsonProperty("country")] + [JsonProperty("country", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Country { get; set; } = null; #endregion @@ -316,13 +316,13 @@ namespace SabreTools.Library.DatItems /// /// Support status /// - [JsonProperty("supported")] + [JsonProperty("supported", DefaultValueHandling = DefaultValueHandling.Ignore)] public Supported Supported { get; set; } = Supported.NULL; /// /// List of shared feature items /// - [JsonProperty("sharedfeat")] + [JsonProperty("sharedfeat", DefaultValueHandling = DefaultValueHandling.Ignore)] public List SharedFeatures { get; set; } = null; #endregion diff --git a/SabreTools.Library/DatItems/Release.cs b/SabreTools.Library/DatItems/Release.cs index 2f752b80..9bf2920e 100644 --- a/SabreTools.Library/DatItems/Release.cs +++ b/SabreTools.Library/DatItems/Release.cs @@ -18,25 +18,25 @@ namespace SabreTools.Library.DatItems /// /// Release region(s) /// - [JsonProperty("region")] + [JsonProperty("region", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Region { get; set; } /// /// Release language(s) /// - [JsonProperty("language")] + [JsonProperty("language", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Language { get; set; } /// /// Date of release /// - [JsonProperty("date")] + [JsonProperty("date", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Date { get; set; } /// /// Default release, if applicable /// - [JsonProperty("default")] + [JsonProperty("default", DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? Default { get; set; } #endregion diff --git a/SabreTools.Library/DatItems/Rom.cs b/SabreTools.Library/DatItems/Rom.cs index 78621429..a333a097 100644 --- a/SabreTools.Library/DatItems/Rom.cs +++ b/SabreTools.Library/DatItems/Rom.cs @@ -36,19 +36,19 @@ namespace SabreTools.Library.DatItems /// /// What BIOS is required for this rom /// - [JsonProperty("bios")] + [JsonProperty("bios", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Bios { get; set; } /// /// Byte size of the rom /// - [JsonProperty("size")] + [JsonProperty("size", DefaultValueHandling = DefaultValueHandling.Ignore)] public long Size { get; set; } /// /// File CRC32 hash /// - [JsonProperty("crc")] + [JsonProperty("crc", DefaultValueHandling = DefaultValueHandling.Ignore)] public string CRC { get { return _crc.IsNullOrEmpty() ? null : Utilities.ByteArrayToString(_crc); } @@ -58,7 +58,7 @@ namespace SabreTools.Library.DatItems /// /// File MD5 hash /// - [JsonProperty("md5")] + [JsonProperty("md5", DefaultValueHandling = DefaultValueHandling.Ignore)] public string MD5 { get { return _md5.IsNullOrEmpty() ? null : Utilities.ByteArrayToString(_md5); } @@ -69,7 +69,7 @@ namespace SabreTools.Library.DatItems /// /// File RIPEMD160 hash /// - [JsonProperty("ripemd160")] + [JsonProperty("ripemd160", DefaultValueHandling = DefaultValueHandling.Ignore)] public string RIPEMD160 { get { return _ripemd160.IsNullOrEmpty() ? null : Utilities.ByteArrayToString(_ripemd160); } @@ -80,7 +80,7 @@ namespace SabreTools.Library.DatItems /// /// File SHA-1 hash /// - [JsonProperty("sha1")] + [JsonProperty("sha1", DefaultValueHandling = DefaultValueHandling.Ignore)] public string SHA1 { get { return _sha1.IsNullOrEmpty() ? null : Utilities.ByteArrayToString(_sha1); } @@ -90,7 +90,7 @@ namespace SabreTools.Library.DatItems /// /// File SHA-256 hash /// - [JsonProperty("sha256")] + [JsonProperty("sha256", DefaultValueHandling = DefaultValueHandling.Ignore)] public string SHA256 { get { return _sha256.IsNullOrEmpty() ? null : Utilities.ByteArrayToString(_sha256); } @@ -100,7 +100,7 @@ namespace SabreTools.Library.DatItems /// /// File SHA-384 hash /// - [JsonProperty("sha384")] + [JsonProperty("sha384", DefaultValueHandling = DefaultValueHandling.Ignore)] public string SHA384 { get { return _sha384.IsNullOrEmpty() ? null : Utilities.ByteArrayToString(_sha384); } @@ -110,7 +110,7 @@ namespace SabreTools.Library.DatItems /// /// File SHA-512 hash /// - [JsonProperty("sha512")] + [JsonProperty("sha512", DefaultValueHandling = DefaultValueHandling.Ignore)] public string SHA512 { get { return _sha512.IsNullOrEmpty() ? null : Utilities.ByteArrayToString(_sha512); } @@ -120,44 +120,44 @@ namespace SabreTools.Library.DatItems /// /// Rom name to merge from parent /// - [JsonProperty("merge")] + [JsonProperty("merge", DefaultValueHandling = DefaultValueHandling.Ignore)] public string MergeTag { get; set; } /// /// Rom region /// - [JsonProperty("region")] + [JsonProperty("region", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Region { get; set; } /// /// Data offset within rom /// - [JsonProperty("offset")] + [JsonProperty("offset", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Offset { get; set; } /// /// File created date /// - [JsonProperty("date")] + [JsonProperty("date", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Date { get; set; } /// /// Rom dump status /// - [JsonProperty("status")] + [JsonProperty("status", DefaultValueHandling = DefaultValueHandling.Ignore)] [JsonConverter(typeof(StringEnumConverter))] public ItemStatus ItemStatus { get; set; } /// /// Determine if the rom is optional in the set /// - [JsonProperty("optional")] + [JsonProperty("optional", DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? Optional { get; set; } /// /// Determine if the CRC32 hash is inverted /// - [JsonProperty("inverted")] + [JsonProperty("inverted", DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? Inverted { get; set; } #endregion diff --git a/SabreTools.Library/IO/XmlTextWriterExtensions.cs b/SabreTools.Library/IO/XmlTextWriterExtensions.cs index 7c22c383..082d2c07 100644 --- a/SabreTools.Library/IO/XmlTextWriterExtensions.cs +++ b/SabreTools.Library/IO/XmlTextWriterExtensions.cs @@ -39,7 +39,7 @@ namespace SabreTools.Library.IO /// Value to write in the attribute public static void WriteOptionalAttributeString(this XmlTextWriter writer, string localName, string value) { - if (string.IsNullOrEmpty(value)) + if (!string.IsNullOrEmpty(value)) writer.WriteAttributeString(localName, value); } @@ -51,7 +51,7 @@ namespace SabreTools.Library.IO /// Value to write in the element public static void WriteOptionalElementString(this XmlTextWriter writer, string localName, string value) { - if (string.IsNullOrEmpty(value)) + if (!string.IsNullOrEmpty(value)) writer.WriteElementString(localName, value); } } diff --git a/SabreTools.Library/Tools/BaseFirstContractResolver.cs b/SabreTools.Library/Tools/BaseFirstContractResolver.cs new file mode 100644 index 00000000..f339d47c --- /dev/null +++ b/SabreTools.Library/Tools/BaseFirstContractResolver.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; + +namespace SabreTools.Library.Tools +{ + // https://github.com/dotnet/runtime/issues/728 + public class BaseFirstContractResolver : DefaultContractResolver + { + public BaseFirstContractResolver() + { + NamingStrategy = new CamelCaseNamingStrategy(); + } + + protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) + { + return base.CreateProperties(type, memberSerialization) + .OrderBy(p => BaseTypesAndSelf(p.DeclaringType).Count()).ToList(); + + IEnumerable BaseTypesAndSelf(Type t) + { + while (t != null) + { + yield return t; + t = t.BaseType; + } + } + } + } +} diff --git a/SabreTools/Features/Sort.cs b/SabreTools/Features/Sort.cs index f725fe0d..1464c834 100644 --- a/SabreTools/Features/Sort.cs +++ b/SabreTools/Features/Sort.cs @@ -68,11 +68,11 @@ namespace SabreTools.Features var outputFormat = GetOutputFormat(features); // If we have TorrentGzip output and the romba flag, update - if (Header.OutputDepot.IsActive && outputFormat == OutputFormat.TorrentGzip) + if ((Header.OutputDepot?.IsActive ?? false) && outputFormat == OutputFormat.TorrentGzip) outputFormat = OutputFormat.TorrentGzipRomba; // If we hae TorrentXZ output and the romba flag, update - if (Header.OutputDepot.IsActive && outputFormat == OutputFormat.TorrentXZ) + if ((Header.OutputDepot?.IsActive ?? false) && outputFormat == OutputFormat.TorrentXZ) outputFormat = OutputFormat.TorrentXZRomba; // Get a list of files from the input datfiles @@ -96,7 +96,7 @@ namespace SabreTools.Features datdata.Header.HeaderSkipper = Header.HeaderSkipper; // If we have the depot flag, respect it - if (Header.InputDepot.IsActive) + if (Header.InputDepot?.IsActive ?? false) datdata.RebuildDepot(Inputs, Path.Combine(OutputDir, datdata.Header.FileName), date, delete, inverse, outputFormat, updateDat); else datdata.RebuildGeneric(Inputs, Path.Combine(OutputDir, datdata.Header.FileName), quickScan, date, delete, inverse, outputFormat, updateDat, asFiles); @@ -126,7 +126,7 @@ namespace SabreTools.Features watch.Stop(); // If we have the depot flag, respect it - if (Header.InputDepot.IsActive) + if (Header.InputDepot?.IsActive ?? false) datdata.RebuildDepot(Inputs, OutputDir, date, delete, inverse, outputFormat, updateDat); else datdata.RebuildGeneric(Inputs, OutputDir, quickScan, date, delete, inverse, outputFormat, updateDat, asFiles); diff --git a/SabreTools/Features/Verify.cs b/SabreTools/Features/Verify.cs index 152b754d..682a3252 100644 --- a/SabreTools/Features/Verify.cs +++ b/SabreTools/Features/Verify.cs @@ -66,7 +66,7 @@ namespace SabreTools.Features datdata.Header.HeaderSkipper = Header.HeaderSkipper; // If we have the depot flag, respect it - if (Header.InputDepot.IsActive) + if (Header.InputDepot?.IsActive ?? false) datdata.VerifyDepot(Inputs, OutputDir); else datdata.VerifyGeneric(Inputs, OutputDir, hashOnly, quickScan, asFiles, Extras, Filter); @@ -96,7 +96,7 @@ namespace SabreTools.Features watch.Stop(); // If we have the depot flag, respect it - if (Header.InputDepot.IsActive) + if (Header.InputDepot?.IsActive ?? false) datdata.VerifyDepot(Inputs, OutputDir); else datdata.VerifyGeneric(Inputs, OutputDir, hashOnly, quickScan, asFiles, Extras, Filter);