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);
        }
Пример #2
0
        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);
        }