/// <summary> /// 将文本行描述的变量定义,解析为管脚类型对象。 /// </summary> /// <param name="decl">管脚的文本行描述</param> /// <param name="typeCreation">自动创建管脚数据类型的方式</param> /// <param name="creator">ViConnType 的创建函数</param> /// <returns>管脚类型对象,null 表示解析失败</returns> public static ViConnType Parse(string decl, ViTypeCreation typeCreation, Func <string, ViDataType, ViConnType> creator) { string name = null, type = null, comment = null; string[] addiInfo = null; if (!SeperateNameType(decl.Trim(), ref name, ref type, ref addiInfo, ref comment)) { return(null); } ViDataType dataType = null; if (!string.IsNullOrEmpty(type)) { dataType = ViDataType.GetDataType(type, typeCreation); if (dataType == null) { return(null); } } ViConnType connType = creator(name, dataType); if (connType == null) { return(null); } // 备注 connType.Comment = comment; if (addiInfo != null) { // 特性 foreach (string info in addiInfo) { if (info.Equals("F_EDGE", StringComparison.OrdinalIgnoreCase)) { connType.Attributes |= ViConnAttributes.F_EDGE; } else if (info.Equals("R_EDGE", StringComparison.OrdinalIgnoreCase)) { connType.Attributes |= ViConnAttributes.R_EDGE; } } // 缺省值 if (addiInfo.Count() >= 2 && addiInfo[addiInfo.Count() - 2] == ":=") { connType.DefaultValue = addiInfo[addiInfo.Count() - 1]; } } return(connType); }
/// <summary> /// 获取 ExternalConnection 目标管脚名称。 /// </summary> public string GetTargetConnectorName() { return(ViConnType.RetrieveConnectorName(this.TargetPath)); }
/// <summary> /// 获取 ExternalConnection 的源管脚名称。 /// </summary> public string GetSourceConnectorName() { return(ViConnType.RetrieveConnectorName(this.SourcePath)); }
/// <summary> /// 获取 ExternalConnection 的目标功能块名称。 /// </summary> public string GetTargetBlockName() { return(ViConnType.RetrieveBlockName(this.TargetPath)); }
/// <summary> /// 获取 ExternalConnection 的源功能块名称。 /// </summary> public string GetSourceBlockName() { return(ViConnType.RetrieveBlockName(this.SourcePath)); }
/// <summary> /// 获取 ExternalConnection 目标管脚的 CPU 名称。 /// </summary> public string GetTargetResourceName() { return(ViConnType.RetrieveCpuName(this.TargetPath)); }
/// <summary> /// 获取 ExternalConnection 源管脚的 CPU 名称。 /// </summary> /// <returns></returns> public string GetSourceResourceName() { return(ViConnType.RetrieveCpuName(this.SourcePath)); }
/// <summary> /// 获取 ExternalConnection 目标管脚的 Program 名称。 /// </summary> public string GetTargetProgramName() { return(ViConnType.RetrievePlanName(this.TargetPath)); }
/// <summary> /// 获取 ExternalConnection 源管脚的 Program 名称。 /// </summary> public string GetSourceProgramName() { return(ViConnType.RetrievePlanName(this.SourcePath)); }
/// <summary> /// 更新功能块数组列表。 /// </summary> public override void UpdatePOUs() { this.DeleteAll(); try { ViFirmBlockType blockType = null; ViConnType connType = null; if (File.Exists(this.SourceFile)) { int stage = 0x00; // 0x00: 未开始 // 0x10: 开始 Proto Type // 0x20: 开始 Function Block // 0x3x: 开始 Function // 0x21: 开始 INPUT // 0x22: 开始 OUTPUT // 0x23: 开始 IN_OUT using (StreamReader reader = new StreamReader(this.SourceFile, Encoding.Default)) { int lineIndex = 0; while (true) { string line = reader.ReadLine(); if (line == null) { break; } ++lineIndex; line = line.Trim(); if (string.IsNullOrEmpty(line)) { continue; } // 注释? if (line.StartsWith(ViTextFile.CommentBegin)) { continue; } if (stage == 0x00) { if (line.StartsWith("GLOBAL_PROTOTYP_BEGIN", StringComparison.OrdinalIgnoreCase)) { stage = 0x10; } } else if (line.StartsWith("GLOBAL_PROTOTYP_END", StringComparison.OrdinalIgnoreCase)) { stage = 0x00; } else if (stage == 0x10) { if (line.StartsWith("FUNCTION_BLOCK ", StringComparison.OrdinalIgnoreCase)) { connType = ViConnType.Parse(line.Substring(15), ViTypeCreation.CreateGlobal); if (connType != null && connType.Type == null) { stage = 0x20; // blockType = new ViFirmBlockType(connType.Name, null); blockType.Comment = connType.Comment; } else { Trace.WriteLine(string.Format("{0}({1}): Invalid FUNCTION_BLOCK declaration!", this.SourceFile, lineIndex)); } } else if (line.StartsWith("FUNCTION ", StringComparison.OrdinalIgnoreCase)) { connType = ViConnType.Parse(line.Substring(9), ViTypeCreation.CreateGlobal); if (connType != null && connType.Type != null) { stage = 0x30; // blockType = new ViFirmBlockType(connType.Name, connType.Type); blockType.Comment = connType.Comment; } else { Trace.WriteLine(string.Format("{0}({1}): Invalid FUNCTION declaration!", this.SourceFile, lineIndex)); } } } else if (stage >= 0x20) { if (line.StartsWith("VAR_INPUT", StringComparison.OrdinalIgnoreCase)) { stage = (stage & 0xF0) | 0x01; } else if (line.StartsWith("VAR_OUTPUT", StringComparison.OrdinalIgnoreCase)) { stage = (stage & 0xF0) | 0x02; } else if (line.StartsWith("VAR_IN_OUT", StringComparison.OrdinalIgnoreCase)) { stage = (stage & 0xF0) | 0x03; } else if (line.StartsWith("END_VAR", StringComparison.OrdinalIgnoreCase)) { stage = (stage & 0xF0) | 0x00; } else if (line.StartsWith("END_FUNCTION", StringComparison.OrdinalIgnoreCase)) { if (blockType != null) { // 功能块后缀描述字符串 blockType.SetSuffixDecl(line); if (ChildByName(blockType.Name) == null) { this.AddChild(blockType); //Trace.WriteLine("Block Type: \n" + blockType.ToString()); } else { Trace.WriteLine(string.Format("{0}({1}): Duplicate POU name [{2}]!", this.SourceFile, lineIndex, blockType.Name)); } } stage = 0x10; } else if ((stage & 0x0F) != 0x00) { connType = ViConnType.Parse(line, ViTypeCreation.CreateGlobal); if (connType != null && connType.Type != null) { switch ((stage & 0x0F)) { case 0x01: // INPUT connType.SetParent(blockType); blockType.InputConnectors.Add(connType); break; case 0x02: // OUTPUT connType.SetParent(blockType); blockType.OutputConnectors.Add(connType); break; case 0x03: // IN_OUT connType.SetParent(blockType); blockType.InputConnectors.Insert(blockType.InOutConnectorCount, connType); blockType.OutputConnectors.Insert(blockType.InOutConnectorCount, connType); blockType.InOutConnectorCount = blockType.InOutConnectorCount + 1; break; } } else { Trace.WriteLine(string.Format("{0}({1}): Invalid connection declaration!", this.SourceFile, lineIndex)); } } } } } } // 从对应配置文件中读取功能块参数/属性信息 if (File.Exists(this.InfoFile)) { IniFile iniFile = new IniFile(this.InfoFile); blockType = null; iniFile.LoopSections( (section) => { blockType = GetPOU(section); return(blockType != null); }, (key, value) => { if (key.Equals("InitMode", StringComparison.OrdinalIgnoreCase) && value.ToBool()) { blockType.Modes |= ViFirmBlockMode.Init; } else if (key.Equals("SystemMode", StringComparison.OrdinalIgnoreCase) && value.ToBool()) { blockType.Modes |= ViFirmBlockMode.System; } else if (key.Equals("NormalMode", StringComparison.OrdinalIgnoreCase) && value.ToBool()) { blockType.Modes |= ViFirmBlockMode.Normal; } else if (key.Equals("LibraryType", StringComparison.OrdinalIgnoreCase) || key.Equals("Category", StringComparison.OrdinalIgnoreCase)) { blockType.Category = value; } else if (key.Equals("FWLibraryName", StringComparison.OrdinalIgnoreCase)) { blockType.FWLibraryName = value; } else if (key.Equals("FWLibraryVersion", StringComparison.OrdinalIgnoreCase)) { blockType.FWLibraryVersion = value; } else if (key.Equals("BlockComment", StringComparison.OrdinalIgnoreCase)) { blockType.Comment = value; } return(true); }); } } catch (Exception ee) { Trace.WriteLine("### [" + ee.Source + "] Exception: " + ee.Message); Trace.WriteLine("### " + ee.StackTrace); } }
public bool DeserializeFrom(ViBlur blur, System.Xml.XmlReader reader) { this.Name = reader.GetAttribute(blur, "name"); string category = reader.GetAttribute("category"); if (!string.IsNullOrEmpty(category)) { this.Category = category; } string mode = reader.GetAttribute("mode"); if (!string.IsNullOrEmpty(mode)) { this.ModesDecl = mode; } if (reader.IsEmptyElement) { return(true); } int stage = 0x00; // 0x00: 未开始 // 0x01: 开始 INPUT // 0x02: 开始 OUTPUT // 0x03: 开始 IN_OUT while (!reader.EOF) { if (!reader.Read()) { break; } if (reader.NodeType == System.Xml.XmlNodeType.Whitespace) { continue; } if (reader.NodeType == System.Xml.XmlNodeType.Element) { if (string.Compare(reader.Name, "dataType", true) == 0) { string typeName = reader.GetAttribute("typeName"); string typeShortName = reader.GetAttribute("typeShortName"); ViDataType dataType = new ViDataType(typeName, typeShortName); this.Type = dataType; } else if (string.Compare(reader.Name, "inputVars", true) == 0) { this.InputConnectors.Clear(); stage = 0x01; } else if (string.Compare(reader.Name, "outputVars", true) == 0) { this.OutputConnectors.Clear(); stage = 0x02; } else if (string.Compare(reader.Name, "inOutVars", true) == 0) { string count = reader.GetAttribute("count"); if (!string.IsNullOrEmpty(count)) { this.InOutConnectorCount = int.Parse(count); } } else if (string.Compare(reader.Name, ViConnType.TAG, true) == 0) { ViConnType connType = new ViConnType(null, null); if (!connType.DeserializeFrom(blur, reader)) { return(false); } if (stage == 0x01) { this.InputConnectors.Add(connType); } else if (stage == 0x02) { this.OutputConnectors.Add(connType); } } } else if (reader.NodeType == System.Xml.XmlNodeType.EndElement) { if (string.Compare(reader.Name, ViFirmBlockType.TAG, true) == 0) { return(true); } } } return(false); }
/// <summary> /// 将对象转化成字符串显示。 /// </summary> /// <param name="comment">是否包含注释信息?</param> /// <param name="leading">每行的前缀</param> /// <param name="tabbing">每个缩进的字符串</param> /// <param name="suffixType">功能块后缀描述类型</param> /// <returns>对象的字符串显示。</returns> public virtual string ToString(bool comment, string leading, string tabbing, ViFirmBlockSuffixType suffixType) { if (leading == null) { leading = string.Empty; } if (tabbing == null) { tabbing = string.Empty; } string str = leading, prefix; if (this.IsFunctionBlock) { str += string.Format("{0} {1}\n", "FUNCTION_BLOCK", this.Name); } else { str += string.Format("{0} {1} : {2}\n", "FUNCTION", this.Name, this.Type.Name); } // Task Usage if (comment) { str += string.Format("\n{0}(* task usage: {1} *)\n\n", leading, this.ModesDecl); } // INPUT if (this.InOutConnectorCount < this.InputConnectors.Count) { str += leading + tabbing + "VAR_INPUT\n"; prefix = leading + tabbing + tabbing; for (int i = this.InOutConnectorCount; i < this.InputConnectors.Count; ++i) { ViConnType connType = this.InputConnectors[i]; str += string.Format("{0}{1}\n", prefix, connType.ToString(comment)); } str += leading + tabbing + "END_VAR\n"; } // OUTPUT if (this.InOutConnectorCount < this.OutputConnectors.Count) { str += leading + tabbing + "VAR_OUTPUT\n"; prefix = leading + tabbing + tabbing; for (int i = this.InOutConnectorCount; i < this.OutputConnectors.Count; ++i) { ViConnType connType = this.OutputConnectors[i]; str += string.Format("{0}{1}\n", prefix, connType.ToString(comment)); } str += leading + tabbing + "END_VAR\n"; } // IN_OUT if (this.InOutConnectorCount > 0) { str += leading + tabbing + "VAR_IN_OUT\n"; prefix = leading + tabbing + tabbing; for (int i = 0; i < this.InOutConnectorCount; ++i) { ViConnType connType = this.InputConnectors[i]; str += string.Format("{0}{1}\n", prefix, connType.ToString(comment)); } str += leading + tabbing + "END_VAR\n"; } if (this.IsFunctionBlock) { str += string.Format("{0}{1}", leading, "END_FUNCTION_BLOCK"); } else { str += string.Format("{0}{1}", leading, "END_FUNCTION"); } // Suffix Decl str += string.Format("{0}{1}", this.GetSuffixDecl(suffixType), "\n"); return(str); }
/// <summary> /// 得到指定 POE 文件的功能块描述信息。 /// </summary> /// <param name="fileName">POE 文件名称</param> /// <param name="reader">文本文件读对象</param> /// <returns>功能块描述信息,null 表示失败。</returns> public static ViPOEBlockType GetBlockType(string fileName, TextReader reader) { ViPOEBlockType blockType = null; ViConnType connType = null; int lineIndex = 0; // 0x00: 没有读取到功能块开始 // 0x01: 读取到功能块开始 // 0x21: 开始 INPUT // 0x22: 开始 OUTPUT // 0x23: 开始 IN_OUT int stage = 0; while (true) { string line = reader.ReadLine(); if (line == null) { break; } ++lineIndex; line = line.Trim(); if (string.IsNullOrEmpty(line)) { continue; } if (stage == 0x00) { if (line.StartsWith("FUNCTION_BLOCK ", StringComparison.OrdinalIgnoreCase)) { connType = ViConnType.Parse(line.Substring(15), ViTypeCreation.None); if (connType != null && connType.Type == null) { blockType = new ViPOEBlockType(connType.Name, null); blockType.Comment = connType.Comment; // stage = 0x01; } else { Trace.WriteLine(string.Format("{0}({1}): Invalid FUNCTION_BLOCK declaration!", fileName, lineIndex)); } } //else if (line.StartsWith("PROGRAM ", StringComparison.OrdinalIgnoreCase)) //{ // connType = ViConnType.Parse(line.Substring(8), ViTypeCreation.None); // if (connType != null && connType.Type == null) // { // blockType = new ViPOEBlockType(connType.Name, null); // blockType.Comment = connType.Comment; // // // stage = 0x01; // } // else // { // Trace.WriteLine(string.Format("{0}({1}): Invalid PROGRAM declaration!", fileName, lineIndex)); // } //} else if (line.StartsWith("FUNCTION ", StringComparison.OrdinalIgnoreCase)) { connType = ViConnType.Parse(line.Substring(9), ViTypeCreation.Create); if (connType != null && connType.Type != null) { blockType = new ViPOEBlockType(connType.Name, connType.Type); blockType.Comment = connType.Comment; // stage = 0x01; } else { Trace.WriteLine(string.Format("{0}({1}): Invalid FUNCTION declaration!", fileName, lineIndex)); } } } else if (stage >= 0x01) { if (stage == 0x01 && line.EndsWith("*)") && line.StartsWith("(* task usage:", StringComparison.OrdinalIgnoreCase)) { blockType.ModesDecl = line.Substring(14, line.Length - 16); } else if (line.StartsWith(ViTextFile.CommentBegin)) { // 注释行 } else if (line.StartsWith("VAR_INPUT", StringComparison.OrdinalIgnoreCase)) { stage = 0x21; } else if (line.StartsWith("VAR_OUTPUT", StringComparison.OrdinalIgnoreCase)) { stage = 0x22; } else if (line.StartsWith("VAR_IN_OUT", StringComparison.OrdinalIgnoreCase)) { stage = 0x23; } else if (line.StartsWith("END_VAR", StringComparison.OrdinalIgnoreCase)) { stage = 0x01; } else if (line.StartsWith("LD ", StringComparison.OrdinalIgnoreCase)) { break; } else if (line.StartsWith("END_FUNCTION", StringComparison.OrdinalIgnoreCase)) { if (blockType != null) { // 功能块后缀描述字符串 blockType.SetSuffixDecl(line); } break; } else if (stage >= 0x21) { connType = ViConnType.Parse(line, ViTypeCreation.Create); if (connType != null && connType.Type != null) { switch ((stage & 0x0F)) { case 0x01: // INPUT connType.SetParent(blockType); blockType.InputConnectors.Add(connType); break; case 0x02: // OUTPUT connType.SetParent(blockType); blockType.OutputConnectors.Add(connType); break; case 0x03: // IN_OUT connType.SetParent(blockType); blockType.InputConnectors.Insert(blockType.InOutConnectorCount, connType); blockType.OutputConnectors.Insert(blockType.InOutConnectorCount, connType); blockType.InOutConnectorCount = blockType.InOutConnectorCount + 1; break; } } else { Trace.WriteLine(string.Format("{0}({1}): Invalid connection declaration!", fileName, lineIndex)); } } } } return(blockType); }
/// <summary> /// 修改 POE 文件内部的类型名称。 /// </summary> /// <param name="fileName">POE 文件名称</param> /// <param name="typeName">POE 类型名称</param> /// <returns>成功与否?</returns> public static bool ChangeName(string fileName, string typeName) { try { ArrayList alLines = new ArrayList(); // 读取文件所有行 using (StreamReader reader = new StreamReader(fileName, Encoding.Default)) { ViConnType connType = null; string oldName = null; string line, trim, type; int lineIndex = 0; while (true) { line = reader.ReadLine(); if (line == null) { break; } ++lineIndex; if (oldName == null) { trim = line.Trim(); if (trim.StartsWith("PROGRAM ", StringComparison.OrdinalIgnoreCase)) { connType = ViConnType.Parse(trim.Substring(8), ViTypeCreation.None); type = "PROGRAM"; } else if (trim.StartsWith("FUNCTION_BLOCK ", StringComparison.OrdinalIgnoreCase)) { connType = ViConnType.Parse(trim.Substring(15), ViTypeCreation.None); type = "FUNCTION_BLOCK"; } else if (trim.StartsWith("FUNCTION ", StringComparison.OrdinalIgnoreCase)) { connType = ViConnType.Parse(trim.Substring(9), ViTypeCreation.Create); type = "FUNCTION"; } else { alLines.Add(line); continue; } if (connType == null) { return(false); } oldName = connType.Name; // 名称一样,不需要修改 if (oldName == typeName) { return(true); } line = type + ' ' + typeName; if (connType.Type != null) { line += " : " + connType.Type.Name; } alLines.Add(line); } else { alLines.Add(line); } } // 没有读取到类型名称? if (oldName == null) { return(false); } } // 写入所有行 using (StreamWriter writer = ViTextFile.CreateWriter(fileName)) { foreach (string line in alLines) { writer.WriteLine(line); } } // 大功告成 return(true); } catch (Exception ee) { Trace.WriteLine("### [" + ee.Source + "] Exception: " + ee.Message); Trace.WriteLine("### " + ee.StackTrace); } return(false); }