369 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			369 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Text;
 | |
| using System.Xml;
 | |
| using System.Reflection;
 | |
| using System.Drawing;
 | |
| using System.ComponentModel;
 | |
| 
 | |
| #if DOTNETBAR
 | |
| namespace DevComponents.DotNetBar
 | |
| #else
 | |
| namespace DevComponents.Tree
 | |
| #endif
 | |
| {
 | |
|     [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Field)]
 | |
|     public class DevCoSerialize : Attribute
 | |
|     {
 | |
|         public DevCoSerialize(){}
 | |
|     }
 | |
| 
 | |
| 	/// <summary>
 | |
| 	/// Represents class that can serialize compatible marked properties.
 | |
| 	/// </summary>
 | |
|     public class ElementSerializer
 | |
|     {
 | |
|         private static string XmlImageName="image";
 | |
|         private static string XmlIconName="icon";
 | |
|         private static string XmlAttributeName="name";
 | |
| //    	private static string XmlCollectionName="collection";
 | |
| //    	private static string XmlTypeName="type";
 | |
| //    	private static string XmlObjectName="object";
 | |
| 
 | |
|         public static void Serialize(object element, XmlElement xmlElem)
 | |
|         {
 | |
|             PropertyInfo[] propInfo = element.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
 | |
|             foreach (PropertyInfo prop in propInfo)
 | |
|             {
 | |
|                 if (prop.GetCustomAttributes(typeof(DevCoSerialize), true).Length > 0)
 | |
|                 {
 | |
|                 	// Check whether property needs to be serialized
 | |
|                 	object[] attributesDefaultValue=prop.GetCustomAttributes(typeof(DefaultValueAttribute), true);
 | |
|                 	if (attributesDefaultValue.Length > 0)
 | |
|                 	{
 | |
|                 		DefaultValueAttribute att=attributesDefaultValue[0] as DefaultValueAttribute;
 | |
|                 		object propertyValue = prop.GetValue(element, null);
 | |
|                 		if(propertyValue==att.Value)
 | |
|                 			continue;
 | |
|                 		if(propertyValue!=null && att.Value!=null && propertyValue.Equals(att.Value))
 | |
|                 			continue;
 | |
|                 	}
 | |
|                 	else if(element.GetType().GetMethod("ShouldSerialize" + prop.Name,BindingFlags.Default | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)!=null)
 | |
|                 	{
 | |
|                 		MethodInfo mi=element.GetType().GetMethod("ShouldSerialize" + prop.Name,BindingFlags.Default | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
 | |
|                 		object result=mi.Invoke(element,null);
 | |
|                 		if(result is bool && !((bool)result))
 | |
|                 			continue;
 | |
|                 	}
 | |
|                 	
 | |
|                     string attributeName=XmlConvert.EncodeName(prop.Name);
 | |
|                     Type t=prop.PropertyType;
 | |
|                     if (t.IsPrimitive || t == typeof(string) || t.IsEnum)
 | |
|                     {
 | |
|                         if (t == typeof(string))
 | |
|                             xmlElem.SetAttribute(attributeName, prop.GetValue(element, null).ToString());
 | |
|                         else if (t.IsEnum)
 | |
|                         {
 | |
|                             xmlElem.SetAttribute(attributeName, Enum.Format(t, prop.GetValue(element, null), "g"));
 | |
|                         }
 | |
|                         else if (t == typeof(bool))
 | |
|                             xmlElem.SetAttribute(attributeName, XmlConvert.ToString((bool)prop.GetValue(element, null)));
 | |
|                         else if (t == typeof(Int32))
 | |
|                             xmlElem.SetAttribute(attributeName, XmlConvert.ToString((Int32)prop.GetValue(element, null)));
 | |
|                         else if (t == typeof(double))
 | |
|                             xmlElem.SetAttribute(attributeName, XmlConvert.ToString((double)prop.GetValue(element, null)));
 | |
|                         else if (t == typeof(float))
 | |
|                             xmlElem.SetAttribute(attributeName, XmlConvert.ToString((float)prop.GetValue(element, null)));
 | |
|                         else if (t == typeof(Int16))
 | |
|                             xmlElem.SetAttribute(attributeName, XmlConvert.ToString((Int16)prop.GetValue(element, null)));
 | |
|                         else if (t == typeof(Int64))
 | |
|                             xmlElem.SetAttribute(attributeName, XmlConvert.ToString((Int64)prop.GetValue(element, null)));
 | |
|                         else if (t == typeof(byte))
 | |
|                             xmlElem.SetAttribute(attributeName, XmlConvert.ToString((byte)prop.GetValue(element, null)));
 | |
|                         else if (t == typeof(char))
 | |
|                             xmlElem.SetAttribute(attributeName, XmlConvert.ToString((char)prop.GetValue(element, null)));
 | |
|                         else if (t == typeof(decimal))
 | |
|                             xmlElem.SetAttribute(attributeName, XmlConvert.ToString((decimal)prop.GetValue(element, null)));
 | |
|                         else if (t == typeof(Guid))
 | |
|                             xmlElem.SetAttribute(attributeName, XmlConvert.ToString((Guid)prop.GetValue(element, null)));
 | |
|                         else if (t == typeof(sbyte))
 | |
|                             xmlElem.SetAttribute(attributeName, XmlConvert.ToString((sbyte)prop.GetValue(element, null)));
 | |
|                         else if (t == typeof(TimeSpan))
 | |
|                             xmlElem.SetAttribute(attributeName, XmlConvert.ToString((TimeSpan)prop.GetValue(element, null)));
 | |
|                         else if (t == typeof(ushort))
 | |
|                             xmlElem.SetAttribute(attributeName, XmlConvert.ToString((ushort)prop.GetValue(element, null)));
 | |
|                         else if (t == typeof(uint))
 | |
|                             xmlElem.SetAttribute(attributeName, XmlConvert.ToString((uint)prop.GetValue(element, null)));
 | |
|                         else if (t == typeof(ulong))
 | |
|                             xmlElem.SetAttribute(attributeName, XmlConvert.ToString((ulong)prop.GetValue(element, null)));
 | |
|                         else
 | |
|                             throw new ApplicationException("Unsupported serialization type '" + t.ToString() + "' on property '" + attributeName + "'");
 | |
|                     }
 | |
|                     else if (t == typeof(Color))
 | |
|                         xmlElem.SetAttribute(attributeName, ColorToString((Color)prop.GetValue(element, null)));
 | |
|                     else if (t == typeof(Image))
 | |
|                     {
 | |
|                         XmlElement imageXmlElement = xmlElem.OwnerDocument.CreateElement(XmlImageName);
 | |
|                         imageXmlElement.SetAttribute(XmlAttributeName, attributeName);
 | |
|                         xmlElem.AppendChild(imageXmlElement);
 | |
|                         SerializeImage((Image)prop.GetValue(element, null), imageXmlElement);
 | |
|                     }
 | |
|                     else if (t == typeof(Icon))
 | |
|                     {
 | |
|                         XmlElement imageXmlElement = xmlElem.OwnerDocument.CreateElement(XmlIconName);
 | |
|                         imageXmlElement.SetAttribute(XmlAttributeName, attributeName);
 | |
|                         xmlElem.AppendChild(imageXmlElement);
 | |
|                         SerializeIcon((Icon)prop.GetValue(element, null), imageXmlElement);
 | |
|                     }
 | |
|                     else if (t == typeof(Font))
 | |
|                     {
 | |
|                         xmlElem.SetAttribute(attributeName, FontToString((Font)prop.GetValue(element, null)));
 | |
|                     }
 | |
|                     else
 | |
|                         throw new ApplicationException("Unsupported serialization type '" + t.ToString() + "'" + "' on property '" + attributeName + "'");
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private static string ColorToString(Color clr)
 | |
|         {
 | |
|             if (clr.IsSystemColor || clr.IsNamedColor || clr.IsKnownColor)
 | |
|                 return ("." + clr.Name);
 | |
|             else
 | |
|                 return clr.ToArgb().ToString();
 | |
|         }
 | |
| 
 | |
|         private static Color ColorFromString(string sclr)
 | |
|         {
 | |
|             if (sclr == "")
 | |
|                 return Color.Empty;
 | |
|             if (sclr[0] == '.')
 | |
|                 return Color.FromName(sclr.Substring(1));
 | |
|             else
 | |
|                 return Color.FromArgb(System.Xml.XmlConvert.ToInt32(sclr));
 | |
|         }
 | |
| 
 | |
|         private static string FontToString(Font font)
 | |
|         {
 | |
|             if (font == null)
 | |
|                 return "";
 | |
| 
 | |
|             string s = font.Name + "," + XmlConvert.ToString(font.Size) + "," + XmlConvert.ToString(font.Bold) + "," + XmlConvert.ToString(font.Italic) + "," +
 | |
|                 XmlConvert.ToString(font.Underline) + "," + XmlConvert.ToString(font.Strikeout);
 | |
| 
 | |
|             return s;
 | |
|         }
 | |
| 
 | |
|         private static Font FontFromString(string fontString)
 | |
|         {
 | |
|             if(fontString=="")
 | |
|                 return null;
 | |
| 
 | |
|             string[] options=fontString.Split(',');
 | |
|             FontStyle fontStyle = FontStyle.Regular;
 | |
|             if (XmlConvert.ToBoolean(options[2]))
 | |
|                 fontStyle |= FontStyle.Bold;
 | |
|             if (XmlConvert.ToBoolean(options[3]))
 | |
|                 fontStyle |= FontStyle.Italic;
 | |
|             if (XmlConvert.ToBoolean(options[4]))
 | |
|                 fontStyle |= FontStyle.Underline;
 | |
|             if (XmlConvert.ToBoolean(options[5]))
 | |
|                 fontStyle |= FontStyle.Strikeout;
 | |
|             Font font = new Font(options[0], XmlConvert.ToSingle(options[1]), fontStyle);
 | |
|             return font;
 | |
|         }
 | |
| 
 | |
|         public static void Deserialize(object element, XmlElement xmlElem)
 | |
|         {
 | |
|             Type type=element.GetType();
 | |
|             foreach(XmlAttribute att in xmlElem.Attributes)
 | |
|             {
 | |
|                 string name=XmlConvert.DecodeName(att.Name);
 | |
|                 PropertyInfo prop=type.GetProperty(name);
 | |
|                 if(prop!=null)
 | |
|                 {
 | |
|                     Type t=prop.PropertyType;
 | |
| 
 | |
|                     if (t.IsPrimitive)
 | |
|                     {
 | |
|                         if(t==typeof(bool))
 | |
|                             prop.SetValue(element, XmlConvert.ToBoolean(att.Value), null);
 | |
|                         else if (t == typeof(Int32))
 | |
|                             prop.SetValue(element, XmlConvert.ToInt32(att.Value), null);
 | |
|                         else if (t == typeof(double))
 | |
|                             prop.SetValue(element, XmlConvert.ToDouble(att.Value), null);
 | |
|                         else if (t == typeof(float))
 | |
|                             prop.SetValue(element, XmlConvert.ToSingle(att.Value), null);
 | |
|                         else if (t == typeof(Int16))
 | |
|                             prop.SetValue(element, XmlConvert.ToInt16(att.Value), null);
 | |
|                         else if (t == typeof(Int64))
 | |
|                             prop.SetValue(element, XmlConvert.ToInt64(att.Value), null);
 | |
|                         else if (t == typeof(byte))
 | |
|                             prop.SetValue(element, XmlConvert.ToByte(att.Value), null);
 | |
|                         else if (t == typeof(char))
 | |
|                             prop.SetValue(element, XmlConvert.ToChar(att.Value), null);
 | |
|                         else if (t == typeof(decimal))
 | |
|                             prop.SetValue(element, XmlConvert.ToDecimal(att.Value), null);
 | |
|                         else if (t == typeof(Guid))
 | |
|                             prop.SetValue(element, XmlConvert.ToGuid(att.Value), null);
 | |
|                         else if (t == typeof(sbyte))
 | |
|                             prop.SetValue(element, XmlConvert.ToSByte(att.Value), null);
 | |
|                         else if (t == typeof(TimeSpan))
 | |
|                             prop.SetValue(element, XmlConvert.ToTimeSpan(att.Value), null);
 | |
|                         else if (t == typeof(ushort))
 | |
|                             prop.SetValue(element, XmlConvert.ToUInt16(att.Value), null);
 | |
|                         else if (t == typeof(uint))
 | |
|                             prop.SetValue(element, XmlConvert.ToUInt32(att.Value), null);
 | |
|                         else if (t == typeof(ulong))
 | |
|                             prop.SetValue(element, XmlConvert.ToUInt64(att.Value), null);
 | |
|                     }
 | |
|                     else if (t == typeof(string))
 | |
|                         prop.SetValue(element, att.Value, null);
 | |
|                     else if (t.IsEnum)
 | |
|                         prop.SetValue(element, Enum.Parse(t, att.Value), null);
 | |
|                     else if (t == typeof(Color))
 | |
|                         prop.SetValue(element, ColorFromString(att.Value), null);
 | |
|                     else if (t == typeof(Font))
 | |
|                         prop.SetValue(element, FontFromString(att.Value), null);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             foreach(XmlElement childElem in xmlElem.ChildNodes)
 | |
|             {
 | |
|                 if (childElem.Name == XmlImageName)
 | |
|                 {
 | |
|                     string name = XmlConvert.DecodeName(childElem.GetAttribute(XmlAttributeName));
 | |
|                     PropertyInfo prop = type.GetProperty(name);
 | |
|                     if (prop != null)
 | |
|                     {
 | |
|                         prop.SetValue(element, DeserializeImage(childElem), null);
 | |
|                     }
 | |
|                 }
 | |
|                 else if (childElem.Name == XmlIconName)
 | |
|                 {
 | |
|                     string name = XmlConvert.DecodeName(childElem.GetAttribute(XmlAttributeName));
 | |
|                     PropertyInfo prop = type.GetProperty(name);
 | |
|                     if (prop != null)
 | |
|                     {
 | |
|                         prop.SetValue(element, DeserializeIcon(childElem), null);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
| 		public static void SerializeImage(System.Drawing.Image image,XmlElement xml)
 | |
| 		{
 | |
| 			if(image==null)
 | |
| 				return;
 | |
| 
 | |
| 			System.IO.MemoryStream mem=new System.IO.MemoryStream(1024);
 | |
| 			// TODO: Beta 2 issue with the ImageFormat. RawFormat on image object does not return the actual image format
 | |
| 			// Right now it is hard coded to PNG but in final version we should get the original image format
 | |
| 			image.Save(mem,System.Drawing.Imaging.ImageFormat.Png);
 | |
| 
 | |
| 			System.Text.StringBuilder sb=new System.Text.StringBuilder();
 | |
| 			System.IO.StringWriter sw=new System.IO.StringWriter(sb);
 | |
| 				
 | |
| 			System.Xml.XmlTextWriter xt=new System.Xml.XmlTextWriter(sw);
 | |
| 			xt.WriteBase64(mem.GetBuffer(),0,(int)mem.Length);
 | |
| 
 | |
| 			xml.InnerText=sb.ToString();
 | |
| 		}
 | |
| 
 | |
| 		public static void SerializeIcon(System.Drawing.Icon icon, XmlElement xml)
 | |
| 		{
 | |
| 			if(icon==null)
 | |
| 				return;
 | |
| 
 | |
| 			System.IO.MemoryStream mem=new System.IO.MemoryStream(1024);
 | |
| 			// TODO: Beta 2 issue with the ImageFormat. RawFormat on image object does not return the actual image format
 | |
| 			// Right now it is hard coded to PNG but in final version we should get the original image format
 | |
| 			icon.Save(mem);
 | |
| 
 | |
| 			System.Text.StringBuilder sb=new System.Text.StringBuilder();
 | |
| 			System.IO.StringWriter sw=new System.IO.StringWriter(sb);
 | |
| 				
 | |
| 			System.Xml.XmlTextWriter xt=new System.Xml.XmlTextWriter(sw);
 | |
| 
 | |
| 			xml.SetAttribute("encoding","binhex");
 | |
| 			//xt.WriteBase64(mem.GetBuffer(),0,(int)mem.Length);
 | |
| 			xt.WriteBinHex(mem.GetBuffer(),0,(int)mem.Length);
 | |
| 
 | |
| 			xml.InnerText=sb.ToString();
 | |
| 		}
 | |
| 
 | |
| 		/// <summary>
 | |
| 		/// XML element is expected to be something like <image>Image data Base64 encoded</image>
 | |
| 		/// </summary>
 | |
| 		/// <param name="xml">Image data</param>
 | |
| 		/// <returns></returns>
 | |
| 		public static System.Drawing.Image DeserializeImage(XmlElement xml)
 | |
| 		{
 | |
| 			System.Drawing.Image img=null;
 | |
| 			if(xml==null || xml.InnerText=="")
 | |
| 				return null;
 | |
| 
 | |
| 			System.IO.StringReader sr=new System.IO.StringReader(xml.OuterXml);
 | |
| 			System.Xml.XmlTextReader xr= new System.Xml.XmlTextReader(sr);
 | |
| 			System.IO.MemoryStream mem=new System.IO.MemoryStream(1024);
 | |
| 			// Skip <image> to data
 | |
| 			xr.Read();
 | |
| 				
 | |
| 			byte[] base64 = new byte[1024];
 | |
| 			int base64len = 0;
 | |
| 			do
 | |
| 			{
 | |
| 				base64len = xr.ReadBase64(base64, 0, 1024);
 | |
| 				if(base64len>0)
 | |
| 					mem.Write(base64,0,base64len);
 | |
| 
 | |
| 			} while (base64len!=0);
 | |
| 
 | |
| 			img=System.Drawing.Image.FromStream(mem);
 | |
| 
 | |
| 			return img;
 | |
| 		}
 | |
| 
 | |
| 		public static System.Drawing.Icon DeserializeIcon(XmlElement xml)
 | |
| 		{
 | |
| 			System.Drawing.Icon img=null;
 | |
| 			if(xml==null || xml.InnerText=="")
 | |
| 				return null;
 | |
| 			bool bDecodeBinHex=false;
 | |
| 			if(xml.HasAttribute("encoding") && xml.GetAttribute("encoding")=="binhex")
 | |
| 				bDecodeBinHex=true;
 | |
| 			System.IO.StringReader sr=new System.IO.StringReader(xml.OuterXml);
 | |
| 			System.Xml.XmlTextReader xr= new System.Xml.XmlTextReader(sr);
 | |
| 			System.IO.MemoryStream mem=new System.IO.MemoryStream(1024);
 | |
| 			// Skip <image> to data
 | |
| 			xr.Read();
 | |
| 				
 | |
| 			byte[] base64 = new byte[1024];
 | |
| 			int base64len = 0;
 | |
| 			if(bDecodeBinHex)
 | |
| 			{
 | |
| 				do
 | |
| 				{
 | |
| 					base64len = xr.ReadBinHex(base64, 0, 1024);
 | |
| 					if(base64len>0)
 | |
| 						mem.Write(base64,0,base64len);
 | |
| 
 | |
| 				} while (base64len!=0);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				do
 | |
| 				{
 | |
| 					base64len = xr.ReadBase64(base64, 0, 1024);
 | |
| 					if(base64len>0)
 | |
| 						mem.Write(base64,0,base64len);
 | |
| 
 | |
| 				} while (base64len!=0);
 | |
| 			}
 | |
| 			mem.Position=0;
 | |
| 			img=new System.Drawing.Icon(mem);
 | |
| 
 | |
| 			return img;
 | |
| 		}
 | |
|     }
 | |
| }
 |