Introduce example for a more flexible deserialization

Also make the CoverGenerator themes serializeable
Rest is automatic reformatting.
This commit is contained in:
Flamefire committed 2014-10-01 00:54:04 +02:00
1 parent 467b619f0a
commit 6ebbf7df6f
33 files changed
+428 -397

No files matched your search

+147
View File
@@ -0,0 +1,147 @@
#region license
// This file is part of Vocaluxe.
//
// Vocaluxe is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vocaluxe is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
using System.Collections.Generic;
using System.Xml.XPath;
namespace VocaluxeLib.Xml
{
public class CXMLReader : CXmlDeserializer
{
private readonly XPathNavigator _Navigator;
private readonly String _FilePath;
public string FilePath
{
get { return _FilePath; }
}
//Private method. Use OpenFile factory method to get an instance
private CXMLReader(string uri)
{
_FilePath = uri;
var xmlDoc = new XPathDocument(uri);
_Navigator = xmlDoc.CreateNavigator();
}
public XPathNavigator Navigator
{
get { return _Navigator; }
}
public static CXMLReader OpenFile(string fileName)
{
try
{
return new CXMLReader(fileName);
}
catch (Exception e)
{
CBase.Log.LogError("Can't open XML file: " + fileName + ": " + e.Message);
return null;
}
}
public bool TryGetColorFromRGBA(string xPath, ref SColorF value)
{
bool result = true;
result &= TryGetNormalizedFloatValue(xPath + "/R", ref value.R);
result &= TryGetNormalizedFloatValue(xPath + "/G", ref value.G);
result &= TryGetNormalizedFloatValue(xPath + "/B", ref value.B);
result &= TryGetNormalizedFloatValue(xPath + "/A", ref value.A);
return result;
}
public override bool GetValue(string xPath, out string value, string defaultValue = "")
{
int resultCt = 0;
string val = string.Empty;
_Navigator.MoveToRoot();
XPathNodeIterator iterator = _Navigator.Select(xPath);
while (iterator.MoveNext())
{
val = iterator.Current.Value;
resultCt++;
}
if (resultCt != 1)
{
value = defaultValue;
return false;
}
value = val;
return true;
}
public override bool GetAttribute(string xPath, string attribute, out string value)
{
_Navigator.MoveToRoot();
XPathNodeIterator iterator = _Navigator.Select(xPath);
if (iterator.MoveNext())
{
value = iterator.Current.GetAttribute(attribute, "");
return true;
}
value = "";
return false;
}
public List<string> GetNames(string xPath)
{
var values = new List<string>();
_Navigator.MoveToRoot();
XPathNodeIterator iterator = _Navigator.Select(xPath);
while (iterator.MoveNext())
values.Add(iterator.Current.LocalName);
return values;
}
public IEnumerable<string> GetAttributes(string xPath, string attribute)
{
var values = new List<string>();
_Navigator.MoveToRoot();
XPathNodeIterator iterator = _Navigator.Select(xPath);
while (iterator.MoveNext())
values.Add(iterator.Current.GetAttribute(attribute, ""));
return values;
}
public bool GetValues(string xPath, ref List<string> values)
{
_Navigator.MoveToRoot();
XPathNodeIterator iterator = _Navigator.Select(xPath);
while (iterator.MoveNext())
values.Add(iterator.Current.Value);
return true;
}
public bool ItemExists(string xPath)
{
_Navigator.MoveToRoot();
return _Navigator.Select(xPath).MoveNext();
}
}
}
+68
View File
@@ -0,0 +1,68 @@
using System.Linq;
namespace VocaluxeLib.Xml
{
public abstract class CXmlDeserializer : CXmlReaderBase
{
public bool Read(string xPath, out SThemeFont el)
{
el = new SThemeFont();
bool ok = true;
ok &= GetValue(xPath + "/Name", out el.Name);
ok &= TryGetFloatValue(xPath + "/Size", ref el.Size);
ok &= TryGetEnumValue(xPath + "/Style", ref el.Style);
return ok;
}
public bool Read(string xPath, out SMargin el)
{
el = new SMargin();
bool ok = true;
bool defOk = TryGetIntValue(xPath + "/Default", ref el.Default);
ok &= TryGetIntValue(xPath + "/Left", ref el.Left, el.Default);
ok &= TryGetIntValue(xPath + "/Right", ref el.Right, el.Default);
ok &= TryGetIntValue(xPath + "/Top", ref el.Top, el.Default);
ok &= TryGetIntValue(xPath + "/Bottom", ref el.Bottom, el.Default);
return ok || defOk;
}
public bool Read(string xPath, out SThemeCoverGeneratorText el)
{
el = new SThemeCoverGeneratorText();
bool ok = true;
ok &= GetValue(xPath + "/Text", out el.Text);
ok &= Read(xPath + "/Font", out el.Font);
ok &= Read(xPath + "/Color", out el.Color);
ok &= Read(xPath + "/Margin", out el.Margin);
if (ok)
TryGetIntValue(xPath + "/Indent", ref el.Indent, 6 * (el.Margin.Left + el.Margin.Right) / 2);
return ok;
}
public bool Read(string xPath, out SThemeColor el)
{
el = new SThemeColor();
bool ok = true;
ok &= TryGetNormalizedFloatValue(xPath + "/R", ref el.Color.R);
ok &= TryGetNormalizedFloatValue(xPath + "/G", ref el.Color.G);
ok &= TryGetNormalizedFloatValue(xPath + "/B", ref el.Color.B);
ok &= TryGetNormalizedFloatValue(xPath + "/A", ref el.Color.A);
if (!ok)
ok = GetValue(xPath, out el.Name) && !el.Name.Contains('<');
return ok;
}
public bool Read(string xPath, out SThemeCoverGenerator el)
{
el = new SThemeCoverGenerator();
bool ok = true;
ok &= TryGetEnumValue(xPath + "/Type", ref el.Type);
ok &= Read(xPath + "/Text", out el.Text);
ok &= Read(xPath + "/BackgroundColor", out el.BackgroundColor);
ok &= GetValue(xPath + "/Image", out el.Image);
TryGetNormalizedFloatValue(xPath + "/ImageAlpha", ref el.ImageAlpha, 0.5f);
TryGetBoolValue(xPath + "/ShowFirstCover", out el.ShowFirstCover);
return ok;
}
}
}
+61
View File
@@ -0,0 +1,61 @@
using System;
namespace VocaluxeLib.Xml
{
/// <summary>
/// Base class that provides basic methods for reading xml, while the actual XML implementation is still abstract to allow different implementations
/// </summary>
public abstract class CXmlReaderBase
{
public abstract bool GetValue(string xPath, out string value, string defaultValue = "");
public abstract bool GetAttribute(string xPath, string attribute, out string value);
public bool TryGetBoolValue(string xPath, out bool value, bool defaultValue = false)
{
value = defaultValue;
string val;
return GetValue(xPath, out val) && bool.TryParse(val, out value);
}
public bool TryGetIntValue(string xPath, ref int value, int? defaultValue = null)
{
string val;
bool ok = GetValue(xPath, out val) && int.TryParse(val, out value);
if (!ok && defaultValue.HasValue)
value = defaultValue.Value;
return ok;
}
public bool TryGetFloatValue(string xPath, ref float value)
{
string val;
return GetValue(xPath, out val, value.ToString()) && CHelper.TryParse(val, out value);
}
public bool TryGetEnumValue<T>(string xPath, ref T value) where T : struct
{
string val;
return GetValue(xPath, out val, Enum.GetName(typeof(T), value)) && CHelper.TryParse(val, out value, true);
}
public bool TryGetIntValueRange(string xPath, ref int value, int min = 0, int max = 100)
{
return TryGetIntValue(xPath, ref value) && value.IsInRange(min, max);
}
/// <summary>
/// Gets a normalized (0&lt;=x&lt;=1) float value
/// </summary>
/// <param name="xPath"></param>
/// <param name="value"></param>
/// <param name="defaultValue"></param>
/// <returns>True if exists and is normalized</returns>
public bool TryGetNormalizedFloatValue(string xPath, ref float value, float defaultValue = 0)
{
bool ok = TryGetFloatValue(xPath, ref value) && value.IsInRange(0f, 1f);
if (!ok)
value = defaultValue;
return ok;
}
}
}