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

306 lines
11 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data;
using Common.Exceptions;
using Common.Data;
namespace NSC
{
/// <summary>
/// 功能:网络报文解码器
/// 作者:王昊昇
/// 时间:2012.11.8
/// </summary>
internal static class PacketsDecoder
{
/// <summary>
/// 解析网络数据流
/// </summary>
/// <param name="ms">来自网络的数据流</param>
/// <returns>返回通用服务数据结构体</returns>
internal static NetServiceStruct ParseNetStream(MemoryStream ms)
{
if (ms == null)
{
return null;
}
byte[] lengthBuffer = null;//长度缓存
int length = 0;//长度
byte[] priBuffer = null;//主体部分缓存
DataSet slvDataSet = null;//附件部分数据表
byte[] slvTmpBuffer = null;
Dictionary<int, byte[]> extData = new Dictionary<int, byte[]>();//二进制附件列表
ms.Position = 0;
try
{
lengthBuffer = new byte[4];
ms.Read(lengthBuffer, 0, 4);
length = BitConverter.ToInt32(lengthBuffer, 0);//主体部分长度
priBuffer = new byte[length];
ms.Read(priBuffer, 0, length);//读取主体部分
while (ms.Position < ms.Length)
{
lengthBuffer = new byte[4];
ms.Read(lengthBuffer, 0, 4);
length = BitConverter.ToInt32(lengthBuffer, 0);//附件部分数据类型
switch (length)
{
case 0://DataTable
lengthBuffer = new byte[4];
ms.Read(lengthBuffer, 0, 4);
length = BitConverter.ToInt32(lengthBuffer, 0);//附件数据表部分长度
slvTmpBuffer = new byte[length];
ms.Read(slvTmpBuffer, 0, length);//读取附件数据表部分
slvDataSet = ByteArrayToDataSet(slvTmpBuffer);
break;
case 1://Binary
lengthBuffer = new byte[4];
ms.Read(lengthBuffer, 0, 4);
int index = BitConverter.ToInt32(lengthBuffer, 0);//二进制附件编号
lengthBuffer = new byte[4];
ms.Read(lengthBuffer, 0, 4);
length = BitConverter.ToInt32(lengthBuffer, 0);//二进制附件长度
byte[] extTmp = new byte[length];
ms.Read(extTmp, 0, length);//读取二进制附件
extData.Add(index, extTmp);
break;
}
}
//解析主体部分
NetServiceStruct list = null;
using (MemoryStream priPart = new MemoryStream(priBuffer.Length))
{
priPart.Write(priBuffer, 0, priBuffer.Length);
list = ParseStreamData(priPart, slvDataSet, extData);
}
return list;
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (slvDataSet != null)
{
slvDataSet.Dispose();
}
}
}
/// <summary>
/// 解析流数据
/// </summary>
/// <param name="priPart">主体数据流</param>
/// <returns>返回通用服务数据结构体</returns>
private static NetServiceStruct ParseStreamData(MemoryStream priPart, DataSet slvDataSet, Dictionary<int, byte[]> extData)
{
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
try
{
doc.LoadXml(Encoding.GetEncoding("gb2312").GetString(priPart.ToArray(), 0, (int)priPart.Length));
return ParseXML(doc, slvDataSet, extData);
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 解码XML内容
/// </summary>
/// <param name="doc">XML对象</param>
/// <param name="slvDataSet">附件</param>
/// <returns>返回通用服务数据结构体</returns>
private static NetServiceStruct ParseXML(System.Xml.XmlDocument doc, DataSet slvDataSet, Dictionary<int, byte[]> extData)
{
NetServiceStruct nss = new NetServiceStruct();
System.Xml.XmlNode pNode = doc.SelectSingleNode("NetworkStreamData");
nss.FirmwareModel = Common.IO.XML.XMLUtil.GetAttribute(pNode, "FirmwareModel");
nss.FirmwareVersion = Common.IO.XML.XMLUtil.GetAttribute(pNode, "FirmwareVersion");
nss.UserName = Common.IO.XML.XMLUtil.GetAttribute(pNode, "UserName");
pNode = pNode.SelectSingleNode("ServiceDefine");
nss.ServiceName = Common.IO.XML.XMLUtil.GetAttribute(pNode, "ServiceName");
nss.ExceptionType = (ExceptionType)Enum.Parse(typeof(ExceptionType), Common.IO.XML.XMLUtil.GetAttribute(pNode, "Exception"), true);
nss.SyncType = (SyncType)Enum.Parse(typeof(SyncType), Common.IO.XML.XMLUtil.GetAttribute(pNode, "SyncType"), true);
nss.ServiceSN = Common.IO.XML.XMLUtil.GetAttribute(pNode, "ServiceSN");
nss.Params = new Dictionary<string, ParameterStruct>();
System.Xml.XmlNodeList args = pNode.SelectNodes("Param");
foreach (System.Xml.XmlNode a in args)
{
ParameterStruct ps = new ParameterStruct();
ps.DataFormat = Common.IO.XML.XMLUtil.GetAttribute(a, "Type");
ps.Link = Common.IO.XML.XMLUtil.GetAttribute(a, "Link");
if (ps.DataFormat == "IList" || ps.DataFormat == "Entity")
{
ps.Data = a;
}
else if (ps.DataFormat == "DataTable")
{
ps.Data = slvDataSet.Tables[ps.Link].Copy();
}
else if (ps.DataFormat == "Array")
{
ps.Data = ParseArray(a.SelectSingleNode("Items"));
}
else if (ps.DataFormat == "Binary")
{
ps.Data = extData[int.Parse(ps.Link)];
}
else
{
ps.SetData(Common.IO.XML.XMLUtil.GetAttribute(a, "Value"));
}
nss.Params.Add(Common.IO.XML.XMLUtil.GetAttribute(a, "Name"), ps);
}
System.Xml.XmlNodeList rets = pNode.SelectNodes("Return");
if (rets.Count > 0)
{
nss.Returns = new Dictionary<string, ParameterStruct>();
}
foreach (System.Xml.XmlNode r in rets)
{
ParameterStruct ps = new ParameterStruct();
ps.DataFormat = Common.IO.XML.XMLUtil.GetAttribute(r, "Type");
ps.Link = Common.IO.XML.XMLUtil.GetAttribute(r, "Link");
if (ps.DataFormat == "IList" || ps.DataFormat == "Entity")
{
ps.Data = r;
}
else if (ps.DataFormat == "DataTable")
{
ps.Data = slvDataSet.Tables[ps.Link].Copy();
}
else if (ps.DataFormat == "Array")
{
ps.Data = ParseArray(r.SelectSingleNode("Items"));
}
else if (ps.DataFormat == "Binary")
{
ps.Data = extData[int.Parse(ps.Link)];
}
else
{
ps.SetData(Common.IO.XML.XMLUtil.GetAttribute(r, "Value"));
}
nss.Returns.Add(Common.IO.XML.XMLUtil.GetAttribute(r, "Name"), ps);
}
return nss;
}
/// <summary>
/// 解码字符串数组
/// </summary>
/// <param name="node">XML节点</param>
/// <returns>返回字符串数组</returns>
private static string[] ParseArray(System.Xml.XmlNode node)
{
string[] array = new string[node.ChildNodes.Count];
for (int i = 0; i < node.ChildNodes.Count; i++)
{
array[i] = Common.IO.XML.XMLUtil.GetAttribute(node.ChildNodes[i], "Value");
}
return array;
}
/// <summary>
/// 解码数据流,可指定读取位置。只支持数据长度和数据链接在一起的数据
/// </summary>
/// <param name="ms">数据流</param>
/// <param name="position">读取位置</param>
/// <returns>返回流中的数据部分</returns>
private static byte[] ParseStream(MemoryStream ms, int position)
{
byte[] tmp = new byte[4];
ms.Read(tmp, position, tmp.Length);
int streamLength = BitConverter.ToInt32(tmp, 0);
if (streamLength > 0)
{
tmp = new byte[streamLength];
ms.Read(tmp, position + 4, tmp.Length);
return tmp;
}
else
{
return null;
}
}
/// <summary>
/// 解码数据流。只支持数据长度和数据链接在一起的数据
/// </summary>
/// <param name="ms">数据流</param>
/// <returns>返回流中的数据部分</returns>
private static byte[] ParseStream(MemoryStream ms)
{
byte[] tmp = new byte[4];
ms.Read(tmp, (int)ms.Position, tmp.Length);
int streamLength = BitConverter.ToInt32(tmp, 0);
if (streamLength > 0)
{
tmp = new byte[streamLength];
ms.Read(tmp, (int)ms.Position, tmp.Length);
return tmp;
}
else
{
return null;
}
}
/// <summary>
/// 将字节数组转换为数据表集合
/// </summary>
/// <param name="data">字节数组</param>
/// <returns>数据表集合</returns>
internal static DataSet ByteArrayToDataSet(byte[] data)
{
using (MemoryStream ms = new MemoryStream())
{
ms.Write(data, 0, data.Length);
ms.Position = 0;
System.Xml.XmlTextWriter xtw = new System.Xml.XmlTextWriter(ms, Encoding.GetEncoding("gb2312"));
xtw.WriteStartDocument();
//创建xml读取器
System.Xml.XmlTextReader xtr = new System.Xml.XmlTextReader(ms);
//创建数据集合
DataSet ds = new DataSet();
//将xml数据读入数据集合
ds.ReadXml(xtr, XmlReadMode.ReadSchema);
//返回数据集合
return ds;
}
}
}
}