public void ResetRead() { _state = HandshakeFrameState.VersionMajor; _receiveStateBytesLeft = 1; //identity length _receiveBufferOffset = 0; _receiveStateLength = -1; RequiredExtensions = new HandshakeExtension[0]; OptionalExtensions = new HandshakeExtension[0]; Identity = ""; }
/// <summary> /// Process bytes that we've received from the other end point. Might be a partial or complete frame. /// </summary> /// <param name="buffer">Buffer to process</param> /// <param name="offset">Where in buffer to start processing bytes</param> /// <param name="bytesToProcess">Bytes available to process</param> /// <returns> /// Offset where the next serializer should start process (unless the offset is the same as amount of bytes /// transferred) /// </returns> public bool Read(byte[] buffer, ref int offset, ref int bytesToProcess) { var numberOfBytesTransferredFromStart = bytesToProcess; var frameCompleted = false; while (bytesToProcess > 0 && !frameCompleted) { bool isBufferCopyCompleted; switch (_state) { case HandshakeFrameState.VersionMajor: VersionMajor = buffer[offset]; _state = HandshakeFrameState.VersionMinor; ++offset; --bytesToProcess; break; case HandshakeFrameState.VersionMinor: VersionMinor = buffer[offset]; _state = HandshakeFrameState.Flags; ++offset; --bytesToProcess; break; case HandshakeFrameState.Flags: Flags = buffer[offset]; _state = HandshakeFrameState.IdentityLength; _receiveStateBytesLeft = 1; ++offset; --bytesToProcess; break; case HandshakeFrameState.IdentityLength: _receiveStateLength = _receiveStateBytesLeft = buffer[offset]; _state = HandshakeFrameState.Identity; ++offset; --bytesToProcess; break; case HandshakeFrameState.Identity: isBufferCopyCompleted = CopyToBuffer(buffer, ref offset, ref bytesToProcess); if (isBufferCopyCompleted) { Identity = Encoding.ASCII.GetString(_receiveBuffer, 0, _receiveStateLength); _receiveStateBytesLeft = 2; _state = HandshakeFrameState.RequiredLength; } break; case HandshakeFrameState.RequiredLength: isBufferCopyCompleted = CopyToBuffer(buffer, ref offset, ref bytesToProcess); if (isBufferCopyCompleted) { if (BitConverter.IsLittleEndian) Array.Reverse(_receiveBuffer, 0, 2); _receiveStateLength = _receiveStateBytesLeft = BitConverter.ToInt16(_receiveBuffer, 0); if (_receiveStateLength == 0) { _state = HandshakeFrameState.OptionalLength; _receiveStateBytesLeft = 2; } else { _state = HandshakeFrameState.Required; } } break; case HandshakeFrameState.Required: isBufferCopyCompleted = CopyToBuffer(buffer, ref offset, ref bytesToProcess); if (isBufferCopyCompleted) { var values = Encoding.ASCII.GetString(_receiveBuffer, 0, _receiveStateLength).Split(';'); RequiredExtensions = values.Select(HandshakeExtension.Parse).ToArray(); _receiveStateBytesLeft = 2; _state = HandshakeFrameState.OptionalLength; } break; case HandshakeFrameState.OptionalLength: isBufferCopyCompleted = CopyToBuffer(buffer, ref offset, ref bytesToProcess); if (isBufferCopyCompleted) { if (BitConverter.IsLittleEndian) Array.Reverse(_receiveBuffer, 0, 2); _receiveStateLength = _receiveStateBytesLeft = BitConverter.ToInt16(_receiveBuffer, 0); if (_receiveStateLength == 0) frameCompleted = true; else _state = HandshakeFrameState.Optional; } break; case HandshakeFrameState.Optional: isBufferCopyCompleted = CopyToBuffer(buffer, ref offset, ref bytesToProcess); if (isBufferCopyCompleted) { var values = Encoding.ASCII.GetString(_receiveBuffer, 0, _receiveStateLength).Split(';'); OptionalExtensions = values.Select(HandshakeExtension.Parse).ToArray(); frameCompleted = true; } break; } } return frameCompleted; }
/// <summary> /// Process bytes that we've received from the other end point. Might be a partial or complete frame. /// </summary> /// <param name="buffer">Buffer to process</param> /// <param name="offset">Where in buffer to start processing bytes</param> /// <param name="bytesToProcess">Bytes available to process</param> /// <returns> /// Offset where the next serializer should start process (unless the offset is the same as amount of bytes /// transferred) /// </returns> public bool Read(byte[] buffer, ref int offset, ref int bytesToProcess) { var numberOfBytesTransferredFromStart = bytesToProcess; var frameCompleted = false; while (bytesToProcess > 0 && !frameCompleted) { bool isBufferCopyCompleted; switch (_state) { case HandshakeFrameState.VersionMajor: VersionMajor = buffer[offset]; _state = HandshakeFrameState.VersionMinor; ++offset; --bytesToProcess; break; case HandshakeFrameState.VersionMinor: VersionMinor = buffer[offset]; _state = HandshakeFrameState.Flags; ++offset; --bytesToProcess; break; case HandshakeFrameState.Flags: Flags = buffer[offset]; _state = HandshakeFrameState.IdentityLength; _receiveStateBytesLeft = 1; ++offset; --bytesToProcess; break; case HandshakeFrameState.IdentityLength: _receiveStateLength = _receiveStateBytesLeft = buffer[offset]; _state = HandshakeFrameState.Identity; ++offset; --bytesToProcess; break; case HandshakeFrameState.Identity: isBufferCopyCompleted = CopyToBuffer(buffer, ref offset, ref bytesToProcess); if (isBufferCopyCompleted) { Identity = Encoding.ASCII.GetString(_receiveBuffer, 0, _receiveStateLength); _receiveStateBytesLeft = 2; _state = HandshakeFrameState.RequiredLength; } break; case HandshakeFrameState.RequiredLength: isBufferCopyCompleted = CopyToBuffer(buffer, ref offset, ref bytesToProcess); if (isBufferCopyCompleted) { if (BitConverter.IsLittleEndian) { Array.Reverse(_receiveBuffer, 0, 2); } _receiveStateLength = _receiveStateBytesLeft = BitConverter.ToInt16(_receiveBuffer, 0); if (_receiveStateLength == 0) { _state = HandshakeFrameState.OptionalLength; _receiveStateBytesLeft = 2; } else { _state = HandshakeFrameState.Required; } } break; case HandshakeFrameState.Required: isBufferCopyCompleted = CopyToBuffer(buffer, ref offset, ref bytesToProcess); if (isBufferCopyCompleted) { var values = Encoding.ASCII.GetString(_receiveBuffer, 0, _receiveStateLength).Split(';'); RequiredExtensions = values.Select(HandshakeExtension.Parse).ToArray(); _receiveStateBytesLeft = 2; _state = HandshakeFrameState.OptionalLength; } break; case HandshakeFrameState.OptionalLength: isBufferCopyCompleted = CopyToBuffer(buffer, ref offset, ref bytesToProcess); if (isBufferCopyCompleted) { if (BitConverter.IsLittleEndian) { Array.Reverse(_receiveBuffer, 0, 2); } _receiveStateLength = _receiveStateBytesLeft = BitConverter.ToInt16(_receiveBuffer, 0); if (_receiveStateLength == 0) { frameCompleted = true; } else { _state = HandshakeFrameState.Optional; } } break; case HandshakeFrameState.Optional: isBufferCopyCompleted = CopyToBuffer(buffer, ref offset, ref bytesToProcess); if (isBufferCopyCompleted) { var values = Encoding.ASCII.GetString(_receiveBuffer, 0, _receiveStateLength).Split(';'); OptionalExtensions = values.Select(HandshakeExtension.Parse).ToArray(); frameCompleted = true; } break; } } return(frameCompleted); }