diff --git a/SabreTools.Library/DatFiles/Json.cs b/SabreTools.Library/DatFiles/Json.cs index e83f3d90..f2307c93 100644 --- a/SabreTools.Library/DatFiles/Json.cs +++ b/SabreTools.Library/DatFiles/Json.cs @@ -640,7 +640,7 @@ namespace SabreTools.Library.DatFiles #region SoftwareList case "supported": - machine.Supported = jtr.ReadAsString().AsYesNo(); + machine.Supported = jtr.ReadAsString().AsSupported(); break; case "sharedfeat": @@ -663,7 +663,7 @@ namespace SabreTools.Library.DatFiles break; case "dipswitches": - machine.DipSwitches = new List(); + machine.DipSwitches = new List(); jtr.Read(); // Start Array while (!sr.EndOfStream) { @@ -678,7 +678,7 @@ namespace SabreTools.Library.DatFiles jtr.Read(); // Mask Key string mask = jtr.ReadAsString(); - var dip = new SoftwareListDipSwitch(name, tag, mask); + var dip = new ListXMLDipSwitch(name, tag, mask); jtr.Read(); // Start dipvalues object while (!sr.EndOfStream) @@ -695,7 +695,7 @@ namespace SabreTools.Library.DatFiles bool? def = jtr.ReadAsString().AsYesNo(); jtr.Read(); // End object - dip.Values.Add(new SoftwareListDipValue(valname, value, def)); + dip.Values.Add(new ListXMLDipValue(valname, value, def)); } jtr.Read(); // End object @@ -1843,17 +1843,22 @@ namespace SabreTools.Library.DatFiles #region SoftwareList - if (!Header.ExcludeFields.Contains(Field.Supported) && datItem.Machine.Supported != null) + if (!Header.ExcludeFields.Contains(Field.Supported) && datItem.Machine.Supported != Supported.NULL) { - if (datItem.Machine.Supported == true) + switch (datItem.Machine.Supported) { - jtw.WritePropertyName("supported"); - jtw.WriteValue("yes"); - } - else if (datItem.Machine.Supported == false) - { - jtw.WritePropertyName("supported"); - jtw.WriteValue("no"); + 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 (!string.IsNullOrWhiteSpace(datItem.GetField(Field.SharedFeatures, Header.ExcludeFields))) @@ -1885,7 +1890,7 @@ namespace SabreTools.Library.DatFiles jtw.WriteValue(dip.Mask); jtw.WriteStartArray(); - foreach (SoftwareListDipValue dipval in dip.Values) + foreach (ListXMLDipValue dipval in dip.Values) { jtw.WriteStartObject(); jtw.WritePropertyName("name"); diff --git a/SabreTools.Library/DatFiles/Listxml.cs b/SabreTools.Library/DatFiles/Listxml.cs index 9d4c7554..b4eb455c 100644 --- a/SabreTools.Library/DatFiles/Listxml.cs +++ b/SabreTools.Library/DatFiles/Listxml.cs @@ -386,23 +386,23 @@ namespace SabreTools.Library.DatFiles break; case "dipswitch": - // TODO: Make a new object for this - // string dipswitch_name = reader.GetAttribute("name"); - // string dipswitch_tag = reader.GetAttribute("tag"); - // string dipswitch_mask = reader.GetAttribute("mask"); + // TODO: Use these dipswitches + var dipSwitch = new ListXMLDipSwitch(reader.GetAttribute("name"), reader.GetAttribute("tag"), reader.GetAttribute("mask")); + ReadDipSwitch(reader.ReadSubtree(), dipSwitch); // // While the subtree contains elements... - // TODO: Make a new object for this + // TODO: Populate the dipswitch with the diplocations // string diplocation_name = reader.GetAttribute("name"); // string diplocation_number = reader.GetAttribute("number"); // bool? diplocation_inverted = Utilities.GetYesNo(reader.GetAttribute("inverted")); // // While the subtree contains elements... - // TODO: Make a new object for this + // TODO: Populate the dipswitch with the dipvalues // string dipvalue_name = reader.GetAttribute("name"); // string dipvalue_value = reader.GetAttribute("value"); // bool? dipvalue_default = Utilities.GetYesNo(reader.GetAttribute("default")); + // Skip the dipswitch now that we've processed it reader.Skip(); break; @@ -584,6 +584,59 @@ namespace SabreTools.Library.DatFiles } } + /// + /// Read DipSwitch DipValues information + /// + /// XmlReader representing a diskarea block + /// ListXMLDipSwitch to populate + private void ReadDipSwitch(XmlReader reader, ListXMLDipSwitch dipSwitch) + { + // If we have an empty trurip, skip it + if (reader == null) + return; + + // Get lists ready + dipSwitch.Locations = new List(); + dipSwitch.Values = new List(); + + // Otherwise, add what is possible + reader.MoveToContent(); + + while (!reader.EOF) + { + // We only want elements + if (reader.NodeType != XmlNodeType.Element) + { + reader.Read(); + continue; + } + + // Get the information from the dipswitch + switch (reader.Name) + { + case "diplocation": + dipSwitch.Locations.Add(new ListXMLDipLocation( + reader.GetAttribute("name"), + reader.GetAttribute("number"), + reader.GetAttribute("inverted").AsYesNo())); + reader.Read(); + break; + + case "dipvalue": + dipSwitch.Values.Add(new ListXMLDipValue( + reader.GetAttribute("name"), + reader.GetAttribute("value"), + reader.GetAttribute("default").AsYesNo())); + reader.Read(); + break; + + default: + reader.Read(); + break; + } + } + } + /// /// Create and open an output file for writing direct from a dictionary /// diff --git a/SabreTools.Library/DatFiles/SeparatedValue.cs b/SabreTools.Library/DatFiles/SeparatedValue.cs index 7d1a6714..561ea027 100644 --- a/SabreTools.Library/DatFiles/SeparatedValue.cs +++ b/SabreTools.Library/DatFiles/SeparatedValue.cs @@ -483,7 +483,7 @@ namespace SabreTools.Library.DatFiles #region SoftwareList case "Machine.Supported": - machine.Supported = value.AsYesNo(); + machine.Supported = value.AsSupported(); break; case "Machine.SharedFeatures": @@ -498,7 +498,7 @@ namespace SabreTools.Library.DatFiles break; case "Machine.DipSwitches": - machine.DipSwitches = new List(); + machine.DipSwitches = new List(); // TODO: There is no way this would work... Just use empty for now break; diff --git a/SabreTools.Library/DatFiles/SoftwareList.cs b/SabreTools.Library/DatFiles/SoftwareList.cs index 765856bf..18e36a34 100644 --- a/SabreTools.Library/DatFiles/SoftwareList.cs +++ b/SabreTools.Library/DatFiles/SoftwareList.cs @@ -142,12 +142,12 @@ namespace SabreTools.Library.DatFiles { Name = reader.GetAttribute("name"), Description = reader.GetAttribute("name"), - Supported = reader.GetAttribute("supported").AsYesNo(), // (yes|partial|no) "yes" + Supported = reader.GetAttribute("supported").AsSupported(), CloneOf = reader.GetAttribute("cloneof") ?? string.Empty, Infos = new List(), SharedFeatures = new List(), - DipSwitches = new List(), + DipSwitches = new List(), MachineType = (machineType == MachineType.NULL ? MachineType.None : machineType), }; @@ -248,7 +248,7 @@ namespace SabreTools.Library.DatFiles areaEndinaness; long? areasize = null; var features = new List(); - var dipswitches = new List(); + var dipswitches = new List(); bool containsItems = false; while (!reader.EOF) @@ -334,13 +334,8 @@ namespace SabreTools.Library.DatFiles case "dipswitch": // TODO: Use these dipswitches - var dip = new SoftwareListDipSwitch( - reader.GetAttribute("name"), - reader.GetAttribute("tag"), - reader.GetAttribute("mask")); - - dip.Values = ReadDipSwitch(reader.ReadSubtree()); - dipswitches.Add(dip); + var dipSwitch = new ListXMLDipSwitch(reader.GetAttribute("name"), reader.GetAttribute("tag"), reader.GetAttribute("mask")); + ReadDipSwitch(reader.ReadSubtree(), dipSwitch); // Skip the dipswitch now that we've processed it reader.Skip(); @@ -568,15 +563,16 @@ namespace SabreTools.Library.DatFiles /// /// Read DipSwitch DipValues information /// - /// True if full pathnames are to be kept, false otherwise (default) - private List ReadDipSwitch(XmlReader reader) + /// XmlReader representing a diskarea block + /// ListXMLDipSwitch to populate + private void ReadDipSwitch(XmlReader reader, ListXMLDipSwitch dipSwitch) { // If we have an empty trurip, skip it if (reader == null) - return null; + return; // Get list ready - List dipValues = new List(); + dipSwitch.Values = new List(); // Otherwise, add what is possible reader.MoveToContent(); @@ -594,10 +590,11 @@ namespace SabreTools.Library.DatFiles switch (reader.Name) { case "dipvalue": - dipValues.Add(new SoftwareListDipValue( + dipSwitch.Values.Add(new ListXMLDipValue( reader.GetAttribute("name"), reader.GetAttribute("value"), reader.GetAttribute("default").AsYesNo())); + reader.Read(); break; default: @@ -605,8 +602,6 @@ namespace SabreTools.Library.DatFiles break; } } - - return dipValues; } /// @@ -792,12 +787,18 @@ namespace SabreTools.Library.DatFiles if (!Header.ExcludeFields.Contains(Field.Supported)) { - if (datItem.Machine.Supported == true) - xtw.WriteAttributeString("supported", "yes"); - else if (datItem.Machine.Supported == false) - xtw.WriteAttributeString("supported", "no"); - else - xtw.WriteAttributeString("supported", "partial"); + switch (datItem.Machine.Supported) + { + case Supported.No: + xtw.WriteAttributeString("supported", "no"); + break; + case Supported.Partial: + xtw.WriteAttributeString("supported", "partial"); + break; + case Supported.Yes: + xtw.WriteAttributeString("supported", "yes"); + break; + } } if (!string.IsNullOrWhiteSpace(datItem.GetField(Field.Description, Header.ExcludeFields))) @@ -833,14 +834,14 @@ namespace SabreTools.Library.DatFiles if (!Header.ExcludeFields.Contains(Field.DipSwitches) && datItem.Machine.DipSwitches != null && datItem.Machine.DipSwitches.Count > 0) { - foreach (SoftwareListDipSwitch dip in datItem.Machine.DipSwitches) + foreach (ListXMLDipSwitch dip in datItem.Machine.DipSwitches) { xtw.WriteStartElement("dipswitch"); xtw.WriteAttributeString("name", dip.Name); xtw.WriteAttributeString("tag", dip.Tag); xtw.WriteAttributeString("mask", dip.Mask); - foreach (SoftwareListDipValue dipval in dip.Values) + foreach (ListXMLDipValue dipval in dip.Values) { xtw.WriteStartElement("dipvalue"); xtw.WriteAttributeString("name", dipval.Name); diff --git a/SabreTools.Library/DatItems/Auxiliary.cs b/SabreTools.Library/DatItems/Auxiliary.cs index f23fde20..2677a9b1 100644 --- a/SabreTools.Library/DatItems/Auxiliary.cs +++ b/SabreTools.Library/DatItems/Auxiliary.cs @@ -45,37 +45,58 @@ namespace SabreTools.Library.DatItems #endregion - #region SoftwareList + #region ListXML /// - /// Represents one SoftwareList dipswitch + /// Represents one ListXML dipswitch /// - public class SoftwareListDipSwitch + /// Also used by SoftwareList + public class ListXMLDipSwitch { public string Name { get; set; } public string Tag { get; set; } public string Mask { get; set; } - public List Values { get; set; } + public List Locations { get; set; } + public List Values { get; set; } - public SoftwareListDipSwitch(string name, string tag, string mask) + public ListXMLDipSwitch(string name, string tag, string mask) { Name = name; Tag = tag; Mask = mask; - Values = new List(); + Locations = new List(); + Values = new List(); } } /// - /// Represents one SoftwareList dipswitch + /// Represents one ListXML diplocation /// - public class SoftwareListDipValue + public class ListXMLDipLocation + { + public string Name { get; set; } + public string Number { get; set; } + public bool? Inverted { get; set; } + + public ListXMLDipLocation(string name, string number, bool? inverted) + { + Name = name; + Number = number; + Inverted = inverted; + } + } + + /// + /// Represents one ListXML dipvalue + /// + /// Also used by SoftwareList + public class ListXMLDipValue { public string Name { get; set; } public string Value { get; set; } public bool? Default { get; set; } - public SoftwareListDipValue(string name, string value, bool? def) + public ListXMLDipValue(string name, string value, bool? def) { Name = name; Value = value; @@ -83,6 +104,10 @@ namespace SabreTools.Library.DatItems } } + #endregion + + #region SoftwareList + /// /// Represents one SoftwareList shared feature object /// diff --git a/SabreTools.Library/DatItems/Enums.cs b/SabreTools.Library/DatItems/Enums.cs index aae939a8..a716bfb6 100644 --- a/SabreTools.Library/DatItems/Enums.cs +++ b/SabreTools.Library/DatItems/Enums.cs @@ -240,4 +240,16 @@ namespace SabreTools.Library.DatItems Device = 1 << 2, Mechanical = 1 << 3, } + + /// + /// Determine machine support status + /// + [Flags] + public enum Supported + { + NULL, + No, + Partial, + Yes, + } } diff --git a/SabreTools.Library/DatItems/Machine.cs b/SabreTools.Library/DatItems/Machine.cs index 07b49a79..e229d68e 100644 --- a/SabreTools.Library/DatItems/Machine.cs +++ b/SabreTools.Library/DatItems/Machine.cs @@ -272,9 +272,8 @@ namespace SabreTools.Library.DatItems /// /// Support status /// - /// yes = true, partial = null, no = false [JsonProperty("supported")] - public bool? Supported { get; set; } = true; + public Supported Supported { get; set; } = Supported.NULL; /// /// List of shared feature items @@ -287,7 +286,7 @@ namespace SabreTools.Library.DatItems /// /// Also in SoftwareList [JsonProperty("dipswitches")] - public List DipSwitches { get; set; } = null; + public List DipSwitches { get; set; } = null; #endregion @@ -451,7 +450,7 @@ namespace SabreTools.Library.DatItems #region SoftwareList case Field.Supported: - fieldValue = Supported?.ToString(); + fieldValue = Supported.ToString(); break; case Field.SharedFeatures: fieldValue = string.Join(";", (SharedFeatures ?? new List()).Select(i => $"{i.Name}={i.Value}")); @@ -640,7 +639,7 @@ namespace SabreTools.Library.DatItems #region SoftwareList if (mappings.Keys.Contains(Field.Supported)) - Supported = mappings[Field.Supported].AsYesNo(); + Supported = mappings[Field.Supported].AsSupported(); if (mappings.Keys.Contains(Field.SharedFeatures)) { @@ -658,7 +657,7 @@ namespace SabreTools.Library.DatItems if (mappings.Keys.Contains(Field.DipSwitches)) { if (DipSwitches == null) - DipSwitches = new List(); + DipSwitches = new List(); // TODO: There's no way this will work... just create the new list for now } @@ -1058,7 +1057,9 @@ namespace SabreTools.Library.DatItems #region SoftwareList // Filter on supported - if (filter.Supported.MatchesNeutral(null, Supported) == false) + if (filter.SupportedStatus.MatchesPositive(Supported.NULL, Supported) == false) + return false; + if (filter.SupportedStatus.MatchesNegative(Supported.NULL, Supported) == true) return false; #endregion @@ -1210,7 +1211,7 @@ namespace SabreTools.Library.DatItems #region SoftwareList if (fields.Contains(Field.Supported)) - Supported = null; + Supported = Supported.NULL; if (fields.Contains(Field.SharedFeatures)) SharedFeatures = null; diff --git a/SabreTools.Library/Filtering/Filter.cs b/SabreTools.Library/Filtering/Filter.cs index 83e98993..3d4bb3e2 100644 --- a/SabreTools.Library/Filtering/Filter.cs +++ b/SabreTools.Library/Filtering/Filter.cs @@ -229,7 +229,7 @@ namespace SabreTools.Library.Filtering /// /// Include or exclude items with the "Supported" tag /// - public FilterItem Supported { get; private set; } = new FilterItem() { Neutral = null }; + public FilterItem SupportedStatus { get; private set; } = new FilterItem() { Positive = Supported.NULL, Negative = Supported.NULL }; // TODO: Machine.SharedFeatures - List @@ -838,10 +838,10 @@ namespace SabreTools.Library.Filtering #region SoftwareList case Field.Supported: - if (negate || value.Equals("false", StringComparison.OrdinalIgnoreCase)) - Supported.Neutral = false; + if (negate) + SupportedStatus.Negative |= value.AsSupported(); else - Supported.Neutral = true; + SupportedStatus.Positive |= value.AsSupported(); break; #endregion diff --git a/SabreTools.Library/Tools/Converters.cs b/SabreTools.Library/Tools/Converters.cs index 5a5d1b56..a2730393 100644 --- a/SabreTools.Library/Tools/Converters.cs +++ b/SabreTools.Library/Tools/Converters.cs @@ -819,6 +819,37 @@ namespace SabreTools.Library.Tools #endif } + /// + /// Get Supported value from input string + /// + /// String to get value from + /// Supported value corresponding to the string + public static Supported AsSupported(this string supported) + { +#if NET_FRAMEWORK + switch (supported?.ToLowerInvariant()) + { + case "no": + return Supported.No; + case "partial": + return Supported.Partial; + case "yes": + return Supported.Yes; + default: + return Supported.NULL; + } +#else + return supported?.ToLowerInvariant() switch + { + "no" => Supported.No, + "partial" => Supported.Partial, + "yes" => Supported.Yes, + _ => Supported.NULL, + }; +#endif + } + + /// /// Get bool? value from input string ///