Handle missing/empty config
Make Deserializer handle default values recursively
This commit is contained in:
1 parent
3919a2064d
commit
831cfd9f20
4 files changed
+104
-41
No files matched your search
@@ -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<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.");
|
||||
if (File.Exists(_FileConfig))
|
||||
{
|
||||
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)
|
||||
{
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<object> subValues = new List<object>();
|
||||
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
|
||||
/// <returns></returns>
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<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]
|
||||
public void TestRealFiles()
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user