private int WriteByte(byte[] buffer, int offset, WriteBuffer writeBuffer) { // The body of this method should rather be inlined where it is called, but doing so seems to cause a huge // (>5x) perf hit. var currentByte = buffer[offset]; if (this.previousWasEscapeByte) { this.previousWasEscapeByte = false; this.crc = Crc.AddCrcCcitt(this.crc, currentByte); currentByte = (byte)(currentByte ^ Frame.EscapeXor); ++offset; } else { if (currentByte < Frame.InvalidStart) { this.crc = Crc.AddCrcCcitt(this.crc, currentByte); ++offset; } else { currentByte = Frame.EscapeByte; this.previousWasEscapeByte = true; } } writeBuffer[writeBuffer.Count++] = currentByte; return(offset); }
private bool ReadByte(ReadBuffer readBuffer) { var currentByte = readBuffer[readBuffer.Index++]; switch (this.state) { case State.BeforeFrame: if (currentByte == Frame.BeginOfFrame) { this.state = State.InFrame; } else { this.outOfFrameByteReceived(currentByte); } break; case State.InFrame: if (currentByte < Frame.InvalidStart) { this.crc = Crc.AddCrcCcitt(this.crc, currentByte); this.decodedQueue.Enqueue(currentByte); } else { switch (currentByte) { case Frame.EscapeByte: this.state = State.InFrameEscaped; break; case Frame.BeginOfFrame: this.decodedQueue.Clear(); this.crc = 0xFFFF; break; case Frame.EndOfFrame: this.state = State.AfterFrame; if (this.crc != 0xF0B8) { this.decodedQueue.Clear(); } return(false); default: this.state = State.AfterFrame; this.decodedQueue.Clear(); break; } } break; case State.InFrameEscaped: if (currentByte >= Frame.InvalidStart) { this.state = State.AfterFrame; this.decodedQueue.Clear(); } currentByte = (byte)(currentByte ^ Frame.EscapeXor); this.crc = Crc.AddCrcCcitt(this.crc, currentByte); this.decodedQueue.Enqueue(currentByte); this.state = State.InFrame; break; } return(true); }