internal static S7DataRow GetInterfaceOrDBFromStep7ProjectString(string txt, ref List<String> ParaList, PLCBlockType blkTP, bool isInstanceDB, BlocksOfflineFolder myFld, S7Block myBlk, byte[] actualValues = null)
        {
            S7DataRow parameterRoot = new S7DataRow("ROOTNODE", S7DataRowType.STRUCT, myBlk);
            S7DataRow parameterRootWithoutTemp = new S7DataRow("ROOTNODE", S7DataRowType.STRUCT, myBlk);

            if (myBlk is S7FunctionBlock)
            {
                (myBlk as S7FunctionBlock).ParameterWithoutTemp = parameterRootWithoutTemp;
            }

            S7DataRow parameterIN = new S7DataRow("IN", S7DataRowType.STRUCT,myBlk);
            S7DataRow parameterOUT = new S7DataRow("OUT", S7DataRowType.STRUCT,myBlk);
            S7DataRow parameterINOUT = new S7DataRow("IN_OUT", S7DataRowType.STRUCT, myBlk);
            S7DataRow parameterSTAT = new S7DataRow("STATIC", S7DataRowType.STRUCT, myBlk);
            S7DataRow parameterTEMP = new S7DataRow("TEMP", S7DataRowType.STRUCT, myBlk);
            //S7DataRow parameterRETVAL = new S7DataRow("RET_VAL", S7DataRowType.STRUCT, myBlk);

            S7DataRow akDataRow = parameterRoot;

            parameterTEMP.isRootBlock = true;

            bool tempAdded = false;

            int Valpos = 0;

            if (txt == null)
            {
                if (blkTP != PLCBlockType.DB)
                    parameterRoot.Add(parameterTEMP);
                return parameterRoot;
            }

            //Todo: read the complete DB from mc5 code first, Read the containing UDTs, compare the UDTs with the Structs, if the UDTs and Structs are not Equal, marke the PLCDataRow as TimeStampConflict

            string[] rows = txt.Split(new string[] {"\n"}, StringSplitOptions.RemoveEmptyEntries);

            S7DataRow lastrow = null;

            Dictionary<string, S7Block> blkHelpers = new Dictionary<string, S7Block>();

            for (int n=0;n<rows.Length;n++) // (string row in rows)
            {
                string rowTr = rows[n].Replace("\0", "").Trim();
                int poscm = rowTr.IndexOf("\t//");
                if (poscm <= 0)
                    poscm = rowTr.Length;

                string switchrow = rowTr.Substring(0,poscm);
                string commnew = "";
                if (poscm != rowTr.Length)
                    commnew = rowTr.Substring(poscm + 1);

                if (rowTr.StartsWith("//"))
                {
                    if (lastrow != null)
                        lastrow.Comment += rowTr;
                    else
                    {
                        if (commnew != null)
                            if (string.IsNullOrEmpty(akDataRow.Comment))
                                akDataRow.Comment += rowTr;
                            else
                                akDataRow.Comment += "\r\n" + rowTr;
                    }
                }
                else
                {
                    switch (switchrow.Trim())
                    {

                        case "VAR_INPUT":
                            akDataRow = parameterIN;
                            akDataRow.Comment = commnew;
                            parameterRoot.Add(parameterIN);
                            parameterRootWithoutTemp.Add(parameterIN);
                            break;
                        case "VAR_OUTPUT":
                            akDataRow = parameterOUT;
                            akDataRow.Comment = commnew;
                            parameterRoot.Add(parameterOUT);
                            parameterRootWithoutTemp.Add(parameterOUT);
                            break;
                        case "VAR_IN_OUT":
                            akDataRow = parameterINOUT;
                            akDataRow.Comment = commnew;

                            parameterRoot.Add(parameterINOUT);
                            parameterRootWithoutTemp.Add(parameterINOUT);
                            break;
                        case "VAR_TEMP":
                            akDataRow = parameterTEMP;
                            if (blkTP != PLCBlockType.DB)
                            {
                                tempAdded = true;
                                parameterRoot.Add(parameterTEMP);
                            }
                            break;
                        case "VAR": //Static Data on a FB
                            akDataRow = parameterSTAT;
                            parameterRoot.Add(parameterSTAT);
                            parameterRootWithoutTemp.Add(parameterSTAT);
                            break;
                        case "END_STRUCT;":
                        case "END_STRUCT ;":
                            akDataRow = ((S7DataRow)akDataRow.Parent);
                            break;
                        case "STRUCT":
                        case "END_VAR":
                        case "":
                            if (commnew != null)
                                if (string.IsNullOrEmpty(akDataRow.Comment))
                                    akDataRow.Comment += commnew;
                                else
                                    akDataRow.Comment += "\r\n" + commnew;
                            break;
                        default:

                            char oldChar = ' ';

                            List<Step7Attribute> Step7Attributes = new List<Step7Attribute>();

                            string tmpName = "";
                            string tmpAttributeName = "";
                            string tmpAttributeValue = "";
                            string tmpType = "";
                            string tmpComment = "";
                            string tmpValue = "";

                            int parseZustand = 0; //0=ParName, 1=AttributeName, 6=AfterAttributeName, 2=AttributeValue, 3=Type, 4=Value, 7=InnerValue (without '), 5=Comment

                            var p1 = rows[n].IndexOf(" OF ");
                            int p2 = 0, p3 = 0;
                            if (p1 > 0)
                            {
                                p2 = rows[n].IndexOf(";", p1);
                                p3 = rows[n].IndexOf("//", p1);
                            }

                            //if (rows[n].Contains("ARRAY") && rows[n].Contains(" OF ") && !rows[n].Contains("\t\r")) //    !rows[n].Contains("\t")
                            if (rows[n].Contains("ARRAY") && rows[n].Contains(" OF ") && (!(p2 > p1 && (p2 < p3 || p3 < 0)) && !rows[n].Contains("\t\r")))
                            {
                                if (rows.Length > n + 1)
                                {
                                    if (rowTr.Contains("//"))
                                    {
                                        int pos = rowTr.IndexOf("//");
                                        rowTr = rowTr.Substring(0, pos) + " " + rows[n + 1].Trim() + rowTr.Substring(pos);
                                    }
                                    else if (rowTr.Contains("OF STRUCT"))
                                    {
                                    }
                                    else if (rowTr[rowTr.Length - 1] != ';')
                                    {
                                        rowTr += " " + rows[n + 1].Trim();
                                    }
                                    n++;
                                }
                            }

                            for (int j = 0; j < rowTr.Length; j++)
                            {
                                char tmpChar = rowTr[j];

                                if (parseZustand == 0 && tmpChar == '{')
                                    parseZustand = 1;
                                else if (parseZustand == 0 && tmpChar != ' ' && tmpChar != ':')
                                    tmpName += tmpChar;
                                else if (parseZustand == 6 && tmpChar == '\'')
                                    parseZustand = 2;
                                else if (parseZustand == 1 && tmpChar == ':' && rowTr[j + 1] == '=')
                                {
                                    parseZustand = 6;
                                    j++;
                                }
                                else if (parseZustand == 1 && tmpChar != ' ' && tmpChar != ':' && tmpChar != '=' && tmpChar != '}' && tmpChar != '\'' && tmpChar != ';')
                                    tmpAttributeName += tmpChar;
                                else if (parseZustand == 1 && tmpChar == '}')
                                    parseZustand = 0;
                                else if (parseZustand == 0 && tmpChar == ':')
                                    parseZustand = 3;
                                else if (parseZustand == 2 && tmpChar == '$')
                                {
                                    tmpAttributeValue += rowTr[j + 1];
                                    j++;
                                }
                                else if (parseZustand == 2 && tmpChar == '\'')
                                {
                                    parseZustand = 1;
                                    Step7Attributes.Add(new Step7Attribute(tmpAttributeName, tmpAttributeValue));
                                    tmpAttributeName = "";
                                    tmpAttributeValue = "";
                                }
                                else if (parseZustand == 2)
                                    tmpAttributeValue += tmpChar;
                                    //else if (parseZustand == 3 && tmpChar == ':')
                                    //    parseZustand = 2;
                                else if (parseZustand == 3 && tmpChar == ':' && rowTr[j + 1] == '=')
                                {
                                    parseZustand = 4;
                                    j++;
                                }
                                else if ((parseZustand == 3 || parseZustand == 4) && tmpChar == '/' && rowTr[j + 1] == '/')
                                {
                                    parseZustand = 5;
                                    j++;
                                }
                                else if (parseZustand == 4 && tmpChar == '\'')
                                {
                                    tmpValue += tmpChar;
                                    parseZustand = 7;
                                }
                                else if (parseZustand == 7 && tmpChar == '$')
                                {
                                    tmpValue += rowTr[j + 1];
                                    j++;
                                }
                                else if (parseZustand == 7 && tmpChar == '\'')
                                {
                                    tmpValue += tmpChar;
                                    parseZustand = 4;
                                }
                                else if (parseZustand == 3 && tmpChar != ';')
                                    tmpType += tmpChar;
                                else if (parseZustand == 4 && tmpChar != ';' && tmpChar != ' ')
                                    tmpValue += tmpChar;
                                else if (parseZustand == 7)
                                    tmpValue += tmpChar;
                                else if (parseZustand == 5)
                                    tmpComment += tmpChar;
                            }

                            tmpType = tmpType.Trim().ToUpper();

                            S7DataRow addRW = new S7DataRow(tmpName, S7DataRowType.UNKNOWN, myBlk);
                            lastrow = addRW;

                            if (tmpType.Replace(" ","").Contains("ARRAY["))
                            {
                                List<int> arrayStart = new List<int>();
                                List<int> arrayStop = new List<int>();

                                int pos1 = tmpType.IndexOf("[");
                                int pos2 = tmpType.IndexOf("]", pos1);
                                string[] arrays = tmpType.Substring(pos1 + 1, pos2 - pos1 - 2).Split(',');

                                foreach (string array in arrays)
                                {
                                    string[] akar = array.Split(new string[] {".."}, StringSplitOptions.RemoveEmptyEntries);
                                    arrayStart.Add(Convert.ToInt32(akar[0].Trim()));
                                    arrayStop.Add(Convert.ToInt32(akar[1].Trim()));
                                }

                                addRW.ArrayStart = arrayStart;
                                addRW.ArrayStop = arrayStop;
                                addRW.IsArray = true;
                                tmpType = tmpType.Substring(pos2 + 5);
                            }

                            addRW.Comment = tmpComment.Replace("$'", "'").Replace("$$", "$");

                            if (Step7Attributes.Count > 0)
                                addRW.Attributes = Step7Attributes;

                            int akRowTypeNumber = 0;
                            if (tmpType.Contains("SFB"))
                            {
                                addRW.DataType = S7DataRowType.SFB;
                                akRowTypeNumber = Convert.ToInt32(tmpType.Substring(4));

                                string blkDesc = "SFB" + akRowTypeNumber.ToString();
                                S7FunctionBlock tmpBlk;
                                if (blkHelpers.ContainsKey(blkDesc))
                                    tmpBlk = (S7FunctionBlock)blkHelpers[blkDesc];
                                else
                                {
                                    tmpBlk = ((S7FunctionBlock)myFld.GetBlock(blkDesc));
                                    blkHelpers.Add(blkDesc, tmpBlk);
                                }

                                if (tmpBlk != null && tmpBlk.Parameter != null && tmpBlk.Parameter.Children != null)
                                    addRW.AddRange(tmpBlk.ParameterWithoutTemp.DeepCopy().Children.Cast<S7DataRow>());
                            }
                            else if (tmpType.Contains("UDT"))
                            {
                                addRW.DataType = S7DataRowType.UDT;
                                akRowTypeNumber = Convert.ToInt32(tmpType.Substring(4));

                                string blkDesc = "UDT" + akRowTypeNumber.ToString();
                                S7DataBlock tmpBlk;
                                if (blkHelpers.ContainsKey(blkDesc))
                                    tmpBlk = (S7DataBlock)blkHelpers[blkDesc];
                                else
                                {
                                    tmpBlk = ((S7DataBlock)myFld.GetBlock(blkDesc));
                                    blkHelpers.Add(blkDesc, tmpBlk);
                                }

                                if (tmpBlk != null && tmpBlk.Structure != null && tmpBlk.Structure.Children != null)
                                    addRW.AddRange(((S7DataRow)tmpBlk.Structure).DeepCopy().Children.Cast<S7DataRow>());

                            }
                            else if (tmpType.Contains("BLOCK_FB"))
                            {
                                addRW.DataType = S7DataRowType.BLOCK_FB;
                                //akRowTypeNumber = Convert.ToInt32(tmpType.Substring(3));

                                //PLCFunctionBlock tmpBlk = ((PLCFunctionBlock)myFld.GetBlock("FB" + akRowTypeNumber.ToString()));
                                //if (tmpBlk != null && tmpBlk.Parameter != null && tmpBlk.Parameter.Children != null)
                                //    addRW.AddRange(tmpBlk.Parameter.Children);
                            }
                            else if (tmpType.Contains("FB"))
                            {
                                addRW.DataType = S7DataRowType.FB;
                                akRowTypeNumber = Convert.ToInt32(tmpType.Substring(3));

                                string blkDesc = "FB" + akRowTypeNumber.ToString();
                                S7FunctionBlock tmpBlk;
                                if (blkHelpers.ContainsKey(blkDesc))
                                    tmpBlk = (S7FunctionBlock) blkHelpers[blkDesc];
                                else
                                {
                                    tmpBlk = ((S7FunctionBlock)myFld.GetBlock(blkDesc));
                                    blkHelpers.Add(blkDesc, tmpBlk);
                                }

                                if (tmpBlk != null && tmpBlk.Parameter != null && tmpBlk.Parameter.Children != null)
                                    addRW.AddRange(tmpBlk.ParameterWithoutTemp.DeepCopy().Children.Cast<S7DataRow>());
                            }
                            else if (tmpType.Contains("STRING"))
                            {
                                addRW.DataType = S7DataRowType.STRING;
                                int pos1 = tmpType.IndexOf("[");
                                int pos2 = tmpType.IndexOf("]", pos1);
                                addRW.StringSize = Convert.ToInt32(tmpType.Substring(pos1 + 1, pos2 - pos1 - 2));
                            }
                            else
                                addRW.DataType = (S7DataRowType) Enum.Parse(typeof (S7DataRowType), tmpType.ToUpper());

                            addRW.DataTypeBlockNumber = akRowTypeNumber;

                            if (tmpValue != "")
                            {
                                //Todo: Startvalues bei arrays...
                                //Mehrere Values...
                                //TRUE,6(FALSE),TRUE,TRUE,7(FALSE)
                                if (addRW.IsArray)
                                {
                                    addRW.StartValue = tmpValue;
                                }
                                else
                                {
                                    addRW.StartValue = Helper.StringValueToObject(tmpValue, addRW.DataType);
                                }
                            }
                            else
                            {
                                if (!addRW.IsArray)
                                    addRW.StartValue = Helper.DefaultValueForType(addRW.DataType);
                            }

                            //if (actualValues != null)
                            //{
                            //    addRW.Value = GetVarTypeVal((byte)addRW.DataType, actualValues, ref Valpos);
                            //}

                            akDataRow.Add(addRW);
                            ParaList.Add(tmpName);

                            if (addRW.DataType == S7DataRowType.STRUCT)
                                akDataRow = addRW;

                            break;
                            /*
                         * Attributname kann nicht ' und } enthalten!
                         * In Attribt Values
                         * $$ zum ausmaskieren von $
                         * $' zum ausmaskieren von '
                         *
                         * Beispielzeilen....
                            // "ID { S7_co := 'agag'; S7_server1 := 'connection' }: INT ;\t// Connection ID 1..16"
                            // "LADDR { S7_co := 'agag'; S7_server1 := 'connection' }: WORD ;\t// Module address in hardware configuration"
                            // "RECV : ANY ;\t// Buffer for received data"
                            // "NDR : BOOL ;\t// Indicates whether new data were received"
                            // "aa { ff := '//ghghf}' }: BOOL ;"
                            // "bb : INT  := 8888;"
                            // "P_1001 : ARRAY  [0 .. 3 ] OF CHAR  := '1', '0', '0', '1';"
                            // "aa : STRING  [20 ] := 'deewedw';"
                            // "aa { dsfs := '' }: BOOL ;"

                            //"res : ARRAY  [1 .. 121 ] OF STRUCT"
                            //      "P_AKL1 : ARRAY  [0 .. 3 ] OF CHAR  := 'A', 'K', 'L', '1';"
                        */
                    }
                }
            }
            if (blkTP != PLCBlockType.DB && blkTP != PLCBlockType.UDT && tempAdded == false)
            {
                parameterRoot.Add(parameterTEMP);
            }

            if (actualValues != null)
            {
                int vPos = 0, bPos = 0;
                FillActualValuesInDataBlock(parameterRoot, actualValues, ref vPos, ref bPos);
            }

            return parameterRoot;
        }
Example #2
0
        internal static S7DataRow GetInterfaceOrDBFromStep7ProjectString(string txt, ref List <String> ParaList, PLCBlockType blkTP, bool isInstanceDB, BlocksOfflineFolder myFld, S7Block myBlk, byte[] actualValues = null)
        {
            S7DataRow parameterRoot            = new S7DataRow("ROOTNODE", S7DataRowType.STRUCT, myBlk);
            S7DataRow parameterRootWithoutTemp = new S7DataRow("ROOTNODE", S7DataRowType.STRUCT, myBlk);

            if (myBlk is S7FunctionBlock)
            {
                (myBlk as S7FunctionBlock).ParameterWithoutTemp = parameterRootWithoutTemp;
            }

            S7DataRow parameterIN    = new S7DataRow("IN", S7DataRowType.STRUCT, myBlk);
            S7DataRow parameterOUT   = new S7DataRow("OUT", S7DataRowType.STRUCT, myBlk);
            S7DataRow parameterINOUT = new S7DataRow("IN_OUT", S7DataRowType.STRUCT, myBlk);
            S7DataRow parameterSTAT  = new S7DataRow("STATIC", S7DataRowType.STRUCT, myBlk);
            S7DataRow parameterTEMP  = new S7DataRow("TEMP", S7DataRowType.STRUCT, myBlk);
            //S7DataRow parameterRETVAL = new S7DataRow("RET_VAL", S7DataRowType.STRUCT, myBlk);

            S7DataRow akDataRow = parameterRoot;

            parameterIN.isRootBlock    = true;
            parameterOUT.isRootBlock   = true;
            parameterINOUT.isRootBlock = true;
            parameterINOUT.isInOut     = true;
            parameterSTAT.isRootBlock  = true;
            parameterTEMP.isRootBlock  = true;

            bool tempAdded = false;

            int Valpos = 0;

            if (txt == null)
            {
                if (blkTP != PLCBlockType.DB)
                {
                    parameterRoot.Add(parameterTEMP);
                }
                return(parameterRoot);
            }

            //Todo: read the complete DB from mc5 code first, Read the containing UDTs, compare the UDTs with the Structs, if the UDTs and Structs are not Equal, marke the PLCDataRow as TimeStampConflict

            string[] rows = txt.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);

            S7DataRow lastrow = null;


            Dictionary <string, S7Block> blkHelpers = new Dictionary <string, S7Block>();

            for (int n = 0; n < rows.Length; n++) // (string row in rows)
            {
                string rowTr = rows[n].Replace("\0", "").Trim();
                int    poscm = rowTr.IndexOf("\t//");
                if (poscm <= 0)
                {
                    poscm = rowTr.Length;
                }

                string switchrow = rowTr.Substring(0, poscm);
                string commnew   = "";
                if (poscm != rowTr.Length)
                {
                    commnew = rowTr.Substring(poscm + 1);
                }

                if (rowTr.StartsWith("//"))
                {
                    if (lastrow != null)
                    {
                        lastrow.Comment += rowTr;
                    }
                    else
                    {
                        if (commnew != null)
                        {
                            if (string.IsNullOrEmpty(akDataRow.Comment))
                            {
                                akDataRow.Comment += rowTr;
                            }
                            else
                            {
                                akDataRow.Comment += "\r\n" + rowTr;
                            }
                        }
                    }
                }
                else
                {
                    switch (switchrow.Trim())
                    {
                    case "VAR_INPUT":
                        akDataRow         = parameterIN;
                        akDataRow.Comment = commnew;
                        parameterRoot.Add(parameterIN);
                        parameterRootWithoutTemp.Add(parameterIN);
                        break;

                    case "VAR_OUTPUT":
                        akDataRow         = parameterOUT;
                        akDataRow.Comment = commnew;
                        parameterRoot.Add(parameterOUT);
                        parameterRootWithoutTemp.Add(parameterOUT);
                        break;

                    case "VAR_IN_OUT":
                        akDataRow         = parameterINOUT;
                        akDataRow.Comment = commnew;

                        parameterRoot.Add(parameterINOUT);
                        parameterRootWithoutTemp.Add(parameterINOUT);
                        break;

                    case "VAR_TEMP":
                        akDataRow = parameterTEMP;
                        if (blkTP != PLCBlockType.DB)
                        {
                            tempAdded = true;
                            parameterRoot.Add(parameterTEMP);
                        }
                        break;

                    case "VAR":     //Static Data on a FB
                        akDataRow = parameterSTAT;
                        parameterRoot.Add(parameterSTAT);
                        parameterRootWithoutTemp.Add(parameterSTAT);
                        break;

                    case "END_STRUCT;":
                    case "END_STRUCT ;":
                        akDataRow = ((S7DataRow)akDataRow.Parent);
                        break;

                    case "STRUCT":
                    case "END_VAR":
                    case "":
                        if (commnew != null)
                        {
                            if (string.IsNullOrEmpty(akDataRow.Comment))
                            {
                                akDataRow.Comment += commnew;
                            }
                            else
                            {
                                akDataRow.Comment += "\r\n" + commnew;
                            }
                        }
                        break;

                    default:

                        char oldChar = ' ';

                        List <Step7Attribute> Step7Attributes = new List <Step7Attribute>();

                        string tmpName           = "";
                        string tmpAttributeName  = "";
                        string tmpAttributeValue = "";
                        string tmpType           = "";
                        string tmpComment        = "";
                        string tmpValue          = "";

                        int parseZustand = 0;     //0=ParName, 1=AttributeName, 6=AfterAttributeName, 2=AttributeValue, 3=Type, 4=Value, 7=InnerValue (without '), 5=Comment

                        var p1 = rows[n].IndexOf(" OF ");
                        int p2 = 0, p3 = 0;
                        if (p1 > 0)
                        {
                            p2 = rows[n].IndexOf(";", p1);
                            p3 = rows[n].IndexOf("//", p1);
                        }

                        //if (rows[n].Contains("ARRAY") && rows[n].Contains(" OF ") && !rows[n].Contains("\t\r")) //    !rows[n].Contains("\t")
                        if (rows[n].Contains("ARRAY") && rows[n].Contains(" OF ") && (!(p2 > p1 && (p2 < p3 || p3 < 0)) && !rows[n].Contains("\t\r")))
                        {
                            if (rows.Length > n + 1)
                            {
                                if (rowTr.Contains("//"))
                                {
                                    int pos = rowTr.IndexOf("//");
                                    rowTr = rowTr.Substring(0, pos) + " " + rows[n + 1].Trim() + rowTr.Substring(pos);
                                }
                                else if (rowTr.Contains("OF STRUCT"))
                                {
                                }
                                else if (rowTr[rowTr.Length - 1] != ';')
                                {
                                    rowTr += " " + rows[n + 1].Trim();
                                }
                                n++;
                            }
                        }

                        for (int j = 0; j < rowTr.Length; j++)
                        {
                            char tmpChar = rowTr[j];

                            if (parseZustand == 0 && tmpChar == '{')
                            {
                                parseZustand = 1;
                            }
                            else if (parseZustand == 0 && tmpChar != ' ' && tmpChar != ':')
                            {
                                tmpName += tmpChar;
                            }
                            else if (parseZustand == 6 && tmpChar == '\'')
                            {
                                parseZustand = 2;
                            }
                            else if (parseZustand == 1 && tmpChar == ':' && rowTr[j + 1] == '=')
                            {
                                parseZustand = 6;
                                j++;
                            }
                            else if (parseZustand == 1 && tmpChar != ' ' && tmpChar != ':' && tmpChar != '=' && tmpChar != '}' && tmpChar != '\'' && tmpChar != ';')
                            {
                                tmpAttributeName += tmpChar;
                            }
                            else if (parseZustand == 1 && tmpChar == '}')
                            {
                                parseZustand = 0;
                            }
                            else if (parseZustand == 0 && tmpChar == ':')
                            {
                                parseZustand = 3;
                            }
                            else if (parseZustand == 2 && tmpChar == '$')
                            {
                                tmpAttributeValue += rowTr[j + 1];
                                j++;
                            }
                            else if (parseZustand == 2 && tmpChar == '\'')
                            {
                                parseZustand = 1;
                                Step7Attributes.Add(new Step7Attribute(tmpAttributeName, tmpAttributeValue));
                                tmpAttributeName  = "";
                                tmpAttributeValue = "";
                            }
                            else if (parseZustand == 2)
                            {
                                tmpAttributeValue += tmpChar;
                            }
                            //else if (parseZustand == 3 && tmpChar == ':')
                            //    parseZustand = 2;
                            else if (parseZustand == 3 && tmpChar == ':' && rowTr[j + 1] == '=')
                            {
                                parseZustand = 4;
                                j++;
                            }
                            else if ((parseZustand == 3 || parseZustand == 4) && tmpChar == '/' && rowTr[j + 1] == '/')
                            {
                                parseZustand = 5;
                                j++;
                            }
                            else if (parseZustand == 4 && tmpChar == '\'')
                            {
                                tmpValue    += tmpChar;
                                parseZustand = 7;
                            }
                            else if (parseZustand == 7 && tmpChar == '$')
                            {
                                tmpValue += rowTr[j + 1];
                                j++;
                            }
                            else if (parseZustand == 7 && tmpChar == '\'')
                            {
                                tmpValue    += tmpChar;
                                parseZustand = 4;
                            }
                            else if (parseZustand == 3 && tmpChar != ';')
                            {
                                tmpType += tmpChar;
                            }
                            else if (parseZustand == 4 && tmpChar != ';' && tmpChar != ' ')
                            {
                                tmpValue += tmpChar;
                            }
                            else if (parseZustand == 7)
                            {
                                tmpValue += tmpChar;
                            }
                            else if (parseZustand == 5)
                            {
                                tmpComment += tmpChar;
                            }
                        }

                        tmpType = tmpType.Trim().ToUpper();

                        S7DataRow addRW = new S7DataRow(tmpName, S7DataRowType.UNKNOWN, myBlk);
                        lastrow = addRW;

                        if (tmpType.Replace(" ", "").Contains("ARRAY["))
                        {
                            List <int> arrayStart = new List <int>();
                            List <int> arrayStop  = new List <int>();

                            int      pos1   = tmpType.IndexOf("[");
                            int      pos2   = tmpType.IndexOf("]", pos1);
                            string[] arrays = tmpType.Substring(pos1 + 1, pos2 - pos1 - 2).Split(',');

                            foreach (string array in arrays)
                            {
                                string[] akar = array.Split(new string[] { ".." }, StringSplitOptions.RemoveEmptyEntries);
                                arrayStart.Add(Convert.ToInt32(akar[0].Trim()));
                                arrayStop.Add(Convert.ToInt32(akar[1].Trim()));
                            }

                            addRW.ArrayStart = arrayStart;
                            addRW.ArrayStop  = arrayStop;
                            addRW.IsArray    = true;
                            tmpType          = tmpType.Substring(pos2 + 5);
                        }

                        addRW.Comment = tmpComment.Replace("$'", "'").Replace("$$", "$");

                        if (Step7Attributes.Count > 0)
                        {
                            addRW.Attributes = Step7Attributes;
                        }

                        int akRowTypeNumber = 0;
                        if (tmpType.Contains("SFB"))
                        {
                            addRW.DataType  = S7DataRowType.SFB;
                            akRowTypeNumber = Convert.ToInt32(tmpType.Substring(4));

                            string          blkDesc = "SFB" + akRowTypeNumber.ToString();
                            S7FunctionBlock tmpBlk;
                            if (blkHelpers.ContainsKey(blkDesc))
                            {
                                tmpBlk = (S7FunctionBlock)blkHelpers[blkDesc];
                            }
                            else
                            {
                                tmpBlk = ((S7FunctionBlock)myFld.GetBlock(blkDesc));
                                blkHelpers.Add(blkDesc, tmpBlk);
                            }

                            if (tmpBlk != null && tmpBlk.Parameter != null && tmpBlk.Parameter.Children != null)
                            {
                                addRW.AddRange(tmpBlk.ParameterWithoutTemp.DeepCopy().Children.Cast <S7DataRow>());
                            }
                        }
                        else if (tmpType.Contains("UDT"))
                        {
                            addRW.DataType  = S7DataRowType.UDT;
                            akRowTypeNumber = Convert.ToInt32(tmpType.Substring(4));

                            string      blkDesc = "UDT" + akRowTypeNumber.ToString();
                            S7DataBlock tmpBlk;
                            if (blkHelpers.ContainsKey(blkDesc))
                            {
                                tmpBlk = (S7DataBlock)blkHelpers[blkDesc];
                            }
                            else
                            {
                                tmpBlk = ((S7DataBlock)myFld.GetBlock(blkDesc));
                                blkHelpers.Add(blkDesc, tmpBlk);
                            }

                            if (tmpBlk != null && tmpBlk.Structure != null && tmpBlk.Structure.Children != null)
                            {
                                addRW.AddRange(((S7DataRow)tmpBlk.Structure).DeepCopy().Children.Cast <S7DataRow>());
                            }
                        }
                        else if (tmpType.Contains("BLOCK_FB"))
                        {
                            addRW.DataType = S7DataRowType.BLOCK_FB;
                            //akRowTypeNumber = Convert.ToInt32(tmpType.Substring(3));

                            //PLCFunctionBlock tmpBlk = ((PLCFunctionBlock)myFld.GetBlock("FB" + akRowTypeNumber.ToString()));
                            //if (tmpBlk != null && tmpBlk.Parameter != null && tmpBlk.Parameter.Children != null)
                            //    addRW.AddRange(tmpBlk.Parameter.Children);
                        }
                        else if (tmpType.Contains("FB"))
                        {
                            addRW.DataType  = S7DataRowType.FB;
                            akRowTypeNumber = Convert.ToInt32(tmpType.Substring(3));

                            string          blkDesc = "FB" + akRowTypeNumber.ToString();
                            S7FunctionBlock tmpBlk;
                            if (blkHelpers.ContainsKey(blkDesc))
                            {
                                tmpBlk = (S7FunctionBlock)blkHelpers[blkDesc];
                            }
                            else
                            {
                                tmpBlk = ((S7FunctionBlock)myFld.GetBlock(blkDesc));
                                blkHelpers.Add(blkDesc, tmpBlk);
                            }

                            if (tmpBlk != null && tmpBlk.Parameter != null && tmpBlk.Parameter.Children != null)
                            {
                                addRW.AddRange(tmpBlk.ParameterWithoutTemp.DeepCopy().Children.Cast <S7DataRow>());
                            }
                        }
                        else if (tmpType.Contains("STRING"))
                        {
                            addRW.DataType = S7DataRowType.STRING;
                            int pos1 = tmpType.IndexOf("[");
                            int pos2 = tmpType.IndexOf("]", pos1);
                            addRW.StringSize = Convert.ToInt32(tmpType.Substring(pos1 + 1, pos2 - pos1 - 2));
                        }
                        else
                        {
                            addRW.DataType = (S7DataRowType)Enum.Parse(typeof(S7DataRowType), tmpType.ToUpper());
                        }

                        addRW.DataTypeBlockNumber = akRowTypeNumber;

                        if (tmpValue != "")
                        {
                            //Todo: Startvalues bei arrays...
                            //Mehrere Values...
                            //TRUE,6(FALSE),TRUE,TRUE,7(FALSE)
                            if (addRW.IsArray)
                            {
                                addRW.StartValue = tmpValue;
                            }
                            else
                            {
                                addRW.StartValue = Helper.StringValueToObject(tmpValue, addRW.DataType);
                            }
                        }
                        else
                        {
                            if (!addRW.IsArray)
                            {
                                addRW.StartValue = Helper.DefaultValueForType(addRW.DataType);
                            }
                        }

                        //if (actualValues != null)
                        //{
                        //    addRW.Value = GetVarTypeVal((byte)addRW.DataType, actualValues, ref Valpos);
                        //}

                        akDataRow.Add(addRW);
                        ParaList.Add(tmpName);

                        if (addRW.DataType == S7DataRowType.STRUCT)
                        {
                            akDataRow = addRW;
                        }

                        break;

                        /*
                         * Attributname kann nicht ' und } enthalten!
                         * In Attribt Values
                         * $$ zum ausmaskieren von $
                         * $' zum ausmaskieren von '
                         *
                         * Beispielzeilen....
                         * // "ID { S7_co := 'agag'; S7_server1 := 'connection' }: INT ;\t// Connection ID 1..16"
                         * // "LADDR { S7_co := 'agag'; S7_server1 := 'connection' }: WORD ;\t// Module address in hardware configuration"
                         * // "RECV : ANY ;\t// Buffer for received data"
                         * // "NDR : BOOL ;\t// Indicates whether new data were received"
                         * // "aa { ff := '//ghghf}' }: BOOL ;"
                         * // "bb : INT  := 8888;"
                         * // "P_1001 : ARRAY  [0 .. 3 ] OF CHAR  := '1', '0', '0', '1';"
                         * // "aa : STRING  [20 ] := 'deewedw';"
                         * // "aa { dsfs := '' }: BOOL ;"
                         *
                         * //"res : ARRAY  [1 .. 121 ] OF STRUCT"
                         * //      "P_AKL1 : ARRAY  [0 .. 3 ] OF CHAR  := 'A', 'K', 'L', '1';"
                         */
                    }
                }
            }
            if (blkTP != PLCBlockType.DB && blkTP != PLCBlockType.UDT && tempAdded == false)
            {
                parameterRoot.Add(parameterTEMP);
            }

            if (actualValues != null)
            {
                int vPos = 0, bPos = 0;
                //FillActualValuesInDataBlock(parameterRoot, actualValues, ref vPos, ref bPos);
            }

            return(parameterRoot);
        }
        /// <summary>
        /// Parse the Header and Footer information from an online MC7Code byte blob
        /// </summary>
        /// <param name="MC7Code">The online MC7 Code blob from the PLC</param>
        /// <param name="MnemoricLanguage">The Mnemoric that should be used when parsing the Blocks data</param>
        /// <returns></returns>
        internal static S7Block ParseBlockHeaderAndFooterFromMC7(byte[] MC7Code, MnemonicLanguage MnemoricLanguage)
        {
            S7Block retBlock = null;

            if (MC7Code != null)
            {
                //Parse Block type and prepare the Return block acordingly
                PLCBlockType BlockType = Helper.GetPLCBlockType(MC7Code[5]);

                if (BlockType == PLCBlockType.DB || BlockType == PLCBlockType.SDB)
                {
                    retBlock = (S7Block) new S7DataBlock();
                }
                else
                {
                    retBlock = (S7Block) new S7FunctionBlock();
                }

                /*
                 * Description of a MC7 Block Header
                 *
                 * 0,1     = Signature ('pp')
                 * 2       = Block Version
                 * 3       = Block Attribute (.0 not unlinked, .1 standart block + know how protect, .3 know how protect, .5 not retain
                 * 4       = Block Language
                 * 5       = Block Type (a=DB, b=SDB)
                 * 6,7     = Block Number
                 * 8-11    = Block Length
                 * 12-15   = Block Password
                 * 16-21   = Last Modified
                 * 22-27   = Last Interface Change
                 * 28,29   = Interface length or DB Body (actual Values Part) length
                 * 30,31   = Segment Table Length  (Normaly 0 on a DB) (Length of networks!)
                 * 32,33   = Local Data Length? (Normaly 0 on a DB)
                 * 34,35   = MC7-Length or DB Body (definitions/initial values)
                 */

                /*
                 * Description of a MC7 Block (Function - Block)
                 * 36-xx     = Header
                 * xx+1,     = 0x01
                 * xx+2,xx+3 = Again Block number, Zero on OB            (but bytes swapped)
                 * xx+4,xx+5 = Interface Length (from xx+6 to yy)
                 * xx+6,xx+7 = Interface Blocks Count (In,Out,Satic,TMP etc) * 2
                 * xx+9-yy   = Interface
                 * yy+1-zz   = Networks
                 *
                 */

                /*
                 * Description of a MC7 Block (Data - Block)
                 * 36-xx        = Header
                 * xx+1,        = 0x05 (DB) 0x10 (DI)
                 * xx+2,xx+3    = Again Block Number or FB Number on a DI   (but bytes swapped)
                 * xx+4,xx+5    = Interface Length
                 * xx+6,xx+7     = Interface Blocks Count (In,Out,Satic,TMP etc) * 2
                 * xx+8-yy      = Interface
                 * yy-zz        = Start-Values
                 */

                //----------------------------------------------------------------------------------------------------
                //Parse header data
                //----------------------------------------------------------------------------------------------------
                retBlock.BlockVersion        = Convert.ToString(MC7Code[2] - 1); //This is not the Block version from the Simatic Manager. It is unclar what data is stored in MC7Code[2]
                retBlock.BlockAttribute      = (S7Block.S7BlockAtributes)MC7Code[3];
                retBlock.BlockLanguage       = (PLCLanguage)MC7Code[4];          // Enum.Parse(typeof(DataTypes.PLCLanguage), Helper.GetLang(MC7Code[4]));
                retBlock.MnemonicLanguage    = (MnemonicLanguage)MnemoricLanguage;
                retBlock.BlockType           = Helper.GetPLCBlockType(MC7Code[5]);
                retBlock.BlockNumber         = (MC7Code[6] * 0x100) + MC7Code[7];
                retBlock.Length              = libnodave.getU32from(MC7Code, 8);
                retBlock.Password            = new byte[] { MC7Code[12], MC7Code[13], MC7Code[14], MC7Code[15] };
                retBlock.KnowHowProtection   = (MC7Code[12] + MC7Code[13] + MC7Code[14] + MC7Code[15]) != 0; //if any of the Password bytes contains an non Zero value
                retBlock.LastCodeChange      = Helper.GetDT(MC7Code[16], MC7Code[17], MC7Code[18], MC7Code[19], MC7Code[20], MC7Code[21]);
                retBlock.LastInterfaceChange = Helper.GetDT(MC7Code[22], MC7Code[23], MC7Code[24], MC7Code[25], MC7Code[26], MC7Code[27]);

                //----------------------------------------------------------------------------------------------------
                //Parse Code and Data lengths
                //----------------------------------------------------------------------------------------------------
                int InterfaceLength_or_DBActualValuesLength = libnodave.getU16from(MC7Code, 28);
                retBlock.SegmentTableSize = libnodave.getU16from(MC7Code, 30); //(Length of networks?)
                int LocalDataLength           = libnodave.getU16from(MC7Code, 32);
                int MC7Length_or_DBBodyLength = libnodave.getU16from(MC7Code, 34);

                retBlock.InterfaceSize  = InterfaceLength_or_DBActualValuesLength;
                retBlock.LocalDataSize  = LocalDataLength;
                retBlock.CodeSize       = MC7Length_or_DBBodyLength;
                retBlock.WorkMemorySize = retBlock.CodeSize + MC7Start_or_DBBodyStart;  //in my tests(about 10 different blocks), this was alwasy 36 bytes more then the MC7 code size

                //----------------------------------------------------------------------------------------------------
                //Parse footer data
                //----------------------------------------------------------------------------------------------------
                //Old: int FooterStart = MC7Start_or_DBBodyStart + MC7Length_or_DBBodyLength + InterfaceLength_or_DBActualValuesLength + retBlock.SegmentTableSize;

                //Testing showed that the Footer always starts 36 bytes (footer lenght) before the end of the MC7 block.
                //so use this version, so that now there is no need for "GetAWLBlockBasicInfoFromBlockHeader" because its actually the same
                int FooterStart = MC7Code.Length - FooterLength;

                retBlock.Author   = Helper.GetString(FooterStart + 0, 8, MC7Code);
                retBlock.Family   = Helper.GetString(FooterStart + 8, 8, MC7Code);
                retBlock.Name     = Helper.GetString(FooterStart + 16, 8, MC7Code);
                retBlock.Version  = Helper.GetVersion(MC7Code[FooterStart + 24]);
                retBlock.CheckSum = libnodave.getU16from(MC7Code, FooterStart + 26);
            }

            return(retBlock);
        }
Example #4
0
 public PLCBlockName(PLCBlockType blockType, int blockNumber)
 {
     BlockType   = blockType;
     BlockNumber = blockNumber;
 }