예제 #1
0
        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);
        }
예제 #2
0
        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
                };
            }
        }