⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 advancedmarshaler.cs

📁 蓝牙通讯
💻 CS
字号:
using System;
using System.IO;
using System.Collections;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;

namespace OpenNETCF.Runtime.InteropServices
{
	
	/// <summary>
	/// AdvancedMarshaler class implementation.
	/// </summary>
	public abstract class AdvancedMarshaler
	{
		#region Fields
		// The internal buffer
		internal byte[] data;
		private MemoryStream stream;
		private BinaryReader binReader;
		private BinaryWriter binWriter;
		//private Timer timer;
		//private TimerCallback timerCallback;
		
		#endregion
	
		#region constructors

		public AdvancedMarshaler()
		{

		}
		
		#endregion

		#region public methods

		public void Deserialize()
		{
			if (data != null)
			{
				if (binReader != null)
				{
					binReader.Close();
					stream.Close();
				}
				// Create a steam from byte array
				stream = new MemoryStream(data);
				binReader = new BinaryReader(stream, System.Text.Encoding.Unicode);
				ReadFromStream(binReader);
				binReader.Close();
			}

		}

		public void Serialize()
		{
			if (data != null)
			{
				stream = new MemoryStream(data);
				binWriter = new BinaryWriter(stream, System.Text.Encoding.Unicode);
				WriteToStream(binWriter);
				binWriter.Close();
			}
		}

		public int GetSize()
		{	
			int size = 0;

			FieldInfo[] fields = this.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance);

			foreach (FieldInfo field in fields )
			{
				if (field.FieldType.IsArray)
				{
					size += GetFieldSize(field);
				}
				else if (field.FieldType == typeof(string))
				{
					size += GetFieldSize(field)*2;
				} 
				else if (field.FieldType.IsPrimitive)
				{
					size += Marshal.SizeOf(field.FieldType);
				}
			}

			return size;
		}

		#endregion

		#region properties

		public byte[] ByteArray
		{
			get
			{
				return data;
			}
		}

		#endregion

		#region virtual and protected methods

		public virtual void ReadFromStream(BinaryReader reader)
		{
			object[] param = null;

			// Get all public fields
			FieldInfo[] fields = this.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance);
			
			// Loop through the fields
			foreach(FieldInfo field in fields)
			{
				// Retrieve the read method from ReadMethods hashtable
				MethodInfo method = (MethodInfo)MarshallingMethods.ReadMethods[field.FieldType];

				if (field.FieldType.IsArray)
				{
					Type element = field.FieldType.GetElementType();
					if (element.IsValueType && element.IsPrimitive)
					{
						if ((element == typeof(char)) || element == typeof(byte))
						{																				 
							param = new object[1];
							param[0] = GetFieldSize(field);
							field.SetValue(this, method.Invoke(reader, param)); 
						}
						else // any other value type array
						{
							param = new object[2];
							param[0] = reader;
							param[1] = GetFieldSize(field);
							field.SetValue(this, method.Invoke(null, param)); 
						}
					}
					else // array of sub structures
					{
						int size = GetFieldSize(field);
						method = (MethodInfo)MarshallingMethods.ReadMethods[typeof(AdvancedMarshaler)];
						Array objArray = Array.CreateInstance(element, size);
						for(int i=0;i<size;i++)
						{
							objArray.SetValue(Activator.CreateInstance(element), i);
							method.Invoke(objArray.GetValue(i), new object[]{reader});
						}
						field.SetValue(this, objArray); 
					}
				}
				else if (field.FieldType == typeof(string))
				{	
					param = new object[2];
					param[0] = reader;
					param[1] = GetFieldSize(field);
					field.SetValue(this, method.Invoke(null, param)); 
				}
				else if (field.FieldType.IsValueType && field.FieldType.IsPrimitive)// regular value type
				{
					field.SetValue(this, method.Invoke(reader, null)); 
				}
				else //process substructure 
				{
					AdvancedMarshaler subStruct = (AdvancedMarshaler)Activator.CreateInstance(field.FieldType);
					subStruct.ReadFromStream(reader);
				}
			}
		}

		public virtual void WriteToStream(BinaryWriter writer)
		{
			object[] param = null;

			FieldInfo[] fields = this.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance);
			
			foreach(FieldInfo field in fields)
			{
				// Check if we have any value
				object value = field.GetValue(this);
				
				MethodInfo method = (MethodInfo)MarshallingMethods.WriteMethods[field.FieldType];
				
				if (field.FieldType.IsArray)
				{
					Type element = field.FieldType.GetElementType();
					if (element.IsValueType && element.IsPrimitive)
					{
						//method.Invoke(writer, new object[] {value});
						Array arrObject = (Array)field.GetValue(this);
						param = new object[2];
						param[0] = writer;
						param[1] = arrObject;
						method.Invoke(null, param);
					}
					else
					{
						//Get field size
						int size = GetFieldSize(field);
						//Get WriteToStream method
						method = (MethodInfo)MarshallingMethods.WriteMethods[typeof(AdvancedMarshaler)];
						Array arrObject = (Array)field.GetValue(this);
						for(int i=0;i<size;i++)
						{
							method.Invoke(arrObject.GetValue(i), new object[]{writer});
						}
					}					
				}
				else if (field.FieldType == typeof(string))
				{	
					param = new object[3];
					param[0] = writer;
					param[1] = field.GetValue(this);
					param[2] = GetFieldSize(field);
					method.Invoke(null, param);
					

				}
				else if (field.FieldType.IsValueType && field.FieldType.IsPrimitive)// regular value type
				{
					method.Invoke(writer, new object[] {value});
				}
			}
		}

		protected int GetFieldSize(FieldInfo field)
		{
			int size = 0;
			CustomMarshalAsAttribute attrib = (CustomMarshalAsAttribute)field.GetCustomAttributes(typeof(CustomMarshalAsAttribute), true)[0];
			
			if (attrib != null)
			{
				if (attrib.SizeField != null)
				{
					FieldInfo sizeField = this.GetType().GetField(attrib.SizeField);
					size = (int)sizeField.GetValue(this);
				}
				else
				{
					size = attrib.SizeConst;	
				}
			}

			return size;
		}

		#endregion

		#region helper methods

		private static bool CompareByteArrays (byte[] data1, byte[] data2)
		{
			// If both are null, they're equal
			if (data1==null && data2==null)
			{
				return true;
			}
			// If either but not both are null, they're not equal
			if (data1==null || data2==null)
			{
				return false;
			}
			if (data1.Length != data2.Length)
			{
				return false;
			}
			for (int i=0; i < data1.Length; i++)
			{
				if (data1[i] != data2[i])
				{
					return false;
				}
			}
			return true;
		}

		#endregion

	}

	#region MarshallingMethods class
	/// <summary>
	/// MarshallingMethods class implementation.
	/// </summary>
	public class MarshallingMethods
	{
		public static Hashtable ReadMethods = new Hashtable();
		public static Hashtable WriteMethods = new Hashtable();
		
		#region constructors

		static MarshallingMethods()
		{
			// Read Methods
			ReadMethods.Add(typeof(bool), typeof(BinaryReader).GetMethod("ReadBoolean"));
			ReadMethods.Add(typeof(byte), typeof(BinaryReader).GetMethod("ReadByte"));
			ReadMethods.Add(typeof(System.SByte), typeof(BinaryReader).GetMethod("ReadSByte"));
			ReadMethods.Add(typeof(System.Single), typeof(BinaryReader).GetMethod("ReadSingle"));
			ReadMethods.Add(typeof(byte[]), typeof(BinaryReader).GetMethod("ReadBytes"));
			ReadMethods.Add(typeof(char[]), typeof(BinaryReader).GetMethod("ReadChars"));
			ReadMethods.Add(typeof(System.Int16), typeof(BinaryReader).GetMethod("ReadInt16"));
			ReadMethods.Add(typeof(System.Int32), typeof(BinaryReader).GetMethod("ReadInt32"));
			ReadMethods.Add(typeof(System.UInt16), typeof(BinaryReader).GetMethod("ReadUInt16"));
			ReadMethods.Add(typeof(System.UInt32), typeof(BinaryReader).GetMethod("ReadUInt32"));
			ReadMethods.Add(typeof(System.String), typeof(MarshallingMethods).GetMethod("ReadString"));
			ReadMethods.Add(typeof(System.DateTime), typeof(MarshallingMethods).GetMethod("ReadDateTime"));
			ReadMethods.Add(typeof(System.Int16[]), typeof(MarshallingMethods).GetMethod("ReadInt16Array"));
			ReadMethods.Add(typeof(System.Int32[]), typeof(MarshallingMethods).GetMethod("ReadInt32Array"));
			ReadMethods.Add(typeof(System.UInt16[]), typeof(MarshallingMethods).GetMethod("ReadUInt16Array"));
			ReadMethods.Add(typeof(System.UInt32[]), typeof(MarshallingMethods).GetMethod("ReadUInt32Array"));
			ReadMethods.Add(typeof(AdvancedMarshaler), typeof(AdvancedMarshaler).GetMethod("ReadFromStream"));
			//Write Methods
			WriteMethods.Add(typeof(bool), typeof(BinaryWriter).GetMethod("Write", new Type[]{typeof(bool)}));
			WriteMethods.Add(typeof(byte), typeof(BinaryWriter).GetMethod("Write", new Type[]{typeof(byte)}));
			WriteMethods.Add(typeof(System.SByte), typeof(BinaryWriter).GetMethod("Write", new Type[]{typeof(System.SByte)}));
			WriteMethods.Add(typeof(System.Single), typeof(BinaryWriter).GetMethod("Write", new Type[]{typeof(System.Single)}));
			//WriteMethods.Add(typeof(byte[]), typeof(BinaryWriter).GetMethod("Write", new Type[]{typeof(byte[])}));
			//WriteMethods.Add(typeof(char[]), typeof(BinaryWriter).GetMethod("Write", new Type[]{typeof(char[])}));
			WriteMethods.Add(typeof(System.Int16), typeof(BinaryWriter).GetMethod("Write", new Type[]{typeof(System.Int16)}));
			WriteMethods.Add(typeof(System.Int32), typeof(BinaryWriter).GetMethod("Write", new Type[]{typeof(System.Int32)}));
			WriteMethods.Add(typeof(System.UInt16), typeof(BinaryWriter).GetMethod("Write", new Type[]{typeof(System.UInt16)}));
			WriteMethods.Add(typeof(System.UInt32), typeof(BinaryWriter).GetMethod("Write", new Type[]{typeof(System.UInt32)}));
			WriteMethods.Add(typeof(System.String), typeof(MarshallingMethods).GetMethod("WriteString"));
			WriteMethods.Add(typeof(AdvancedMarshaler), typeof(AdvancedMarshaler).GetMethod("WriteToStream"));

			WriteMethods.Add(typeof(bool[]), typeof(MarshallingMethods).GetMethod("WriteArray", new Type[] { typeof(BinaryWriter), typeof(bool[]) }));
			WriteMethods.Add(typeof(char[]), typeof(MarshallingMethods).GetMethod("WriteArray", new Type[] { typeof(BinaryWriter), typeof(char[]) }));
			WriteMethods.Add(typeof(short[]), typeof(MarshallingMethods).GetMethod("WriteArray", new Type[] { typeof(BinaryWriter), typeof(short[]) }));
			WriteMethods.Add(typeof(ushort[]), typeof(MarshallingMethods).GetMethod("WriteArray", new Type[] { typeof(BinaryWriter), typeof(ushort[]) }));
			WriteMethods.Add(typeof(int[]), typeof(MarshallingMethods).GetMethod("WriteArray", new Type[] { typeof(BinaryWriter), typeof(int[]) }));
			WriteMethods.Add(typeof(uint[]), typeof(MarshallingMethods).GetMethod("WriteArray", new Type[] { typeof(BinaryWriter), typeof(uint[]) }));
			WriteMethods.Add(typeof(long[]), typeof(MarshallingMethods).GetMethod("WriteArray", new Type[] { typeof(BinaryWriter), typeof(long[]) }));
			WriteMethods.Add(typeof(ulong[]), typeof(MarshallingMethods).GetMethod("WriteArray", new Type[] { typeof(BinaryWriter), typeof(ulong[]) }));
			WriteMethods.Add(typeof(float[]), typeof(MarshallingMethods).GetMethod("WriteArray", new Type[] { typeof(BinaryWriter), typeof(float[]) }));

		}

		#endregion

		#region static helper methods

		public static short[] ReadInt16Array(BinaryReader reader, int count)
		{
			short[] result = new short[count];

			for(int i=0;i<count;i++)
			{
				result[i] = reader.ReadInt16();
			}
			return result;
		}

		public static int[] ReadInt32Array(BinaryReader reader, int count)
		{
			int[] result = new int[count];

			for(int i=0;i<count;i++)
			{
				result[i] = reader.ReadInt32();
			}
			return result;
		}

		[CLSCompliant(false)]
		public static ushort[] ReadUInt16Array(BinaryReader reader, int count)
		{
			ushort[] result = new ushort[count];

			for(int i=0;i<count;i++)
			{
				result[i] = reader.ReadUInt16();
			}
			return result;
		}

		[CLSCompliant(false)]
		public static uint[] ReadUInt32Array(BinaryReader reader, int count)
		{
			uint[] result = new uint[count];

			for(int i=0;i<count;i++)
			{
				result[i] = reader.ReadUInt32();
			}
			return result;
		}

		public static string ReadString(BinaryReader reader, int count)
		{
			string result = "";
			if (count == 0)
			{
				count = 255; //default	
			}
			char[] data = reader.ReadChars(count);

			result = new string(data).TrimEnd('\0');
			return result;
		}

		public static void WriteString(BinaryWriter writer, string value, int size)
		{
			if (value!=null)
			{
				byte[] bstring = System.Text.Encoding.Unicode.GetBytes(value.Substring(0, size)); 
				writer.Write(bstring);
			}
		}

		public static DateTime ReadDateTime(BinaryReader reader)
		{
			return DateTime.FromFileTime(reader.ReadInt64());
		}


		public static void WriteArray(BinaryWriter writer, bool[] arr)
		{
			for (int i = 0; i < arr.Length; i++)
			{
				writer.Write(arr[i]);
			}
		}
		public static void WriteArray(BinaryWriter writer, char[] arr)
		{
			for (int i = 0; i < arr.Length; i++)
			{
				writer.Write(arr[i]);
			}
		}

		public static void WriteArray(BinaryWriter writer, byte[] arr)
		{
			for (int i = 0; i < arr.Length; i++)
			{
				writer.Write(arr[i]);
			}
		}

		public static void WriteArray(BinaryWriter writer, short[] arr)
		{
			for (int i = 0; i < arr.Length; i++)
			{
				writer.Write(arr[i]);
			}
		}

		[CLSCompliant(false)]
		public static void WriteArray(BinaryWriter writer, ushort[] arr)
		{
			for (int i = 0; i < arr.Length; i++)
			{
				writer.Write(arr[i]);
			}
		}
		public static void WriteArray(BinaryWriter writer, int[] arr)
		{
			for (int i = 0; i < arr.Length; i++)
			{
				writer.Write(arr[i]);
			}
		}

		[CLSCompliant(false)]
		public static void WriteArray(BinaryWriter writer, uint[] arr)
		{
			for (int i = 0; i < arr.Length; i++)
			{
				writer.Write(arr[i]);
			}
		}

		public static void WriteArray(BinaryWriter writer, long[] arr)
		{
			for (int i = 0; i < arr.Length; i++)
			{
				writer.Write(arr[i]);
			}
		}

		[CLSCompliant(false)]
		public static void WriteArray(BinaryWriter writer, ulong[] arr)
		{
			for (int i = 0; i < arr.Length; i++)
			{
				writer.Write(arr[i]);
			}
		}
		public static void WriteArray(BinaryWriter writer, float[] arr)
		{
			for (int i = 0; i < arr.Length; i++)
			{
				writer.Write(arr[i]);
			}
		}

		public static void WriteSerializers(BinaryWriter writer, AdvancedMarshaler[] arr)
		{
			for (int i = 0; i < arr.Length; i++)
			{
				arr[i].WriteToStream(writer);
			}
		}

		#endregion
	}

	#endregion

	#region CustomMarshalAsAttribute
	/// <summary>
	/// CustomMarshalAsAttribute implementaion.
	/// </summary>
	public sealed class CustomMarshalAsAttribute : Attribute
	{
		public int SizeConst = 0;
		public string  SizeField = null;
	}

	#endregion

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -