private static bool DecodeAndCopy(XmlReader reader, XmlWriter writer, RdmFieldDictionary fieldDictionary, RdmEnumTypeDef enumTypeDef, out string errorMsg, int numFragments, bool verbose) { errorMsg = string.Empty; bool bMrnDecoding = false; long totalSize = 0; long currentFragmentSize = 0; long guidSize = 0; var mrnStrings = new StringBuilder(); var guidstr = string.Empty; JToken jsonToken = null; var currentElementName = string.Empty; mrnStrings.Clear(); int currentFragmentNum = 0; int percent = 5; try { while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: { currentFragmentNum++; var percentRead = currentFragmentNum / (double)numFragments; percentRead *= 100.0; if (percentRead >= percent) { Console.WriteLine($"Processing completed {percent}% {currentFragmentNum}/{numFragments} elements"); var r = new Random(); percent += r.Next(10, 18); if (percent > 100) { percent = 100; } } currentElementName = reader.Name; writer.WriteStartElement(reader.Name); if (reader.HasAttributes) { if (currentElementName != "fieldEntry") { writer.WriteAttributes(reader, true); } else { string fieldValue; reader.MoveToFirstAttribute(); var fidId = 0; bMrnDecoding = false; do { // display attribute information var attributeName = reader.Name.Trim(); var attributeVal = reader.Value.Trim(); var fieldName = "Unknown"; fieldValue = attributeVal; if (attributeName.ToLower() != "fieldid") { if (attributeName.ToLower() == "data") { if (FieldValueToString( fidId, attributeVal, out var output, out errorMsg, fieldDictionary: fieldDictionary, enumTypeDef: enumTypeDef)) { fieldValue = output; } writer.WriteAttributeString("decodedData", fieldName == "Unknown" ? fieldValue : string.Empty); writer.WriteAttributeString(attributeName, attributeVal); if (fidId == 32480) // Found total_size { bMrnDecoding = false; totalSize = 0; currentFragmentSize = 0; guidSize = 0; mrnStrings = new StringBuilder(); guidstr = string.Empty; if (fieldValue != "") { totalSize = long.Parse(fieldValue); } } else if (fidId == 32641) //Found fragment { mrnStrings.Append(fieldValue); currentFragmentSize = RdmDataConverter.StringToByteArray(fieldValue) .Length; guidSize += currentFragmentSize; if (totalSize > 0 && guidSize > 0 && (totalSize == guidSize)) { bMrnDecoding = true; } } else if (fidId == 4271 && fieldValue != string.Empty) // Found GUID { guidstr = fieldValue; } } } else { fidId = int.Parse(attributeVal); if (fieldDictionary.GetDictEntryById(fidId, out var rdmEntry)) { fieldName = rdmEntry.Acronym; } writer.WriteAttributeString(attributeName, attributeVal); writer.WriteAttributeString("fieldName", fieldName); } } while (reader.MoveToNextAttribute()); } } // Move reader pointer back to element reader.MoveToElement(); if (reader.IsEmptyElement) { writer.WriteEndElement(); } if (bMrnDecoding) { var pByteArray = RdmDataConverter.StringToByteArray(mrnStrings.ToString()); var jsonString = string.Empty; using (var compressedStream = new MemoryStream(pByteArray)) using (var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress)) using (var resultStream = new MemoryStream()) { zipStream.CopyTo(resultStream); jsonString = Encoding.UTF8.GetString(resultStream.ToArray()); } jsonToken = JToken.Parse(jsonString); if (verbose) { Console.WriteLine($"{jsonToken.ToString(Newtonsoft.Json.Formatting.Indented)}"); } mrnStrings.Clear(); guidSize = 0; totalSize = 0; bMrnDecoding = false; } } break; case XmlNodeType.Comment: writer.WriteComment(reader.Value); break; case XmlNodeType.EndElement: writer.WriteEndElement(); if (reader.Name == "updateMsg" && jsonToken != null) { writer.WriteWhitespace("\r\n"); writer.WriteComment($"{jsonToken.ToString(Newtonsoft.Json.Formatting.Indented)}"); jsonToken = null; } break; case XmlNodeType.Text: writer.WriteString(reader.Value); break; case XmlNodeType.Whitespace: writer.WriteWhitespace(reader.Value); break; } writer.Flush(); } } catch (Exception ex) { errorMsg = $"Error when decoding XML file\r\n{ex.Message}\r\n{ex.StackTrace}"; return(false); } return(true); }
private static bool FieldValueToString(int fidId, string value, out string outputStr, out string errorMsg, RdmFieldDictionary fieldDictionary, RdmEnumTypeDef enumTypeDef) { outputStr = string.Empty; errorMsg = string.Empty; if (value.Trim() == string.Empty) { errorMsg = $"Fid {fidId} Data is null or empty"; return(false); } if (!fieldDictionary.GetDictEntryById(fidId, out var rdmEntry)) { errorMsg = $"Unable to find fid {fidId} in data dictionary"; return(false); } var pBuffer = new string(value.ToCharArray() .Where(c => !char.IsWhiteSpace(c)) .ToArray()); try { switch (rdmEntry.RwfType) { case RwfTypeEnum.Buffer: outputStr = pBuffer; break; case RwfTypeEnum.Date: var dt = RdmDataConverter.HexStringToDateTime(pBuffer); outputStr = $"{(dt.HasValue ? $"{dt.Value.Day}/{dt.Value.Month}/{dt.Value.Year}" : string.Empty)}"; break; case RwfTypeEnum.Enum: outputStr = enumTypeDef.GetEnumDisplayValue(fidId, RdmDataConverter.HexStringToInt(pBuffer) ?? 0, out var display) ? $"{display.EnumDisplay.Replace("\"", "")}({RdmDataConverter.HexStringToInt(pBuffer)})" : $"Unknown Enum({int.Parse(pBuffer)})"; break; case RwfTypeEnum.Int64: case RwfTypeEnum.Uint64: var intVal = RdmDataConverter.HexStringToInt(pBuffer) ?? 0; outputStr = rdmEntry.Acronym.Contains("_MS") ? $"{RdmDataConverter.TimeMsToString(intVal)}" : $"{intVal}"; break; case RwfTypeEnum.Real64: outputStr = $"{RdmDataConverter.RealStringtoDouble(pBuffer).ToString()}"; break; case RwfTypeEnum.RmtesString: { // Check if RMTES Header contains 0x1B 0x25 0x30 follow by UTF-8 string. Then remove the header if (pBuffer.StartsWith("1B2530")) { pBuffer = pBuffer.Remove(0, 6); outputStr = Encoding.UTF8.GetString(RdmDataConverter.StringToByteArray(pBuffer.Trim())); } else if (pBuffer.StartsWith("1B5B")) { outputStr = DecodePartialUpdate( fidId, Encoding.UTF8.GetString(RdmDataConverter.StringToByteArray(pBuffer.Trim()))); } else { outputStr = Encoding.UTF8.GetString(RdmDataConverter.StringToByteArray(pBuffer.Trim())); } var validXmlString = new StringBuilder(); validXmlString.Append(outputStr.Where(XmlConvert.IsXmlChar).ToArray()); outputStr = validXmlString.ToString(); } break; case RwfTypeEnum.AsciiString: outputStr = Encoding.UTF8.GetString( RdmDataConverter.StringToByteArray(pBuffer.Trim())); break; case RwfTypeEnum.Time: outputStr = $"{RdmDataConverter.HexStringToTime(pBuffer.Trim())}"; break; case RwfTypeEnum.Unhandled: outputStr = $"{value}"; break; } } catch (Exception exception) { errorMsg = $"Fid {fidId} {exception.Message}"; return(false); } return(true); }
private async Task BuildTreeAsync(XmlReader reader, TreeViewItem treeViewItem) { // TreeViewItem to add to existing tree var newNode = new TreeViewItem { IsExpanded = true }; while (await reader.ReadAsync()) { // build tree based on node type switch (reader.NodeType) { // if Text node, add its value to tree case XmlNodeType.Text: newNode.Header = reader.Value; treeViewItem.Items.Add(newNode); break; case XmlNodeType.EndElement: // if EndElement, move up tree treeViewItem = (TreeViewItem)treeViewItem.Parent; break; // if new element, add name and traverse tree case XmlNodeType.Element: { var elementType = reader.NodeType.ToString(); var elementName = reader.Name; var attributeStr = string.Empty; //To keep atrribute Name and its Value in Dictionary if (reader.HasAttributes) { var count = reader.AttributeCount; var fidId = 0; for (var i = 0; i < count; i++) { reader.MoveToAttribute(i); var attributeName = reader.Name.Trim(); var attributeVal = reader.Value.Trim(); var hexValue = ""; if (elementName == "fieldEntry") { switch (attributeName) { case "fieldId": { fidId = int.Parse(attributeVal); if (_fieldDictionary.GetDictEntryById(fidId, out var rdmEntry)) { attributeVal = $"{rdmEntry.Acronym}({int.Parse(attributeVal)})"; } else { attributeVal = $"Unknown({int.Parse(attributeVal)})"; } break; } case "data": { hexValue = attributeVal; if (XMLFragmentsData.FieldValueToString( fidId, attributeVal, _fieldDictionary, _enumTypeDef, out var output, out var errorMsg)) { attributeVal = $"{output}"; } break; } } } attributeStr += $" {attributeName}=\"{attributeVal}\""; if (attributeName == "data") { attributeStr += $" Hex=\"{hexValue}\""; } } } newNode.Header = $"{elementName} {attributeStr}"; reader.MoveToElement(); treeViewItem.Items.Add(newNode); if (!reader.IsEmptyElement) { treeViewItem = newNode; } } break; default: newNode.Header = reader.NodeType.ToString(); treeViewItem.Items.Add(newNode); break; } newNode = new TreeViewItem { IsExpanded = true }; } }