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