wasSharpNET – Rev 28
?pathlinks?
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
// Based on: Danilow @ https://stackoverflow.com/questions/23897145/memory-leak-using-streamreader-and-xmlserializer/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
namespace wasSharpNET.Serialization
{
public static class XmlSerializerCache
{
private static readonly ReaderWriterLockSlim SerializerCacheLock =
new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
private static readonly Dictionary<string, XmlSerializer> SerializerCache =
new Dictionary<string, XmlSerializer>();
public static XmlSerializer GetSerializer<T>()
{
return GetSerializer<T>(null);
}
public static XmlSerializer GetSerializer<T>(Type[] ExtraTypes)
{
return GetSerializer(typeof(T), ExtraTypes);
}
public static XmlSerializer GetSerializer(Type MainTypeForSerialization)
{
return GetSerializer(MainTypeForSerialization, null);
}
public static XmlSerializer GetSerializer(Type MainTypeForSerialization, Type[] ExtraTypes)
{
var Signature = MainTypeForSerialization.FullName;
if (ExtraTypes != null)
Signature = ExtraTypes.Aggregate(Signature, (current, tp) => current + "-" + tp.FullName);
SerializerCacheLock.EnterReadLock();
XmlSerializer XmlEventSerializer;
if (SerializerCache.TryGetValue(Signature, out XmlEventSerializer))
{
SerializerCacheLock.ExitReadLock();
return XmlEventSerializer;
}
SerializerCacheLock.ExitReadLock();
if (ExtraTypes == null)
return new XmlSerializer(MainTypeForSerialization);
XmlEventSerializer = new XmlSerializer(MainTypeForSerialization, ExtraTypes);
SerializerCacheLock.EnterWriteLock();
SerializerCache.Add(Signature, XmlEventSerializer);
SerializerCacheLock.ExitWriteLock();
return XmlEventSerializer;
}
public static T Deserialize<T>(XDocument XmlData)
{
return Deserialize<T>(XmlData, null);
}
public static T Deserialize<T>(XDocument XmlData, Type[] ExtraTypes)
{
try
{
using (var XmlReader = XmlData.Root.CreateReader())
{
return (T) GetSerializer<T>(ExtraTypes).Deserialize(XmlReader);
}
}
catch (Exception ex)
{
throw new Exception("Could not deserialize to " + typeof(T).Name, ex);
}
}
public static T Deserialize<T>(string XmlData)
{
return Deserialize<T>(XmlData, null);
}
public static T Deserialize<T>(string XmlData, Type[] ExtraTypes)
{
try
{
using (var XmlReader = XDocument.Parse(XmlData).Root.CreateReader())
{
return (T) GetSerializer<T>(ExtraTypes).Deserialize(XmlReader);
}
}
catch (Exception ex)
{
throw new Exception("Could not deserialize to " + typeof(T).Name, ex);
}
}
public static XDocument Serialize<T>(T Object, Type[] ExtraTypes)
{
try
{
using (var memoryStream = new MemoryStream())
{
using (var streamReader = new StreamReader(memoryStream))
{
using (var xmlWriter = XmlWriter.Create(memoryStream, new XmlWriterSettings {Indent = true}))
{
var ns = new XmlSerializerNamespaces();
ns.Add(string.Empty, string.Empty);
GetSerializer<T>(ExtraTypes).Serialize(xmlWriter, Object, ns);
xmlWriter.Flush();
memoryStream.Position = 0L;
return XDocument.Load(streamReader, LoadOptions.None);
}
}
}
}
catch (Exception ex)
{
throw new Exception("Could not serialize from " + typeof(T).Name + " to xml string", ex);
}
}
public static XDocument Serialize<T>(T Object)
{
return Serialize(Object, null);
}
public static async Task<T> Deserialize<T>(StreamReader streamReader)
{
return Deserialize<T>(await streamReader.ReadToEndAsync(), null);
}
public static async Task<T> Deserialize<T>(Stream stream)
{
using (var memoryStream = new MemoryStream())
{
await stream.CopyToAsync(memoryStream);
memoryStream.Position = 0L;
using (var streamReader = new StreamReader(memoryStream))
{
return Deserialize<T>(streamReader.ReadToEnd(), null);
}
}
}
public static void Serialize<T>(Stream stream, T value)
{
Serialize(value, null).Save(stream);
}
public static void Serialize<T>(StreamWriter streamWriter, T value)
{
Serialize(value, null).Save(streamWriter);
}
public static void Serialize<T>(StringWriter stringWriter, T value)
{
Serialize(value, null).Save(stringWriter);
}
public static async Task<T> Deserialize<T>(TextReader reader)
{
return Deserialize<T>(await reader.ReadToEndAsync(), null);
}
}
}
Generated by GNU Enscript 1.6.5.90.