/// <summary> /// Queries all structures contained in the Structures data table using a wildcard query. The '?' and '*' wildcard characters can be used to /// query the structures in the function. The '?' character will serve as a single character wildcard in the string, whereas the '*' character /// will serve as a wildcard for any number of characters proceeding the wildcard symbol. If the MatchCase parameter is set to true, then /// the wildcard query will be case-sensitive. /// </summary> /// <param name="strExpression"></param> /// <param name="blMatchCase"></param> /// <returns></returns> public CHeaderDataSet.tblStructuresRow[] QueryStructsByWildcard( string strExpression, bool blMatchCase = false, SortOrderEnum sortOrder = SortOrderEnum.Ascending, StructUnionEnum structOrUnion = StructUnionEnum.Both) { try { IEnumerable <CHeaderDataSet.tblStructuresRow> qryStructRows = null; CHeaderDataSet.tblStructuresRow[] aryStructRows = null; strExpression = "^" + strExpression.Replace('?', '.').Replace("*", "\\w*") + "\\z"; if (!blMatchCase) { strExpression = "(?i)" + strExpression; qryStructRows = StructuresTable.Where(s => Regex.IsMatch(s.StructName, strExpression)); } else { strExpression = "(?-i)" + strExpression; qryStructRows = StructuresTable.Where(s => Regex.IsMatch(s.StructName, strExpression)); }//end if if (structOrUnion != StructUnionEnum.Both) { if (structOrUnion == StructUnionEnum.Structure) { qryStructRows = qryStructRows.Where(s => s.StructUnion == 1); } else { qryStructRows = qryStructRows.Where(s => s.StructUnion == 2); } }//end if if (sortOrder == SortOrderEnum.Ascending) { qryStructRows = qryStructRows.OrderBy(s => s.StructName); } else { qryStructRows = qryStructRows.OrderByDescending(s => s.StructName); } aryStructRows = qryStructRows.ToArray(); return(aryStructRows); } catch (Exception err) { ErrorHandler.ShowErrorMessage(err, "Error in QueryStructsByWildcard function of DataAccess class."); return(null); } }
/// <summary> /// Queries all structures from the Structure data table contained in the linked HeaderData data set that are within a specified range of data sizes. /// The structure rows will be queried and sorted in ascending or descending order. This function can be used to query either sets of structures or unions. /// </summary> /// <param name="iMinSize"></param> /// <param name="iMaxSize"></param> /// <param name="sortOrder"></param> /// <param name="structOrUnion"></param> /// <returns></returns> public CHeaderDataSet.tblStructuresRow[] QueryStructsBySize(int iMinSize, int iMaxSize = -1, SortOrderEnum sortOrder = SortOrderEnum.Ascending, StructUnionEnum structOrUnion = StructUnionEnum.Structure) { try { if (iMaxSize == -1) { iMaxSize = Int32.MaxValue; } IEnumerable <CHeaderDataSet.tblStructuresRow> qryStructRows = null; CHeaderDataSet.tblStructuresRow[] aryStructRows = null; qryStructRows = StructuresTable.Where(s => s.DataSize >= iMinSize && s.DataSize <= iMaxSize); if (structOrUnion != StructUnionEnum.Both) { if (structOrUnion == StructUnionEnum.Structure) { qryStructRows = qryStructRows.Where(s => s.StructUnion == 1); } else { qryStructRows = qryStructRows.Where(s => s.StructUnion == 2); } }//end if if (sortOrder == SortOrderEnum.Ascending) { qryStructRows = qryStructRows.OrderBy(s => s.DataSize); } else { qryStructRows = qryStructRows.OrderByDescending(s => s.DataSize); } aryStructRows = qryStructRows.ToArray(); return(aryStructRows); } catch (Exception err) { ErrorHandler.ShowErrorMessage(err, "Error in QueryStructsBySize function of DataAccess class."); return(null); } }
/// <summary> /// Queries all structures contained in the Structures data table using a regular expression query. The results will match exactly to criteria /// specified in the regular expression and will be case and space sensitive. /// </summary> /// <param name="strRegex"></param> /// <returns></returns> public CHeaderDataSet.tblStructuresRow[] QueryStructsByRegex(string strRegex, SortOrderEnum sortOrder = SortOrderEnum.Ascending, StructUnionEnum structOrUnion = StructUnionEnum.Both) { try { IEnumerable <CHeaderDataSet.tblStructuresRow> qryStructRows = null; CHeaderDataSet.tblStructuresRow[] aryStructRows = null; qryStructRows = StructuresTable.Where(s => Regex.IsMatch(s.StructName, strRegex)); if (structOrUnion != StructUnionEnum.Both) { if (structOrUnion == StructUnionEnum.Structure) { qryStructRows = qryStructRows.Where(s => s.StructUnion == 1); } else { qryStructRows = qryStructRows.Where(s => s.StructUnion == 2); } }//end if if (sortOrder == SortOrderEnum.Ascending) { qryStructRows = qryStructRows.OrderBy(s => s.StructName); } else { qryStructRows = qryStructRows.OrderByDescending(s => s.StructName); } aryStructRows = qryStructRows.ToArray(); return(aryStructRows); } catch (Exception err) { ErrorHandler.ShowErrorMessage(err, "Error in QueryStructsByRegex function of DataAccess class."); return(null); } }
/* NOT USED: Structures and Unions can be queried specifically by the StructOrUnion parameter. * /// <summary> * /// Queries all unions from the Structure data table contained in the linked HeaderData data set that are within a specified range of data sizes. * /// The union rows will be queried and sorted in ascending or descending order. * /// </summary> * /// <param name="iMinSize"></param> * /// <param name="iMaxSize"></param> * /// <param name="sortOrder"></param> * /// <param name="structOrUnion"></param> * /// <returns></returns> * public CHeaderDataSet.tblStructuresRow[] QueryUnionsBySize(int iMinSize, int iMaxSize = -1, * SortOrderEnum sortOrder = SortOrderEnum.Ascending) * { * try * { * return QueryStructsBySize(iMinSize, iMaxSize, sortOrder, StructUnionEnum.Union); * } * catch (Exception err) * { * ErrorHandler.ShowErrorMessage(err, "Error in QueryUnionsBySize function of DataAccess class."); * * return null; * } * } */ /// <summary> /// Queries all structures contained in the Structures data table that match either a portion or the entire name of the structure query string passed /// to the function. The structure query can also be case-sensitive depending on the parameters that are set in the function. /// NOTE: This version of the function does not use wildcards, but will just match a portion or the entire name of each structure stored in the /// Structures data table. /// </summary> /// <param name="strStructQuery"></param> /// <returns></returns> public CHeaderDataSet.tblStructuresRow[] QueryStructsByName( string strStructQuery, bool blMatchAny = true, bool blMatchExact = false, bool blMatchCase = false, SortOrderEnum sortOrder = SortOrderEnum.Ascending, StructUnionEnum structOrUnion = StructUnionEnum.Both) { try { IEnumerable <CHeaderDataSet.tblStructuresRow> qryStructRows = null; CHeaderDataSet.tblStructuresRow[] aryStructRows = null; if (!blMatchExact) { if (!blMatchCase) { qryStructRows = StructuresTable.Where(s => blMatchAny ? s.StructName.ToUpper().Contains(strStructQuery.ToUpper()) : s.StructName.ToUpper().StartsWith(strStructQuery.ToUpper())); } else { qryStructRows = StructuresTable.Where(s => blMatchAny ? s.StructName.Contains(strStructQuery) : s.StructName.StartsWith(strStructQuery)); }//end if } else { if (!blMatchCase) { qryStructRows = StructuresTable.Where(s => s.StructName.ToUpper() == strStructQuery.ToUpper()); } else { qryStructRows = StructuresTable.Where(s => s.StructName == strStructQuery); } //end if } //end if if (structOrUnion != StructUnionEnum.Both) { if (structOrUnion == StructUnionEnum.Structure) { qryStructRows = qryStructRows.Where(s => s.StructUnion == 1); } else { qryStructRows = qryStructRows.Where(s => s.StructUnion == 2); } }//end if if (sortOrder == SortOrderEnum.Ascending) { qryStructRows = qryStructRows.OrderBy(s => s.StructName); } else { qryStructRows = qryStructRows.OrderByDescending(s => s.StructName); } aryStructRows = qryStructRows.ToArray(); return(aryStructRows); } catch (Exception err) { ErrorHandler.ShowErrorMessage(err, "Error in QueryStructsByName function of DataAccess 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); } }