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

📄 advancedmarshaler.cs

📁 本源码为OpenNETCF源代码
💻 CS
📖 第 1 页 / 共 2 页
字号:
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
		protected byte[] data;
		private MemoryStream stream;
		private BinaryReader binReader;
		private BinaryWriter binWriter;
		private int	size = 0;

		public int Size 
		{
			get
			{
				return size;
			}
		}
		
		#endregion
	
		#region constructors

		public AdvancedMarshaler()
		{
			size = GetSize();
			data = new byte [size];
		}
		
		#endregion

		#region public methods

		/// <summary>
		/// Copy bytes from a user array to the internal data array
		/// and then call the internal Deserialize routine
		/// </summary>
		/// <param name="b">The byte array to be copied to the 
		/// internal array and then deserialized</param>
		public void DeserializeFromByteArray(byte[] b)
		{
			int ln = (b.Length < data.Length) ? b.Length : data.Length;

			Array.Copy(b, 0, data, 0, ln); 
			Deserialize();
		}

		public void Deserialize()
		{
			if (data != null)
			{
				if (binReader != null)
				{
					binReader.Close();
					stream.Close();
				}
				// Create a stream 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);
				}
					// This else condition added by JTF, 8/17/04 to handle sizing of structures within structures
				else //process substructure 
				{
					AdvancedMarshaler subStruct = (AdvancedMarshaler)Activator.CreateInstance(field.FieldType);
					size += subStruct.GetSize();
				}
				// End of Modifications
			}

			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;
							
							int fldSize = 1;
							if (element == typeof(int))
								fldSize = 4;

							param[1] = GetFieldSize(field) / fldSize;

							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 
				{
					// modified by JTF - 08/19/04 
					// code should be using existing instance of a substructure but original code created new
					// instance.
					AdvancedMarshaler subStruct = (AdvancedMarshaler) field.GetValue(this);
					//					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});
				}
				else //process substructure 
				{
					// modified by JTF - 08/18/04
					// original code creates new empty instance of substructure and attempts to write to its
					// empty "data" byte array
					AdvancedMarshaler subStruct = (AdvancedMarshaler) value;
					//					AdvancedMarshaler subStruct = (AdvancedMarshaler)Activator.CreateInstance(field.FieldType);
					subStruct.WriteToStream(writer);
				}

			}
		}

		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);

⌨️ 快捷键说明

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