// ========================================================
namespace Kerosene.Tools
{
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;
// ====================================================
/// <summary>
/// Helpers and extensions for serialization scenarios.
/// </summary>
public static partial class SerializationHelper
{
/// <summary>
/// Serializes the given object on this stream given, using the specified formatter.
/// </summary>
/// <param name="sm">The stream.</param>
/// <param name="obj">The object to serialize.</param>
/// <param name="formatter">The formatter to use.</param>
public static void Serialize(this Stream sm, object obj, IFormatter formatter)
{
if (sm == null) throw new NullReferenceException("Stream cannot be null.");
if (obj == null) throw new ArgumentNullException("obj", "Object cannot be null.");
if (formatter == null) throw new ArgumentNullException("formatter", "IFormatter cannot be null.");
formatter.Serialize(sm, obj);
}
/// <summary>
/// Deserializes an object from this stream given using the specified formatter.
/// </summary>
/// <param name="sm">The stream.</param>
/// <param name="formatter">The formatter.</param>
/// <returns>The deserialized object.</returns>
public static object Deserialize(this Stream sm, IFormatter formatter)
{
if (sm == null) throw new NullReferenceException("Stream cannot be null.");
if (formatter == null) throw new ArgumentNullException("formatter", "IFormatter cannot be null.");
object obj = formatter.Deserialize(sm);
return obj;
}
/// <summary>
/// Serializes the given object on this stream given, using a binary or soap formatter.
/// </summary>
/// <param name="sm">The stream.</param>
/// <param name="obj">The object to serialize.</param>
/// <param name="binary">True to use a binary formatter, false to use a soap one.</param>
public static void Serialize(this Stream sm, object obj, bool binary)
{
if (sm == null) throw new ArgumentNullException("sm", "Stream cannot be null.");
if (obj == null) throw new ArgumentNullException("obj", "Object cannot be null.");
IFormatter formatter = binary ? (IFormatter)(new BinaryFormatter()) : (IFormatter)(new SoapFormatter());
Serialize(sm, obj, formatter);
}
/// <summary>
/// Deserializes an object from this stream given using a binary or soap formatter.
/// </summary>
/// <param name="sm">The stream.</param>
/// <param name="binary">True to use a binary formatter, false to use a soap one.</param>
/// <returns>The deserialized object.</returns>
public static object Deserialize(this Stream sm, bool binary)
{
if (sm == null) throw new NullReferenceException("Stream cannot be null.");
IFormatter formatter = binary ? (IFormatter)(new BinaryFormatter()) : (IFormatter)(new SoapFormatter());
return Deserialize(sm, formatter);
}
/// <summary>
/// Serializes the given object on the file specified by the path given, using a binary or soap formatter.
/// </summary>
/// <param name="path">The path of the file.</param>
/// <param name="obj">The object to serialize.</param>
/// <param name="binary">True to use a binary formatter, false to use a soap one.</param>
public static void Serialize(string path, object obj, bool binary)
{
path = path == null ? path : path.Trim();
if (obj == null) throw new ArgumentNullException("obj", "Object cannot be null.");
if (string.IsNullOrEmpty(path)) throw new ArgumentException(
string.Format("Path '{0}' is invalid.", path ?? "-"));
using (FileStream sm = new FileStream(path, FileMode.Create))
{
SerializationHelper.Serialize(sm, obj, binary);
}
}
/// <summary>
/// Deserializes an object from the file whose path is given using a binary or soap formatter.
/// </summary>
/// <param name="path">The path of the file.</param>
/// <param name="binary">True to use a binary formatter, false to use a soap one.</param>
/// <returns>The deserialized object.</returns>
public static object Deserialize(string path, bool binary)
{
path = path == null ? path : path.Trim();
if (string.IsNullOrEmpty(path)) throw new ArgumentException(
string.Format("Path '{0}' is invalid.", path ?? "-"));
using (FileStream sm = new FileStream(path, FileMode.Open))
{
return SerializationHelper.Deserialize(sm, binary);
}
}
}
// ====================================================
public static partial class SerializationHelper
{
const string TYPETAG = "_TYPE";
const string PAYLOADTAG = "_PAYLOAD";
const string NULLVALUE = "NULL";
/// <summary>
/// Adds into the serialization info instance the name and value given, including its type and payload.
/// </summary>
/// <param name="info">The SerializationInfo instance.</param>
/// <param name="name">The name of the entry to add.</param>
/// <param name="value">The value of the entry, from which to obtain its type and payload.</param>
public static void AddExtended(this SerializationInfo info, string name, object value)
{
if (value == null) info.AddValue(name + TYPETAG, NULLVALUE);
else
{
var type = value.GetType();
info.AddValue(name + TYPETAG, type.AssemblyQualifiedName);
info.AddValue(name + PAYLOADTAG, value);
}
}
/// <summary>
/// Gets from the serialization info instance the entry whose name is given, which has been serialized with
/// its type and payload.
/// </summary>
/// <param name="info">The SerializationInfo instance.</param>
/// <param name="name">The name of the entry to get.</param>
public static object GetExtended(this SerializationInfo info, string name)
{
var typestr = info.GetString(name + TYPETAG);
if (typestr == NULLVALUE) return null;
var type = Type.GetType(typestr);
var value = info.GetValue(name + PAYLOADTAG, type);
return value;
}
}
}
// ========================================================