/// <summary> /// Connection failed. Reset state until a new connection is received. /// </summary> public void ResetRead() { _receiveBytesLeft = -1; _stateLength = -1; _state = MessageFrameState.Flags; _payloadBuffer = WriterContext.EmptySegment; _readOffset = 0; Properties.Clear(); if (_payloadStream != null) { _payloadStream.Close(); _payloadStream = null; } }
public bool Read(byte[] buffer, ref int offset, ref int bytesTransferred) { var numberOfBytesTransferredFromStart = bytesTransferred; var allCompleted = false; while (bytesTransferred > 0 && !allCompleted) { bool isBufferCopyCompleted; switch (_state) { case MessageFrameState.Flags: if (buffer[offset] == 32) { throw new BackTrackException("", offset); } Flags = (FrameFlags) buffer[offset]; _state = MessageFrameState.SequenceNumber; ++offset; --bytesTransferred; _receiveBytesLeft = 2; break; case MessageFrameState.SequenceNumber: isBufferCopyCompleted = CopyToReadBuffer(buffer, ref offset, ref bytesTransferred); if (isBufferCopyCompleted) { if (BitConverter.IsLittleEndian) Array.Reverse(_stateBuffer, 0, 2); SequenceNumber = BitConverter.ToUInt16(_stateBuffer, 0); _state = MessageFrameState.DestinationLength; } break; case MessageFrameState.DestinationLength: _stateLength = _receiveBytesLeft = buffer[offset]; _state = _stateLength == 0 ? MessageFrameState.FilterLength : MessageFrameState.Destination; ++offset; --bytesTransferred; if (_state == MessageFrameState.FilterLength) { _receiveBytesLeft = 2; } break; case MessageFrameState.Destination: isBufferCopyCompleted = CopyToReadBuffer(buffer, ref offset, ref bytesTransferred); if (isBufferCopyCompleted) { Destination = Encoding.ASCII.GetString(_stateBuffer, 0, _stateLength); _receiveBytesLeft = 2; _state = MessageFrameState.FilterLength; } break; case MessageFrameState.FilterLength: isBufferCopyCompleted = CopyToReadBuffer(buffer, ref offset, ref bytesTransferred); if (isBufferCopyCompleted) { if (BitConverter.IsLittleEndian) Array.Reverse(_stateBuffer, 0, 2); _stateLength = _receiveBytesLeft = BitConverter.ToInt16(_stateBuffer, 0); _state = _stateLength == 0 ? MessageFrameState.PayloadLength : MessageFrameState.Filter; if (_state == MessageFrameState.PayloadLength) { _receiveBytesLeft = IsFlaggedAsSmall ? 1 : 4; } } break; case MessageFrameState.Filter: isBufferCopyCompleted = CopyToReadBuffer(buffer, ref offset, ref bytesTransferred); if (isBufferCopyCompleted) { var filters = Encoding.ASCII.GetString(_stateBuffer, 0, _stateLength); DecodeFilters(filters); _state = MessageFrameState.PayloadLength; _receiveBytesLeft = IsFlaggedAsSmall ? 1 : 4; } break; case MessageFrameState.PayloadLength: if (IsFlaggedAsSmall) { _receivePayloadLength = buffer[offset]; _state = MessageFrameState.SmallPayload; _receiveBytesLeft = _receivePayloadLength; ++offset; --bytesTransferred; } else { isBufferCopyCompleted = CopyToReadBuffer(buffer, ref offset, ref bytesTransferred); if (isBufferCopyCompleted) { if (BitConverter.IsLittleEndian) Array.Reverse(_stateBuffer, 0, 4); _receivePayloadLength = BitConverter.ToInt32(_stateBuffer, 0); _receiveBytesLeft = _receivePayloadLength; _state = _receivePayloadLength <= BufferLimit ? MessageFrameState.SmallPayload : MessageFrameState.LargePayload; } } if (_state == MessageFrameState.SmallPayload) { if (_internalPayloadBuffer == null || _payloadBuffer.Array.Length < _receivePayloadLength) { _internalPayloadBuffer = new byte[_receivePayloadLength*2]; } } break; case MessageFrameState.SmallPayload: var bytesToCopy = Math.Min(_receiveBytesLeft, bytesTransferred); Buffer.BlockCopy(buffer, offset, _internalPayloadBuffer, _readOffset, bytesToCopy); _receiveBytesLeft -= bytesToCopy; bytesTransferred -= bytesToCopy; offset += bytesToCopy; if (_receiveBytesLeft == 0) { _payloadBuffer = new ArraySegment<byte>(_internalPayloadBuffer, 0, _receivePayloadLength); allCompleted = true; } else { _readOffset += bytesToCopy; } break; case MessageFrameState.LargePayload: allCompleted = true; break; } } if (offset < 0) throw new InvalidOperationException(); return allCompleted; }
public bool Read(byte[] buffer, ref int offset, ref int bytesTransferred) { var numberOfBytesTransferredFromStart = bytesTransferred; var allCompleted = false; while (bytesTransferred > 0 && !allCompleted) { bool isBufferCopyCompleted; switch (_state) { case MessageFrameState.Flags: if (buffer[offset] == 32) { throw new BackTrackException("", offset); } Flags = (FrameFlags)buffer[offset]; _state = MessageFrameState.SequenceNumber; ++offset; --bytesTransferred; _receiveBytesLeft = 2; break; case MessageFrameState.SequenceNumber: isBufferCopyCompleted = CopyToReadBuffer(buffer, ref offset, ref bytesTransferred); if (isBufferCopyCompleted) { if (BitConverter.IsLittleEndian) { Array.Reverse(_stateBuffer, 0, 2); } SequenceNumber = BitConverter.ToUInt16(_stateBuffer, 0); _state = MessageFrameState.DestinationLength; } break; case MessageFrameState.DestinationLength: _stateLength = _receiveBytesLeft = buffer[offset]; _state = _stateLength == 0 ? MessageFrameState.FilterLength : MessageFrameState.Destination; ++offset; --bytesTransferred; if (_state == MessageFrameState.FilterLength) { _receiveBytesLeft = 2; } break; case MessageFrameState.Destination: isBufferCopyCompleted = CopyToReadBuffer(buffer, ref offset, ref bytesTransferred); if (isBufferCopyCompleted) { Destination = Encoding.ASCII.GetString(_stateBuffer, 0, _stateLength); _receiveBytesLeft = 2; _state = MessageFrameState.FilterLength; } break; case MessageFrameState.FilterLength: isBufferCopyCompleted = CopyToReadBuffer(buffer, ref offset, ref bytesTransferred); if (isBufferCopyCompleted) { if (BitConverter.IsLittleEndian) { Array.Reverse(_stateBuffer, 0, 2); } _stateLength = _receiveBytesLeft = BitConverter.ToInt16(_stateBuffer, 0); _state = _stateLength == 0 ? MessageFrameState.PayloadLength : MessageFrameState.Filter; if (_state == MessageFrameState.PayloadLength) { _receiveBytesLeft = IsFlaggedAsSmall ? 1 : 4; } } break; case MessageFrameState.Filter: isBufferCopyCompleted = CopyToReadBuffer(buffer, ref offset, ref bytesTransferred); if (isBufferCopyCompleted) { var filters = Encoding.ASCII.GetString(_stateBuffer, 0, _stateLength); DecodeFilters(filters); _state = MessageFrameState.PayloadLength; _receiveBytesLeft = IsFlaggedAsSmall ? 1 : 4; } break; case MessageFrameState.PayloadLength: if (IsFlaggedAsSmall) { _receivePayloadLength = buffer[offset]; _state = MessageFrameState.SmallPayload; _receiveBytesLeft = _receivePayloadLength; ++offset; --bytesTransferred; } else { isBufferCopyCompleted = CopyToReadBuffer(buffer, ref offset, ref bytesTransferred); if (isBufferCopyCompleted) { if (BitConverter.IsLittleEndian) { Array.Reverse(_stateBuffer, 0, 4); } _receivePayloadLength = BitConverter.ToInt32(_stateBuffer, 0); _receiveBytesLeft = _receivePayloadLength; _state = _receivePayloadLength <= BufferLimit ? MessageFrameState.SmallPayload : MessageFrameState.LargePayload; } } if (_state == MessageFrameState.SmallPayload) { if (_internalPayloadBuffer == null || _payloadBuffer.Array.Length < _receivePayloadLength) { _internalPayloadBuffer = new byte[_receivePayloadLength * 2]; } } break; case MessageFrameState.SmallPayload: var bytesToCopy = Math.Min(_receiveBytesLeft, bytesTransferred); Buffer.BlockCopy(buffer, offset, _internalPayloadBuffer, _readOffset, bytesToCopy); _receiveBytesLeft -= bytesToCopy; bytesTransferred -= bytesToCopy; offset += bytesToCopy; if (_receiveBytesLeft == 0) { _payloadBuffer = new ArraySegment <byte>(_internalPayloadBuffer, 0, _receivePayloadLength); allCompleted = true; } else { _readOffset += bytesToCopy; } break; case MessageFrameState.LargePayload: allCompleted = true; break; } } if (offset < 0) { throw new InvalidOperationException(); } return(allCompleted); }