/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); |
} |
} |
} |