diff --git a/Vocaluxe/Base/CConfig.cs b/Vocaluxe/Base/CConfig.cs index 62ed6143..1e3ca15e 100644 --- a/Vocaluxe/Base/CConfig.cs +++ b/Vocaluxe/Base/CConfig.cs @@ -244,10 +244,9 @@ namespace Vocaluxe.Base return; // Init config file + _LoadConfig(); if (!File.Exists(_FileConfig)) SaveConfig(); - else - _LoadConfig(); _Initialized = true; } @@ -263,9 +262,14 @@ namespace Vocaluxe.Base { _XmlErrorsOccured = false; var xml = new CXmlDeserializer(new CXmlErrorHandler(_HandleXmlError)); - Config = xml.Deserialize(_FileConfig); - if (_XmlErrorsOccured) - CLog.LogError("There were some warnings or errors loading the config file. Some values might have been reset to their defaults."); + if (File.Exists(_FileConfig)) + { + Config = xml.Deserialize(_FileConfig); + if (_XmlErrorsOccured) + CLog.LogError("There were some warnings or errors loading the config file. Some values might have been reset to their defaults."); + } + else + Config = xml.DeserializeString(""); if (Config.Game.SongFolder.Length > 0) { @@ -278,7 +282,7 @@ namespace Vocaluxe.Base if (Config.Game.MinLineBreakTime < 0) Config.Game.MinLineBreakTime = 0.1f; - if (Config.Game.NumPlayers < 1 || Config.Game.NumPlayers > CSettings.MaxNumPlayer) + if (!Config.Game.NumPlayers.IsInRange(1, CSettings.MaxNumPlayer)) Config.Game.NumPlayers = 2; Array.Resize(ref Config.Game.Players, CSettings.MaxNumPlayer); @@ -290,9 +294,10 @@ namespace Vocaluxe.Base CLanguage.SetLanguage(Config.Game.Language); } + Array.Resize(ref Config.Record.MicConfig, CSettings.MaxNumPlayer); Config.Record.MicDelay = (int)(20 * Math.Round(Config.Record.MicDelay / 20.0)); - if (Config.Server.ServerPort < 1 || Config.Server.ServerPort > 65535) + if (!Config.Server.ServerPort.IsInRange(1, 65535)) Config.Server.ServerPort = 3000; Config.Info = new SConfigInfo @@ -498,8 +503,6 @@ namespace Vocaluxe.Base //Check if there is one or more channels if (device.Channels >= 2) { - if (Config.Record.MicConfig.Length < 2) - Config.Record.MicConfig = new SMicConfig[2]; //Set this device to player 1 Config.Record.MicConfig[0].DeviceName = device.Name; Config.Record.MicConfig[0].DeviceDriver = device.Driver; diff --git a/Vocaluxe/Base/CRecord.cs b/Vocaluxe/Base/CRecord.cs index 1fa22c16..9b671f76 100644 --- a/Vocaluxe/Base/CRecord.cs +++ b/Vocaluxe/Base/CRecord.cs @@ -135,10 +135,9 @@ namespace Vocaluxe.Base private static int _GetPlayerFromMicConfig(string device, string devicedriver, int channel) { - for (int p = 0; p < CConfig.Config.Record.MicConfig.Length; p++) + for (int p = 0; p < CSettings.MaxNumPlayer; p++) { - if (CConfig.Config.Record.MicConfig[p].Channel != 0 && - CConfig.Config.Record.MicConfig[p].DeviceName == device && + if (CConfig.Config.Record.MicConfig[p].DeviceName == device && CConfig.Config.Record.MicConfig[p].DeviceDriver == devicedriver && CConfig.Config.Record.MicConfig[p].Channel == channel) return p + 1; diff --git a/VocaluxeLib/Xml/CXmlDeserializer.cs b/VocaluxeLib/Xml/CXmlDeserializer.cs index 2bdb2361..cc51c26f 100644 --- a/VocaluxeLib/Xml/CXmlDeserializer.cs +++ b/VocaluxeLib/Xml/CXmlDeserializer.cs @@ -190,6 +190,8 @@ namespace VocaluxeLib.Xml { if (type.IsEnum) { + if (node == null) + return null; string stringValue = node.InnerText; try { @@ -202,12 +204,12 @@ namespace VocaluxeLib.Xml } } if (type == typeof(string)) - return node.InnerText; + return node == null ? null : node.InnerText; if (type.IsPrimitive) return _GetPrimitiveValue(node, type) ?? value; if (type.IsNullable()) { - if (!node.HasChildNodes) + if (node == null || !node.HasChildNodes) return null; Type subType = type.GetGenericArguments()[0]; return _GetValue(node, subType, subName, value); @@ -219,15 +221,18 @@ namespace VocaluxeLib.Xml subName = subType.GetTypeName(); subName = subName.ToLowerInvariant(); List subValues = new List(); - foreach (XmlNode subNode in node.ChildNodes) + if (node != null) { - if (subNode is XmlComment) - continue; - if (subName == subNode.Name.ToLowerInvariant() && !subNode.Name.ToLowerInvariant().StartsWith(subName)) - _ErrorHandler.HandleError(new CXmlException("Invalid list entry '" + subNode.Name + "' in %n; Expected: " + subName, node)); - object subValue = _GetValue(subNode, subType); - if (subValue != null) - subValues.Add(subValue); + foreach (XmlNode subNode in node.ChildNodes) + { + if (subNode is XmlComment) + continue; + if (subName == subNode.Name.ToLowerInvariant() && !subNode.Name.ToLowerInvariant().StartsWith(subName)) + _ErrorHandler.HandleError(new CXmlException("Invalid list entry '" + subNode.Name + "' in %n; Expected: " + subName, node)); + object subValue = _GetValue(subNode, subType); + if (subValue != null) + subValues.Add(subValue); + } } if (value == null) return _CreateList(type, subValues); @@ -241,28 +246,31 @@ namespace VocaluxeLib.Xml MethodInfo add = type.GetMethod("Add"); if (subName != null) subName = subName.ToLowerInvariant(); - foreach (XmlNode subNode in node.ChildNodes) + if (node != null) { - if (subNode is XmlComment) - continue; - string key; - if (subName != null) + foreach (XmlNode subNode in node.ChildNodes) { - if (subName != subNode.Name.ToLowerInvariant() && !subNode.Name.ToLowerInvariant().StartsWith(subName)) - _ErrorHandler.HandleError(new CXmlException("Invalid dictionary entry '" + subNode.Name + "' in %n; Expected: " + subName, node)); - XmlNode nameAtt = (subNode.Attributes == null) ? null : subNode.Attributes.GetNamedItem("name"); - if (nameAtt == null) - { - _ErrorHandler.HandleError(new CXmlException("'name' attribute is missing in %n", subNode)); + if (subNode is XmlComment) continue; + string key; + if (subName != null) + { + if (subName != subNode.Name.ToLowerInvariant() && !subNode.Name.ToLowerInvariant().StartsWith(subName)) + _ErrorHandler.HandleError(new CXmlException("Invalid dictionary entry '" + subNode.Name + "' in %n; Expected: " + subName, node)); + XmlNode nameAtt = (subNode.Attributes == null) ? null : subNode.Attributes.GetNamedItem("name"); + if (nameAtt == null) + { + _ErrorHandler.HandleError(new CXmlException("'name' attribute is missing in %n", subNode)); + continue; + } + key = nameAtt.Value; } - key = nameAtt.Value; + else + key = subNode.Name; + object subValue = _GetValue(subNode, subType); + if (subValue != null) + add.Invoke(dict, new object[] {key, subValue}); } - else - key = subNode.Name; - object subValue = _GetValue(subNode, subType); - if (subValue != null) - add.Invoke(dict, new object[] {key, subValue}); } return dict; } @@ -292,6 +300,8 @@ namespace VocaluxeLib.Xml /// private object _GetPrimitiveValue(XmlNode node, Type type) { + if (node == null) + return null; object value; string nodeVal = node.InnerText; try @@ -396,7 +406,9 @@ namespace VocaluxeLib.Xml private void _ReadChildNodes(XmlNode parent, object o, bool attributes) { IEnumerable nodes; - if (attributes) + if (parent == null) + nodes = null; + else if (attributes) nodes = parent.Attributes; else nodes = parent.ChildNodes; @@ -491,7 +503,13 @@ namespace VocaluxeLib.Xml foreach (SFieldInfo field in fields) { if (!_CheckAndSetDefaultValue(o, field)) - _ErrorHandler.HandleError(new CXmlException("element: " + field.Name + " is missing in %n", parent)); + { + if (parent != null) + _ErrorHandler.HandleError(new CXmlException("element: " + field.Name + " is missing in %n", parent)); + object value = _GetValue(null, field.Type, field.ArrayItemName, field.GetValue(o)); + if (value != null) + field.SetValue(o, value); + } } } diff --git a/VocaluxeTests/XmlSerializerTest.cs b/VocaluxeTests/XmlSerializerTest.cs index a3c8ae43..6b59e5ec 100644 --- a/VocaluxeTests/XmlSerializerTest.cs +++ b/VocaluxeTests/XmlSerializerTest.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.IO; using System.Xml.Serialization; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -87,6 +88,22 @@ namespace VocaluxeTests [XmlIgnore] public int I; public int J; } + + private struct SDefaultSub + { + [DefaultValue(111)] + public int I; + } + + private struct SDefault + { + [DefaultValue(1337)] public int I; + [DefaultValue("Foo")] public string S; + public float? F; + [DefaultValue(666.0)] public double D; + public SDefaultSub Sub; + } + #pragma warning restore 169 #pragma warning restore 649 @@ -416,6 +433,32 @@ namespace VocaluxeTests _AssertSerDeserMatch>(s); } + [TestMethod] + public void TestDefaultValues() + { + const string s = _Head + @" + 1 + 2 + 3 + 4 + + 22 + +"; + _AssertSerDeserMatch(s); + var xml = new CXmlDeserializer(new CXmlErrorHandler(exception => { })); + SDefault foo = xml.DeserializeString(@""); + Assert.AreEqual(foo.I, 1337); + Assert.AreEqual(foo.F, null); + Assert.AreEqual(foo.S, "Foo"); + Assert.AreEqual(foo.D, 666); + Assert.AreEqual(foo.Sub.I, 111); + string newXml = new CXmlSerializer().Serialize(foo); + Assert.AreEqual(_Head +@" + +", newXml); + } + [TestMethod] public void TestRealFiles() {