190 lines
5.3 KiB
C#
190 lines
5.3 KiB
C#
using System;
|
|
using System.ComponentModel;
|
|
using System.IO;
|
|
using System.Text;
|
|
using JD.Kernel.StaticHelpers;
|
|
using JD.Reflection;
|
|
using JD.Serializers.Stream;
|
|
|
|
namespace JD.Serializers.Xml
|
|
{
|
|
/// <summary>
|
|
/// Base class for all Xml Serializers
|
|
/// </summary>
|
|
public abstract class XmlSerializer : IDisposable
|
|
{
|
|
#region Variables
|
|
|
|
/// <summary>
|
|
/// Name of the root element of all Xml documents read or written by XmlSerializers
|
|
/// </summary>
|
|
public const string RootElement = "TeaBox";
|
|
/// <summary>
|
|
/// Name of the attribute representing the version of all Xml documents read of written by XmlSerializer
|
|
/// </summary>
|
|
protected const string VersionAttribute = "version";
|
|
/// <summary>
|
|
/// Default Array Separator.
|
|
/// </summary>
|
|
protected const char DefaultArraySeparator = ',';
|
|
|
|
private bool m_disposed;
|
|
private readonly string m_streamName;
|
|
|
|
private readonly TypeConverterCache m_cache = new TypeConverterCache();
|
|
|
|
#endregion
|
|
|
|
#region IDisposable Members
|
|
|
|
/// <summary>
|
|
/// Finalizer.
|
|
/// </summary>
|
|
~XmlSerializer()
|
|
{
|
|
System.Diagnostics.Debug.Assert(!m_disposed);
|
|
Dispose(false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Disposes the serializer.
|
|
/// </summary>
|
|
public void Dispose()
|
|
{
|
|
if (!m_disposed)
|
|
{
|
|
Dispose(true);
|
|
GC.SuppressFinalize(this);
|
|
m_disposed = true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Protected implementation of the Dispose pattern.
|
|
/// </summary>
|
|
/// <param name="disposing"></param>
|
|
protected virtual void Dispose(bool disposing)
|
|
{
|
|
}
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Default constructor. Must be called by base class to initialize the stream's name.
|
|
/// </summary>
|
|
/// <param name="stream"></param>
|
|
protected XmlSerializer(System.IO.Stream stream)
|
|
: this(stream, null)
|
|
{ }
|
|
|
|
/// <summary>
|
|
/// Constructor with a fallback filename.
|
|
/// </summary>
|
|
/// <param name="stream"></param>
|
|
/// <param name="fallbackFileName"></param>
|
|
protected XmlSerializer(System.IO.Stream stream, string fallbackFileName)
|
|
{
|
|
Throw.IfNull(stream, "stream");
|
|
|
|
FileStream fileStream = FindFileStream(stream);
|
|
m_streamName = fileStream != null ? FileUtility.FormatPath(fileStream.Name) : fallbackFileName;
|
|
}
|
|
|
|
#region Properties
|
|
|
|
/// <summary>
|
|
/// Name of the file if the steam is a FileStream, null otherwise.
|
|
/// </summary>
|
|
public string FileName
|
|
{
|
|
get
|
|
{
|
|
return m_streamName;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Whether this <see cref="XmlSerializer"/> is disposed.
|
|
/// </summary>
|
|
public bool IsDisposed
|
|
{
|
|
get
|
|
{
|
|
return m_disposed;
|
|
}
|
|
}
|
|
|
|
public static Encoding Encoding
|
|
{
|
|
get { return Encoding.UTF8; }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Methods
|
|
|
|
private static FileStream FindFileStream(System.IO.Stream stream)
|
|
{
|
|
IStreamWrapper wrapper;
|
|
|
|
do
|
|
{
|
|
wrapper = stream as IStreamWrapper;
|
|
|
|
if (wrapper != null)
|
|
{
|
|
stream = wrapper.UnderlyingStream;
|
|
}
|
|
}
|
|
while (wrapper != null);
|
|
|
|
return stream as FileStream;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Starts an xml element.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Disposing the returned object will end the element.
|
|
/// </remarks>
|
|
/// <param name="element">Name of the xml element to start.</param>
|
|
public abstract IXmlElement StartElement(string element);
|
|
|
|
/// <summary>
|
|
/// Helper function to write and then read xml data.
|
|
/// </summary>
|
|
/// <param name="write">Action that writes data.</param>
|
|
/// <param name="read">Action that reads the written data.</param>
|
|
public static void WriteRead(Action<XmlSerializerWriter> write, Action<XmlSerializerReader> read)
|
|
{
|
|
Throw.IfNull(write, "write");
|
|
Throw.IfNull(read, "read");
|
|
|
|
byte[] writtenData;
|
|
using (MemoryStream writeStream = new MemoryStream())
|
|
{
|
|
using (XmlSerializerWriter writer = new XmlSerializerWriter(writeStream))
|
|
using (writer.StartElement("PlaceHolder"))
|
|
{
|
|
write(writer);
|
|
}
|
|
writeStream.Close();
|
|
writtenData = writeStream.ToArray();
|
|
}
|
|
|
|
using (MemoryStream readStream = new MemoryStream(writtenData))
|
|
using (XmlSerializerReader reader = new XmlSerializerReader(readStream))
|
|
using (reader.StartElement("PlaceHolder"))
|
|
{
|
|
read(reader);
|
|
}
|
|
}
|
|
|
|
protected TypeConverter GetConverter(Type type)
|
|
{
|
|
return m_cache.GetConverter(type);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|