Пример #1
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);
        }
Пример #2
0
        /// <summary>
        /// 导入并合并现有的契约规范定义
        /// </summary>
        /// <param name="srcSpecFile">原始请求规范文件定义</param>
        /// <param name="specDef">规范文件路径或名称,相对路径。</param>
        public static void ImportSpecFile(SpecFile srcSpecFile, string specDef)
        {
            if (!specDef.EndsWith(".spec"))
            {
                specDef += ".spec";
            }

            string   impnewFile = Path.Combine(Path.GetDirectoryName(srcSpecFile.FileUrl), specDef);
            SpecFile newSpec    = ParseContractFile(impnewFile, SpecFileFormat.Ini);

            srcSpecFile.MerginWithSpecFile(newSpec);
        }
Пример #3
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);
            }
        }
Пример #4
0
        /// <summary>
        /// [ST:DEBUG]读取配置项词典为数据契约定义
        /// </summary>
        /// <param name="srcSpecFile">原始请求规范文件定义</param>
        /// <param name="contractName">数据契约名称</param>
        /// <param name="itemDict">配置项词典</param>
        /// <param name="cmtHandler">获取项描述的委托</param>
        /// <param name="importHandler">导入(import)规范委托</param>
        /// <returns></returns>
        static DataContract ReadAsContract(SpecFile srcSpecFile, string contractName, Dictionary <string, string> itemDict, DataItemCommentFetchHanlder cmtHandler, ImportSpecFileHandler importHandler)
        {
            DataContract contract = new DataContract();

            contract.ContractName = contractName;

            List <DataItem> itemList = new List <DataItem>();

            foreach (string key in itemDict.Keys)
            {
                if (key.StartsWith("!"))
                {
                    if (key.Equals("!Compatibility", StringComparison.InvariantCultureIgnoreCase))
                    {
                        contract.Compatibility = itemDict[key];
                    }
                    else if (key.Equals("!Compatibility-Reference", StringComparison.InvariantCultureIgnoreCase))
                    {
                        contract.Compatibility_Reference = itemDict[key];
                    }
                    else if (key.Equals("!Import", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (importHandler != null)
                        {
                            string[] defArr = itemDict[key].Trim().Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
                            foreach (string impItem in defArr)
                            {
                                importHandler(srcSpecFile, impItem);
                            }
                        }
                    }
                    else if (key.Equals("!base", StringComparison.InvariantCultureIgnoreCase))
                    {
                        DataContract absDC = srcSpecFile[itemDict[key]];
                        if (absDC != null && absDC.TransItems != null)
                        {
                            itemList.AddRange(absDC.TransItems);
                        }
                    }
                    continue;
                }

                DataItem item = new DataItem();
                item.DataName     = key;
                item.NetworkBytes = true;

                #region 设置数据类型和条件传输表达式
                string itemDefine = itemDict[key];
                int    idx        = itemDefine.IndexOf('{');
                if (idx == -1)
                {
                    item.DataType = itemDefine.Trim();
                }
                else
                {
                    item.DataType = itemDefine.Substring(0, idx).Trim();
                    item.ConditionalExpression = itemDefine.Substring(idx).Trim();
                }
                #endregion

                item.Description = cmtHandler(contractName, key);
                itemList.Add(item);
            }

            contract.ConfigItemCount = itemList.Count;
            contract.TransItems      = itemList.ToArray();

            return(contract);
        }
Пример #5
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);
        }
Пример #6
0
 /// <summary>
 /// 初始化一个 <see cref="StreamContext"/> class 实例。
 /// </summary>
 /// <param name="spec">当前协议规范定义实例</param>
 /// <param name="exchangeStream">协议交互共享的字节序列</param>
 public StreamContext(SpecFile spec, Stream exchangeStream)
     : this(spec, exchangeStream, exchangeStream)
 {
 }
Пример #7
0
 /// <summary>
 /// 初始化一个 <see cref="StreamContext"/> class 实例。
 /// </summary>
 /// <param name="spec">当前协议规范定义实例</param>
 /// <param name="readStream">读取字节序列</param>
 /// <param name="writeStream">写入字节序列</param>
 public StreamContext(SpecFile spec, Stream readStream, Stream writeStream)
 {
     ContractSpec = spec;
     _reader      = new BinaryReader(readStream);
     _writer      = new BinaryWriter(writeStream);
 }