private void ProcessStatsMessage(string msg, string[] values)
        {
            var statsMessage = StatsMessage.CreateStatsMessage(values);

            Stats?.Invoke(statsMessage);
        }
Exemple #2
0
    private void start()
    {
        var numBytesRead = 0;

        while (_isProcessing)
        {
            var n = ReadFromStream(prelude);
            numBytesRead += n;
            n             = ReadFromStream(preludeCRC);
            var preludeCRCBytes = preludeCRC.ToArray();
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(preludeCRCBytes);
            }
            numBytesRead += n;
            var inputArray = new byte[prelude.Length + 4];
            Buffer.BlockCopy(prelude, 0, inputArray, 0, prelude.Length);

            // write real data to inputArray
            Crc32Algorithm.ComputeAndWriteToEnd(inputArray); // last 4 bytes contains CRC
            // transferring data or writing reading, and checking as final operation
            if (!Crc32Algorithm.IsValidWithCrcAtEnd(inputArray))
            {
                throw new ArgumentException("invalid prelude CRC");
            }

            if (!inputArray.Skip(prelude.Length).Take(4).SequenceEqual(preludeCRCBytes))
            {
                throw new ArgumentException("Prelude CRC Mismatch");
            }
            var bytes = prelude.Take(4).ToArray();
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(bytes);
            }
            var totalLength = BitConverter.ToInt32(bytes, 0);
            bytes = prelude.Skip(4).Take(4).ToArray();
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(bytes);
            }

            var headerLength  = BitConverter.ToInt32(bytes, 0);
            var payloadLength = totalLength - headerLength - 16;

            var headers = new byte[headerLength];
            var payload = new byte[payloadLength];
            var num     = ReadFromStream(headers);
            if (num != headerLength)
            {
                throw new IOException("insufficient data");
            }
            num = ReadFromStream(payload);
            if (num != payloadLength)
            {
                throw new IOException("insufficient data");
            }

            numBytesRead += num;
            num           = ReadFromStream(messageCRC);
            var messageCRCBytes = messageCRC.ToArray();
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(messageCRCBytes);
            }
            // now verify message CRC
            inputArray = new byte[totalLength];
            Buffer.BlockCopy(prelude, 0, inputArray, 0, prelude.Length);
            Buffer.BlockCopy(preludeCRC, 0, inputArray, prelude.Length, preludeCRC.Length);
            Buffer.BlockCopy(headers, 0, inputArray, prelude.Length + preludeCRC.Length, headerLength);
            Buffer.BlockCopy(payload, 0, inputArray, prelude.Length + preludeCRC.Length + headerLength, payloadLength);

            // write real data to inputArray
            Crc32Algorithm.ComputeAndWriteToEnd(inputArray); // last 4 bytes contains CRC
            // transferring data or writing reading, and checking as final operation
            if (!Crc32Algorithm.IsValidWithCrcAtEnd(inputArray))
            {
                throw new ArgumentException("invalid message CRC");
            }

            if (!inputArray.Skip(totalLength - 4).Take(4).SequenceEqual(messageCRCBytes))
            {
                throw new ArgumentException("message CRC Mismatch");
            }
            var headerMap = extractHeaders(headers);

            string value = null;
            if (headerMap.TryGetValue(":message-type", out value))
            {
                if (value.Equals(":error"))
                {
                    string errorCode    = null;
                    string errorMessage = null;
                    headerMap.TryGetValue(":error-code", out errorCode);
                    headerMap.TryGetValue(":error-message", out errorMessage);
                    throw new SelectObjectContentException(errorCode + ":" + errorMessage);
                }
            }

            if (headerMap.TryGetValue(":event-type", out value))
            {
                if (value.Equals("End"))
                {
                    // throw new UnexpectedShortReadException("Insufficient data");
                    _isProcessing = false;
                    break;
                }

                if (value.Equals("Cont") || payloadLength < 1)
                {
                    continue;
                }
                if (value.Equals("Progress"))
                {
                    var progress = new ProgressMessage();
                    using (var stream = new MemoryStream(payload))
                    {
                        progress = (ProgressMessage) new XmlSerializer(typeof(ProgressMessage)).Deserialize(stream);
                    }

                    Progress = progress;
                }

                if (value.Equals("Stats"))
                {
                    var stats = new StatsMessage();
                    using (var stream = new MemoryStream(payload))
                    {
                        stats = (StatsMessage) new XmlSerializer(typeof(StatsMessage)).Deserialize(stream);
                    }

                    Stats = stats;
                }

                if (value.Equals("Records"))
                {
                    Payload.Write(payload, 0, payloadLength);
                }
            }
        }

        _isProcessing = false;
        Payload.Seek(0, SeekOrigin.Begin);
        payloadStream.Close();
    }