Ejemplo n.º 1
0
        public void ParseTest()
        {
            EnumContract ec = EnumContract.Parse("StatusCode", "服务器响应码(short 3.2-2.6.9)",
                                                 "short=>{Exception:-1/*服务器异常*/, Success:0/*服务器处理成功*/, Updatable:1/*主程序有更新 请按照客户端更新策略下载*/}");

            Console.WriteLine(ec.Definition.Length);
        }
Ejemplo n.º 2
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
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 加载并解析协议定义文件[TODO]
        /// </summary>
        /// <param name="specUrl">协议定义文件地址</param>
        /// <returns></returns>
        public static SpecFile ParseContractFile(string specUrl, SpecFileFormat format)
        {
            if (format != SpecFileFormat.Ini)
            {
                throw new NotSupportedException();
            }

            List <EnumContract> defList    = new List <EnumContract>();
            List <DataContract> impList    = new List <DataContract>();
            SpecFile            fileDefine = new SpecFile();

            using (IniFile ini = new IniFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, specUrl)))
            {
                fileDefine.FileUrl  = ini.Path;
                fileDefine.FileName = Path.GetFileName(ini.Path);

                string[] allSecNames = ini.GetSectionNames();

                Dictionary <string, string> secDict = new Dictionary <string, string>();
                foreach (string secName in allSecNames)
                {
                    #region 对定义区间解析
                    if (secName.Equals("define", StringComparison.InvariantCultureIgnoreCase))
                    {
                        secDict = ini.GetSectionValues(secName);
                        string itemComment = string.Empty;
                        #region 读取枚举定义(define)
                        foreach (var k in secDict.Keys)
                        {
                            itemComment = ini.GetComment(secName, k);
                            defList.Add(EnumContract.Parse(k, itemComment, secDict[k]));
                        }
                        #endregion
                    }
                    else if (secName.Equals("RequestContract", StringComparison.InvariantCultureIgnoreCase))
                    {
                        fileDefine.RequestContract = ReadAsContract(fileDefine, secName, ini.GetSectionValues(secName), (s, k) => ini.GetComment(s, k), ImportSpecFile);
                    }
                    else if (secName.Equals("ResponseContract", StringComparison.InvariantCultureIgnoreCase))
                    {
                        fileDefine.ResponseContract = ReadAsContract(fileDefine, secName, ini.GetSectionValues(secName), (s, k) => ini.GetComment(s, k), ImportSpecFile);
                    }
                    else
                    {
                        #region 读取规范导入(import)
                        impList.Add(ReadAsContract(fileDefine, secName, ini.GetSectionValues(secName), (s, k) => ini.GetComment(s, k), ImportSpecFile));
                        #endregion
                    }
                    #endregion
                }
            }

            fileDefine.MerginDefineWith(defList);
            fileDefine.MerginImportWith(impList);
            return(fileDefine);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 解析为枚举项数据
        /// </summary>
        /// <param name="name">枚举定义名称</param>
        /// <param name="description">枚举定义描述</param>
        /// <param name="defRaw">原始定义字符串</param>
        /// <returns></returns>
        public static EnumContract Parse(string name, string description, string defRaw)
        {
            EnumContract enc = new EnumContract();

            //EaseSuccessFlag = short=>{Error:-1, UnKnown:0, Success:1010, SuccessUserAgent:1020, SuccessExpress:1120}
            //#服务器响应码(short 3.2-2.6.9)
            //StatusCode=short=>{Exception:-1/*服务器异常*/, Success:0/*服务器处理成功*/, Updatable:1/*主程序有更新,请按照客户端更新策略下载*/}

            enc.TypeName    = name;
            enc.Description = description;
            int idx = defRaw.IndexOf("=>");

            if (idx == -1)
            {
                throw new SpecDataDefineException("没有找到枚举数据类型定义的分隔标识符号:'=>'!");
            }
            enc.BaseType = defRaw.Substring(0, idx).Trim();
            string itemDefExp = defRaw.Substring(idx + 2).Trim().Trim('{', '}');

            #region 最简定义解析
            string[] itemArr = itemDefExp.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            string   key = null, value = null;
            foreach (string item in itemArr)
            {
                idx = item.IndexOf(':');
                if (idx == -1)
                {
                    continue;
                }
                else
                {
                    key   = item.Substring(0, idx).Trim();
                    value = item.Substring(idx + 1);

                    //检查是否包含注释
                    idx = value.IndexOf('/');
                    if (idx == -1)
                    {
                        enc.SetEnumItem(key, value);
                    }
                    else
                    {
                        enc[key] = new DataItem
                        {
                            DataName    = key,
                            ItemValue   = value.Substring(0, idx).Trim(),
                            Description = value.Substring(idx).Trim('/', '*')
                        };
                    }
                }
            }
            #endregion

            #region 灵活定义解析
            //using (StringParseHelper dep = new StringParseHelper(itemDefExp))
            //{
            //    //{Exception:-1/*服务器异常*/, Success:0/*服务器处理成功*/, Updatable:1/*主程序有更新,请按照客户端更新策略下载*/}
            //    /*
            //     * when found : => getBufferAsKey -> readToChar([',','}']) -> getBufferAsValue
            //     * when found / => checkNextCharIs('*') -> readToChar(['*']) and peekNextChar == '/' as Key Comment
            //     *
            //     */
            //    dep.Parse();
            //}
            #endregion

            return(enc);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// 合并导入规范数据
        /// </summary>
        /// <param name="impSpec">规范数据文件实例</param>
        public void MerginWithSpecFile(SpecFile impSpec)
        {
            if (ImportSpecDict.ContainsKey(impSpec.FileUrl))
            {
                return;
            }
            else
            {
                int i = 0, j = 0;
                #region 导入枚举定义
                if (impSpec.AllDefinition != null && impSpec.AllDefinition.Length > 0)
                {
                    List <EnumContract> enumList = new List <EnumContract>();

                    EnumContract current = null;
                    for (i = 0, j = impSpec.AllDefinition.Length; i < j; i++)
                    {
                        current = impSpec.AllDefinition[i];
                        if (GetDefine(current.TypeName) != null)
                        {
                            continue;
                        }
                        else
                        {
                            enumList.Add(current);
                        }
                    }

                    #region 导入现有定义
                    if (AllDefinition != null)
                    {
                        enumList.AddRange(AllDefinition);
                    }
                    #endregion
                    AllDefinition = enumList.ToArray();
                }
                #endregion

                #region 导入数据契约定义
                if (impSpec.AllImportContracts != null && impSpec.AllImportContracts.Length > 0)
                {
                    List <DataContract> impList = new List <DataContract>();

                    DataContract crtContract = null;
                    for (i = 0, j = impSpec.AllImportContracts.Length; i < j; i++)
                    {
                        crtContract = impSpec.AllImportContracts[i];
                        if (this[crtContract.ContractName] != null)
                        {
                            continue;
                        }
                        else
                        {
                            impList.Add(crtContract);
                        }
                    }

                    #region 导入现有契约定义
                    if (AllImportContracts != null)
                    {
                        impList.AddRange(AllImportContracts);
                    }
                    #endregion

                    AllImportContracts = impList.ToArray();
                }
                #endregion
                ImportSpecDict.Add(impSpec.FileUrl, impSpec);
            }
        }
Ejemplo n.º 6
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);
        }
Ejemplo n.º 7
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);
        }