internal string GetDesc(SubrecordStructure[] sss, dFormIDLookupI formIDLookup) { var start = "[Record]" + Environment.NewLine + GetBaseDesc(); string end; try { end = GetExtendedDesc(sss, formIDLookup); } catch { end = "Warning: An error occured while processing the record. It may not conform to the strucure defined in RecordStructure.xml"; } if (end == null) { return(start); } return(start + Environment.NewLine + Environment.NewLine + "[Formatted information]" + Environment.NewLine + end); }
private string GetExtendedDesc(SubrecordStructure[] sss, dFormIDLookupI formIDLookup) { if (sss == null) { return(null); } var s = RecordStructure.Records[Name].description + Environment.NewLine; for (var i = 0; i < sss.Length; i++) { if (sss[i].elements == null) { return(s); } if (sss[i].notininfo) { continue; } s += Environment.NewLine + SubRecords[i].GetFormattedData(sss[i], formIDLookup); } return(s); }
internal string GetFormattedData(SubrecordStructure ss, dFormIDLookupI formIDLookup) { int offset = 0; string s = ss.name + " (" + ss.desc + ")" + Environment.NewLine; try { for (int j = 0; j < ss.elements.Length; j++) { if (offset == Data.Length && j == ss.elements.Length - 1 && ss.elements[j].optional) break; string s2 = ""; if (!ss.elements[j].notininfo) s2 += ss.elements[j].name + ": "; switch (ss.elements[j].type) { case ElementValueType.Int: string tmps = TypeConverter.h2si(Data[offset], Data[offset + 1], Data[offset + 2], Data[offset + 3]).ToString(); if (!ss.elements[j].notininfo) { if (ss.elements[j].hexview) s2 += TypeConverter.h2i(Data[offset], Data[offset + 1], Data[offset + 2], Data[offset + 3]).ToString("X8"); else s2 += tmps; if (ss.elements[j].options != null) { for (int k = 0; k < ss.elements[j].options.Length; k += 2) { if (tmps == ss.elements[j].options[k + 1]) s2 += " (" + ss.elements[j].options[k] + ")"; } } else if (ss.elements[j].flags != null) { uint val = TypeConverter.h2i(Data[offset], Data[offset + 1], Data[offset + 2], Data[offset + 3]); string tmp2 = ""; for (int k = 0; k < ss.elements[j].flags.Length; k++) { if ((val & (1 << k)) != 0) { if (tmp2.Length > 0) tmp2 += ", "; tmp2 += ss.elements[j].flags[k]; } } if (tmp2.Length > 0) s2 += " (" + tmp2 + ")"; } } offset += 4; break; case ElementValueType.Short: tmps = TypeConverter.h2ss(Data[offset], Data[offset + 1]).ToString(); if (!ss.elements[j].notininfo) { if (ss.elements[j].hexview) s2 += TypeConverter.h2ss(Data[offset], Data[offset + 1]).ToString("X4"); else s2 += tmps; if (ss.elements[j].options != null) { for (int k = 0; k < ss.elements[j].options.Length; k += 2) { if (tmps == ss.elements[j].options[k + 1]) s2 += " (" + ss.elements[j].options[k] + ")"; } } else if (ss.elements[j].flags != null) { uint val = TypeConverter.h2s(Data[offset], Data[offset + 1]); string tmp2 = ""; for (int k = 0; k < ss.elements[j].flags.Length; k++) { if ((val & (1 << k)) != 0) { if (tmp2.Length > 0) tmp2 += ", "; tmp2 += ss.elements[j].flags[k]; } } if (tmp2.Length > 0) s2 += " (" + tmp2 + ")"; } } offset += 2; break; case ElementValueType.Byte: tmps = Data[offset].ToString(); if (!ss.elements[j].notininfo) { if (ss.elements[j].hexview) s2 += Data[offset].ToString("X2"); else s2 += tmps; if (ss.elements[j].options != null) { for (int k = 0; k < ss.elements[j].options.Length; k += 2) { if (tmps == ss.elements[j].options[k + 1]) s2 += " (" + ss.elements[j].options[k] + ")"; } } else if (ss.elements[j].flags != null) { int val = Data[offset]; string tmp2 = ""; for (int k = 0; k < ss.elements[j].flags.Length; k++) { if ((val & (1 << k)) != 0) { if (tmp2.Length > 0) tmp2 += ", "; tmp2 += ss.elements[j].flags[k]; } } if (tmp2.Length > 0) s2 += " (" + tmp2 + ")"; } } offset++; break; case ElementValueType.FormID: uint id = TypeConverter.h2i(Data[offset], Data[offset + 1], Data[offset + 2], Data[offset + 3]); if (!ss.elements[j].notininfo) s2 += id.ToString("X8"); if (formIDLookup != null) s2 += ": " + formIDLookup(id); offset += 4; break; case ElementValueType.Float: if (!ss.elements[j].notininfo) s2 += TypeConverter.h2f(Data[offset], Data[offset + 1], Data[offset + 2], Data[offset + 3]).ToString(); offset += 4; break; case ElementValueType.String: if (!ss.elements[j].notininfo) { while (Data[offset] != 0) s2 += (char)Data[offset++]; } else { while (Data[offset] != 0) offset++; } offset++; break; case ElementValueType.fstring: s2 += GetStrData(); break; case ElementValueType.Blob: s2 += GetHexData(); break; default: throw new ApplicationException(); } if (!ss.elements[j].notininfo) s2 += Environment.NewLine; if (offset < Data.Length && j == ss.elements.Length - 1 && ss.elements[j].repeat) j--; s += s2; } } catch { s += "Warning: Subrecord doesn't seem to match the expected structure" + Environment.NewLine; } return s; }
internal string GetDesc(SubrecordStructure[] sss, dFormIDLookupI formIDLookup) { string start = "[Record]" + Environment.NewLine + GetBaseDesc(); string end; try { end = GetExtendedDesc(sss, formIDLookup); } catch { end = "Warning: An error occured while processing the record. It may not conform to the strucure defined in RecordStructure.xml"; } if (end == null) return start; else return start + Environment.NewLine + Environment.NewLine + "[Formatted information]" + Environment.NewLine + end; }
private string GetExtendedDesc(SubrecordStructure[] sss, dFormIDLookupI formIDLookup) { if (sss == null) return null; string s = RecordStructure.Records[Name].description + Environment.NewLine; for (int i = 0; i < sss.Length; i++) { if (sss[i].elements == null) return s; if (sss[i].notininfo) continue; s += Environment.NewLine + SubRecords[i].GetFormattedData(sss[i], formIDLookup); } return s; }
public static void GetFormattedData(this SubRecord rec, StringBuilder s) { SubrecordStructure ss = rec.Structure; if (ss == null) { return; } var p = rec.GetPlugin(); dFormIDLookupI formIDLookup = p.LookupFormID; dLStringLookup strLookup = p.LookupFormStrings; dFormIDLookupR formIDLookupR = p.GetRecordByID; var recdata = rec.GetReadonlyData(); int offset = 0; s.AppendFormat("{0} ({1})", ss.name, ss.desc); s.AppendLine(); try { for (int eidx = 0, elen = 1; eidx < ss.elements.Length; eidx += elen) { var sselem = ss.elements[eidx]; bool repeat = sselem.repeat > 0; elen = sselem.repeat > 1 ? sselem.repeat : 1; do { for (int eoff = 0; eoff < elen && offset < recdata.Length; ++eoff) { sselem = ss.elements[eidx + eoff]; if (offset == recdata.Length && eidx == ss.elements.Length - 1 && sselem.optional > 0) { break; } if (!sselem.notininfo) { s.Append(sselem.name).Append(": "); } switch (sselem.type) { case ElementValueType.Int: { string tmps = TypeConverter.h2si(recdata[offset], recdata[offset + 1], recdata[offset + 2], recdata[offset + 3]).ToString(); if (!sselem.notininfo) { if (sselem.hexview) { s.Append(TypeConverter.h2i(recdata[offset], recdata[offset + 1], recdata[offset + 2], recdata[offset + 3]).ToString("X8")); } else { s.Append(tmps); } if (sselem.options != null && sselem.options.Length > 0) { for (int k = 0; k < sselem.options.Length; k += 2) { if (tmps == sselem.options[k + 1]) { s.AppendFormat(" ({0})", sselem.options[k]); } } } else if (sselem.flags != null && sselem.flags.Length > 0) { uint val = TypeConverter.h2i(recdata[offset], recdata[offset + 1], recdata[offset + 2], recdata[offset + 3]); var tmp2 = new StringBuilder(); for (int k = 0; k < sselem.flags.Length; k++) { if ((val & (1 << k)) != 0) { if (tmp2.Length > 0) { tmp2.Append(", "); } tmp2.Append(sselem.flags[k]); } } if (tmp2.Length > 0) { s.AppendFormat(" ({0})", tmp2); } } } offset += 4; } break; case ElementValueType.UInt: { string tmps = TypeConverter.h2i(recdata[offset], recdata[offset + 1], recdata[offset + 2], recdata[offset + 3]).ToString(); if (!sselem.notininfo) { if (sselem.hexview) { s.Append(TypeConverter.h2i(recdata[offset], recdata[offset + 1], recdata[offset + 2], recdata[offset + 3]).ToString("X8")); } else { s.Append(tmps); } if (sselem.options != null && sselem.options.Length > 0) { for (int k = 0; k < sselem.options.Length; k += 2) { if (tmps == sselem.options[k + 1]) { s.AppendFormat(" ({0})", sselem.options[k]); } } } else if (sselem.flags != null && sselem.flags.Length > 0) { uint val = TypeConverter.h2i(recdata[offset], recdata[offset + 1], recdata[offset + 2], recdata[offset + 3]); var tmp2 = new StringBuilder(); for (int k = 0; k < sselem.flags.Length; k++) { if ((val & (1 << k)) != 0) { if (tmp2.Length > 0) { tmp2.Append(", "); } tmp2.Append(sselem.flags[k]); } } if (tmp2.Length > 0) { s.AppendFormat(" ({0})", tmp2); } } } offset += 4; } break; case ElementValueType.Short: { string tmps = TypeConverter.h2ss(recdata[offset], recdata[offset + 1]).ToString(); if (!sselem.notininfo) { if (sselem.hexview) { s.Append(TypeConverter.h2ss(recdata[offset], recdata[offset + 1]).ToString("X4")); } else { s.Append(tmps); } if (sselem.options != null && sselem.options.Length > 0) { for (int k = 0; k < sselem.options.Length; k += 2) { if (tmps == sselem.options[k + 1]) { s.AppendFormat(" ({0})", sselem.options[k]); } } } else if (sselem.flags != null && sselem.flags.Length > 0) { uint val = TypeConverter.h2s(recdata[offset], recdata[offset + 1]); var tmp2 = new StringBuilder(); for (int k = 0; k < sselem.flags.Length; k++) { if ((val & (1 << k)) != 0) { if (tmp2.Length > 0) { tmp2.Append(", "); } tmp2.Append(sselem.flags[k]); } } if (tmp2.Length > 0) { s.AppendFormat(" ({0})", tmp2); } } } offset += 2; } break; case ElementValueType.UShort: { string tmps = TypeConverter.h2s(recdata[offset], recdata[offset + 1]).ToString(); if (!sselem.notininfo) { if (sselem.hexview) { s.Append(TypeConverter.h2s(recdata[offset], recdata[offset + 1]).ToString("X4")); } else { s.Append(tmps); } if (sselem.options != null && sselem.options.Length > 0) { for (int k = 0; k < sselem.options.Length; k += 2) { if (tmps == sselem.options[k + 1]) { s.Append(" (").Append(sselem.options[k]).Append(")"); } } } else if (sselem.flags != null && sselem.flags.Length > 0) { uint val = TypeConverter.h2s(recdata[offset], recdata[offset + 1]); var tmp2 = new StringBuilder(); for (int k = 0; k < sselem.flags.Length; k++) { if ((val & (1 << k)) != 0) { if (tmp2.Length > 0) { tmp2.Append(", "); } tmp2.Append(sselem.flags[k]); } } if (tmp2.Length > 0) { s.AppendFormat(" ({0})", tmp2); } } } offset += 2; } break; case ElementValueType.Byte: { string tmps = recdata[offset].ToString(); if (!sselem.notininfo) { if (sselem.hexview) { s.Append(recdata[offset].ToString("X2")); } else { s.Append(tmps); } if (sselem.options != null && sselem.options.Length > 0) { for (int k = 0; k < sselem.options.Length; k += 2) { if (tmps == sselem.options[k + 1]) { s.AppendFormat(" ({0})", sselem.options[k]); } } } else if (sselem.flags != null && sselem.flags.Length > 0) { int val = recdata[offset]; var tmp2 = new StringBuilder(); for (int k = 0; k < sselem.flags.Length; k++) { if ((val & (1 << k)) != 0) { if (tmp2.Length > 0) { tmp2.Append(", "); } tmp2.Append(sselem.flags[k]); } } if (tmp2.Length > 0) { s.AppendFormat(" ({0})", tmp2); } } } offset++; } break; case ElementValueType.SByte: { string tmps = ((sbyte)recdata[offset]).ToString(); if (!sselem.notininfo) { if (sselem.hexview) { s.Append(recdata[offset].ToString("X2")); } else { s.Append(tmps); } if (sselem.options != null && sselem.options.Length > 0) { for (int k = 0; k < sselem.options.Length; k += 2) { if (tmps == sselem.options[k + 1]) { s.AppendFormat(" ({0})", sselem.options[k]); } } } else if (sselem.flags != null && sselem.flags.Length > 0) { int val = recdata[offset]; var tmp2 = new StringBuilder(); for (int k = 0; k < sselem.flags.Length; k++) { if ((val & (1 << k)) != 0) { if (tmp2.Length > 0) { tmp2.Append(", "); } tmp2.Append(sselem.flags[k]); } } if (tmp2.Length > 0) { s.AppendFormat(" ({0})", tmp2); } } } offset++; } break; case ElementValueType.FormID: { uint id = TypeConverter.h2i(recdata[offset], recdata[offset + 1], recdata[offset + 2], recdata[offset + 3]); if (!sselem.notininfo) { s.Append(id.ToString("X8")); } if (id != 0 && formIDLookup != null) { s.Append(": ").Append(formIDLookup(id)); } offset += 4; } break; case ElementValueType.Float: if (!sselem.notininfo) { s.Append(TypeConverter.h2f(recdata[offset], recdata[offset + 1], recdata[offset + 2], recdata[offset + 3])); } offset += 4; break; case ElementValueType.String: if (!sselem.notininfo) { while (recdata[offset] != 0) { s.Append((char)recdata[offset++]); } } else { while (recdata[offset] != 0) { offset++; } } offset++; break; case ElementValueType.Blob: if (!sselem.notininfo) { s.Append(TypeConverter.GetHexData(recdata, offset, recdata.Length - offset)); } offset += recdata.Length - offset; break; case ElementValueType.BString: { int len = TypeConverter.h2s(recdata[offset], recdata[offset + 1]); if (!sselem.notininfo) { s.Append(TESVSnip.Framework.Services.Encoding.Instance.GetString(recdata, offset + 2, len)); } offset += 2 + len; } break; case ElementValueType.IString: { int len = TypeConverter.h2si(recdata[offset], recdata[offset + 1], recdata[offset + 2], recdata[offset + 3]); if (!sselem.notininfo) { s.Append(TESVSnip.Framework.Services.Encoding.Instance.GetString(recdata, offset + 4, len)); } offset += 4 + len; } break; case ElementValueType.LString: { // Try to guess if string or string index. Do not know if the external string checkbox is set or not in this code int left = recdata.Length - offset; var data = new ArraySegment <byte>(recdata, offset, left); bool isString = TypeConverter.IsLikelyString(data); uint id = TypeConverter.h2i(data); string lvalue = strLookup(id); if (!string.IsNullOrEmpty(lvalue) || !isString) { if (!sselem.notininfo) { s.Append(id.ToString("X8")); } if (strLookup != null) { s.Append(": ").Append(lvalue); } offset += 4; } else { if (!sselem.notininfo) { while (recdata[offset] != 0) { s.Append((char)recdata[offset++]); } } else { while (recdata[offset] != 0) { offset++; } } offset++; } } break; case ElementValueType.Str4: { if (!sselem.notininfo) { s.Append(TESVSnip.Framework.Services.Encoding.Instance.GetString(recdata, offset, 4)); } offset += 4; } break; default: throw new ApplicationException(); } if (!sselem.notininfo) { s.AppendLine(); } } }while (repeat && offset < recdata.Length); } if (offset < recdata.Length) { s.AppendLine(); s.AppendLine("Remaining Data: "); s.Append(TypeConverter.GetHexData(recdata, offset, recdata.Length - offset)); } } catch { s.AppendLine("Warning: Subrecord doesn't seem to match the expected structure"); } }
public static void GetFormattedData(this SubRecord rec, RTFBuilder s) { SubrecordStructure ss = rec.Structure; if (ss == null || ss.elements == null) { s.Append("String:\t").AppendLine(rec.GetStrData()).AppendLine(); s.Append("Hex: \t").AppendLine(rec.GetHexData()); s.AppendPara(); return; } bool addTerminatingParagraph = false; try { var p = rec.GetPlugin(); dFormIDLookupI formIDLookup = p.LookupFormID; dLStringLookup strLookup = p.LookupFormStrings; dFormIDLookupR formIDLookupR = p.GetRecordByID; // Table of items var table = new List <List <RTFCellDefinition> >(); // set up elements float maxWidth = 0; int maxFirstCellWidth = 0; var elems = rec.EnumerateElements(true).Where(x => x.Structure != null && !x.Structure.notininfo).ToList(); if (elems.Count == 0) { return; } foreach (var element in elems) { Size sz = s.MeasureText(element.Structure.name); int width = Math.Max(sz.Width / 11, 10); // approximate convert pixels to twips as the rtflib has crap documentation if (width > maxFirstCellWidth) { maxFirstCellWidth = width; } } foreach (var element in elems) { var row = new List <RTFCellDefinition>(); table.Add(row); var sselem = element.Structure; bool hasOptions = sselem.options != null && sselem.options.Length > 0; bool hasFlags = sselem.flags != null && sselem.flags.Length > 1; // setup borders for header var value = element.Value; var nameCell = new RTFCellDefinition(maxFirstCellWidth, RTFAlignment.MiddleLeft, RTFBorderSide.Default, 15, Color.DarkGray, Padding.Empty); row.Add(nameCell); switch (sselem.type) { case ElementValueType.FormID: row.Add(new RTFCellDefinition(12, RTFAlignment.MiddleLeft, RTFBorderSide.Default, 15, Color.DarkGray, Padding.Empty)); row.Add(new RTFCellDefinition(30, RTFAlignment.MiddleLeft, RTFBorderSide.Default, 15, Color.DarkGray, Padding.Empty)); // Optional Add cell for break; case ElementValueType.LString: row.Add(new RTFCellDefinition(12, RTFAlignment.MiddleLeft, RTFBorderSide.Default, 15, Color.DarkGray, Padding.Empty)); row.Add(new RTFCellDefinition(30, RTFAlignment.MiddleLeft, RTFBorderSide.Default, 15, Color.DarkGray, Padding.Empty)); break; case ElementValueType.BString: case ElementValueType.IString: case ElementValueType.String: row.Add(new RTFCellDefinition(42, RTFAlignment.MiddleLeft, RTFBorderSide.Default, 15, Color.DarkGray, Padding.Empty)); break; case ElementValueType.Int: case ElementValueType.UInt: case ElementValueType.Byte: case ElementValueType.SByte: case ElementValueType.Short: case ElementValueType.UShort: case ElementValueType.Float: row.Add(new RTFCellDefinition(20, RTFAlignment.MiddleLeft, RTFBorderSide.Default, 15, Color.DarkGray, Padding.Empty)); row.Add(new RTFCellDefinition(30, RTFAlignment.MiddleLeft, RTFBorderSide.Default, 15, Color.DarkGray, Padding.Empty)); break; case ElementValueType.Blob: row.Add(new RTFCellDefinition(42, RTFAlignment.MiddleLeft, RTFBorderSide.Default, 15, Color.DarkGray, Padding.Empty)); break; case ElementValueType.Str4: row.Add(new RTFCellDefinition(42, RTFAlignment.MiddleLeft, RTFBorderSide.Default, 15, Color.DarkGray, Padding.Empty)); break; default: row.Add(new RTFCellDefinition(42, RTFAlignment.MiddleLeft, RTFBorderSide.Default, 15, Color.DarkGray, Padding.Empty)); break; } maxWidth = Math.Max(maxWidth, row.Sum(x => x.CellWidthRaw)); } var rowWidth = (int)(maxWidth * 100.0f); var pd = new Padding { All = 50 }; var hdrd = new RTFRowDefinition(rowWidth, RTFAlignment.TopLeft, RTFBorderSide.Default, 15, SystemColors.WindowText, pd); var hdrcds = new[] { new RTFCellDefinition(rowWidth, RTFAlignment.MiddleLeft, RTFBorderSide.Default, 15, Color.DarkGray, Padding.Empty) }; addTerminatingParagraph = true; s.Reset(); using (IRTFRow ie = s.CreateRow(hdrd, hdrcds)) { foreach (var item in ie) { var rb = item.Content; item.Content.FontSize(s.DefaultFontSize + 1).FontStyle(FontStyle.Bold).ForeColor(KnownColor.DarkCyan).AppendFormat("{0} ({1})", ss.name, ss.desc); } } for (int rowIdx = 0; rowIdx < elems.Count; ++rowIdx) { var rd = new RTFRowDefinition(rowWidth, RTFAlignment.TopLeft, RTFBorderSide.Default, 15, SystemColors.WindowText, pd); var cds = table[rowIdx]; var elem = elems[rowIdx]; var sselem = elem.Structure; var value = elem.Value; string recprefix = null; Record record = null; string strValue = null; // value to display string strDesc = null; // first description string strDesc2 = null; // second description bool hasOptions = sselem.options != null && sselem.options.Length > 0; bool hasFlags = sselem.flags != null && sselem.flags.Length > 1; if (!string.IsNullOrWhiteSpace(elem.Structure.funcr)) { if (elem.Type == ElementValueType.Float) { value = PyInterpreter.ExecuteFunction <float>(elem, FunctionOperation.ForReading); } else if (elem.Type == ElementValueType.Int) { value = PyInterpreter.ExecuteFunction <int>(elem, FunctionOperation.ForReading); } else if (elem.Type == ElementValueType.Short) { value = PyInterpreter.ExecuteFunction <short>(elem, FunctionOperation.ForReading); } else if (elem.Type == ElementValueType.UShort) { value = PyInterpreter.ExecuteFunction <ushort>(elem, FunctionOperation.ForReading); } else if (elem.Type == ElementValueType.UInt) { value = PyInterpreter.ExecuteFunction <uint>(elem, FunctionOperation.ForReading); } } // Pre row write caching to avoid expensive duplicate calls between cells switch (sselem.type) { case ElementValueType.FormID: { var id = (uint)value; strValue = id.ToString("X8"); if (id != 0) { record = formIDLookupR != null?formIDLookupR(id) : null; } if (record != null) { var pref = record.GetPlugin(); recprefix = pref != null?string.Format("{0}@{1}", pref.Name, record.Name) : record.Name; strDesc = record.DescriptiveName; var full = record.SubRecords.FirstOrDefault(x => x.Name == "FULL"); if (full != null) { // split the cell 2 in 2 if full name found var data = new ArraySegment <byte>(full.GetReadonlyData()); bool isString = TypeConverter.IsLikelyString(data); string lvalue = isString ? full.GetStrData() : strLookup != null?strLookup(TypeConverter.h2i(data)) : null; if (!string.IsNullOrEmpty(lvalue)) { var first = cds[cds.Count - 1]; Size sz = s.MeasureText(lvalue); int width = Math.Min(40, Math.Max(sz.Width / 12, 10)); // approximate convert pixels to twips as the rtflib has crap documentation var second = new RTFCellDefinition(width, RTFAlignment.MiddleLeft, RTFBorderSide.Default, 0, Color.DarkGray, Padding.Empty); cds.Add(second); strDesc2 = lvalue; } } } } break; case ElementValueType.LString: { if (elem.Type == ElementValueType.String) { strValue = string.Empty; strDesc = value.ToString(); } else if (TypeConverter.IsLikelyString(elem.Data)) { strValue = string.Empty; strDesc = TypeConverter.GetString(elem.Data); } else { uint id = TypeConverter.h2i(elem.Data); strValue = id.ToString("X8"); strDesc = strLookup != null?strLookup(id) : null; } } break; case ElementValueType.Blob: strValue = TypeConverter.GetHexData(elem.Data); break; case ElementValueType.SByte: case ElementValueType.Int: case ElementValueType.Short: { if (sselem.hexview || hasFlags) { if (sselem.hexviewwithdec) { strValue = string.Format(string.Format("{{0:X{0}}}", elem.Data.Count * 2), value) + string.Format(" : {0}", value); } else { strValue = string.Format(string.Format("{{0:X{0}}}", elem.Data.Count * 2), value); } } else { strValue = value == null ? string.Empty : value.ToString(); } if (hasOptions) { int intVal = Convert.ToInt32(value); for (int k = 0; k < sselem.options.Length; k += 2) { int intValOption; if (int.TryParse(sselem.options[k + 1], out intValOption) && intVal == intValOption) { strDesc = sselem.options[k]; } } } else if (hasFlags) { int intVal = Convert.ToInt32(value); var tmp2 = new StringBuilder(); for (int k = 0; k < sselem.flags.Length; k++) { if ((intVal & (1 << k)) != 0) { if (tmp2.Length > 0) { tmp2.Append(", "); } tmp2.Append(sselem.flags[k]); } } strDesc = tmp2.ToString(); } } break; case ElementValueType.UInt: case ElementValueType.Byte: case ElementValueType.UShort: { if (sselem.hexview || hasFlags) { if (sselem.hexviewwithdec) { strValue = string.Format(string.Format("{{0:X{0}}}", elem.Data.Count * 2), value) + string.Format(" : {0}", value); } else { strValue = string.Format(string.Format("{{0:X{0}}}", elem.Data.Count * 2), value); } } else { strValue = value == null ? string.Empty : value.ToString(); } if (hasOptions) { uint intVal = Convert.ToUInt32(value); for (int k = 0; k < sselem.options.Length; k += 2) { if (intVal == uint.Parse(sselem.options[k + 1])) { strDesc = sselem.options[k]; } } } else if (hasFlags) { uint intVal = Convert.ToUInt32(value); var tmp2 = new StringBuilder(); for (int k = 0; k < sselem.flags.Length; k++) { if ((intVal & (1 << k)) != 0) { if (tmp2.Length > 0) { tmp2.Append(", "); } tmp2.Append(sselem.flags[k]); } } strDesc = tmp2.ToString(); } } break; case ElementValueType.Str4: strValue = TypeConverter.GetString(elem.Data); break; case ElementValueType.BString: strValue = TypeConverter.GetBString(elem.Data); break; case ElementValueType.IString: strValue = TypeConverter.GetIString(elem.Data); break; default: strValue = value == null ? string.Empty : value.ToString(); break; } // Now create row and fill in cells using (IRTFRow ie = s.CreateRow(rd, cds)) { int colIdx = 0; IEnumerator <IBuilderContent> ie2 = ie.GetEnumerator(); for (bool ok = ie2.MoveNext(); ok; ok = ie2.MoveNext(), ++colIdx) { using (var item = ie2.Current) { var rb = item.Content; if (colIdx == 0) { // name rb.FontStyle(FontStyle.Bold).Append(sselem.name); } else if (colIdx == 1) { // value switch (sselem.type) { case ElementValueType.FormID: if (((uint)value) == 0) { rb.Append(strValue); } else if (record != null) { RTFRenderer.AppendLink(rb, strValue, record.GetLink()); } else if (!string.IsNullOrEmpty(sselem.FormIDType)) { RTFRenderer.AppendLink(rb, strValue, string.Format("{0}:{1}", sselem.FormIDType, strValue)); } else { RTFRenderer.AppendLink(rb, strValue, string.Format("XXXX:{0}", strValue)); } break; default: rb.Append(strValue); break; } } else if (colIdx == 2) { // desc if (!string.IsNullOrEmpty(strDesc)) { rb.Append(strDesc); } } else if (colIdx == 3) { // desc2 if (!string.IsNullOrEmpty(strDesc2)) { rb.Append(strDesc2); } } } } } } } catch { s.AppendLine("Warning: Subrecord doesn't seem to match the expected structure"); } finally { if (addTerminatingParagraph) { s.Reset(); s.AppendPara(); } } }
internal string GetFormattedData(SubrecordStructure ss, dFormIDLookupI formIDLookup) { var offset = 0; var s = ss.name + " (" + ss.desc + ")" + Environment.NewLine; try { for (var j = 0; j < ss.elements.Length; j++) { if (offset == Data.Length && j == ss.elements.Length - 1 && ss.elements[j].optional) { break; } var s2 = ""; if (!ss.elements[j].notininfo) { s2 += ss.elements[j].name + ": "; } switch (ss.elements[j].type) { case ElementValueType.Int: var tmps = TypeConverter.h2si(Data[offset], Data[offset + 1], Data[offset + 2], Data[offset + 3]).ToString(); if (!ss.elements[j].notininfo) { if (ss.elements[j].hexview) { s2 += TypeConverter.h2i(Data[offset], Data[offset + 1], Data[offset + 2], Data[offset + 3]).ToString("X8"); } else { s2 += tmps; } if (ss.elements[j].options != null) { for (var k = 0; k < ss.elements[j].options.Length; k += 2) { if (tmps == ss.elements[j].options[k + 1]) { s2 += " (" + ss.elements[j].options[k] + ")"; } } } else if (ss.elements[j].flags != null) { var val = TypeConverter.h2i(Data[offset], Data[offset + 1], Data[offset + 2], Data[offset + 3]); var tmp2 = ""; for (var k = 0; k < ss.elements[j].flags.Length; k++) { if ((val & (1 << k)) != 0) { if (tmp2.Length > 0) { tmp2 += ", "; } tmp2 += ss.elements[j].flags[k]; } } if (tmp2.Length > 0) { s2 += " (" + tmp2 + ")"; } } } offset += 4; break; case ElementValueType.Short: tmps = TypeConverter.h2ss(Data[offset], Data[offset + 1]).ToString(); if (!ss.elements[j].notininfo) { if (ss.elements[j].hexview) { s2 += TypeConverter.h2ss(Data[offset], Data[offset + 1]).ToString("X4"); } else { s2 += tmps; } if (ss.elements[j].options != null) { for (var k = 0; k < ss.elements[j].options.Length; k += 2) { if (tmps == ss.elements[j].options[k + 1]) { s2 += " (" + ss.elements[j].options[k] + ")"; } } } else if (ss.elements[j].flags != null) { uint val = TypeConverter.h2s(Data[offset], Data[offset + 1]); var tmp2 = ""; for (var k = 0; k < ss.elements[j].flags.Length; k++) { if ((val & (1 << k)) != 0) { if (tmp2.Length > 0) { tmp2 += ", "; } tmp2 += ss.elements[j].flags[k]; } } if (tmp2.Length > 0) { s2 += " (" + tmp2 + ")"; } } } offset += 2; break; case ElementValueType.Byte: tmps = Data[offset].ToString(); if (!ss.elements[j].notininfo) { if (ss.elements[j].hexview) { s2 += Data[offset].ToString("X2"); } else { s2 += tmps; } if (ss.elements[j].options != null) { for (var k = 0; k < ss.elements[j].options.Length; k += 2) { if (tmps == ss.elements[j].options[k + 1]) { s2 += " (" + ss.elements[j].options[k] + ")"; } } } else if (ss.elements[j].flags != null) { int val = Data[offset]; var tmp2 = ""; for (var k = 0; k < ss.elements[j].flags.Length; k++) { if ((val & (1 << k)) != 0) { if (tmp2.Length > 0) { tmp2 += ", "; } tmp2 += ss.elements[j].flags[k]; } } if (tmp2.Length > 0) { s2 += " (" + tmp2 + ")"; } } } offset++; break; case ElementValueType.FormID: var id = TypeConverter.h2i(Data[offset], Data[offset + 1], Data[offset + 2], Data[offset + 3]); if (!ss.elements[j].notininfo) { s2 += id.ToString("X8"); } if (formIDLookup != null) { s2 += ": " + formIDLookup(id); } offset += 4; break; case ElementValueType.Float: if (!ss.elements[j].notininfo) { s2 += TypeConverter.h2f(Data[offset], Data[offset + 1], Data[offset + 2], Data[offset + 3]).ToString(); } offset += 4; break; case ElementValueType.String: if (!ss.elements[j].notininfo) { while (Data[offset] != 0) { s2 += (char)Data[offset++]; } } else { while (Data[offset] != 0) { offset++; } } offset++; break; case ElementValueType.fstring: s2 += GetStrData(); break; case ElementValueType.Blob: s2 += GetHexData(); break; default: throw new ApplicationException(); } if (!ss.elements[j].notininfo) { s2 += Environment.NewLine; } if (offset < Data.Length && j == ss.elements.Length - 1 && ss.elements[j].repeat) { j--; } s += s2; } } catch { s += "Warning: Subrecord doesn't seem to match the expected structure" + Environment.NewLine; } return(s); }