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);
}