You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
380 lines
11 KiB
380 lines
11 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Specialized;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Runtime.Serialization.Formatters.Binary;
|
|
using System.Security;
|
|
using System.Security.Permissions;
|
|
using System.Text;
|
|
using System.Xml;
|
|
using System.Xml.Serialization;
|
|
|
|
namespace SiteServer.Utils
|
|
{
|
|
public class Serializer
|
|
{
|
|
//Do not allow this class to be instantiated
|
|
private Serializer()
|
|
{
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Static Constructor is used to set the CanBinarySerialize value only once for the given security policy
|
|
/// </summary>
|
|
static Serializer()
|
|
{
|
|
var sp = new SecurityPermission(SecurityPermissionFlag.SerializationFormatter);
|
|
try
|
|
{
|
|
sp.Demand();
|
|
CanBinarySerialize = true;
|
|
}
|
|
catch(SecurityException)
|
|
{
|
|
CanBinarySerialize = false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Readonly value indicating if Binary Serialization (using BinaryFormatter) is allowed
|
|
/// </summary>
|
|
public static readonly bool CanBinarySerialize;
|
|
|
|
/// <summary>
|
|
/// Converts a .NET object to a byte array. Before the conversion happens, a check with
|
|
/// Serializer.CanBinarySerialize will be made
|
|
/// </summary>
|
|
/// <param name="objectToConvert">Object to convert</param>
|
|
/// <returns>A byte arry representing the object paramter. Null will be return if CanBinarySerialize is false</returns>
|
|
public static byte[] ConvertToBytes(object objectToConvert)
|
|
{
|
|
byte[] byteArray = null;
|
|
|
|
if(CanBinarySerialize)
|
|
{
|
|
var binaryFormatter = new BinaryFormatter();
|
|
using(var ms = new MemoryStream())
|
|
{
|
|
|
|
binaryFormatter.Serialize(ms, objectToConvert);
|
|
|
|
|
|
// Set the position of the MemoryStream back to 0
|
|
//
|
|
ms.Position = 0;
|
|
|
|
// Read in the byte array
|
|
//
|
|
byteArray = new Byte[ms.Length];
|
|
ms.Read(byteArray, 0, byteArray.Length);
|
|
ms.Close();
|
|
}
|
|
}
|
|
return byteArray;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Saves an object to disk as a binary file.
|
|
/// </summary>
|
|
/// <param name="objectToSave">Object to Save</param>
|
|
/// <param name="path">Location of the file</param>
|
|
/// <returns>true if the save was succesful.</returns>
|
|
public static bool SaveAsBinary(object objectToSave, string path)
|
|
{
|
|
if(objectToSave != null && CanBinarySerialize)
|
|
{
|
|
var ba = ConvertToBytes(objectToSave);
|
|
if(ba != null)
|
|
{
|
|
using(var fs = new FileStream(path,FileMode.OpenOrCreate,FileAccess.Write))
|
|
{
|
|
using(var bw = new BinaryWriter(fs))
|
|
{
|
|
bw.Write(ba);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Converts a .NET object to a string of XML. The object must be marked as Serializable or an exception
|
|
/// will be thrown.
|
|
/// </summary>
|
|
/// <param name="objectToConvert">Object to convert</param>
|
|
/// <returns>A xml string represting the object parameter. The return value will be null of the object is null</returns>
|
|
public static string ConvertToString(object objectToConvert)
|
|
{
|
|
string xml = null;
|
|
|
|
if(objectToConvert != null)
|
|
{
|
|
//we need the type to serialize
|
|
var t = objectToConvert.GetType();
|
|
|
|
var ser = new XmlSerializer(t);
|
|
//will hold the xml
|
|
using(var writer = new StringWriter(CultureInfo.InvariantCulture))
|
|
{
|
|
ser.Serialize(writer, objectToConvert);
|
|
xml = writer.ToString();
|
|
writer.Close();
|
|
}
|
|
}
|
|
|
|
return xml;
|
|
}
|
|
|
|
public static void SaveAsXML(object objectToConvert, string path)
|
|
{
|
|
if(objectToConvert != null)
|
|
{
|
|
//we need the type to serialize
|
|
var t = objectToConvert.GetType();
|
|
|
|
var ser = new XmlSerializer(t);
|
|
//will hold the xml
|
|
using(var writer = new StreamWriter(path))
|
|
{
|
|
ser.Serialize(writer, objectToConvert);
|
|
writer.Close();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Converts a byte array to a .NET object. You will need to cast this object back to its expected type.
|
|
/// If the array is null or empty, it will return null.
|
|
/// </summary>
|
|
/// <param name="byteArray">An array of bytes represeting a .NET object</param>
|
|
/// <returns>The byte array converted to an object or null if the value of byteArray is null or empty</returns>
|
|
public static object ConvertToObject(byte[] byteArray)
|
|
{
|
|
object convertedObject = null;
|
|
if(CanBinarySerialize && byteArray != null && byteArray.Length > 0)
|
|
{
|
|
var binaryFormatter = new BinaryFormatter();
|
|
using(var ms = new MemoryStream())
|
|
{
|
|
ms.Write(byteArray, 0, byteArray.Length);
|
|
|
|
// Set the memory stream position to the beginning of the stream
|
|
//
|
|
ms.Position = 0;
|
|
|
|
if( byteArray.Length > 4 )
|
|
convertedObject = binaryFormatter.Deserialize(ms);
|
|
|
|
ms.Close();
|
|
}
|
|
}
|
|
return convertedObject;
|
|
}
|
|
|
|
public static object ConvertFileToObject(string path, Type objectType)
|
|
{
|
|
object convertedObject = null;
|
|
|
|
if(path != null && path.Length > 0)
|
|
{
|
|
using(var fs = new FileStream(path,FileMode.Open,FileAccess.Read))
|
|
{
|
|
var ser = new XmlSerializer(objectType);
|
|
convertedObject = ser.Deserialize(fs);
|
|
fs.Close();
|
|
}
|
|
}
|
|
return convertedObject;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts a string of xml to the supplied object type.
|
|
/// </summary>
|
|
/// <param name="xml">Xml representing a .NET object</param>
|
|
/// <param name="objectType">The type of object which the xml represents</param>
|
|
/// <returns>A instance of object or null if the value of xml is null or empty</returns>
|
|
public static object ConvertToObject(string xml, Type objectType)
|
|
{
|
|
object convertedObject = null;
|
|
|
|
if(!string.IsNullOrEmpty(xml))
|
|
{
|
|
using(var reader = new StringReader(xml))
|
|
{
|
|
var ser = new XmlSerializer(objectType);
|
|
convertedObject = ser.Deserialize(reader);
|
|
reader.Close();
|
|
}
|
|
}
|
|
return convertedObject;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts a string of xml to the supplied object type.
|
|
/// </summary>
|
|
/// <param name="xml">Xml representing a .NET object</param>
|
|
/// <param name="objectType">The type of object which the xml represents</param>
|
|
/// <returns>A instance of object or null if the value of xml is null or empty</returns>
|
|
public static object ConvertToObject(XmlNode node, Type objectType)
|
|
{
|
|
object convertedObject = null;
|
|
|
|
if(node != null)
|
|
{
|
|
using(var reader = new StringReader(node.OuterXml))
|
|
{
|
|
|
|
var ser = new XmlSerializer(objectType);
|
|
|
|
convertedObject = ser.Deserialize(reader);
|
|
|
|
reader.Close();
|
|
}
|
|
}
|
|
return convertedObject;
|
|
}
|
|
|
|
|
|
public static object LoadBinaryFile(string path)
|
|
{
|
|
if(!File.Exists(path))
|
|
return null;
|
|
|
|
using(var fs = new FileStream(path,FileMode.Open,FileAccess.Read))
|
|
{
|
|
var br =new BinaryReader(fs);
|
|
var ba = new byte[fs.Length];
|
|
br.Read(ba,0,(int)fs.Length);
|
|
return ConvertToObject(ba);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a NameValueCollection from two string. The first contains the key pattern and the second contains the values
|
|
/// spaced according to the kys
|
|
/// </summary>
|
|
/// <param name="keys">Keys for the namevalue collection</param>
|
|
/// <param name="values">Values for the namevalue collection</param>
|
|
/// <returns>A NVC populated based on the keys and vaules</returns>
|
|
/// <example>
|
|
/// string keys = "key1:S:0:3:key2:S:3:2:";
|
|
/// string values = "12345";
|
|
/// This would result in a NameValueCollection with two keys (Key1 and Key2) with the values 123 and 45
|
|
/// </example>
|
|
public static NameValueCollection ConvertToNameValueCollection(string keys, string values)
|
|
{
|
|
var nvc = new NameValueCollection();
|
|
|
|
if(keys != null && values != null && keys.Length > 0 && values.Length > 0)
|
|
{
|
|
var splitter = new char[1] { ':' } ;
|
|
var keyNames = keys.Split(splitter);
|
|
|
|
for (var i = 0; i < (keyNames.Length / 4); i++)
|
|
{
|
|
var start = int.Parse(keyNames[(i * 4) + 2], CultureInfo.InvariantCulture);
|
|
var len = int.Parse(keyNames[(i * 4) + 3], CultureInfo.InvariantCulture);
|
|
var key = keyNames[i * 4];
|
|
|
|
//Future version will support more complex types
|
|
if (((keyNames[(i * 4) + 1] == "S") && (start >= 0)) && (len > 0) && (values.Length >= (start + len)))
|
|
{
|
|
nvc[key] = values.Substring(start, len);
|
|
}
|
|
}
|
|
}
|
|
|
|
return nvc;
|
|
}
|
|
|
|
public static Dictionary<string, string> ConvertToDictionary(string keys, string values)
|
|
{
|
|
var nvc = new Dictionary<string, string>();
|
|
|
|
if (keys != null && values != null && keys.Length > 0 && values.Length > 0)
|
|
{
|
|
var splitter = new char[1] { ':' };
|
|
var keyNames = keys.Split(splitter);
|
|
|
|
for (var i = 0; i < (keyNames.Length / 4); i++)
|
|
{
|
|
var start = int.Parse(keyNames[(i * 4) + 2], CultureInfo.InvariantCulture);
|
|
var len = int.Parse(keyNames[(i * 4) + 3], CultureInfo.InvariantCulture);
|
|
var key = keyNames[i * 4];
|
|
|
|
//Future version will support more complex types
|
|
if (((keyNames[(i * 4) + 1] == "S") && (start >= 0)) && (len > 0) && (values.Length >= (start + len)))
|
|
{
|
|
nvc[key] = values.Substring(start, len);
|
|
}
|
|
}
|
|
}
|
|
|
|
return nvc;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a the keys and values strings for the simple serialization based on a NameValueCollection
|
|
/// </summary>
|
|
/// <param name="nvc">NameValueCollection to convert</param>
|
|
/// <param name="keys">the ref string will contain the keys based on the key format</param>
|
|
/// <param name="values">the ref string will contain all the values of the namevaluecollection</param>
|
|
public static void ConvertFromNameValueCollection(NameValueCollection nvc, ref string keys, ref string values)
|
|
{
|
|
if(nvc == null || nvc.Count == 0)
|
|
return;
|
|
|
|
var sbKey = new StringBuilder();
|
|
var sbValue = new StringBuilder();
|
|
|
|
var index = 0;
|
|
foreach(var key in nvc.AllKeys)
|
|
{
|
|
if(key.IndexOf(':') != -1)
|
|
throw new ArgumentException("ExtendedAttributes Key can not contain the character \":\"");
|
|
|
|
var v = nvc[key];
|
|
if(!string.IsNullOrEmpty(v))
|
|
{
|
|
sbKey.Append($"{key}:S:{index}:{v.Length}:");
|
|
sbValue.Append(v);
|
|
index += v.Length;
|
|
}
|
|
}
|
|
keys = sbKey.ToString();
|
|
values = sbValue.ToString();
|
|
}
|
|
|
|
public static void ConvertFromDictionary(Dictionary<string, string> nvc, ref string keys, ref string values)
|
|
{
|
|
if (nvc == null || nvc.Count == 0)
|
|
return;
|
|
|
|
var sbKey = new StringBuilder();
|
|
var sbValue = new StringBuilder();
|
|
|
|
var index = 0;
|
|
foreach (var key in nvc.Keys)
|
|
{
|
|
if (key.IndexOf(':') != -1)
|
|
throw new ArgumentException("ExtendedAttributes Key can not contain the character \":\"");
|
|
|
|
var v = nvc[key];
|
|
if (!string.IsNullOrEmpty(v))
|
|
{
|
|
sbKey.Append($"{key}:S:{index}:{v.Length}:");
|
|
sbValue.Append(v);
|
|
index += v.Length;
|
|
}
|
|
}
|
|
keys = sbKey.ToString();
|
|
values = sbValue.ToString();
|
|
}
|
|
}
|
|
}
|