Esempio n. 1
0
        /// <summary>
        /// Extracts all data contained within the structure/union block passed in the Struct parameter of the function and loads the data into a StructData data
        /// object.  The structure/union block will be parsed and each field in the structure/union, including sub-structures and unions will be extracted
        /// and loaded into the appropriate FieldData data class object's and added to the Fields collection in the StructData object, thereby linking each
        /// field to the structure.   If nested structure/union declarations are detected, then the ExtractStructData function will be called recursively
        /// from the ExtractFieldData function to extract the appropriate data out of the nested structure/union and generate a child StructData object
        /// that will be linked as a field to the parent structure/union.
        /// </summary>
        /// <param name="strStruct">Complete structure/union block of code to extract.  This will contain the beginning to the end of the structure/union
        /// declaration.</param>
        public StructData ExtractStructData(string strStruct)
        {
            try
            {
                StructData sdStructure = new StructData();

                //Checks to see if the structure is defined as an array and verifies that the array contains only numeric values.  If
                //non-numeric values are presented in the structure array declaration, they are first converted to their numeric equivalents
                //before proceeding with extracting the type definition declaration.  This operation will both convert the non-numeric array
                //elements of the fields contained in the structure, as well as the structure, itself.
                if (strStruct.Contains('[') && strStruct.Contains(']'))
                {
                    if (!ExtractorUtils.IsNumericArray(strStruct))
                    {
                        strStruct = ExtractorUtils.ConvertNonNumericElements(m_HeaderAccess, strStruct);
                    }
                }//end if

                int iStartBracketIndex = strStruct.IndexOf('{', 0);
                int iEndBracketIndex   = strStruct.LastIndexOf('}');

                string strDeclarator = strStruct.Substring(0, iStartBracketIndex).Trim();

                if (strDeclarator.Contains("struct"))
                {
                    sdStructure.StructUnion = StructUnionEnum.Structure;
                }
                else
                {
                    sdStructure.StructUnion = StructUnionEnum.Union;
                }

                if (strDeclarator.Contains("typedef"))
                {
                    //Extracts name of structure after ending of typedef struct closing bracket.
                    string strStructName = strStruct.Substring(iEndBracketIndex + 1, strStruct.Length - iEndBracketIndex - 1).Split(';')[0].Trim();

                    if (strStructName.Contains('['))
                    {
                        strStructName = strStructName.Substring(0, strStructName.IndexOf('[')).Trim();
                    }

                    sdStructure.StructName = strStructName;
                }
                else
                {
                    int iStartNameIndex = 0;

                    if (sdStructure.StructUnion == StructUnionEnum.Structure)
                    {
                        iStartNameIndex = strStruct.IndexOf("struct") + "struct".Length;
                    }
                    else
                    {
                        iStartNameIndex = strStruct.IndexOf("union") + "union".Length;
                    }

                    //Extracts name of the structure or union in the structure/union declaration before opening bracket.
                    sdStructure.StructName = strStruct.Substring(iStartNameIndex, iStartBracketIndex - iStartNameIndex).Trim();

                    if (sdStructure.StructName.Trim() == "")
                    {
                        //Extracts name of structure after ending of struct closing bracket.
                        string strStructName = strStruct.Substring(iEndBracketIndex + 1, strStruct.Length - iEndBracketIndex - 1).Split(';')[0].Trim();

                        if (strStructName.Contains('['))
                        {
                            strStructName = strStructName.Substring(0, strStructName.IndexOf('['));
                        }

                        sdStructure.StructName = strStructName;
                    } //end if
                }     //end if

                //Parses body of structure and extracts each field (including sub-structures/unions) and loads them into FieldData objects which
                //then are linked to the structure data class.
                int iCurPos = iStartBracketIndex + 1;

                bool        blDeclaratorFound = false;
                FieldData[] aryFields         = null;
                int         iCurFieldIndex    = 0;
                int         iFieldByteOffset  = 0;

                bool   blBitDetected       = false;
                int    iBitFieldDataSize   = 0;
                int    iBitCount           = 0;
                string strBitFieldTypeName = "";

                while (iCurPos < iEndBracketIndex)
                {
                    if (char.IsLetter(strStruct[iCurPos]) || strStruct[iCurPos] == '*')
                    {
                        blDeclaratorFound = true;
                    }
                    else
                    {
                        iCurPos++;
                    }

                    if (blDeclaratorFound)
                    {
                        aryFields = ExtractStructFieldData(strStruct, sdStructure.StructName, sdStructure.StructUnion,
                                                           ref iCurPos, ref iCurFieldIndex, ref iFieldByteOffset,
                                                           ref blBitDetected, ref iBitFieldDataSize, ref iBitCount,
                                                           ref strBitFieldTypeName);

                        if (aryFields != null)
                        {
                            sdStructure.Fields.AddRange(aryFields);
                        }

                        blDeclaratorFound = false;
                    } //end if
                }     //end while

                //If the structure is declared as an array, then the total number of elements declared for the structure
                //will be calculated.
                int    iTotalElements = 1;
                string strAnalyze     = strStruct.Substring(iEndBracketIndex + 1, strStruct.Length - iEndBracketIndex - 1);

                if (strAnalyze.Contains('[') && strAnalyze.Contains(']'))
                {
                    iTotalElements = ExtractorUtils.CalculateFieldElements(strAnalyze);
                }

                sdStructure.Elements = iTotalElements;

                if (sdStructure.StructUnion == StructUnionEnum.Structure)
                {
                    //Calculates the total number of bytes of each field in the structure.  Once the total number of bytes
                    //of all fields are calculated, the Data Size property of the structure data object will be assigned by
                    //multiplying the total number of elements of the structure by the calculated number of bytes of each field.
                    sdStructure.DataSize = sdStructure.Fields.Sum(fld => fld.DataSize) * iTotalElements;
                }
                else
                {
                    //If a union is being extracted, then the union's data size will be set to the field with the maximum data size
                    //multiplied by the total number of elements of the union.
                    sdStructure.DataSize = sdStructure.Fields.Max(fld => fld.DataSize) * iTotalElements;
                }//end if

                return(sdStructure);
            }
            catch (Exception err)
            {
                ErrorHandler.ShowErrorMessage(err, "Error in GetStructData function of StructExtractor class.");
                return(null);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Examines a type definition declaration and extracts the appropriate information about the definition into a TypeDefData data object.  The
        /// ExtractTypeDefData function will be used to extract type defintions derived from primitive data types and other type definitions,
        /// pointers (including functions) and enumerations.  Union and Structure type definitions will be extracted using the ExtractStructData function
        /// of the StructExtractor class instead.  Once the appropriate data is extracted from the type definition string supplied to the function, the data
        ///  can be loaded into the appropriate data table and have their data types be identified in declared variables in structures.
        /// </summary>
        /// <param name="strTypeDef"></param>
        /// <returns></returns>
        public TypeDefData ExtractTypeDefData(string strTypeDef)
        {
            try
            {
                TypeDefData tdTypeDef = new TypeDefData();

                //Checks to see if the type definition is defined as an array and verifies that the array contains only numeric values.  If
                //non-numeric values are presented in the type definition array declaration, they are first converted to their numeric equivalents
                //before proceeding with extracting the type definition declaration.
                if (!strTypeDef.StartsWith("typedef enum") && !strTypeDef.StartsWith("enum"))
                {
                    if (strTypeDef.Contains('[') && strTypeDef.Contains(']'))
                    {
                        if (!ExtractorUtils.IsNumericArray(strTypeDef))
                        {
                            strTypeDef = ExtractorUtils.ConvertNonNumericElements(m_HeaderAccess, strTypeDef);
                        }
                    }//end if

                    string strAnalyze = strTypeDef.Trim();
                    strAnalyze = strAnalyze.Replace("typedef", "").Replace(";", "").Replace("\n", "").Trim();

                    string[] aryTypeDefStr = strAnalyze.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                    //Extract Primitive C++ Data Type Name
                    string strTypeDefDataType = "";

                    for (int i = 0; i < aryTypeDefStr.Length - 1; i++)
                    {
                        strTypeDefDataType += aryTypeDefStr[i] + " ";
                    }

                    strTypeDefDataType = strTypeDefDataType.TrimEnd();

                    //Extract Typedef Declaration Name
                    string strTypeDefName = aryTypeDefStr[aryTypeDefStr.Length - 1];

                    //Set the number of bytes associated with the primitive C++ data type which will then be linked to the typedef declaration name.
                    int iDataSizeBytes = 0;

                    if (!strTypeDefDataType.Contains("*") && !strTypeDefName.Contains("*"))
                    {
                        if (DataAccess.PrimDataTypes.IsPrimitiveDataType(strTypeDefDataType))
                        {
                            //Locates the associated primitive data type associated with the type definition and set the data size of the type definition, according
                            //to the data type.
                            switch (strTypeDefDataType)
                            {
                            case "RMascii":
                            case "RMbool":
                            case "RMuint8":
                            case "RMint8":
                            case "char":
                            case "unsigned char":
                            case "signed char":
                            case "bool":
                                iDataSizeBytes = 1;
                                break;

                            case "RMuint16":
                            case "RMint16":
                            case "short":
                            case "short int":
                            case "unsigned short":
                            case "unsigned short int":
                            case "signed short":
                            case "signed short int":
                            case "wchar_t":
                                iDataSizeBytes = 2;
                                break;

                            case "RMuint32":
                            case "RMint32":
                            case "RMnewOperatorSize":
                            case "int":
                            case "unsigned int":
                            case "signed int":
                            case "long":
                            case "long int":
                            case "signed long":
                            case "signed long int":
                            case "unsigned long":
                            case "unsigned long int":
                            case "float":
                                iDataSizeBytes = 4;
                                break;

                            case "RMint64":
                            case "RMuint64":
                            case "RMreal":
                            case "long long":
                            case "unsigned long long":
                            case "double":
                            case "long double":
                                iDataSizeBytes = 8;
                                break;
                            }
                            ; //end switch
                        }
                        else
                        {
                            //If the data type of the type definition is associated with another type definition, then the type definition will be located and the
                            //data size of the type definition which is the associated data type of the type definition will be assigned to the type definition being
                            //extracted.
                            CHeaderDataSet.tblTypeDefsRow rowTypeDef = m_HeaderAccess.GetTypeDef(strTypeDefDataType);

                            if (rowTypeDef == null)
                            {
                                return(null);
                            }

                            iDataSizeBytes = rowTypeDef.DataSize;
                        }//end if
                    }
                    else
                    {
                        if (strTypeDefName.Contains('*'))
                        {
                            strTypeDefName = strTypeDefName.Replace("*", "");
                        }

                        //Pointers variables will always be set to the pre-defined size of the pointer length on the operating system, which is preset in the
                        //program's settings by the user.
                        iDataSizeBytes = PointerSizeBytes;
                    }//end if

                    int iTotalElements = 1;

                    //If the type definition is declared as an array, then the total number of elements in the array and data size of the type definition array
                    //will be calculated.  The data size of a type definition will be the data size of the data type associated with the type definition multiplied
                    //by the number of elements in the array.
                    if (strTypeDefName.Contains('[') && strTypeDefName.Contains(']'))
                    {
                        iTotalElements = ExtractorUtils.CalculateFieldElements(strTypeDefName);
                        strTypeDefName = strTypeDefName.Split('[')[0].Trim();
                    }//end if

                    tdTypeDef.TypeDefName = strTypeDefName;
                    tdTypeDef.Elements    = iTotalElements;
                    tdTypeDef.DataSize    = iDataSizeBytes * iTotalElements;
                }
                else
                {
                    //Enumerations and Enumeration TypeDefs handled by ExtractEnumData function.
                    tdTypeDef = ExtractEnumData(strTypeDef);
                }//end if

                return(tdTypeDef);
            }
            catch (Exception err)
            {
                ErrorHandler.ShowErrorMessage(err, "Error in ExtractTypeDefData function of TypeExtractor class.");
                return(null);
            }
        }