Exemple #1
0
        Channel[] ReadChannels(ParityStreamReader reader, int channelIdOffset, int numberOfChannels)
        {
            var channels = new Channel[numberOfChannels];

            for (var i = 0; i < numberOfChannels; ++i)
            {
                var channelData = reader.ReadUntil(',');

                var channelState = ' ';
                var channelValue = 0.0;

                if (channelData[0] != ' ' && (channelData[0] < '0' || channelData[0] > '9'))
                {
                    // There is something other than a number in the first character
                    channelState = channelData[0];
                    double.TryParse(channelData.AsSpan().Slice(1), out channelValue);
                }
                else
                {
                    // Just a number
                    double.TryParse(channelData, out channelValue);
                }

                channels[i] = new Channel
                {
                    Id    = i + channelIdOffset,
                    Value = new ChannelValue
                    {
                        State       = channelState,
                        Value       = channelValue,
                        ParityError = false,
                    },
                };
            }

            return(channels);
        }
Exemple #2
0
        /// <inheritdoc/>
        public void BeginParse(Stream stream, Action <Channel> callback, Action <Exception> exceptionOccurred = null)
        {
            try
            {
                var reader = new ParityStreamReader(stream);

                // Keep track of the blocks
                var lastSeenBlock   = -1;
                var channelIdOffset = 0;

                for (;;)
                {
                    reader.SkipTill(StartBlock);

                    var blockNumber      = reader.ReadAsciiInt(3);
                    var numberOfChannels = reader.ReadAsciiInt(3);

                    var outOfOrderBlock = false;

                    if (blockNumber == 0)
                    {
                        lastSeenBlock   = 0;
                        channelIdOffset = 0;
                    }
                    else if (blockNumber == lastSeenBlock + 1)
                    {
                        lastSeenBlock = blockNumber;
                    }
                    else
                    {
                        outOfOrderBlock = true;
                        _logger.Warning($"An out of order block '{blockNumber}' was detected, data will have to be thrown away.");
                    }

                    _logger.Information($"Handling block '{blockNumber}' with '{numberOfChannels}' channels");

                    var channels         = ReadChannels(reader, channelIdOffset, numberOfChannels);
                    var calculatedParity = reader.Parity;

                    if (reader.ReadByte() != '*')
                    {
                        throw new InvalidDataException("Expected '*' after all channel data");
                    }

                    var transmittedParity = reader.ReadAsciiHexByte();

                    if (calculatedParity != transmittedParity)
                    {
                        _logger.Warning($"A parity error was detected while reading block '{blockNumber}'.");
                    }

                    reader.ReadByte(); // There should be an end-of-text here, but there's no need to check

                    // Transmit the data if the block was in order
                    if (!outOfOrderBlock)
                    {
                        for (var i = 0; i < numberOfChannels; ++i)
                        {
                            channels[i].Value.ParityError = calculatedParity != transmittedParity;
                            callback(channels[i]);
                        }
                    }

                    // Keep track of channels seen
                    channelIdOffset += numberOfChannels;
                }
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "Error while parsing");
                if (exceptionOccurred != null)
                {
                    exceptionOccurred(ex);
                }
            }
        }