Add normalized attribute

Allow empty embedded lists
This commit is contained in:
Flamefire committed 2014-10-24 23:46:45 +02:00
1 parent c3affed9b1
commit b044efe50e
3 files changed
+71 -23

No files matched your search

+13 -4
View File
@@ -21,6 +21,7 @@ using System.Drawing;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Xml.Serialization;
using VocaluxeLib; using VocaluxeLib;
using VocaluxeLib.Draw; using VocaluxeLib.Draw;
using VocaluxeLib.Menu; using VocaluxeLib.Menu;
@@ -167,16 +168,24 @@ namespace Vocaluxe.Base
return new SThemeCover(); return new SThemeCover();
} }
private static void Foo(STheme a, STheme b)
{
a = b;
}
private static void _TestNewLoad(string path) private static void _TestNewLoad(string path)
{ {
/*SThemeCover theme; SThemeCover theme;
using (var stream = new FileStream(path, FileMode.Open)) using (var stream = new FileStream(path, FileMode.Open))
theme = CMyXmlDeserializer.Deserialize<SThemeCover>(stream); theme = CMyXmlDeserializer.Deserialize<SThemeCover>(stream);
string cover = theme.Info.Author;*/ string cover = theme.Info.Author;
STheme themescreen; STheme themescreen;
using (var stream = new FileStream(@"C:\Users\Alex\Documents\Vocaluxe\Output\Themes\Ambient\Screens\ScreenMain.xml", FileMode.Open)) using (var stream = new StreamReader(Path.Combine(CBase.Themes.GetThemeScreensPath(-1), "ScreenMain.xml")))
themescreen = CMyXmlDeserializer.Deserialize<STheme>(stream); themescreen = CMyXmlDeserializer.Deserialize<STheme>(stream);
string foo = themescreen.Informations.ScreenName; TextReader textReader = new StreamReader(Path.Combine(CBase.Themes.GetThemeScreensPath(-1), "ScreenMain.xml"));
XmlSerializer deserializer = new XmlSerializer(typeof(STheme));
STheme theme2 = (STheme)deserializer.Deserialize(textReader);
Foo(theme2, themescreen);
} }
/// <summary> /// <summary>
+5 -4
View File
@@ -24,6 +24,7 @@ using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
using System.Xml.Serialization; using System.Xml.Serialization;
using VocaluxeLib.Songs; using VocaluxeLib.Songs;
using VocaluxeLib.Xml;
namespace VocaluxeLib namespace VocaluxeLib
{ {
@@ -120,10 +121,10 @@ namespace VocaluxeLib
public struct SThemeColor public struct SThemeColor
{ {
[DefaultValue(null), XmlAttribute] public string Name; [DefaultValue(null), XmlAttribute] public string Name;
public float? R; [XmlNormalized] public float? R;
public float? G; [XmlNormalized] public float? G;
public float? B; [XmlNormalized] public float? B;
public float? A; [XmlNormalized] public float? A;
//Needed for serialization //Needed for serialization
public bool NameSpecified public bool NameSpecified
+53 -15
View File
@@ -2,6 +2,7 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@@ -12,16 +13,22 @@ using System.Xml.Serialization;
namespace VocaluxeLib.Xml namespace VocaluxeLib.Xml
{ {
// ReSharper disable InconsistentNaming
[AttributeUsage(AttributeTargets.Field)]
public class XmlNormalizedAttribute : Attribute {}
// ReSharper restore InconsistentNaming
public static class CMyXmlDeserializer public static class CMyXmlDeserializer
{ {
private struct SFieldInfo private struct SFieldInfo
{ {
public string Name; public string Name;
public FieldInfo Info; public FieldInfo Info;
public FieldInfo SpecifiedField;
public bool IsList; //List with child elements (<List><El/><El/></List>) public bool IsList; //List with child elements (<List><El/><El/></List>)
public bool IsEmbeddedList; //List w/o child elements(<List/><List/>) public bool IsEmbeddedList; //List w/o child elements(<List/><List/>)
public bool IsNullable; public bool IsNullable;
public bool IsNormalized;
public Type SubType; public Type SubType;
} }
@@ -72,13 +79,18 @@ namespace VocaluxeLib.Xml
} }
#endregion Debug Helpers #endregion Debug Helpers
private static bool _HasAttribute(this FieldInfo field, Type attributeType)
{
return field.GetCustomAttributes(attributeType, false).Length > 0;
}
private static List<SFieldInfo> _GetFields(Type type, bool attributes) private static List<SFieldInfo> _GetFields(Type type, bool attributes)
{ {
List<SFieldInfo> result = new List<SFieldInfo>(); List<SFieldInfo> result = new List<SFieldInfo>();
FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance); FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
foreach (FieldInfo field in fields) foreach (FieldInfo field in fields)
{ {
if (field.GetCustomAttributes(typeof(XmlIgnoreAttribute), false).Length > 0) if (field._HasAttribute(typeof(XmlIgnoreAttribute)))
continue; continue;
object[] attElement = field.GetCustomAttributes(typeof(XmlAttributeAttribute), false); object[] attElement = field.GetCustomAttributes(typeof(XmlAttributeAttribute), false);
if (attElement.Length > 0 != attributes) if (attElement.Length > 0 != attributes)
@@ -108,6 +120,11 @@ namespace VocaluxeLib.Xml
info.IsNullable = true; info.IsNullable = true;
info.SubType = field.FieldType.GetGenericArguments()[0]; info.SubType = field.FieldType.GetGenericArguments()[0];
} }
if (field._HasAttribute(typeof(XmlNormalizedAttribute)))
{
Debug.Assert(field.FieldType == typeof(float) || (info.IsNullable && info.SubType == typeof(float)), "Only floats can be normalized");
info.IsNormalized = true;
}
result.Add(info); result.Add(info);
} }
return result; return result;
@@ -125,16 +142,6 @@ namespace VocaluxeLib.Xml
return type.Name; return type.Name;
} }
public static T Deserialize<T>(Stream stream) where T : new()
{
return Deserialize<T>(new XmlTextReader(stream)
{
WhitespaceHandling = WhitespaceHandling.Significant,
Normalization = true,
XmlResolver = null
});
}
private static object _GetValue(XmlNode node, Type type) private static object _GetValue(XmlNode node, Type type)
{ {
if (type.IsEnum) if (type.IsEnum)
@@ -202,6 +209,11 @@ namespace VocaluxeLib.Xml
private static bool _CheckAndSetDefaultValue(ref object result, SFieldInfo field) private static bool _CheckAndSetDefaultValue(ref object result, SFieldInfo field)
{ {
if (field.IsEmbeddedList)
{
_AddList(result, field, new List<object>());
return true;
}
object[] defAtt = field.Info.GetCustomAttributes(typeof(DefaultValueAttribute), false); object[] defAtt = field.Info.GetCustomAttributes(typeof(DefaultValueAttribute), false);
if (defAtt.Length == 0) if (defAtt.Length == 0)
return field.IsNullable; return field.IsNullable;
@@ -237,11 +249,11 @@ namespace VocaluxeLib.Xml
List<SFieldInfo> fields = _GetFields(result.GetType(), attributes); List<SFieldInfo> fields = _GetFields(result.GetType(), attributes);
int curField = 0; int curField = 0;
List<object> subValues = new List<object>();
SFieldInfo curListField = new SFieldInfo();
string curListName = null;
if (nodes != null) if (nodes != null)
{ {
List<object> subValues = new List<object>();
SFieldInfo curListField = new SFieldInfo();
string curListName = null;
foreach (XmlNode node in nodes) foreach (XmlNode node in nodes)
{ {
if (node is XmlComment) if (node is XmlComment)
@@ -288,6 +300,12 @@ namespace VocaluxeLib.Xml
else else
{ {
object value = _GetValue(node, field.Info.FieldType); object value = _GetValue(node, field.Info.FieldType);
if (field.IsNormalized)
{
if (field.IsNullable && !((float?)value).Value.IsInRange(0, 1) ||
!field.IsNullable && !((float)value).IsInRange(0, 1))
throw new XmlException("Value in " + _FindXPath(node) + " is not normalized. (Value=" + value + ")");
}
field.Info.SetValue(result, value); field.Info.SetValue(result, value);
curField++; curField++;
} }
@@ -320,5 +338,25 @@ namespace VocaluxeLib.Xml
_ProcessChildNodes(xDoc.DocumentElement, ref result, false); _ProcessChildNodes(xDoc.DocumentElement, ref result, false);
return (T)result; return (T)result;
} }
public static T Deserialize<T>(Stream stream) where T : new()
{
return Deserialize<T>(new XmlTextReader(stream)
{
WhitespaceHandling = WhitespaceHandling.Significant,
Normalization = true,
XmlResolver = null
});
}
public static T Deserialize<T>(TextReader textReader) where T : new()
{
return Deserialize<T>(new XmlTextReader(textReader)
{
WhitespaceHandling = WhitespaceHandling.Significant,
Normalization = true,
XmlResolver = null
});
}
} }
} }