Handle missing/empty config

Make Deserializer handle default values recursively
This commit is contained in:
Flamefire committed 2014-11-24 22:14:33 +01:00
1 parent 3919a2064d
commit 831cfd9f20
4 files changed
+104 -41

No files matched your search

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