/* NOT USED: Type Definition Arrays will now be handled in the same manner as non-array type definition declarations * /// <summary> * /// TODO * /// </summary> * /// <param name="strTypeDefAry"></param> * /// <returns></returns> * public object[] ExtractTypeDefArrayData(string strTypeDefAry) * { * try * { * CHeaderDataSet.tblTypeDefsDataTable dtTypeDefs = m_dsHeaderData.tblTypeDefs; * * object[] aryTypeDefAryVarData = null; * * string strAnalyze = strTypeDefAry.Trim(); * strAnalyze = strAnalyze.Replace("typedef", "").Replace(";", "").Trim(); * * string[] aryTypeDefAryStr = strAnalyze.Split(' '); * * //Extract TypeDef Variable Name * string strTypeDefName = aryTypeDefAryStr[0]; * * //Extract Typedef Array Declaration Name and Total Number of elements in the array. * int iTotalAryElements = ExtractorUtils.CalculateFieldElements(aryTypeDefAryStr[aryTypeDefAryStr.Length - 1]); * string strTypeDefAryName = aryTypeDefAryStr[aryTypeDefAryStr.Length - 1].Split('[')[0].Trim(); * * //Set the number of bytes associated with the array type definition which will then be linked to the array typedef declaration name. * //The number of bytes will be calculated by multiplying the number of bytes associated with the primitive derived type definition associated * //with the array type definition. * CHeaderDataSet.tblTypeDefsRow rowTypeDef = dtTypeDefs.FindByTypeDefName(strTypeDefName); * * if (rowTypeDef == null) * return null; * * int iSrcTypeDefBytes = rowTypeDef.DataSize; * int iDataSizeBytes = iTotalAryElements * iSrcTypeDefBytes; * * aryTypeDefAryVarData = new object[] { strTypeDefAryName, strTypeDefName, iTotalAryElements, iDataSizeBytes }; * * return aryTypeDefAryVarData; * } * catch (Exception err) * { * ErrorHandler.ShowErrorMessage(err, "Error in ExtractTypeDefArrayData function of TypeExtractor class."); * return null; * } * } */ #endregion #region Enumeration Extraction Functions /// <summary> /// Examines an enumeration declaration and extracts the appropriate information about the definition into a TypeDefData data object. Once /// the appropriate data is extracted from the enumeration 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="strEnumDef"></param> /// <returns></returns> public TypeDefData ExtractEnumData(string strEnumDef) { try { TypeDefData tdEnum = null; string[] aryEnumDefStr = null; string strEnumName = ""; if (strEnumDef.StartsWith("enum")) { strEnumDef = strEnumDef.Replace("enum", "").Trim(); aryEnumDefStr = strEnumDef.Split('{'); strEnumName = aryEnumDefStr[0].Trim(); } else { aryEnumDefStr = strEnumDef.Split('}'); //Extract Enumeration Typedef Declaration Name strEnumName = aryEnumDefStr[aryEnumDefStr.Length - 1]; strEnumName = strEnumName.Replace(";", "").Trim(); }//end if int iTotalElements = 1; //If the enumeration is declared as an array, then the total number of elements in the array and data size of the enumeration array //will be calculated. The data size of an enumeration will be the data size of enumerations on the system multiplied by the number //of elements in the array. if (strEnumName.Contains('[') && strEnumName.Contains(']')) { iTotalElements = ExtractorUtils.CalculateFieldElements(strEnumName); strEnumName = strEnumName.Split('[')[0].Trim(); }//end if tdEnum = new TypeDefData() { TypeDefName = strEnumName, Elements = iTotalElements, DataSize = EnumSizeBytes * iTotalElements }; return(tdEnum); } catch (Exception err) { ErrorHandler.ShowErrorMessage(err, "Error in ExtractEnumData function of TypeExtractor class."); return(null); } }
/// <summary> /// Extracts the next detected field (or set of fields) contained within a structure/union block. The fields will be extracted from the structure/union within the code block /// passed in the Struct parameter of the function. The next field to be extracted in the structure block will be determined by the position marker passed by reference /// in the CurPos parameter. In the case that a set of fields are declared in one line and separated by commas, a set of fields for the declared /// data type will be extracted and loaded into the FieldData array. Once a field or set of fields are detected and extracted they will be loaded /// into a FieldData array that will be returned by the function and can be added to the associated StructData data object. The function will also /// update the current position marker of the structure body, the current field index and byte offset. /// </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> /// <param name="strStructName">The name of the structure whose fields are to be extracted.</param> /// <param name="structOrUnion">Indicates if the block of code represents a structure or union.</param> /// <param name="iCurPos">The current position in the structure/union code block.</param> /// <param name="iCurFieldIndex">The next available field index in the structure to be assigned to the next extracted field.</param> /// <param name="iFieldByteOffset">The current byte offset to be assigned to the next field in the structure to be extracted.</param> /// <param name="blBitDetected">Indicates if the previous field extracted from the structure was a field with a bit declaration that has not currently /// exceeded the boundary of its associated data type.</param> /// <param name="iBitFieldDataSize">If bit fields are currently being extracted from the structure, then this field must be set to size /// of the data type associated with the bit fields that are being extracted. The BitFieldDataSize will be used to increment the byte offset /// of the structure after the end of the bit field declaration is detected.</param> /// <param name="iBitCount">The total number of bits that are currently calculated for the current set of bit fields being extracted from /// the structure. If the bit count surpasses the data size, then it indicates the end of the current set of bit fields being extracted and /// the beginning of a new set of bit fields in the structure.</param> /// <param name="strBitFieldTypeName">If bit fields are currently being extracted from the structure, then this field must be set with the /// previous data type name associated with the bit field declaration being extracted. Once a new field type is detected, the current bit field /// extraction will stop for that field declaration.</param> /// <returns></returns> private FieldData[] ExtractStructFieldData(string strStruct, string strStructName, StructUnionEnum structOrUnion, ref int iCurPos, ref int iCurFieldIndex, ref int iFieldByteOffset, ref bool blBitDetected, ref int iBitFieldDataSize, ref int iBitCount, ref string strBitFieldTypeName) { try { FieldData[] aryFields = null; FieldData fdFieldSchema = new FieldData(); bool blIsStructDeclaration = false; if (strStruct.IndexOf("struct", iCurPos) == iCurPos || strStruct.IndexOf("union", iCurPos) == iCurPos) { int iBracketIndex = strStruct.IndexOf('{', iCurPos); if (iBracketIndex != -1) { if (iBracketIndex < strStruct.IndexOf(';', iCurPos)) { blIsStructDeclaration = true; } } //end if } //end if int iFieldEndPos = -1; string strFieldData = ""; bool blIsEnum = false; bool blIsStruct = false; bool blIsPointer = false; bool blIsFunction = false; bool blNewFieldDetected = true; if (blBitDetected) { blNewFieldDetected = false; } if (!blIsStructDeclaration) { iFieldEndPos = strStruct.IndexOf(';', iCurPos); strFieldData = strStruct.Substring(iCurPos, iFieldEndPos - iCurPos).Trim(); }//end if if (strStruct.IndexOf("enum", iCurPos) == iCurPos) { fdFieldSchema.FieldType = FieldTypeEnum.Enum; iCurPos += "enum".Length; blIsEnum = true; blNewFieldDetected = true; } else if (strStruct.IndexOf("struct", iCurPos) == iCurPos) { fdFieldSchema.FieldType = FieldTypeEnum.Structure; if (!blIsStructDeclaration) { iCurPos += "struct".Length; } blIsStruct = true; blNewFieldDetected = true; } else if (strStruct.IndexOf("union", iCurPos) == iCurPos) { fdFieldSchema.FieldType = FieldTypeEnum.Structure; if (!blIsStructDeclaration) { iCurPos += "union".Length; } blIsStruct = true; blNewFieldDetected = true; }//end if if (strFieldData.Contains("*") || (strFieldData.Contains("(") && strFieldData.EndsWith(")"))) { if (blIsStruct) { blIsStruct = false; } fdFieldSchema.FieldType = FieldTypeEnum.Pointer; fdFieldSchema.DataSize = PointerSizeBytes; blIsPointer = true; blNewFieldDetected = true; if (strFieldData.Contains("(") && strFieldData.EndsWith(")")) { blIsFunction = true; fdFieldSchema.FieldTypeName = "function"; } //end if } //end if if (!blIsStructDeclaration) { strFieldData = strStruct.Substring(iCurPos, iFieldEndPos - iCurPos).Trim(); //int iFieldCurPos = 0; if (!blIsFunction) { int iFieldCount = 0; List <string> lstFieldNames = new List <string>(); string[] aryFieldSections = null; string strFieldTypeName = ""; int iFieldNameStartIndex = 0; //The field names will begin either at the last element in the split field sections array string or when the first element //containing a comma (which indicates the beginning of a multiple single field type declaration) is located. if (!strFieldData.Contains(',')) { aryFieldSections = strFieldData.Split(new char[] { ' ', '\n' }, StringSplitOptions.RemoveEmptyEntries); iFieldNameStartIndex = aryFieldSections.Length - 1; for (int i = 0; i < aryFieldSections.Length - 1; i++) { strFieldTypeName += aryFieldSections[i]; }//next i iFieldNameStartIndex = aryFieldSections.Length - 1; lstFieldNames.Add(aryFieldSections[iFieldNameStartIndex].Trim().Replace(";", "")); } else { string[] aryFieldCommaSections = strFieldData.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); string strSection = aryFieldCommaSections[0]; if (strSection.IndexOf(':') == -1) { aryFieldSections = strSection.Split(new char[] { ' ', '\n' }, StringSplitOptions.RemoveEmptyEntries); } else { int iColonIndex = strSection.IndexOf(':'); string strSectionSub = strSection.Substring(iColonIndex, strSection.Length - iColonIndex); strSection = strSection.Remove(iColonIndex); strSection += strSectionSub.Replace(" ", ""); aryFieldSections = strSection.Split(new char[] { ' ', '\n' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 1; i < aryFieldCommaSections.Length; i++) { aryFieldCommaSections[i] = aryFieldCommaSections[i].Replace(" ", "").Replace("\n", ""); } //next i } //end if for (int i = 0; i < aryFieldSections.Length - 1; i++) { strFieldTypeName += aryFieldSections[i]; }//next i iFieldNameStartIndex = aryFieldSections.Length - 1; lstFieldNames.Add(aryFieldSections[iFieldNameStartIndex].Trim().Replace(";", "")); for (int i = 1; i < aryFieldCommaSections.Length; i++) { lstFieldNames.Add(aryFieldCommaSections[i].Trim().Replace(";", "")); } }//end if fdFieldSchema.FieldTypeName = strFieldTypeName; if (!blIsPointer && !blIsStruct && !blIsEnum) { fdFieldSchema.FieldType = GetVarFieldType(fdFieldSchema.FieldTypeName); } //If fields in the structure are declared with bit values, then a check will be made to determine if any of the bit fields //in the bit field set are declared without field names. Bit fields declared without field names indicate either unused //bits in the field or the repositioning to a new byte in the bit declared field set. If an empty bit field name is declared //with a bit value of zero, it indicates that the new bit field declared in the set will be positioned at a beginning of a new //byte. if (lstFieldNames[0].Contains(":")) { int iCheckBitFieldCounter = 0; int iFieldNameCountBitCheck = lstFieldNames.Count; int iCheckBitIndex = 0; int iFieldBits = 0; while (iCheckBitFieldCounter < iFieldNameCountBitCheck) { string strFieldName = lstFieldNames[iCheckBitIndex].Replace(" ", ""); if (strFieldName.StartsWith(":")) { iFieldBits = Convert.ToInt32(strFieldName.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries)[1]); if (iFieldBits == 0) { //If a blank field with a zero value is detected, then advance the bit field counter to the beginning position //of the next byte of the field. int iByteAlignedBits = Convert.ToInt32(Math.Truncate(iBitFieldDataSize / 8d)); iBitCount = 8 + iByteAlignedBits; } else { //If a blank field with a bit value declaration is detected, then the bit field counter is advanced to the number //of bits specified in the field. iBitCount += iFieldBits; }//end if //Since blank name bit field declarations are used only for repositioning the bit fields, these fields will be removed //from the field data list and not added to the structure. lstFieldNames.RemoveAt(iCheckBitIndex); } else { iCheckBitIndex++; } iCheckBitFieldCounter++; }//end while if (lstFieldNames.Count == 0) { return(null); } }//end if iFieldCount = lstFieldNames.Count; aryFields = new FieldData[iFieldCount]; int iFieldTypeDataSize = 0; if (!blIsPointer) { iFieldTypeDataSize = GetVarFieldDataSize(fdFieldSchema.FieldTypeName); } else { iFieldTypeDataSize = PointerSizeBytes; if (!fdFieldSchema.FieldTypeName.Contains("*")) { fdFieldSchema.FieldTypeName += "*"; } }//end if for (int i = 0; i < lstFieldNames.Count; i++) { if (blBitDetected && i > 0) { blNewFieldDetected = false; } aryFields[i] = new FieldData(); string[] aryFieldNameRaw = lstFieldNames[i].Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries); string strFieldName = aryFieldNameRaw[0].Trim(); int iFieldBits = 0; //FOR DEBUGGING //if (aryFieldNameRaw.Length > 1) // Debugger.Break(); ////////////// if (blBitDetected) { bool blBitFieldEndDetect = false; //If a bit field declaration extraction is currently in progress in the structure, then a check will be made to see if //another field of the same bit declaration is detected or if a new field outside the set of fields of the bit declaration //is detected, which will signal an end to the extraction of the previous set of bit fields. if (aryFieldNameRaw.Length == 1) { if (blBitDetected) { blBitFieldEndDetect = true; } } else if (fdFieldSchema.FieldTypeName != strBitFieldTypeName) { //A field with a new data type, even being the beginning of a new bit field declaration, will result in the ending //of the previous set of bit field declarations, thereby advancing the offset position to the boundary of the //previous bit field declaration's data type. blBitFieldEndDetect = true; } else if (iBitCount >= (iBitFieldDataSize * 8)) { //If the previous set of bit fields that were extracted have been calculated to equal the size of the data type //associated with the set of bit fields then it can be determine that the end of the declaration for the set of //bit fields has been reached. If a new set of bit field declarations are detected, then a new extraction operation //will be performed for the new set of bit fields. The offset position will be advanced to the boundary of the //previous bit fields declaration's data type. blBitFieldEndDetect = true; }//end if if (blBitFieldEndDetect) { //Once a new field is detected in the structure, the byte offset will be advanced in the structure. The byte offset //will be advanced to a position that is equal to the size of the previous data type associated with the bit field //declaration. blNewFieldDetected = true; iFieldByteOffset += iBitFieldDataSize; blBitDetected = false; } //end if } //end if if (blNewFieldDetected && aryFieldNameRaw.Length > 1) { //If a new bit field declaration is detected in the structure, then the appropriate variables will be set to indicate //that the next set of fields being extracted in the structure are part of a bit field declaration, until the end of the //bit field declaration (or structure declaration) is detected. blBitDetected = true; iBitFieldDataSize = iFieldTypeDataSize; strBitFieldTypeName = strFieldTypeName; }//end if if (aryFieldNameRaw.Length > 1) { iFieldBits = Convert.ToInt32(aryFieldNameRaw[1].Trim()); iBitCount += iFieldBits; }//end if int iTotalElements = 1; if (strFieldName.Contains("[")) { iTotalElements = ExtractorUtils.CalculateFieldElements(strFieldName); strFieldName = strFieldName.Split('[')[0].Trim(); }//end if if (strFieldName.Contains("*")) { strFieldName = strFieldName.Replace("*", "").Trim(); } aryFields[i].FieldName = strFieldName; aryFields[i].Elements = iTotalElements; if (blNewFieldDetected) { aryFields[i].DataSize = iFieldTypeDataSize * iTotalElements; } else { //Bit field declarations will only have their data size set to the field's data size for the first field of the bit //declaration that is extracted. This will also allow for the structure's total data size to be properly calculated. aryFields[i].DataSize = 0; } if (blBitDetected) { aryFields[i].Bits = iFieldBits; } }//next strFieldName foreach (FieldData fdField in aryFields) { fdField.FieldIndex = iCurFieldIndex; iCurFieldIndex++; fdField.FieldKey = strStructName + "_" + fdField.FieldIndex; fdField.ParentName = strStructName; fdField.FieldType = fdFieldSchema.FieldType; fdField.FieldTypeName = fdFieldSchema.FieldTypeName; fdField.FieldByteOffset = iFieldByteOffset; //Field byte offsets will only be incremented during the extraction of fields if the fields are being extracted from a structure. If a union //block is having its fields, extracted, the byte offset of all fields will be the same (all fields occupy shared memory space within a union) //and the field byte offset variable will be incremented only after the entire union's data is extracted. if (structOrUnion == StructUnionEnum.Structure) { //Field byte offsets will only be advanced if the field being extracted is not part of a bit declaration. Byte offsets will //be the same for each bit declaration and each declared bit variable will be treated as a single field of its associated //data type. if (!blBitDetected) { //Advances byte offset position in structure to next field after the total bytes of the current field are calculated. iFieldByteOffset += fdField.DataSize; } } //end if } //next fdField } else { //If the current field being extracted in the structure is a pointer to a function, then the function field will be extracted //as a pointer. In addition, to being identified as a pointer field, the function will have a field name set to the //word "Function" concatenated with the index of the function field in the structure. This way the function //field can be identified in the structure. All additional settings of the function, such as field type name will have been //set previously in the code. fdFieldSchema.FieldIndex = iCurFieldIndex; iCurFieldIndex++; fdFieldSchema.FieldName = "Function" + "_" + fdFieldSchema.FieldIndex.ToString(); fdFieldSchema.FieldKey = strStructName + "_" + fdFieldSchema.FieldIndex.ToString(); fdFieldSchema.ParentName = strStructName; fdFieldSchema.FieldByteOffset = iFieldByteOffset; //Field byte offsets will only be incremented during the extraction of fields if the fields are being extracted from a structure. If a union //block is having its fields, extracted, the byte offset of all fields will be the same (all fields occupy shared memory space within a union) //and the field byte offset variable will be incremented only after the entire union's data is extracted. if (structOrUnion == StructUnionEnum.Structure) { //Advances byte offset position in structure to next field after the total bytes of the current field are calculated. iFieldByteOffset += fdFieldSchema.DataSize; }//end if aryFields = new FieldData[] { fdFieldSchema }; }//end if //Advances the cursor of the structure to the end of the current field data that was extracted and to the beginning of the //next set of field data to be extracted or to the end of the structure, if it has been reached. iCurPos = iFieldEndPos + 1; } else { string strNestedStruct = ""; int[] aryNestedBlockIndexes = ParserUtils.GetBlockIndexes(ref strStruct, iCurPos); if (aryNestedBlockIndexes == null) { return(null); } int iEndNestStructIndex = strStruct.IndexOf(';', aryNestedBlockIndexes[1]); strNestedStruct = strStruct.Substring(iCurPos, iEndNestStructIndex + 1 - iCurPos); StructData sdChild = ExtractStructData(strNestedStruct); if (sdChild == null) { return(null); } FieldData fdField = new FieldData(); fdField.FieldType = FieldTypeEnum.Structure; fdField.FieldTypeName = sdChild.StructName; fdField.FieldName = sdChild.StructName; if (fdField.FieldName.Trim() == "") { //If a nested structure or union is unnamed, then a field type name of "struct" or "union" will be set as the field type //name of the field. if (sdChild.StructUnion == StructUnionEnum.Structure) { fdField.FieldTypeName = "struct"; } else { fdField.FieldTypeName = "union"; } //If a nested structure or union is unnamed, then a generated field name of "Structure" or "Union" concatenated //with the field index will be set as the name of the field in the structure. if (sdChild.StructUnion == StructUnionEnum.Structure) { fdField.FieldName = "Structure_" + iCurFieldIndex.ToString(); } else { fdField.FieldName = "Union_" + iCurFieldIndex.ToString(); } } else { //Since there will be no way of identifying if nested structures/unions contained within structures and unions are either //a structure or union type (as of the current version), it will be neccessary to concatenate to the name of the //field, whether it is a nested structure or union. if (sdChild.StructUnion == StructUnionEnum.Structure) { fdField.FieldName += " <struct>"; } else { fdField.FieldName += " <union>"; } }//end if fdField.Elements = sdChild.Elements; fdField.DataSize = sdChild.DataSize; fdField.FieldIndex = iCurFieldIndex; iCurFieldIndex++; fdField.FieldKey = strStructName + "_" + fdField.FieldIndex; fdField.ParentName = strStructName; fdField.FieldByteOffset = iFieldByteOffset; //Field byte offsets will only be incremented during the extraction of fields if the fields are being extracted from a structure. If a union //block is having its fields, extracted, the byte offset of all fields will be the same (all fields occupy shared memory space within a union) //and the field byte offset variable will be incremented only after the entire union's data is extracted. if (structOrUnion == StructUnionEnum.Structure) { //Advances byte offset position in structure to next field after the total bytes of the current field are calculated. iFieldByteOffset += fdField.DataSize; }//end if aryFields = new FieldData[] { fdField }; //Advances the cursor of the structure to the end of the current field data that was extracted and to the beginning of the //next set of field data to be extracted or to the end of the structure, if it has been reached. iCurPos = iEndNestStructIndex + 1; }//end if return(aryFields); } catch (Exception err) { ErrorHandler.ShowErrorMessage(err, "Error in ExtractStructFieldData function of StructExtractor class."); return(null); } }
/// <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); } }
/// <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); } }