📄 advancedmarshaler.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
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 + -