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 void XmlFragmentGrid1_OnMouseDoubleClick(object sender, MouseButtonEventArgs e) { var xmlGridData = (XMLFragmentsData)XmlFragmentGrid1.SelectedItem; if (xmlGridData == null) { return; } _selectedIndex = xmlGridData.Index - 1; XmlTreeView.Items.Clear(); //MessageBox.Show($"{_selectedIndex} {_fragmentCollection.Count}"); if (_fragmentCollection.Count <= 0 || _selectedIndex < 0) { return; } if (!(_rdmFieldDictLoaded && _enumTypeDefDictLoaded)) { Title = $"{_defaultTitle}::Loading RDMFieldDictioanary file"; // Test Rdm dict var rdmResult = await RdmUtils.LoadRdmDictionaryAsync(_rdmDictFilePath); _fieldDictionary = rdmResult.Item2; if (!rdmResult.Item1) { _rdmFieldDictLoaded = false; MessageBox.Show(rdmResult.Item3); } Title = $"{_defaultTitle}::Loading enumtype.def file"; var enumResult = await RdmUtils.LoadEnumTypeDefAsync(_enumTypeDefFilePath); _enumTypeDef = enumResult.Item2; if (!enumResult.Item1) { _enumTypeDefDictLoaded = false; MessageBox.Show(enumResult.Item3); } _rdmFieldDictLoaded = true; _enumTypeDefDictLoaded = true; } Title = $"{_defaultTitle}::Building TreeView from selected XML Fragment"; var settings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment, Async = true, IgnoreWhitespace = true }; using (var reader = XmlReader.Create(new StringReader(_fragmentCollection[_selectedIndex].XmlRawData), settings)) { var tree = new TreeViewItem { // Header =$"{_fragmentCollection[_selectedIndex].TimeStamp} {_fragmentCollection[_selectedIndex].MsgDirection}", Header = $"{XmlFragments.Get(_selectedIndex + 1).MsgTypeRawXmlData}\r\n{XmlFragments.Get(_selectedIndex + 1).TimeRawXmlData}\r\n{XmlFragments.Get(_selectedIndex + 1).RWFMajorMinorVersionRawXmlData}", IsExpanded = true }; // instantiate TreeViewItem // assign name to TreeViewItem XmlTreeView.Items.Add(tree); // add TreeViewItem to TreeView await BuildTreeAsync(reader, tree).ConfigureAwait(false); } UnpackMrnBtn.IsEnabled = !string.IsNullOrEmpty(_fragmentCollection[_selectedIndex].GUID); UnpackMrnBtn.Visibility = UnpackMrnBtn.IsEnabled ? Visibility.Visible : Visibility.Collapsed; XmlTreeView.Visibility = Visibility.Visible; XmlTreeView.IsEnabled = true; Title = _defaultTitle; }