Пример #1
0
 /// <summary>
 /// 按照数据规范输出数据
 /// </summary>
 /// <param name="context">当前字节序列上下文</param>
 /// <param name="writer">二进制写入器</param>
 /// <param name="respDict">输出数据词典</param>
 /// <param name="contracts">当前协议规范</param>
 public static void WriteByContract(StreamContext context, BinaryWriter writer, Dictionary <string, object> respDict, DataContract contracts)
 {
     context.ContextObjectDictionary = respDict;
     foreach (DataItem item in contracts.TransItems)
     {
         #region 判断是否写入当前项
         if (!string.IsNullOrEmpty(item.ConditionalExpression))
         {
             if (!new SpecExpression(item.ConditionalExpression).IsPass(context))
             {
                 continue;
             }
         }
         #endregion
         SpecDataType dType   = SpecDataType.Parse(context, item.DataType);
         Type         clrType = dType.GetRuntimeType();
         if (clrType == null)
         {
             throw new SpecDataDefineException(string.Format("数据类型{0}不能识别!", item.DataType));
         }
         else
         {
             WriteKnownTypeObject(context, writer, dType, respDict[item.DataName], item.NetworkBytes);
         }
         //设置最近一个解析项
         context._lastDataItem = item;
     }
 }
Пример #2
0
        /// <summary>
        /// 按照数据规范读取数据为数据词典
        /// </summary>
        /// <param name="context">当前字节序列上下文</param>
        /// <param name="reader">二进制读取器</param>
        /// <param name="contracts">协议规范</param>
        /// <returns></returns>
        public static Dictionary <string, object> ReadByContract(StreamContext context, BinaryReader reader, DataContract contracts)
        {
            Dictionary <string, object> reqDict = new Dictionary <string, object>(StringComparer.InvariantCultureIgnoreCase);

            context.ContextObjectDictionary = reqDict;
            foreach (DataItem item in contracts.TransItems)
            {
                #region 判断是否读取当前项
                if (!string.IsNullOrEmpty(item.ConditionalExpression))
                {
                    if (!new SpecExpression(item.ConditionalExpression).IsPass(context))
                    {
                        continue;
                    }
                }
                #endregion
                SpecDataType dType   = SpecDataType.Parse(context, item.DataType);
                Type         clrType = dType.GetRuntimeType();
                if (clrType == null)
                {
                    throw new SpecDataDefineException(string.Format("数据类型{0}不能识别!", item.DataType));
                }
                else
                {
                    reqDict[item.DataName] = ReadKnownTypeObject(context, reader, dType);
                }

                //设置最近一个解析项
                context._lastDataItem = item;
            }
            return(reqDict);
        }
Пример #3
0
        /// <summary>
        /// 在当前上下文中写入已知类型数据,并移动上下文写入游标索引。
        /// </summary>
        /// <param name="context">当前字节序列上下文</param>
        /// <param name="writer">二进制写入器</param>
        /// <param name="dType">规范数据定义</param>
        /// <param name="objData">写入对象实例</param>
        /// <param name="isNetworkBytes">是否写入网络序</param>
        public static void WriteKnownTypeObject(StreamContext context, BinaryWriter writer, SpecDataType dType, object objData, bool isNetworkBytes)
        {
            Type clrType = dType.GetRuntimeType();

            if (dType.Prototype == SpecDataPrototype.Native)
            {
                context.IncreasePosition(SpecData.CLRObjectWrite(clrType, writer, objData, isNetworkBytes));
            }
            else
            {
                if (dType.Prototype == SpecDataPrototype.Array)
                {
                    Type  elementType = dType.GetElementType();
                    Array arrObj      = (Array)objData;
                    if (SpecDataType.IsNativeType(TypeCache.ToSimpleType(elementType)))
                    {
                        #region 写入基础数据类型数组
                        for (int i = 0, j = dType.ElementLength; i < j; i++)
                        {
                            context.IncreasePosition(SpecData.CLRObjectWrite(elementType, writer, arrObj.GetValue(i), isNetworkBytes));
                        }
                        #endregion
                    }
                    else
                    {
                        for (int m = 0, n = dType.ElementLength; m < n; m++)
                        {
                            WriteKnownTypeObject(context, writer, dType.GetElementDataType(), arrObj.GetValue(m), isNetworkBytes);
                        }
                    }
                }
                else
                {
                    #region 扩展写入
                    if (clrType.Equals(typeof(EnumContract)))
                    {
                        EnumContract enc = (EnumContract)dType.GetDefineInstance();
                        clrType = enc.GetBaseRuntimeType();
                        if (!objData.GetType().Equals(clrType))
                        {
                            objData = enc.GetEnumUnderlyingValue(objData.ToString());
                        }
                        context.IncreasePosition(SpecData.CLRObjectWrite(clrType, writer, objData, isNetworkBytes));
                    }
                    else if (clrType.Equals(typeof(DataContract)))
                    {
                        DataContract dac = (DataContract)dType.GetDefineInstance();
                        WriteByContract(context, writer, (Dictionary <string, object>)objData, dac);
                    }
                    else
                    {
                        throw new SpecDataDefineException(string.Format("不能读取数据类型{0}!", clrType.FullName));
                    }
                    #endregion
                }
            }
        }
Пример #4
0
        /// <summary>
        /// 解析数据类型
        /// </summary>
        /// <param name="context">当前解析上下文</param>
        /// <param name="rawTypeDefine">原始定义字符串</param>
        /// <returns></returns>
        public static SpecDataType Parse(StreamContext context, string rawTypeDefine)
        {
            SpecDataType sType = new SpecDataType();

            sType.TypeName = rawTypeDefine;

            int idx = -1, idx2 = -1;

            idx  = rawTypeDefine.IndexOf('[');
            idx2 = rawTypeDefine.IndexOf(']');
            if (idx != -1 && idx2 != -1)
            {
                if (idx2 - idx == 1)
                {
                    throw new SpecDataDefineException("数组类型定义[" + rawTypeDefine + "]错误,[]必须包含数据项长度或使用上下文计算的-1!");
                }

                sType.Prototype = SpecDataPrototype.Array;

                string       strTemp = rawTypeDefine.Substring(0, idx);
                SpecDataType esType  = Parse(context, strTemp);
                sType._elementType    = esType.GetRuntimeType();
                sType.eleSpecDataType = esType;

                strTemp = rawTypeDefine.Substring(idx + 1, idx2 - idx - 1).Trim();
                if (strTemp == "-1")
                {
                    DataItem?item = context.GetLastDataItem();
                    if (!item.HasValue)
                    {
                        throw new SpecDataDefineException("数组类型定义[-1]在上下文中没有前置传输定义项!");
                    }
                    else
                    {
                        sType.ElementLength = Convert.ToInt32(context.ContextObjectDictionary[item.Value.DataName]);
                    }
                }
                else
                {
                    if (!context.ContextObjectDictionary.ContainsKey(strTemp))
                    {
                        throw new SpecDataDefineException("数组长度定义[" + strTemp + "]在上下文的没有找到长度定义!");
                    }
                    else
                    {
                        sType.ElementLength = Convert.ToInt32(context.ContextObjectDictionary[strTemp]);
                    }
                }
                sType.SetRuntimeType(sType._elementType.MakeArrayType());
            }
            else
            {
                #region 非数组定义
                if (IsNativeType(rawTypeDefine))
                {
                    sType.Prototype = SpecDataPrototype.Native;
                    sType.SetRuntimeType(TypeCache.GetRuntimeType(rawTypeDefine));
                }
                else
                {
                    SpecFile     specDef = context.ContractSpec;
                    EnumContract enc     = TypeCache.FirstOrDefault <EnumContract>(specDef.AllDefinition, d => d.TypeName.Equals(rawTypeDefine));
                    if (enc != null)
                    {
                        sType.Prototype = SpecDataPrototype.Enum;
                        sType.SetRuntimeType(typeof(EnumContract));
                        sType.typeDefineInstance = enc;
                    }
                    else
                    {
                        DataContract dac = TypeCache.FirstOrDefault <DataContract>(specDef.AllImportContracts, c => c.ContractName.Equals(rawTypeDefine));
                        if (dac == null)
                        {
                            throw new SpecDataDefineException("类型定义" + rawTypeDefine + "不能识别!");
                        }
                        sType.Prototype = SpecDataPrototype.Composite;
                        sType.SetRuntimeType(typeof(DataContract));
                        sType.typeDefineInstance = dac;
                    }
                }
                #endregion
            }
            return(sType);
        }
Пример #5
0
        /// <summary>
        /// 在当前上下文中读取已知类型读取数据,并移动上下文读取游标索引。
        /// </summary>
        /// <param name="context">当前字节序列上下文</param>
        /// <param name="reader">二进制读取器</param>
        /// <param name="dType">规范数据定义</param>
        /// <returns></returns>
        public static object ReadKnownTypeObject(StreamContext context, BinaryReader reader, SpecDataType dType)
        {
            object itemObj = null;

            Type clrType = dType.GetRuntimeType();

            if (dType.Prototype == SpecDataPrototype.Native)
            {
                itemObj = SpecData.CLRObjectFromReader(clrType, reader);
                context.IncreasePosition(SpecData.GetCLRTypeByteLength(clrType));
            }
            else
            {
                if (dType.Prototype == SpecDataPrototype.Array)
                {
                    Type  elementType = dType.GetElementType();
                    Array arrObj      = Array.CreateInstance(elementType, dType.ElementLength);
                    if (SpecDataType.IsNativeType(TypeCache.ToSimpleType(elementType)))
                    {
                        #region 读取基础数据类型数组
                        long unitLen = SpecData.GetCLRTypeByteLength(elementType);
                        for (int i = 0, j = dType.ElementLength; i < j; i++)
                        {
                            arrObj.SetValue(SpecData.CLRObjectFromReader(elementType, reader), i);
                            context.IncreasePosition(unitLen);
                        }
                        #endregion
                    }
                    else
                    {
                        for (int m = 0, n = dType.ElementLength; m < n; m++)
                        {
                            arrObj.SetValue(ReadKnownTypeObject(context, reader, dType.GetElementDataType()), m);
                        }
                    }
                    itemObj = arrObj;
                }
                else
                {
                    #region 扩展读取
                    if (clrType.Equals(typeof(EnumContract)))
                    {
                        EnumContract enc = (EnumContract)dType.GetDefineInstance();
                        clrType = enc.GetBaseRuntimeType();
                        itemObj = SpecData.CLRObjectFromReader(clrType, reader);
                        context.IncreasePosition(SpecData.GetCLRTypeByteLength(clrType));
                    }
                    else if (clrType.Equals(typeof(DataContract)))
                    {
                        DataContract dac = (DataContract)dType.GetDefineInstance();
                        itemObj = ReadByContract(context, reader, dac);
                    }
                    else
                    {
                        throw new SpecDataDefineException(string.Format("不能读取数据类型{0}!", clrType.FullName));
                    }
                    #endregion
                }
            }

            return(itemObj);
        }