diff --git a/INTV.Core/Model/Program/ProgramDescription.cs b/INTV.Core/Model/Program/ProgramDescription.cs index 954ac819..910222be 100644 --- a/INTV.Core/Model/Program/ProgramDescription.cs +++ b/INTV.Core/Model/Program/ProgramDescription.cs @@ -30,6 +30,13 @@ namespace INTV.Core.Model.Program /// public class ProgramDescription : INTV.Core.ComponentModel.ModelBase, IProgramDescription { + #region Property Names + + public const string NamePropertyName = "Name"; + public const string ShortNamePropertyName = "ShortName"; + + #endregion // Property Names + /// /// Maximum length for a program name. /// @@ -59,7 +66,9 @@ public ProgramDescription(uint crc, IRom rom, IProgramInformation programInfo) _rom = rom; _programInfo = new UserSpecifiedProgramInformation(programInfo); _name = _programInfo.GetNameForCrc(crc); + _xmlName = new MetadataString() { Text = _name }; _shortName = programInfo.ShortName; + _xmlShortName = new MetadataString() { Text = _shortName }; _programFiles = new ProgramSupportFiles(rom); var allIncompatibilities = _programInfo.Crcs.Select(c => c.Incompatibilities); var crcData = _programInfo.Crcs.First(c => c.Crc == crc); @@ -119,6 +128,8 @@ public IProgramInformation ProgramInformation private IProgramInformation _programInfo; /// + /// For purposes of XML serialization, the XmlName property is used. + [System.Xml.Serialization.XmlIgnore] public string Name { get @@ -130,13 +141,15 @@ public string Name { if (!string.IsNullOrWhiteSpace(value)) { - this.AssignAndUpdateProperty("Name", value.EnforceNameLength(MaxProgramNameLength, false), ref _name, (p, v) => UpdateNameFromXml(v)); + this.AssignAndUpdateProperty(NamePropertyName, value.EnforceNameLength(MaxProgramNameLength, false), ref _name, (p, v) => UpdateNameFromXml(v)); } } } private string _name; /// + /// For purposes of XML serialization, the XmlShortName property is used. + [System.Xml.Serialization.XmlIgnore] public string ShortName { get @@ -146,7 +159,7 @@ public string ShortName set { - this.AssignAndUpdateProperty("ShortName", value.EnforceNameLength(RomInfoIndexHelpers.MaxShortNameLength, false), ref _shortName, (p, v) => UpdateShortNameFromXml(v)); + this.AssignAndUpdateProperty(ShortNamePropertyName, value.EnforceNameLength(RomInfoIndexHelpers.MaxShortNameLength, false), ref _shortName, (p, v) => UpdateShortNameFromXml(v)); } } private string _shortName; @@ -213,6 +226,46 @@ public string Code } #endif // false + /// + /// XML-safe version of the property. + /// + /// This should only be accessed via the XmlSerializer. + [System.Xml.Serialization.XmlElement(NamePropertyName)] + public MetadataString XmlName + { + get + { + return _xmlName; + } + + set + { + _xmlName = value; + Name = _xmlName.Text; + } + } + private MetadataString _xmlName; + + /// + /// XML-safe version of the property. + /// + /// This should only be accessed via the XmlSerializer. + [System.Xml.Serialization.XmlElement(ShortNamePropertyName)] + public MetadataString XmlShortName + { + get + { + return _xmlShortName; + } + + set + { + _xmlShortName = value; + ShortName = _xmlShortName.Text; + } + } + private MetadataString _xmlShortName; + #endregion // Properties /// @@ -277,7 +330,9 @@ public ProgramDescription Copy() { var description = new ProgramDescription(Crc, Rom, ProgramInformation); description._name = _name; + description._xmlName = new MetadataString() { Text = _name }; description._shortName = _shortName; + description._xmlShortName = new MetadataString() { Text = _shortName }; description._programFiles = _programFiles.Copy(); return description; } @@ -345,6 +400,7 @@ private void UpdateRomFromXml(ProgramSupportFiles supportFiles) private void UpdateNameFromXml(string name) { + XmlName.Text = name; var info = _programInfo as UserSpecifiedProgramInformation; if (info != null) { @@ -354,6 +410,7 @@ private void UpdateNameFromXml(string name) private void UpdateShortNameFromXml(string shortName) { + XmlShortName.Text = shortName; var info = _programInfo as UserSpecifiedProgramInformation; if (info != null) { diff --git a/Tests/INTV.Core.Tests/Model/Program/ProgramDescriptionTests.cs b/Tests/INTV.Core.Tests/Model/Program/ProgramDescriptionTests.cs index 44b1caec..bc559258 100644 --- a/Tests/INTV.Core.Tests/Model/Program/ProgramDescriptionTests.cs +++ b/Tests/INTV.Core.Tests/Model/Program/ProgramDescriptionTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright (c) 2018-2019 All Rights Reserved // Steven A. Orth // @@ -563,6 +563,7 @@ public void ProgramDescription_Copy_ProducesEquivalentCopy() information.AddCrc(crc, name); var description0 = new ProgramDescription(crc, null, information); + description0.ShortName = "A\aa"; var description1 = description0.Copy(); Assert.Equal(description0.Name, description1.Name); @@ -570,6 +571,11 @@ public void ProgramDescription_Copy_ProducesEquivalentCopy() Assert.Equal(description0.Vendor, description1.Vendor); Assert.Equal(description0.Year, description1.Year); Assert.Equal(description0.Features, description1.Features); + Assert.Equal(description0.XmlName.XmlText, description1.XmlName.XmlText); + Assert.Equal(description0.XmlName.Escaped, description1.XmlName.Escaped); + Assert.Equal(description0.XmlShortName.XmlText, description1.XmlShortName.XmlText); + Assert.Equal(description0.XmlShortName.Escaped, description1.XmlShortName.Escaped); + Assert.Equal(description0.Vendor, description1.Vendor); Assert.True(object.ReferenceEquals(description0.Rom, description1.Rom)); VerifyProgramInformation(description0.ProgramInformation, description1.ProgramInformation); VerifyProgramSupportFiles(description0.Files, description1.Files); @@ -640,6 +646,136 @@ public void ProgramDescription_ParseFromXml_ProducesValidProgramDescription() Assert.Equal(@"/Users/tester/Projects/MinGW/msys/1.0/home/tester/lui_src/LtoFlash/bin/tools/0.cfg", description.Rom.ConfigPath); } + [Fact] + public void ProgramDescription_ParseFromXmlWithBinHexName_ProducesValidProgramDescription() + { + ProgramDescriptionTestStorage.Initialize(null); + var xmlProgramDescription = @" + + 3971627767 + 546167616C6F6E67200720546F646421 + T.T. + Zbiciak Electronics + 1999 + + Tolerates + Tolerates + None + Tolerates + Tolerates + Tolerates + Tolerates + Tolerates + Tolerates + Tolerates + Tolerates + Incompatible + None + 0 + Incompatible + Incompatible + Incompatible + + + \Users\tester\Projects\perforce\intellivision\roms\tagalong.bin + /Users/tester/Projects/MinGW/msys/1.0/home/tester/lui_src/LtoFlash/bin/tools/0.cfg + + + + +"; + ProgramDescription description; + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xmlProgramDescription))) + { + var serializer = new XmlSerializer(typeof(ProgramDescription)); + description = serializer.Deserialize(stream) as ProgramDescription; + } + + Assert.NotNull(description); + Assert.Equal("Tagalong \a Todd!", description.Name); + Assert.Equal("T.T.", description.ShortName); + Assert.Equal("Zbiciak Electronics", description.Vendor); + Assert.Equal("1999", description.Year); + Assert.Equal(TestRomResources.TestBinCrc, description.Crc); + Assert.Equal(ProgramFeatures.DefaultFeatures, description.Features); + Assert.Equal(@"\Users\tester\Projects\perforce\intellivision\roms\tagalong.bin", description.Files.RomImagePath); + Assert.Equal(@"/Users/tester/Projects/MinGW/msys/1.0/home/tester/lui_src/LtoFlash/bin/tools/0.cfg", description.Files.RomConfigurationFilePath); + Assert.Empty(description.Files.AlternateRomImagePaths); + Assert.Empty(description.Files.AlternateRomConfigurationFilePaths); + Assert.NotNull(description.Rom); + Assert.True(description.Rom is XmlRom); + Assert.Null(((XmlRom)description.Rom).ResolvedRom); + Assert.Equal(0u, description.Rom.Crc); + Assert.Equal(0u, description.Rom.CfgCrc); + Assert.Equal(@"\Users\tester\Projects\perforce\intellivision\roms\tagalong.bin", description.Rom.RomPath); + Assert.Equal(@"/Users/tester/Projects/MinGW/msys/1.0/home/tester/lui_src/LtoFlash/bin/tools/0.cfg", description.Rom.ConfigPath); + } + + [Fact] + public void ProgramDescription_ParseFromXmlWithBinHexShortName_ProducesValidProgramDescription() + { + ProgramDescriptionTestStorage.Initialize(null); + var xmlProgramDescription = @" + + 3971627767 + 546167616C6F6E67200720546F646421 + 546167616C6F6E67200720546F646421 + Zbiciak Electronics + 1999 + + Tolerates + Tolerates + None + Tolerates + Tolerates + Tolerates + Tolerates + Tolerates + Tolerates + Tolerates + Tolerates + Incompatible + None + 0 + Incompatible + Incompatible + Incompatible + + + \Users\tester\Projects\perforce\intellivision\roms\tagalong.bin + /Users/tester/Projects/MinGW/msys/1.0/home/tester/lui_src/LtoFlash/bin/tools/0.cfg + + + + +"; + ProgramDescription description; + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xmlProgramDescription))) + { + var serializer = new XmlSerializer(typeof(ProgramDescription)); + description = serializer.Deserialize(stream) as ProgramDescription; + } + + Assert.NotNull(description); + Assert.Equal("546167616C6F6E67200720546F646421", description.Name); + Assert.Equal("Tagalong \a Todd!", description.ShortName); + Assert.Equal("Zbiciak Electronics", description.Vendor); + Assert.Equal("1999", description.Year); + Assert.Equal(TestRomResources.TestBinCrc, description.Crc); + Assert.Equal(ProgramFeatures.DefaultFeatures, description.Features); + Assert.Equal(@"\Users\tester\Projects\perforce\intellivision\roms\tagalong.bin", description.Files.RomImagePath); + Assert.Equal(@"/Users/tester/Projects/MinGW/msys/1.0/home/tester/lui_src/LtoFlash/bin/tools/0.cfg", description.Files.RomConfigurationFilePath); + Assert.Empty(description.Files.AlternateRomImagePaths); + Assert.Empty(description.Files.AlternateRomConfigurationFilePaths); + Assert.NotNull(description.Rom); + Assert.True(description.Rom is XmlRom); + Assert.Null(((XmlRom)description.Rom).ResolvedRom); + Assert.Equal(0u, description.Rom.Crc); + Assert.Equal(0u, description.Rom.CfgCrc); + Assert.Equal(@"\Users\tester\Projects\perforce\intellivision\roms\tagalong.bin", description.Rom.RomPath); + Assert.Equal(@"/Users/tester/Projects/MinGW/msys/1.0/home/tester/lui_src/LtoFlash/bin/tools/0.cfg", description.Rom.ConfigPath); + } + private void VerifyProgramInformation(IProgramInformation information0, IProgramInformation information1) { Assert.Equal(information0.DataOrigin, information1.DataOrigin);