protected override string GetOffsetDescriptions() { StringBuilder sb = new StringBuilder(); // CPI will have one or more repeating groups. The length of each is found in the CPC field CPC cpcField = LowestLevelContainer.GetStructure <CPC>(); // Single byte code points are length 10, double are length 11 int standardLength = cpcField.IsSingleByteCodePage ? 10 : 11; // Loop through however many sections we need to for (int curIndex = 0; curIndex < Data.Length;) { // Retrieve the byte sections byte[] GCGID = GetSectionedData(curIndex, 8); byte[] PrtFlags = GetSectionedData(curIndex + 8, 1); byte[] CodePoint = GetSectionedData(curIndex + 9, cpcField.IsSingleByteCodePage ? 1 : 2); // Display first 3 semantics based on predefined offsets above sb.AppendLine(Offsets[0].DisplayDataByType(GCGID)); sb.AppendLine(Offsets[1].DisplayDataByType(PrtFlags)); sb.AppendLine(Offsets[2].DisplayDataByType(CodePoint)); // If this code point includes Unicode scalar value entries, parse them here if (!cpcField.IsSingleByteCodePage) { int numScalarValues = Data[standardLength]; for (int i = 0; i < numScalarValues; i += 4) { Offset fakeOffset = new Offset(0, Lookups.DataTypes.UBIN, $"Unicode Scalar Value {i + 1}"); // Each scalar value is a four byte UBIN int startingIndex = standardLength + (i * 4); byte[] scalarValue = GetSectionedData(startingIndex, 4); sb.AppendLine(fakeOffset.DisplayDataByType(scalarValue)); } // Take extra semantics into account curIndex += 1 + (numScalarValues * 4); } sb.AppendLine(); // Go to the next one curIndex += standardLength; } return(sb.ToString()); }
public override void ParseData() { int curIndex = 0; CPC cpcField = LowestLevelContainer.GetStructure <CPC>(); List <Info> allInfo = new List <Info>(); while (curIndex < Data.Length) { string gid = GetReadableDataPiece(curIndex + 0, 8); byte[] codePoints = GetSectionedData(curIndex + 9, cpcField.IsSingleByteCodePage ? 1 : 2); allInfo.Add(new Info(gid, codePoints)); // 10 bytes RG Length for single bytes, 11 for double curIndex += cpcField.IsSingleByteCodePage ? 10 : 11; } CPIInfos = allInfo; }
protected override string GetSingleOffsetDescription(Offset oSet, byte[] sectionedData) { // Get the object classification triplet from the BOC field in our container ObjectClassification oc = LowestLevelContainer.GetStructure <BOC>()?.Triplets.OfType <ObjectClassification>().FirstOrDefault(); if (oc != null) { StringBuilder sb = new StringBuilder(); string byteLevel = " bytes"; float byteSize = Data.Length; if (byteSize > 1024) { byteSize /= 1024; byteLevel = "KB"; } if (byteSize > 1024) { byteSize /= 1024; byteLevel = "MB"; } ; if (byteSize % 1 > 0) { byteSize = (float)Math.Round(byteSize, 2); } string dataType = "UNKNOWN"; if (Lookups.OIDs.ContainsKey(oc.RegisteredObjectID)) { dataType = Lookups.OIDs[oc.RegisteredObjectID]; } sb.AppendLine($"Data Type: {dataType}"); sb.AppendLine($"Data Length: {byteSize} {byteLevel}"); return(sb.ToString()); } return("Could not find BOC/Object Classification Triplet"); }
private string GetOutlineData() { StringBuilder sb = new StringBuilder(); // Loop through each repeating group of patterns FNC refFNC = LowestLevelContainer.GetStructure <FNC>(); int curIndex = 0; do { uint groupLength = GetNumericValueFromData <uint>(0, 4); uint checksum = GetNumericValueFromData <uint>(4, 4); sb.AppendLine($"Checksum: {checksum}"); int idLength = GetNumericValueFromData <int>(8, 2); string id = idLength > 2 ? GetReadableDataPiece(10, idLength - 2) : string.Empty; sb.AppendLine($"ID: {id}"); // If FNC's pattern tech identifier isn't PFB Type 1, we should have a description int descriptorLength = !string.IsNullOrEmpty(id) && refFNC.PatternTech != FNC.ePatternTech.PFBType1 ? GetNumericValueFromData <ushort>(8 + idLength, 2) : 0; byte[] descriptor = descriptorLength > 2 ? GetSectionedData(8 + idLength + 2, descriptorLength - 2) : new byte[0]; // Object descriptor if (descriptor.Length > 0) { switch (descriptor[0]) { case 1: // CMap file string precedenceCode = descriptor[1] == 0 ? "Primary" : "Auxiliary"; string linkageCode = descriptor[2] == 0 ? "Linked" : "Unlinked"; string writingDirectionCode = descriptor[3] == 1 ? "Horizontal" : descriptor[3] == 2 ? "Vertical" : "Vertical and Horizontal"; string GCSGID = GetReadableDataPiece(8 + idLength + 4, 2); string CPSGID = GetReadableDataPiece(8 + idLength + 6, 2); sb.AppendLine($"Precedence Code: {precedenceCode}"); sb.AppendLine($"Linkage Code: {linkageCode}"); sb.AppendLine($"Writing Direction Code: {writingDirectionCode}"); sb.AppendLine($"GCSGID: {GCSGID}"); sb.AppendLine($"CPSGID: {CPSGID}"); break; case 5: // CID file precedenceCode = descriptor[1] == 0 ? "Primary" : "Auxiliary"; ushort maxV = GetNumericValueFromData <ushort>(8 + idLength + 2, 2); ushort maxW = GetNumericValueFromData <ushort>(8 + idLength + 4, 2); sb.AppendLine($"Precedence Code: {precedenceCode}"); sb.AppendLine($"Max V(y) value: {maxV}"); sb.AppendLine($"Max W(y) value: {maxW}"); break; case 6: // PFB file case 7: // AFM file case 8: // Filename map file sb.AppendLine("No descriptor info provided."); break; } // Object data int dataStartIndex = 8 + idLength + descriptorLength; if (Data.Length > dataStartIndex) { byte[] objData = GetSectionedData(dataStartIndex, Data.Length - dataStartIndex); sb.AppendLine($"Raw Data: {BitConverter.ToString(objData).Replace("-", " ")}"); // Out of curiosity, verify the checksum WE calculate matches up with the one stored! (No current use) uint testChecksum = GetChecksum(objData); } } } while (curIndex < Data.Length); return(sb.ToString()); }