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
{
///
/// Base class for all Xml Serializers
///
public abstract class XmlSerializer : IDisposable
{
#region Variables
///
/// Name of the root element of all Xml documents read or written by XmlSerializers
///
public const string RootElement = "TeaBox";
///
/// Name of the attribute representing the version of all Xml documents read of written by XmlSerializer
///
protected const string VersionAttribute = "version";
///
/// Default Array Separator.
///
protected const char DefaultArraySeparator = ',';
private bool m_disposed;
private readonly string m_streamName;
private readonly TypeConverterCache m_cache = new TypeConverterCache();
#endregion
#region IDisposable Members
///
/// Finalizer.
///
~XmlSerializer()
{
System.Diagnostics.Debug.Assert(!m_disposed);
Dispose(false);
}
///
/// Disposes the serializer.
///
public void Dispose()
{
if (!m_disposed)
{
Dispose(true);
GC.SuppressFinalize(this);
m_disposed = true;
}
}
///
/// Protected implementation of the Dispose pattern.
///
///
protected virtual void Dispose(bool disposing)
{
}
#endregion
///
/// Default constructor. Must be called by base class to initialize the stream's name.
///
///
protected XmlSerializer(System.IO.Stream stream)
: this(stream, null)
{ }
///
/// Constructor with a fallback filename.
///
///
///
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
///
/// Name of the file if the steam is a FileStream, null otherwise.
///
public string FileName
{
get
{
return m_streamName;
}
}
///
/// Whether this is disposed.
///
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;
}
///
/// Starts an xml element.
///
///
/// Disposing the returned object will end the element.
///
/// Name of the xml element to start.
public abstract IXmlElement StartElement(string element);
///
/// Helper function to write and then read xml data.
///
/// Action that writes data.
/// Action that reads the written data.
public static void WriteRead(Action write, Action 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
}
}