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.
506 lines
17 KiB
506 lines
17 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.IO;
|
|
using System.Data;
|
|
using System.Reflection;
|
|
using System.Collections;
|
|
|
|
namespace NSC
|
|
{
|
|
/// <summary>
|
|
/// 功能:网络报文编码器
|
|
/// 作者:王昊昇
|
|
/// 时间:2012.11.8
|
|
/// </summary>
|
|
internal static class PacketsEncoder
|
|
{
|
|
/// <summary>
|
|
/// 写入实体开始部分
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
private static void WriteEntityBegin(System.Xml.XmlTextWriter xtw)
|
|
{
|
|
xtw.WriteStartElement("Items");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入任意元素的结束部分
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
private static void WriteElementEnd(System.Xml.XmlTextWriter xtw)
|
|
{
|
|
xtw.WriteEndElement();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入网络数据传输数据开始部分
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
private static void WriteNetDataBegin(System.Xml.XmlTextWriter xtw)
|
|
{
|
|
xtw.WriteStartElement("NetworkStreamData");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入服务定义开始部分
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
private static void WriteServiceDefineBegin(System.Xml.XmlTextWriter xtw)
|
|
{
|
|
xtw.WriteStartElement("ServiceDefine");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入参数定义开始部分
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
private static void WriteParameterDefineBegin(System.Xml.XmlTextWriter xtw)
|
|
{
|
|
xtw.WriteStartElement("Param");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入返回值定义开始部分
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
private static void WriteReturnDefineBegin(System.Xml.XmlTextWriter xtw)
|
|
{
|
|
xtw.WriteStartElement("Return");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入实体属性开始部分
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
private static void WriteEntityAttributeBegin(System.Xml.XmlTextWriter xtw)
|
|
{
|
|
xtw.WriteStartElement("Item");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入实体属性
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
/// <param name="publicProperties">实体公共属性列表</param>
|
|
/// <param name="entity">实体引用</param>
|
|
private static void WriteEntityAttribute(System.Xml.XmlTextWriter xtw, PropertyInfo[] publicProperties, object entity)
|
|
{
|
|
foreach (var p in publicProperties)
|
|
{
|
|
var v = p.GetValue(entity, null);
|
|
if (v != null)
|
|
{
|
|
if (v.GetType().IsValueType || v is string)
|
|
{
|
|
xtw.WriteAttributeString(p.Name, v.ToString());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
xtw.WriteAttributeString(p.Name, "");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入链接属性
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
/// <param name="value">链接属性值</param>
|
|
private static void WriteLinkAttribute(System.Xml.XmlTextWriter xtw, string value)
|
|
{
|
|
xtw.WriteAttributeString("Link", value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入值属性
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
/// <param name="value">属性值</param>
|
|
private static void WriteValueAttribute(System.Xml.XmlTextWriter xtw, string value)
|
|
{
|
|
xtw.WriteAttributeString("Value", value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入固件类型属性
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
/// <param name="value">固件类型</param>
|
|
private static void WriteFirmwareModelAttribute(System.Xml.XmlTextWriter xtw, string value)
|
|
{
|
|
xtw.WriteAttributeString("FirmwareModel", value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入固件版本属性
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
/// <param name="value">固件版本</param>
|
|
private static void WriteFirmwareVersionAttribute(System.Xml.XmlTextWriter xtw, string value)
|
|
{
|
|
xtw.WriteAttributeString("FirmwareVersion", value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入用户姓名属性
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
/// <param name="value">用户姓名属性</param>
|
|
private static void WriteUserNameAttribute(System.Xml.XmlTextWriter xtw, string value)
|
|
{
|
|
xtw.WriteAttributeString("UserName", value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入服务代码属性
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
/// <param name="value">服务代码</param>
|
|
private static void WriteServiceNameAttribute(System.Xml.XmlTextWriter xtw, string value)
|
|
{
|
|
xtw.WriteAttributeString("ServiceName", value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入执行异常属性
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
/// <param name="value">异常属性值</param>
|
|
private static void WriteExceptionAttribute(System.Xml.XmlTextWriter xtw, string value)
|
|
{
|
|
xtw.WriteAttributeString("Exception", value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入同步方式属性
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
/// <param name="value">同步方式属性值</param>
|
|
private static void WriteSyncTypeAttribute(System.Xml.XmlTextWriter xtw, string value)
|
|
{
|
|
xtw.WriteAttributeString("SyncType", value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入服务流水号属性
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
/// <param name="value">服务流水号属性值</param>
|
|
private static void WriteServiceSNAttribute(System.Xml.XmlTextWriter xtw, string value)
|
|
{
|
|
xtw.WriteAttributeString("ServiceSN", value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入参数名称属性
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
/// <param name="value">参数名称属性值</param>
|
|
private static void WriteParameterNameAttribute(System.Xml.XmlTextWriter xtw, string value)
|
|
{
|
|
xtw.WriteAttributeString("Name", value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入参数类型属性
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
/// <param name="value">参数类型属性值</param>
|
|
private static void WriteParameterTypeAttribute(System.Xml.XmlTextWriter xtw, string value)
|
|
{
|
|
xtw.WriteAttributeString("Type", value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入DataTable参数
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
/// <param name="n">数据</param>
|
|
/// <param name="ds">附件</param>
|
|
/// <param name="i">附件索引</param>
|
|
private static void WriteParameterDataTable(System.Xml.XmlTextWriter xtw, ParameterStruct n, DataSet ds, ref int i)
|
|
{
|
|
string tabName = "Tab" + i.ToString();
|
|
|
|
WriteLinkAttribute(xtw, tabName);
|
|
WriteValueAttribute(xtw, "");
|
|
|
|
DataTable table = (n.Data as DataTable).Copy();
|
|
table.TableName = tabName;
|
|
ds.Tables.Add(table);
|
|
i++;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入实体参数
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
/// <param name="n">数据</param>
|
|
private static void WriteParameterEntity(System.Xml.XmlTextWriter xtw, ParameterStruct n)
|
|
{
|
|
WriteEntityBegin(xtw);
|
|
|
|
PropertyInfo[] publicProperties = Common.AssemblyUtil.EntityFactory.GetProperties(n.Data);
|
|
|
|
WriteEntityAttributeBegin(xtw);
|
|
|
|
WriteEntityAttribute(xtw, publicProperties, n.Data);
|
|
|
|
WriteElementEnd(xtw);
|
|
|
|
WriteElementEnd(xtw);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入数组参数
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
/// <param name="n">数据</param>
|
|
private static void WriteParameterArray(System.Xml.XmlTextWriter xtw, ParameterStruct n)
|
|
{
|
|
WriteLinkAttribute(xtw, "");
|
|
WriteEntityBegin(xtw);
|
|
|
|
foreach (var s in n.Data as string[])
|
|
{
|
|
WriteEntityAttributeBegin(xtw);
|
|
|
|
WriteValueAttribute(xtw, s);
|
|
|
|
WriteElementEnd(xtw);
|
|
}
|
|
|
|
WriteElementEnd(xtw);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入实体列表参数
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
/// <param name="n">数据</param>
|
|
private static void WriteParameterEntityList(System.Xml.XmlTextWriter xtw, ParameterStruct n)
|
|
{
|
|
WriteLinkAttribute(xtw, "");
|
|
IList list = (IList)n.Data;
|
|
if (list.Count > 0)
|
|
{
|
|
WriteEntityBegin(xtw);
|
|
|
|
if (list[0].GetType().IsValueType || list[0].GetType() == typeof(string))
|
|
{
|
|
//写元素
|
|
foreach (var m in list)
|
|
{
|
|
WriteEntityAttributeBegin(xtw);
|
|
|
|
WriteValueAttribute(xtw, m.ToString());
|
|
|
|
WriteElementEnd(xtw);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PropertyInfo[] publicProperties =Common.AssemblyUtil.EntityFactory.GetProperties(list[0]);
|
|
|
|
//写元素
|
|
foreach (var m in list)
|
|
{
|
|
publicProperties = Common.AssemblyUtil.EntityFactory.GetProperties(m);
|
|
|
|
WriteEntityAttributeBegin(xtw);
|
|
|
|
WriteEntityAttribute(xtw, publicProperties, m);
|
|
|
|
WriteElementEnd(xtw);
|
|
}
|
|
}
|
|
|
|
WriteElementEnd(xtw);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入二进制参数
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
/// <param name="n">数据</param>
|
|
/// <param name="i">附件索引</param>
|
|
/// <param name="extData">扩展数据流</param>
|
|
private static void WriteParameterBinary(System.Xml.XmlTextWriter xtw, ParameterStruct n, ref int i, ref Dictionary<int, byte[]> extData)
|
|
{
|
|
WriteLinkAttribute(xtw, i.ToString());
|
|
WriteValueAttribute(xtw, "");
|
|
|
|
extData.Add(i, n.Data as byte[]);
|
|
|
|
i++;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写入参数及返回信息
|
|
/// </summary>
|
|
/// <param name="xtw">XML写入器</param>
|
|
/// <param name="n">数据</param>
|
|
/// <param name="ds">附件</param>
|
|
/// <param name="i">附件索引</param>
|
|
/// <param name="extData">扩展数据流</param>
|
|
private static void WriteParameters(System.Xml.XmlTextWriter xtw, ParameterStruct n, DataSet ds, ref int i, ref Dictionary<int, byte[]> extData)
|
|
{
|
|
if (n.Data == null)
|
|
{
|
|
throw new Common.Exceptions.ParameterCannotNullException();
|
|
}
|
|
if (n.Data is DataTable)
|
|
{
|
|
WriteParameterTypeAttribute(xtw, "DataTable");
|
|
WriteParameterDataTable(xtw, n, ds, ref i);
|
|
}
|
|
else if (n.Data is string[])
|
|
{
|
|
WriteParameterTypeAttribute(xtw, "Array");
|
|
WriteParameterArray(xtw, n);
|
|
}
|
|
else if (n.Data is byte[])
|
|
{
|
|
WriteParameterTypeAttribute(xtw, "Binary");
|
|
WriteParameterBinary(xtw, n, ref i, ref extData);
|
|
}
|
|
else if (n.Data is IList)
|
|
{
|
|
WriteParameterTypeAttribute(xtw, "IList");
|
|
WriteParameterEntityList(xtw, n);
|
|
}
|
|
else if (n.Data.GetType().IsValueType)
|
|
{
|
|
WriteParameterTypeAttribute(xtw, n.Data.GetType().Name);
|
|
WriteLinkAttribute(xtw, "");
|
|
WriteValueAttribute(xtw, n.Data.ToString());
|
|
}
|
|
else if (n.Data is string)
|
|
{
|
|
WriteParameterTypeAttribute(xtw, "String");
|
|
WriteLinkAttribute(xtw, "");
|
|
WriteValueAttribute(xtw, n.Data.ToString());
|
|
}
|
|
else
|
|
{
|
|
WriteParameterTypeAttribute(xtw, "Entity");
|
|
WriteLinkAttribute(xtw, "");
|
|
WriteParameterEntity(xtw, n);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 由网络数据结构转换到内存流
|
|
/// </summary>
|
|
/// <param name="data">服务请求或响应的数据</param>
|
|
/// <returns>返回转换后的内存流</returns>
|
|
internal static MemoryStream ConvertToStream(NetServiceStruct data)
|
|
{
|
|
MemoryStream ms = new MemoryStream();
|
|
|
|
//附件
|
|
using (DataSet ds = new DataSet())
|
|
{
|
|
Dictionary<int, byte[]> extData = new Dictionary<int, byte[]>();
|
|
|
|
//主数据部分
|
|
using (MemoryStream tmpStream = new MemoryStream())
|
|
{
|
|
System.Xml.XmlTextWriter xtw = new System.Xml.XmlTextWriter(tmpStream, Common.TextUtil.EncodingHelper.GB2312);
|
|
xtw.WriteStartDocument();
|
|
|
|
WriteNetDataBegin(xtw);
|
|
WriteFirmwareModelAttribute(xtw, data.FirmwareModel);
|
|
WriteFirmwareVersionAttribute(xtw, data.FirmwareVersion);
|
|
WriteUserNameAttribute(xtw, data.UserName);
|
|
|
|
WriteServiceDefineBegin(xtw);
|
|
WriteServiceNameAttribute(xtw, data.ServiceName);
|
|
WriteExceptionAttribute(xtw, data.ExceptionType.GetHashCode().ToString());
|
|
WriteSyncTypeAttribute(xtw, data.SyncType.GetHashCode().ToString());
|
|
WriteServiceSNAttribute(xtw, "");
|
|
|
|
int i = 0;
|
|
|
|
//参数部分
|
|
foreach (var n in data.Params)
|
|
{
|
|
WriteParameterDefineBegin(xtw);
|
|
WriteParameterNameAttribute(xtw, n.Key);
|
|
|
|
WriteParameters(xtw, n.Value, ds, ref i, ref extData);
|
|
|
|
WriteElementEnd(xtw);
|
|
}
|
|
|
|
//返回值部分
|
|
if (data.Returns != null)
|
|
{
|
|
foreach (var n in data.Returns)
|
|
{
|
|
WriteReturnDefineBegin(xtw);
|
|
WriteParameterNameAttribute(xtw, n.Key);
|
|
|
|
WriteParameters(xtw, n.Value, ds, ref i, ref extData);
|
|
|
|
WriteElementEnd(xtw);
|
|
}
|
|
}
|
|
|
|
WriteElementEnd(xtw);
|
|
WriteElementEnd(xtw);
|
|
|
|
xtw.WriteEndDocument();
|
|
|
|
xtw.Flush();
|
|
|
|
ms.Write(BitConverter.GetBytes((int)tmpStream.Length), 0, 4);
|
|
ms.Write(tmpStream.ToArray(), 0, (int)tmpStream.Length);
|
|
}
|
|
|
|
//写附件
|
|
if (ds.Tables.Count > 0)
|
|
{
|
|
using (MemoryStream tmpStream = DataSetToMemoryStream(ds))
|
|
{
|
|
ms.Write(BitConverter.GetBytes(0), 0, 4);//DataTable数据类型标识
|
|
ms.Write(BitConverter.GetBytes((int)tmpStream.Length), 0, 4);
|
|
ms.Write(tmpStream.ToArray(), 0, (int)tmpStream.Length);
|
|
}
|
|
}
|
|
|
|
//写二进制附件
|
|
foreach (var d in extData)
|
|
{
|
|
ms.Write(BitConverter.GetBytes(1), 0, 4);//二进制数据类型标识
|
|
ms.Write(BitConverter.GetBytes(d.Key), 0, 4);
|
|
ms.Write(BitConverter.GetBytes(d.Value.Length), 0, 4);
|
|
ms.Write(d.Value, 0, d.Value.Length);
|
|
}
|
|
}
|
|
|
|
return ms;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 将数据表集合转换为内存流
|
|
/// </summary>
|
|
/// <param name="dataSet">数据表集合</param>
|
|
/// <returns>返回转换后的内存流</returns>
|
|
internal static MemoryStream DataSetToMemoryStream(DataSet dataSet)
|
|
{
|
|
//创建内存流
|
|
MemoryStream ms = new MemoryStream();
|
|
|
|
//将数据以xml方式写入流
|
|
dataSet.WriteXml(ms, XmlWriteMode.WriteSchema);
|
|
|
|
//返回字节数组
|
|
return ms;
|
|
}
|
|
}
|
|
}
|
|
|