天津投入产出系统后端
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

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