wasSharpNET

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 15  →  ?path2? @ 16
/Serialization/XmlSerializerCache.cs
@@ -0,0 +1,184 @@
///////////////////////////////////////////////////////////////////////////
// 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.Text;
using System.Threading;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using wasSharp;
 
namespace wasSharpNET.Serialization
{
public static class XmlSerializerCache
{
private static ReaderWriterLockSlim SerializerCacheLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
private static 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)
{
string Signature = MainTypeForSerialization.FullName;
if (ExtraTypes != null)
{
foreach (Type Tp in ExtraTypes)
Signature += "-" + Tp.FullName;
}
 
SerializerCacheLock.EnterReadLock();
XmlSerializer XmlEventSerializer = null;
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 (MemoryStream memoryStream = new MemoryStream())
{
using (StreamWriter streamWriter = new StreamWriter(memoryStream))
{
streamWriter.Write(XmlData);
streamWriter.Flush();
memoryStream.Position = 0;
return (T)GetSerializer<T>(ExtraTypes).Deserialize(memoryStream);
}
}
}
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 (MemoryStream memoryStream = new MemoryStream())
{
using (StreamReader streamReader = new StreamReader(memoryStream))
{
using (var xmlWriter = XmlWriter.Create(memoryStream, new XmlWriterSettings { Indent = true }))
{
XmlSerializerNamespaces 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 T Deserialize<T>(StreamReader streamReader)
{
return Deserialize<T>(streamReader.ReadToEnd(), null);
}
 
public static T Deserialize<T>(Stream stream)
{
using (MemoryStream memoryStream = new MemoryStream())
{
stream.CopyTo(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 T Deserialize<T>(TextReader reader)
{
return Deserialize<T>(reader.ReadToEnd(), null);
}
}
}