System.IO.Ports.SerialPortBase.OnDataReceived C# (CSharp) Method

OnDataReceived() protected method

Adds the received data into internal circular read buffer and fires DataReceived event.
protected OnDataReceived ( byte data, int validLength ) : void
data byte An array with data received.
validLength int Number of valid bytes in the array.
return void
        protected virtual void OnDataReceived(byte[] data, int validLength)
        {
            // See GetBufferedData(byte[], int, int) for the illustration of circular buffer.

            if (validLength == 0)
            {
                return;
            }

            lock (_bufferSync)
            {
                if (_incomingBufferPosition == 0)
                {
                    if (_incomingBufferValidLength + validLength > _incomingBuffer.Length)
                    {
                        _incomingBuffer = GetBufferedData(Math.Max(validLength, _incomingBuffer.Length * 2));
                    }
                    Array.Copy(data, 0, _incomingBuffer, _incomingBufferValidLength, validLength);
                    _incomingBufferValidLength += validLength;
                }
                else
                {
                    if (_incomingBufferValidLength + validLength > _incomingBuffer.Length)      // If the received data would not fit in the internal buffer,
                    {
                        _incomingBuffer = GetBufferedData(Math.Max(validLength, _incomingBuffer.Length * 2));          // make it bigger and align the current data at the buffer beginning.
                        _incomingBufferPosition = 0;
                    }

                    int start1 = (_incomingBufferPosition + _incomingBufferValidLength) % _incomingBuffer.Length;   // where the first phase of copy should start (start2 = 0)
                    int end1 = start1 + validLength;                                                                // virtual copy end
                    int end2 = 0;

                    if (end1 > _incomingBuffer.Length)                                                              // if the end is actually wrapped in the circular buffer
                    {
                        end2 = end1 % _incomingBuffer.Length;                                                       // move the overlapping part into the second phase of copy
                        end1 = _incomingBuffer.Length;
                    }

                    Array.Copy(data, 0, _incomingBuffer, start1, end1 - start1);                                    // first phase of copy (to the middle of the buffer up to its end)
                    Array.Copy(data, end1 - start1, _incomingBuffer, 0, end2);                                      // second one          (to the beginning of the buffer up to the wrapped end)
                    _incomingBufferValidLength += validLength;
                }
            }

            if (_readToEvent != null)
                _readToEvent.Set();

            if (_dataReceivedHandlers != null)
                _dataReceivedHandlers(this, null);
        }