Split serializer/deserializer

This commit is contained in:
Flamefire committed 2014-10-30 16:49:14 +01:00
1 parent 3928fee041
commit 12e48d0446
8 files changed
+438 -420

No files matched your search

+1 -1
View File
@@ -250,7 +250,7 @@ namespace Vocaluxe.Base
private static void _LoadConfig()
{
var xml = new CXmlSerializer();
var xml = new CXmlDeserializer();
Config = xml.Deserialize<SConfig>(_FileConfig);
if (Config.Game.SongFolder.Length > 0)
+1 -1
View File
@@ -260,7 +260,7 @@ namespace Vocaluxe.Base.Fonts
SDefaultFonts defaultFonts;
try
{
var xml = new CXmlSerializer();
var xml = new CXmlDeserializer();
defaultFonts = xml.Deserialize<SDefaultFonts>(Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameFonts, CSettings.FileNameFonts));
}
catch (Exception e)
+1 -1
View File
@@ -69,7 +69,7 @@ namespace Vocaluxe.Base.ThemeSystem
{
try
{
var xml = new CXmlSerializer();
var xml = new CXmlDeserializer();
_Data = xml.Deserialize<STheme>(Path.Combine(_Folder, _FileName));
if (_Data.ThemeSystemVersion != _ThemeSystemVersion)
{
+5 -5
View File
@@ -60,10 +60,10 @@ namespace Vocaluxe.Lib.Playlist
File = CHelper.GetUniqueFileName(Path.Combine(CSettings.DataFolder, CConfig.FolderPlaylists), filename + ".xml");
}
SPlaylist data=new SPlaylist {Info = {Name = Name}, Songs = Songs.Select(plSong => plSong.ToStruct()).ToArray()};
SPlaylist data = new SPlaylist {Info = {Name = Name}, Songs = Songs.Select(plSong => plSong.ToStruct()).ToArray()};
var xml = new CXmlSerializer();
xml.Serialize(File,data);
xml.Serialize(File, data);
}
public bool _Load(string file)
@@ -72,17 +72,17 @@ namespace Vocaluxe.Lib.Playlist
SPlaylist data;
try
{
var xml = new CXmlSerializer();
var xml = new CXmlDeserializer();
data = xml.Deserialize<SPlaylist>(File);
}
catch (Exception e)
{
CLog.LogError("Cannot load playlist from "+file+": "+e.Message);
CLog.LogError("Cannot load playlist from " + file + ": " + e.Message);
return false;
}
Name = data.Info.Name;
Songs = new List<CPlaylistSong>();
foreach (var songEntry in data.Songs)
foreach (SPlaylistSong songEntry in data.Songs)
{
CSong plSong = CSongs.AllSongs.FirstOrDefault(song => song.Artist == songEntry.Artist && song.Title == songEntry.Title);
if (plSong == null)
+4 -3
View File
@@ -89,7 +89,7 @@ namespace VocaluxeLib.Profile
public bool LoadProfile()
{
var xml = new CXmlSerializer();
var xml = new CXmlDeserializer();
try
{
xml.Deserialize(FilePath, this);
@@ -106,11 +106,12 @@ namespace VocaluxeLib.Profile
private bool _ConvertProfile(ref Exception e)
{
var xml = new CXmlSerializer();
var xml = new CXmlDeserializer();
var ser = new CXmlSerializer();
try
{
var old = xml.Deserialize<SOldXmlProfile>(FilePath);
string newXml = xml.Serialize(old.Info);
string newXml = ser.Serialize(old.Info);
xml.DeserializeString(newXml, this);
}
catch (Exception e2)
+389
View File
@@ -0,0 +1,389 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml;
namespace VocaluxeLib.Xml
{
public class CXmlDeserializer
{
#region Debug Helpers
private string _GetXPath(XmlNode node)
{
StringBuilder builder = new StringBuilder();
while (node != null)
{
switch (node.NodeType)
{
case XmlNodeType.Attribute:
builder.Insert(0, "/@" + node.Name);
node = ((XmlAttribute)node).OwnerElement;
break;
case XmlNodeType.Element:
string index = _FindElementIndex(node);
builder.Insert(0, "/" + node.Name + index);
node = node.ParentNode;
break;
case XmlNodeType.Document:
return builder.ToString();
default:
throw new ArgumentException("Only elements and attributes are supported");
}
}
throw new ArgumentException("Node was not in a document");
}
private string _FindElementIndex(XmlNode element)
{
XmlNode parentNode = element.ParentNode;
if (parentNode is XmlDocument)
return "";
XmlElement parent = (XmlElement)parentNode;
int index = 1;
if (parent != null)
{
XmlNode[] siblings = parent.ChildNodes.Cast<XmlNode>().Where(candidate => candidate is XmlElement && candidate.Name == element.Name).ToArray();
foreach (XmlNode candidate in siblings)
{
if (candidate == element)
return siblings.Length > 1 ? "[" + index + "]" : "";
index++;
}
}
throw new ArgumentException("Couldn't find element within parent");
}
#endregion Debug Helpers
private object _GetValue(XmlNode node, Type type, string arrayItemName = null, object result = null)
{
if (type.IsEnum)
{
string stringValue = node.InnerText;
try
{
return Enum.Parse(type, stringValue);
}
catch (Exception)
{
throw new XmlException("Invalid value in " + _GetXPath(node));
}
}
if (type == typeof(string))
return node.InnerText;
if (type.IsPrimitive)
return _GetPrimitiveValue(node, type);
if (type.IsNullable())
{
if (!node.HasChildNodes)
return null;
Type subType = type.GetGenericArguments()[0];
return _GetValue(node, subType, arrayItemName, result);
}
if (type.IsList() || type.IsArray)
{
Type subType = type.IsArray ? type.GetElementType() : type.GetGenericArguments()[0];
String subName = arrayItemName ?? subType.GetTypeName();
subName = subName.ToLowerInvariant();
List<object> subValues = new List<object>();
foreach (XmlNode subNode in node.ChildNodes)
{
if (subNode is XmlComment)
continue;
if (subName == subNode.Name.ToLowerInvariant() && !subNode.Name.ToLowerInvariant().StartsWith(subName))
throw new XmlException("Invalid list entry '" + subNode.Name + "' in " + _GetXPath(node) + "; Expected: " + subName);
object subValue = _GetValue(subNode, subType);
subValues.Add(subValue);
}
if (result == null)
return _CreateList(type, subValues);
_FillList(result, type, subValues);
return result;
}
if (type.IsDictionary())
{
Type subType = type.GetGenericArguments()[1];
object dict = result ?? Activator.CreateInstance(type);
MethodInfo add = type.GetMethod("Add");
if (arrayItemName != null)
arrayItemName = arrayItemName.ToLowerInvariant();
foreach (XmlNode subNode in node.ChildNodes)
{
if (subNode is XmlComment)
continue;
object subValue = _GetValue(subNode, subType);
string subName;
if (arrayItemName != null)
{
if (arrayItemName != subNode.Name.ToLowerInvariant() && !subNode.Name.ToLowerInvariant().StartsWith(arrayItemName))
throw new XmlException("Invalid dictionary entry '" + subNode.Name + "' in " + _GetXPath(node) + "; Expected: " + arrayItemName);
if (subNode.Attributes == null)
throw new XmlException("'name' attribute is missing in " + _GetXPath(subNode));
XmlNode nameAtt = subNode.Attributes.GetNamedItem("name");
if (nameAtt == null)
throw new XmlException("'name' attribute is missing in " + _GetXPath(subNode));
subName = nameAtt.Value;
}
else
subName = subNode.Name;
add.Invoke(dict, new object[] { subName, subValue });
}
return dict;
}
object value;
try
{
value = result ?? Activator.CreateInstance(type);
}
catch (Exception)
{
throw new XmlException("Could not create instance of " + _GetXPath(node) + "(Type=" + type.Name + ")");
}
_ReadChildNodes(node, ref value, true);
_ReadChildNodes(node, ref value, false);
return value;
}
private object _GetPrimitiveValue(XmlNode node, Type type)
{
object value;
string nodeVal = node.InnerText;
try
{
int p = nodeVal.IndexOf(',');
if (p > 0 && p >= nodeVal.Length - 3)
{
CBase.Log.LogError("German number format converted to english in " + _GetXPath(node));
char[] tmp = nodeVal.ToCharArray();
tmp[p] = '.';
nodeVal = new string(tmp);
}
value = Convert.ChangeType(nodeVal, type, CultureInfo.InvariantCulture);
}
catch (FormatException e)
{
throw new XmlException("Invalid format in " + _GetXPath(node) + ": '" + nodeVal + "' (" + e.Message + ")");
}
catch (InvalidCastException e)
{
throw new XmlException(e.Message + " in " + _GetXPath(node) + ": '" + nodeVal + "'");
}
return value;
}
private static bool _CheckAndSetDefaultValue(object result, SFieldInfo field)
{
if (field.IsEmbeddedList)
{
_AddList(result, field, new List<object>());
return true;
}
if (!field.HasDefaultValue)
return false;
field.SetValue(result, field.DefaultValue);
return true;
}
private static void _FillList(object list, Type type, ICollection values)
{
if (values.Count <= 0)
return;
if (type.IsArray)
{
Array array = (Array)list;
int i = 0;
foreach (object value in values)
array.SetValue(value, i++);
}
else
{
MethodInfo addMethod = type.GetMethod("Add");
foreach (object value in values)
addMethod.Invoke(list, new object[] { value });
}
}
private static object _CreateList(Type type, ICollection values)
{
object list = type.IsArray ? Array.CreateInstance(type.GetElementType(), values.Count) : Activator.CreateInstance(type, new object[] { values.Count });
_FillList(list, type, values);
return list;
}
private static void _AddList(object result, SFieldInfo listField, ICollection list)
{
listField.SetValue(result, _CreateList(listField.Type, list));
}
private void _ReadChildNodes(XmlNode parent, ref object result, bool attributes)
{
IEnumerable nodes;
if (attributes)
nodes = parent.Attributes;
else
nodes = parent.ChildNodes;
List<SFieldInfo> fields = result.GetType().GetFields(attributes);
if (nodes != null)
{
//Dictionary of all embedded lists to allow interleaved/mixed elements
Dictionary<string, Tuple<SFieldInfo, List<object>>> embLists = new Dictionary<string, Tuple<SFieldInfo, List<object>>>();
foreach (XmlNode node in nodes)
{
if (node is XmlComment)
continue;
SFieldInfo field = new SFieldInfo();
int curField;
for (curField = 0; curField < fields.Count; curField++)
{
field = fields[curField];
if (field.Name == node.Name || field.AltName == node.Name || (field.IsEmbeddedList && node.Name.StartsWith(field.Name)))
break;
}
if (curField >= fields.Count)
{
string msg = "Unexpected element: " + _GetXPath(node);
if (fields.Count > 0)
msg += " Expected: " + string.Join(", ", fields.Select(f => f.Name));
throw new XmlException(msg);
}
if (field.IsByteArray)
{
field.SetValue(result, Convert.FromBase64String(node.InnerText));
fields.RemoveAt(curField);
}
else if (field.IsEmbeddedList)
{
Tuple<SFieldInfo, List<object>> entry;
if (!embLists.TryGetValue(field.Name, out entry))
{
entry = new Tuple<SFieldInfo, List<object>>(field, new List<object>());
embLists.Add(field.Name, entry);
}
object subValue = _GetValue(node, field.SubType);
entry.Item2.Add(subValue);
}
else
{
object value = _GetValue(node, field.Type, field.ArrayItemName);
if (field.IsNormalized)
{
if (field.IsNullable && !((float?)value).Value.IsInRange(0, 1) ||
!field.IsNullable && !((float)value).IsInRange(0, 1))
throw new XmlException("Value in " + _GetXPath(node) + " is not normalized. (Value=" + value + ")");
}
if (field.Ranged != null && value != null)
{
bool ok = false;
if (field.Type == typeof(int))
ok = ((int)value).IsInRange(field.Ranged.Min, field.Ranged.Max);
else if (field.Type == typeof(float))
ok = ((float)value).IsInRange(field.Ranged.Min, field.Ranged.Max);
else if (field.Type == typeof(double))
ok = ((double)value).IsInRange(field.Ranged.Min, field.Ranged.Max);
else
Debug.Assert(false, "Ranged attribute has invalid type");
if (!ok)
{
throw new XmlException("Value in " + _GetXPath(node) + " is not in the range " + field.Ranged.Min + "-" + field.Ranged.Max + ". (Value=" + value +
")");
}
}
field.SetValue(result, value);
fields.RemoveAt(curField);
}
}
//Add embedded lists
foreach (Tuple<SFieldInfo, List<object>> entry in embLists.Values)
{
_AddList(result, entry.Item1, entry.Item2);
fields.Remove(entry.Item1);
}
}
foreach (SFieldInfo field in fields)
{
if (!_CheckAndSetDefaultValue(result, field))
throw new XmlException("element: " + field.Name + " is missing in " + _GetXPath(parent));
}
}
private T _Deserialize<T>(XmlReader reader, object result) where T : new()
{
if (reader.IsEmptyElement)
return (T)result;
XmlDocument xDoc = new XmlDocument();
xDoc.Load(reader);
if (xDoc.DocumentElement == null)
throw new XmlException("No root element found!");
try
{
result = _GetValue(xDoc.DocumentElement, typeof(T), typeof(T).GetSubTypeName(), result);
}
catch (TargetInvocationException e)
{
throw e.InnerException ?? e;
}
return (T)result;
}
public T DeserializeString<T>(string xml) where T : new()
{
return DeserializeString(xml, new T());
}
public T DeserializeString<T>(string xml, T o) where T : new()
{
var reader = new XmlTextReader(new StringReader(xml))
{
WhitespaceHandling = WhitespaceHandling.Significant,
Normalization = true,
XmlResolver = null
};
try
{
return _Deserialize<T>(reader, o);
}
finally
{
reader.Close();
}
}
public T Deserialize<T>(string filePath) where T : new()
{
return Deserialize(filePath, new T());
}
public T Deserialize<T>(string filePath, T o) where T : new()
{
if (!File.Exists(filePath))
throw new FileNotFoundException(filePath);
var reader = new XmlTextReader(filePath)
{
WhitespaceHandling = WhitespaceHandling.Significant,
Normalization = true,
XmlResolver = null
};
try
{
return _Deserialize<T>(reader, o);
}
finally
{
reader.Close();
}
}
}
}
-377
View File
@@ -4,8 +4,6 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
@@ -35,312 +33,6 @@ namespace VocaluxeLib.Xml
ConformanceLevel = ConformanceLevel.Document
};
#region Debug Helpers
private string _GetXPath(XmlNode node)
{
StringBuilder builder = new StringBuilder();
while (node != null)
{
switch (node.NodeType)
{
case XmlNodeType.Attribute:
builder.Insert(0, "/@" + node.Name);
node = ((XmlAttribute)node).OwnerElement;
break;
case XmlNodeType.Element:
string index = _FindElementIndex(node);
builder.Insert(0, "/" + node.Name + index);
node = node.ParentNode;
break;
case XmlNodeType.Document:
return builder.ToString();
default:
throw new ArgumentException("Only elements and attributes are supported");
}
}
throw new ArgumentException("Node was not in a document");
}
private string _FindElementIndex(XmlNode element)
{
XmlNode parentNode = element.ParentNode;
if (parentNode is XmlDocument)
return "";
XmlElement parent = (XmlElement)parentNode;
int index = 1;
if (parent != null)
{
XmlNode[] siblings = parent.ChildNodes.Cast<XmlNode>().Where(candidate => candidate is XmlElement && candidate.Name == element.Name).ToArray();
foreach (XmlNode candidate in siblings)
{
if (candidate == element)
return siblings.Length > 1 ? "[" + index + "]" : "";
index++;
}
}
throw new ArgumentException("Couldn't find element within parent");
}
#endregion Debug Helpers
#region Deserialization
private object _GetValue(XmlNode node, Type type, string arrayItemName = null, object result = null)
{
if (type.IsEnum)
{
string stringValue = node.InnerText;
try
{
return Enum.Parse(type, stringValue);
}
catch (Exception)
{
throw new XmlException("Invalid value in " + _GetXPath(node));
}
}
if (type == typeof(string))
return node.InnerText;
if (type.IsPrimitive)
return _GetPrimitiveValue(node, type);
if (type.IsNullable())
{
if (!node.HasChildNodes)
return null;
Type subType = type.GetGenericArguments()[0];
return _GetValue(node, subType, arrayItemName, result);
}
if (type.IsList() || type.IsArray)
{
Type subType = type.IsArray ? type.GetElementType() : type.GetGenericArguments()[0];
String subName = arrayItemName ?? subType.GetTypeName();
subName = subName.ToLowerInvariant();
List<object> subValues = new List<object>();
foreach (XmlNode subNode in node.ChildNodes)
{
if (subNode is XmlComment)
continue;
if (subName == subNode.Name.ToLowerInvariant() && !subNode.Name.ToLowerInvariant().StartsWith(subName))
throw new XmlException("Invalid list entry '" + subNode.Name + "' in " + _GetXPath(node) + "; Expected: " + subName);
object subValue = _GetValue(subNode, subType);
subValues.Add(subValue);
}
if (result == null)
return _CreateList(type, subValues);
_FillList(result, type, subValues);
return result;
}
if (type.IsDictionary())
{
Type subType = type.GetGenericArguments()[1];
object dict = result ?? Activator.CreateInstance(type);
MethodInfo add = type.GetMethod("Add");
if (arrayItemName != null)
arrayItemName = arrayItemName.ToLowerInvariant();
foreach (XmlNode subNode in node.ChildNodes)
{
if (subNode is XmlComment)
continue;
object subValue = _GetValue(subNode, subType);
string subName;
if (arrayItemName != null)
{
if (arrayItemName != subNode.Name.ToLowerInvariant() && !subNode.Name.ToLowerInvariant().StartsWith(arrayItemName))
throw new XmlException("Invalid dictionary entry '" + subNode.Name + "' in " + _GetXPath(node) + "; Expected: " + arrayItemName);
if (subNode.Attributes == null)
throw new XmlException("'name' attribute is missing in " + _GetXPath(subNode));
XmlNode nameAtt = subNode.Attributes.GetNamedItem("name");
if (nameAtt == null)
throw new XmlException("'name' attribute is missing in " + _GetXPath(subNode));
subName = nameAtt.Value;
}
else
subName = subNode.Name;
add.Invoke(dict, new object[] {subName, subValue});
}
return dict;
}
object value;
try
{
value = result ?? Activator.CreateInstance(type);
}
catch (Exception)
{
throw new XmlException("Could not create instance of " + _GetXPath(node) + "(Type=" + type.Name + ")");
}
_ReadChildNodes(node, ref value, true);
_ReadChildNodes(node, ref value, false);
return value;
}
private object _GetPrimitiveValue(XmlNode node, Type type)
{
object value;
string nodeVal = node.InnerText;
try
{
int p = nodeVal.IndexOf(',');
if (p > 0 && p >= nodeVal.Length - 3)
{
CBase.Log.LogError("German number format converted to english in " + _GetXPath(node));
char[] tmp = nodeVal.ToCharArray();
tmp[p] = '.';
nodeVal = new string(tmp);
}
value = Convert.ChangeType(nodeVal, type, CultureInfo.InvariantCulture);
}
catch (FormatException e)
{
throw new XmlException("Invalid format in " + _GetXPath(node) + ": '" + nodeVal + "' (" + e.Message + ")");
}
catch (InvalidCastException e)
{
throw new XmlException(e.Message + " in " + _GetXPath(node) + ": '" + nodeVal + "'");
}
return value;
}
private static bool _CheckAndSetDefaultValue(object result, SFieldInfo field)
{
if (field.IsEmbeddedList)
{
_AddList(result, field, new List<object>());
return true;
}
if (!field.HasDefaultValue)
return false;
field.SetValue(result, field.DefaultValue);
return true;
}
private static void _FillList(object list, Type type, ICollection values)
{
if (values.Count <= 0)
return;
if (type.IsArray)
{
Array array = (Array)list;
int i = 0;
foreach (object value in values)
array.SetValue(value, i++);
}
else
{
MethodInfo addMethod = type.GetMethod("Add");
foreach (object value in values)
addMethod.Invoke(list, new object[] {value});
}
}
private static object _CreateList(Type type, ICollection values)
{
object list = type.IsArray ? Array.CreateInstance(type.GetElementType(), values.Count) : Activator.CreateInstance(type, new object[] {values.Count});
_FillList(list, type, values);
return list;
}
private static void _AddList(object result, SFieldInfo listField, ICollection list)
{
listField.SetValue(result, _CreateList(listField.Type, list));
}
private void _ReadChildNodes(XmlNode parent, ref object result, bool attributes)
{
IEnumerable nodes;
if (attributes)
nodes = parent.Attributes;
else
nodes = parent.ChildNodes;
List<SFieldInfo> fields = result.GetType().GetFields(attributes);
if (nodes != null)
{
//Dictionary of all embedded lists to allow interleaved/mixed elements
Dictionary<string, Tuple<SFieldInfo, List<object>>> embLists = new Dictionary<string, Tuple<SFieldInfo, List<object>>>();
foreach (XmlNode node in nodes)
{
if (node is XmlComment)
continue;
SFieldInfo field = new SFieldInfo();
int curField;
for (curField = 0; curField < fields.Count; curField++)
{
field = fields[curField];
if (field.Name == node.Name || field.AltName == node.Name || (field.IsEmbeddedList && node.Name.StartsWith(field.Name)))
break;
}
if (curField >= fields.Count)
{
string msg = "Unexpected element: " + _GetXPath(node);
if (fields.Count > 0)
msg += " Expected: " + string.Join(", ", fields.Select(f => f.Name));
throw new XmlException(msg);
}
if (field.IsByteArray)
{
field.SetValue(result, Convert.FromBase64String(node.InnerText));
fields.RemoveAt(curField);
}
else if (field.IsEmbeddedList)
{
Tuple<SFieldInfo, List<object>> entry;
if (!embLists.TryGetValue(field.Name, out entry))
{
entry = new Tuple<SFieldInfo, List<object>>(field, new List<object>());
embLists.Add(field.Name, entry);
}
object subValue = _GetValue(node, field.SubType);
entry.Item2.Add(subValue);
}
else
{
object value = _GetValue(node, field.Type, field.ArrayItemName);
if (field.IsNormalized)
{
if (field.IsNullable && !((float?)value).Value.IsInRange(0, 1) ||
!field.IsNullable && !((float)value).IsInRange(0, 1))
throw new XmlException("Value in " + _GetXPath(node) + " is not normalized. (Value=" + value + ")");
}
if (field.Ranged != null && value != null)
{
bool ok = false;
if (field.Type == typeof(int))
ok = ((int)value).IsInRange(field.Ranged.Min, field.Ranged.Max);
else if (field.Type == typeof(float))
ok = ((float)value).IsInRange(field.Ranged.Min, field.Ranged.Max);
else if (field.Type == typeof(double))
ok = ((double)value).IsInRange(field.Ranged.Min, field.Ranged.Max);
else
Debug.Assert(false, "Ranged attribute has invalid type");
if (!ok)
{
throw new XmlException("Value in " + _GetXPath(node) + " is not in the range " + field.Ranged.Min + "-" + field.Ranged.Max + ". (Value=" + value +
")");
}
}
field.SetValue(result, value);
fields.RemoveAt(curField);
}
}
//Add embedded lists
foreach (Tuple<SFieldInfo, List<object>> entry in embLists.Values)
{
_AddList(result, entry.Item1, entry.Item2);
fields.Remove(entry.Item1);
}
}
foreach (SFieldInfo field in fields)
{
if (!_CheckAndSetDefaultValue(result, field))
throw new XmlException("element: " + field.Name + " is missing in " + _GetXPath(parent));
}
}
#endregion Deserialization
#region Serialization
private void _WriteNode(XmlWriter writer, string name, Type type, object value, bool isAttribute, string arrayItemName = null, string nameAttribute = null)
{
if (!isAttribute && _GetCommentCallback != null)
@@ -445,75 +137,6 @@ namespace VocaluxeLib.Xml
_WriteNode(writer, field.Name, field.Type, value, field.IsAttribute, field.ArrayItemName);
}
}
#endregion
private T _Deserialize<T>(XmlReader reader, object result) where T : new()
{
if (reader.IsEmptyElement)
return (T)result;
XmlDocument xDoc = new XmlDocument();
xDoc.Load(reader);
if (xDoc.DocumentElement == null)
throw new XmlException("No root element found!");
try
{
result = _GetValue(xDoc.DocumentElement, typeof(T), typeof(T).GetSubTypeName(), result);
}
catch (TargetInvocationException e)
{
throw e.InnerException ?? e;
}
return (T)result;
}
public T DeserializeString<T>(string xml) where T : new()
{
return DeserializeString(xml, new T());
}
public T DeserializeString<T>(string xml, T o) where T : new()
{
var reader = new XmlTextReader(new StringReader(xml))
{
WhitespaceHandling = WhitespaceHandling.Significant,
Normalization = true,
XmlResolver = null
};
try
{
return _Deserialize<T>(reader, o);
}
finally
{
reader.Close();
}
}
public T Deserialize<T>(string filePath) where T : new()
{
return Deserialize(filePath, new T());
}
public T Deserialize<T>(string filePath, T o) where T : new()
{
if (!File.Exists(filePath))
throw new FileNotFoundException(filePath);
var reader = new XmlTextReader(filePath)
{
WhitespaceHandling = WhitespaceHandling.Significant,
Normalization = true,
XmlResolver = null
};
try
{
return _Deserialize<T>(reader, o);
}
finally
{
reader.Close();
}
}
private void _Serialize(object o, XmlWriter writer)
{
+37 -32
View File
@@ -106,15 +106,16 @@ namespace VocaluxeTests
private static void _AssertFail<T, T2>(String xmlString) where T2 : Exception where T : new()
{
var xml = new CXmlSerializer();
_AssertFail<T2>(() => xml.DeserializeString<T>(xmlString));
var deserializer = new CXmlDeserializer();
_AssertFail<T2>(() => deserializer.DeserializeString<T>(xmlString));
}
private static T _AssertSerDeserMatch<T>(string xmlString) where T : new()
{
var xml = new CXmlSerializer();
T foo = xml.DeserializeString<T>(xmlString);
string xmlNew = xml.Serialize(foo);
var deserializer = new CXmlDeserializer();
var serializer = new CXmlSerializer();
T foo = deserializer.DeserializeString<T>(xmlString);
string xmlNew = serializer.Serialize(foo);
Assert.AreEqual(xmlString, xmlNew);
return foo;
}
@@ -134,7 +135,7 @@ namespace VocaluxeTests
<F>3</F>
<S>2</S>
</root>";
var xml = new CXmlSerializer();
var xml = new CXmlDeserializer();
SBasic foo = xml.DeserializeString<SBasic>(s);
Assert.AreEqual(1, foo.I);
Assert.AreEqual("2", foo.S);
@@ -235,20 +236,22 @@ namespace VocaluxeTests
[TestMethod]
public void TestList()
{
var xml = new CXmlSerializer();
var xml = new CXmlDeserializer();
var ser = new CXmlSerializer();
SList foo = xml.DeserializeString<SList>(_XMLList[0]);
Assert.AreEqual(foo.Ints.Count, 2, "Deserialization failed");
Assert.AreEqual(foo.Ints[0].I, 1, "Deserialization failed");
Assert.AreEqual(foo.Ints[1].I, 1, "Deserialization failed");
string res = xml.Serialize(foo);
string res = ser.Serialize(foo);
Assert.AreEqual(_XMLList[0], res, "Serialization failed");
foo = xml.DeserializeString<SList>(_XMLList[1]);
Assert.AreEqual(foo.Ints.Count, 0, "Deserialization2 failed");
res = xml.Serialize(foo);
res = ser.Serialize(foo);
Assert.AreEqual(_XMLList[2], res, "Serialization2 failed");
foo = xml.DeserializeString<SList>(_XMLList[2]);
Assert.AreEqual(foo.Ints.Count, 0, "Deserialization2 failed");
res = xml.Serialize(foo);
_AssertSerDeserMatch<SList>(_XMLList[2]);
res = ser.Serialize(foo);
Assert.AreEqual(_XMLList[2], res, "Serialization2 failed");
_AssertFail<SList, XmlException>(_Empty);
}
@@ -256,20 +259,21 @@ namespace VocaluxeTests
[TestMethod]
public void TestArray()
{
var xml = new CXmlSerializer();
var xml = new CXmlDeserializer();
var ser = new CXmlSerializer();
SArray foo = xml.DeserializeString<SArray>(_XMLList[0]);
Assert.AreEqual(foo.Ints.Length, 2, "Deserialization failed");
Assert.AreEqual(foo.Ints[0].I, 1, "Deserialization failed");
Assert.AreEqual(foo.Ints[1].I, 1, "Deserialization failed");
string res = xml.Serialize(foo);
string res = ser.Serialize(foo);
Assert.AreEqual(_XMLList[0], res, "Serialization failed");
foo = xml.DeserializeString<SArray>(_XMLList[1]);
Assert.AreEqual(foo.Ints.Length, 0, "Deserialization2 failed");
res = xml.Serialize(foo);
res = ser.Serialize(foo);
Assert.AreEqual(_XMLList[2], res, "Serialization2 failed");
foo = xml.DeserializeString<SArray>(_XMLList[2]);
Assert.AreEqual(foo.Ints.Length, 0, "Deserialization2 failed");
res = xml.Serialize(foo);
res = ser.Serialize(foo);
Assert.AreEqual(_XMLList[2], res, "Serialization2 failed");
_AssertFail<SArray, XmlException>(_Empty);
}
@@ -299,20 +303,21 @@ namespace VocaluxeTests
[TestMethod]
public void TestListEmbedded()
{
var xml = new CXmlSerializer();
var xml = new CXmlDeserializer();
var ser = new CXmlSerializer();
SListEmb foo = xml.DeserializeString<SListEmb>(_XMLListEmb);
Assert.AreEqual(foo.Ints.Count, 1, "Deserialization failed");
Assert.AreEqual(foo.Ints[0].I, 1, "Deserialization failed");
string res = xml.Serialize(foo);
string res = ser.Serialize(foo);
Assert.AreEqual(_XMLListEmb, res, "Serialization failed");
foo = xml.DeserializeString<SListEmb>(_XMLListEmb2);
Assert.AreEqual(foo.Ints.Count, 2, "Deserialization failed");
Assert.AreEqual(foo.Ints[1].I, 2, "Deserialization failed");
res = xml.Serialize(foo);
res = ser.Serialize(foo);
Assert.AreEqual(_XMLListEmb2, res, "Serialization failed");
foo = xml.DeserializeString<SListEmb>(_XMLListEmb3);
Assert.AreEqual(foo.Ints.Count, 0, "Deserialization failed");
res = xml.Serialize(foo);
res = ser.Serialize(foo);
Assert.AreEqual(_XMLListEmb3, res, "Serialization failed");
_AssertFail<SListEmb, XmlException>(_Empty);
}
@@ -320,20 +325,21 @@ namespace VocaluxeTests
[TestMethod]
public void TestArrayEmbedded()
{
var xml = new CXmlSerializer();
var xml = new CXmlDeserializer();
var ser = new CXmlSerializer();
SArrayEmb foo = xml.DeserializeString<SArrayEmb>(_XMLListEmb);
Assert.AreEqual(foo.Ints.Length, 1, "Deserialization failed");
Assert.AreEqual(foo.Ints[0].I, 1, "Deserialization failed");
string res = xml.Serialize(foo);
string res = ser.Serialize(foo);
Assert.AreEqual(_XMLListEmb, res, "Serialization failed");
foo = xml.DeserializeString<SArrayEmb>(_XMLListEmb2);
Assert.AreEqual(foo.Ints.Length, 2, "Deserialization failed");
Assert.AreEqual(foo.Ints[1].I, 2, "Deserialization failed");
res = xml.Serialize(foo);
res = ser.Serialize(foo);
Assert.AreEqual(_XMLListEmb2, res, "Serialization failed");
foo = xml.DeserializeString<SArrayEmb>(_XMLListEmb3);
Assert.AreEqual(foo.Ints.Length, 0, "Deserialization failed");
res = xml.Serialize(foo);
res = ser.Serialize(foo);
Assert.AreEqual(_XMLListEmb3, res, "Serialization failed");
_AssertFail<SArrayEmb, XmlException>(_Empty);
}
@@ -345,12 +351,9 @@ namespace VocaluxeTests
<Public>2</Public>
<Auto>3</Auto>
</root>";
var xml = new CXmlSerializer();
SProperty foo = xml.DeserializeString<SProperty>(xmlString);
SProperty foo = _AssertSerDeserMatch<SProperty>(xmlString);
Assert.AreEqual(3, foo.Private);
Assert.AreEqual(3, foo.Auto);
string newXml = xml.Serialize(foo);
Assert.AreEqual(xmlString, newXml);
}
[TestMethod]
@@ -381,16 +384,17 @@ namespace VocaluxeTests
public void TestExisting()
{
var foo = new SIgnore {I = 1};
var xml = new CXmlSerializer();
var xml = new CXmlDeserializer();
var ser = new CXmlSerializer();
SIgnore bar = xml.DeserializeString(_XmlIgnore, foo);
Assert.AreEqual(1, bar.I);
Assert.AreEqual(_XmlIgnore, xml.Serialize(bar));
Assert.AreEqual(_XmlIgnore, ser.Serialize(bar));
var foo2 = new CIgnore {I = 1};
CIgnore bar2 = xml.DeserializeString(_XmlIgnore, foo2);
Assert.AreEqual(1, bar2.I);
Assert.AreEqual(foo2.J, bar2.J, "Original classes should be modified by the deserialization");
Assert.AreEqual(_XmlIgnore, xml.Serialize(bar2));
Assert.AreEqual(_XmlIgnore, ser.Serialize(bar2));
}
[TestMethod]
@@ -421,18 +425,19 @@ namespace VocaluxeTests
foreach (Type type in types)
{
string xmlPath = Path.Combine(filePath, type.Name + ".xml");
var xml = new CXmlSerializer(type == typeof(CConfig.SConfig));
var deser = new CXmlDeserializer();
object foo = null;
try
{
foo = xml.Deserialize(xmlPath, Activator.CreateInstance(type));
foo = deser.Deserialize(xmlPath, Activator.CreateInstance(type));
}
catch (Exception e)
{
Assert.Fail("Exception with " + type.Name + ": {0}", new object[] {e.Message});
}
Assert.IsInstanceOfType(foo, type, "Wrong type with " + type.Name);
string newXml = xml.Serialize(foo);
var ser = new CXmlSerializer(type == typeof(CConfig.SConfig));
string newXml = ser.Serialize(foo);
string oldXml = File.ReadAllText(xmlPath);
Assert.AreEqual(oldXml, newXml, "Error with " + type.Name);
}